Fix mistake in version-info. Age wasn't supposed to be incremented.
[shibboleth/cpp-sp.git] / shib / ScopedAttribute.cpp
1 /*
2  *  Copyright 2001-2005 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* ScopedAttribute.cpp - eduPerson scoped attribute base class
18
19    Scott Cantor
20    6/4/02
21
22    $History:$
23 */
24
25 #include "internal.h"
26 #include <xercesc/util/regx/RegularExpression.hpp>
27
28 using namespace shibboleth::logging;
29 using namespace shibboleth;
30 using namespace saml;
31 using namespace std;
32
33 const XMLCh ScopedAttribute::Scope[] = { chLatin_S, chLatin_c, chLatin_o, chLatin_p, chLatin_e, chNull };
34
35 ScopedAttribute::ScopedAttribute(
36     const XMLCh* name,
37     const XMLCh* ns,
38     const saml::QName* type,
39     long lifetime,
40     const saml::Iterator<const XMLCh*>& scopes,
41     const saml::Iterator<const XMLCh*>& values
42     ) : SAMLAttribute(name,ns,type,lifetime,values)
43 {
44     RTTI(ScopedAttribute);
45     if (scopes.size()!=values.size())
46         throw MalformedException("ScopedAttribute() requires the number of scopes to equal the number of values");
47
48     while (scopes.hasNext())
49         m_scopes.push_back(saml::XML::assign(scopes.next()));
50 }
51
52 ScopedAttribute::ScopedAttribute(DOMElement* e) : SAMLAttribute(e,false)
53 {
54     RTTI(ScopedAttribute);
55     fromDOM(e);
56 }
57
58 ScopedAttribute::ScopedAttribute(istream& in) : SAMLAttribute(in,false)
59 {
60     RTTI(ScopedAttribute);
61     fromDOM(m_document->getDocumentElement());
62 }
63
64 ScopedAttribute::~ScopedAttribute()
65 {
66     if (m_bOwnStrings) {
67         for (vector<const XMLCh*>::iterator i=m_scopes.begin(); i!=m_scopes.end(); i++) {
68             XMLCh* p = const_cast<XMLCh*>(*i);
69             XMLString::release(&p);
70         }
71     }
72
73     // We always own any scoped values we've built.
74     for (vector<const XMLCh*>::iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++) {
75         XMLCh* p = const_cast<XMLCh*>(*i);
76         XMLString::release(&p);
77     }
78 }
79
80 void ScopedAttribute::ownStrings()
81 {
82     if (!m_bOwnStrings) {
83         for (vector<const XMLCh*>::iterator i=m_scopes.begin(); i!=m_scopes.end(); i++)
84             (*i)=saml::XML::assign(*i);
85         SAMLAttribute::ownStrings();
86     }
87 }
88
89 Iterator<const XMLCh*> ScopedAttribute::getValues() const
90 {
91     static XMLCh at[]={chAt, chNull};
92
93     if (m_scopedValues.empty()) {
94         vector<const XMLCh*>::const_iterator j=m_scopes.begin();
95         for (vector<const XMLCh*>::const_iterator i=m_values.begin(); i!=m_values.end(); i++, j++) {
96             XMLCh* temp=new XMLCh[XMLString::stringLen(*i) + XMLString::stringLen(*j) + 2];
97             temp[0]=chNull;
98             XMLString::catString(temp,*i);
99             XMLString::catString(temp,at);
100             XMLString::catString(temp,*j);
101             m_scopedValues.push_back(temp);
102         }
103     }
104     return m_scopedValues;
105 }
106
107 Iterator<string> ScopedAttribute::getSingleByteValues() const
108 {
109     getValues();
110     if (m_sbValues.empty()) {
111         for (vector<const XMLCh*>::const_iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++) {
112             auto_ptr<char> temp(toUTF8(*i));
113             if (temp.get())
114                 m_sbValues.push_back(temp.get());
115         }
116     }
117     return m_sbValues;
118 }
119
120 void ScopedAttribute::setValues(const Iterator<const XMLCh*>& values)
121 {
122     throw SAMLException("unsupported operation");
123 }
124
125 void ScopedAttribute::addValue(const XMLCh* value)
126 {
127     throw SAMLException("unsupported operation");
128 }
129
130 void ScopedAttribute::removeValue(unsigned long index)
131 {
132     if (m_bOwnStrings) {
133         XMLCh* p=const_cast<XMLCh*>(m_scopes[index]);
134         XMLString::release(&p);
135     }
136     m_scopes.erase(m_scopes.begin()+index);
137     
138     if (!m_scopedValues.empty()) {
139         XMLCh* p=const_cast<XMLCh*>(m_scopedValues[index]);
140         XMLString::release(&p);
141         m_scopedValues.erase(m_scopedValues.begin()+index);
142     }
143
144     SAMLAttribute::removeValue(index);
145 }
146
147 void ScopedAttribute::valueFromDOM(DOMElement* e)
148 {
149     SAMLAttribute::valueFromDOM(e);
150     m_scopes.push_back(e->getAttributeNS(NULL,Scope));
151 }
152
153 void ScopedAttribute::valueToDOM(unsigned int index, DOMElement* e) const
154 {
155     SAMLAttribute::valueToDOM(index,e);
156     const XMLCh* scope=m_scopes[index];
157     if (!saml::XML::isEmpty(scope))
158         e->setAttributeNS(NULL,Scope,m_scopes[index]);
159 }
160
161 SAMLObject* ScopedAttribute::clone() const
162 {
163     return new ScopedAttribute(m_name,m_namespace,m_type,m_lifetime,m_scopes,m_values);
164 }