2efde222d45a4f5ab2b2e488d30b53b1951a0274
[shibboleth/cpp-xmltooling.git] / xmltooling / AbstractAttributeExtensibleXMLObject.cpp
1 /*
2  *  Copyright 2001-2007 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 /**
18  * AbstractAttributeExtensibleXMLObject.cpp
19  * 
20  * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject. 
21  */
22
23 #include "internal.h"
24 #include "AbstractAttributeExtensibleXMLObject.h"
25
26 #include <algorithm>
27 #include <functional>
28
29 using namespace xmltooling;
30 using namespace std;
31
32 set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;
33
34 AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()
35 {
36     for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)
37         XMLString::release(&(i->second));
38 }
39
40 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)
41     : AbstractXMLObject(src)
42 {
43     m_idAttribute = m_attributeMap.end();
44     for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {
45         m_attributeMap[i->first] = XMLString::replicate(i->second);
46     }
47     if (src.m_idAttribute != src.m_attributeMap.end()) {
48         m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);
49     }
50 }
51
52 void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)
53 {
54     map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);
55     if (i!=m_attributeMap.end()) {
56         releaseThisandParentDOM();
57         XMLString::release(&(i->second));
58         if (value && *value) {
59             i->second=XMLString::replicate(value);
60             if (ID)
61                 m_idAttribute=i;
62         }
63         else {
64             if (m_idAttribute==i)
65                 m_idAttribute=m_attributeMap.end();
66             m_attributeMap.erase(i);
67         }
68     }
69     else if (value && *value) {
70         releaseThisandParentDOM();
71         m_attributeMap[qualifiedName]=XMLString::replicate(value);
72         if (ID)
73             m_idAttribute = m_attributeMap.find(qualifiedName);
74     }
75 }
76
77 void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)
78 {
79     QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());
80     bool ID = attribute->isId() || isRegisteredIDAttribute(q);
81     setAttribute(q,attribute->getNodeValue(),ID);
82     if (ID) {
83         attribute->getOwnerElement()->setIdAttributeNode(attribute);
84     }
85 }
86
87 void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const
88 {
89     for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
90         DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
91         if (i->first.hasPrefix())
92             attr->setPrefix(i->first.getPrefix());
93         attr->setNodeValue(i->second);
94         domElement->setAttributeNodeNS(attr);
95         if (m_idAttribute==i)
96             domElement->setIdAttributeNode(attr);
97     }
98 }