Update copyright.
[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) {
59             i->second=XMLString::replicate(value);
60         }
61         else {
62             if (m_idAttribute==i)
63                 m_idAttribute=m_attributeMap.end();
64             m_attributeMap.erase(i);
65         }
66         
67         if (ID) {
68             m_idAttribute=i;
69         }
70     }
71     else if (value) {
72         releaseThisandParentDOM();
73         m_attributeMap[qualifiedName]=XMLString::replicate(value);
74         if (ID) {
75             m_idAttribute = m_attributeMap.find(qualifiedName);
76         } 
77     }
78 }
79
80 void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)
81 {
82     QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());
83     bool ID = attribute->isId() || isRegisteredIDAttribute(q);
84     setAttribute(q,attribute->getNodeValue(),ID);
85     if (ID) {
86         attribute->getOwnerElement()->setIdAttributeNode(attribute);
87     }
88 }
89
90 void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const
91 {
92     for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
93         DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
94         if (i->first.hasPrefix())
95             attr->setPrefix(i->first.getPrefix());
96         attr->setNodeValue(i->second);
97         domElement->setAttributeNodeNS(attr);
98         if (m_idAttribute==i)
99             domElement->setIdAttributeNode(attr);
100     }
101 }