ff13baaff59d78d63d3b4978e7b702b9f505eb1e
[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 #include <log4cpp/Category.hh>
28
29 using namespace shibboleth;
30 using namespace saml;
31 using namespace log4cpp;
32 using namespace std;
33
34 const XMLCh ScopedAttribute::Scope[] = { chLatin_S, chLatin_c, chLatin_o, chLatin_p, chLatin_e, chNull };
35
36 ScopedAttribute::ScopedAttribute(
37     const XMLCh* name,
38     const XMLCh* ns,
39     const saml::QName* type,
40     long lifetime,
41     const saml::Iterator<const XMLCh*>& scopes,
42     const saml::Iterator<const XMLCh*>& values
43     ) : SAMLAttribute(name,ns,type,lifetime,values)
44 {
45     RTTI(ScopedAttribute);
46     if (scopes.size()!=values.size())
47         throw MalformedException("ScopedAttribute() requires the number of scopes to equal the number of values");
48
49     while (scopes.hasNext())
50         m_scopes.push_back(saml::XML::assign(scopes.next()));
51 }
52
53 ScopedAttribute::ScopedAttribute(DOMElement* e) : SAMLAttribute(e,false)
54 {
55     RTTI(ScopedAttribute);
56     fromDOM(e);
57 }
58
59 ScopedAttribute::ScopedAttribute(istream& in) : SAMLAttribute(in,false)
60 {
61     RTTI(ScopedAttribute);
62     fromDOM(m_document->getDocumentElement());
63 }
64
65 ScopedAttribute::~ScopedAttribute()
66 {
67     if (m_bOwnStrings) {
68         for (vector<const XMLCh*>::iterator i=m_scopes.begin(); i!=m_scopes.end(); i++) {
69             XMLCh* p = const_cast<XMLCh*>(*i);
70             XMLString::release(&p);
71         }
72     }
73
74     // We always own any scoped values we've built.
75     for (vector<const XMLCh*>::iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++) {
76         XMLCh* p = const_cast<XMLCh*>(*i);
77         XMLString::release(&p);
78     }
79 }
80
81 void ScopedAttribute::ownStrings()
82 {
83     if (!m_bOwnStrings) {
84         for (vector<const XMLCh*>::iterator i=m_scopes.begin(); i!=m_scopes.end(); i++)
85             (*i)=saml::XML::assign(*i);
86         SAMLAttribute::ownStrings();
87     }
88 }
89
90 Iterator<const XMLCh*> ScopedAttribute::getValues() const
91 {
92     static XMLCh at[]={chAt, chNull};
93
94     if (m_scopedValues.empty()) {
95         vector<const XMLCh*>::const_iterator j=m_scopes.begin();
96         for (vector<const XMLCh*>::const_iterator i=m_values.begin(); i!=m_values.end(); i++, j++) {
97             XMLCh* temp=new XMLCh[XMLString::stringLen(*i) + XMLString::stringLen(*j) + 2];
98             temp[0]=chNull;
99             XMLString::catString(temp,*i);
100             XMLString::catString(temp,at);
101             XMLString::catString(temp,*j);
102             m_scopedValues.push_back(temp);
103         }
104     }
105     return m_scopedValues;
106 }
107
108 Iterator<string> ScopedAttribute::getSingleByteValues() const
109 {
110     getValues();
111     if (m_sbValues.empty()) {
112         for (vector<const XMLCh*>::const_iterator i=m_scopedValues.begin(); i!=m_scopedValues.end(); i++) {
113             auto_ptr<char> temp(toUTF8(*i));
114             if (temp.get())
115                 m_sbValues.push_back(temp.get());
116         }
117     }
118     return m_sbValues;
119 }
120
121 void ScopedAttribute::setValues(const Iterator<const XMLCh*>& values)
122 {
123     throw SAMLException("unsupported operation");
124 }
125
126 void ScopedAttribute::addValue(const XMLCh* value)
127 {
128     throw SAMLException("unsupported operation");
129 }
130
131 void ScopedAttribute::removeValue(unsigned long index)
132 {
133     if (m_bOwnStrings) {
134         XMLCh* p=const_cast<XMLCh*>(m_scopes[index]);
135         XMLString::release(&p);
136     }
137     m_scopes.erase(m_scopes.begin()+index);
138     
139     if (!m_scopedValues.empty()) {
140         XMLCh* p=const_cast<XMLCh*>(m_scopedValues[index]);
141         XMLString::release(&p);
142         m_scopedValues.erase(m_scopedValues.begin()+index);
143     }
144
145     SAMLAttribute::removeValue(index);
146 }
147
148 void ScopedAttribute::valueFromDOM(DOMElement* e)
149 {
150     SAMLAttribute::valueFromDOM(e);
151     m_scopes.push_back(e->getAttributeNS(NULL,Scope));
152 }
153
154 void ScopedAttribute::valueToDOM(unsigned int index, DOMElement* e) const
155 {
156     SAMLAttribute::valueToDOM(index,e);
157     const XMLCh* scope=m_scopes[index];
158     if (!saml::XML::isEmpty(scope))
159         e->setAttributeNS(NULL,Scope,m_scopes[index]);
160 }
161
162 SAMLObject* ScopedAttribute::clone() const
163 {
164     return new ScopedAttribute(m_name,m_namespace,m_type,m_lifetime,m_scopes,m_values);
165 }