Handle IDness during (un)marshalling, move more work to base class.
[shibboleth/cpp-xmltooling.git] / xmltooling / AbstractAttributeExtensibleXMLObject.cpp
1 /*\r
2  *  Copyright 2001-2006 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * AbstractAttributeExtensibleXMLObject.cpp\r
19  * \r
20  * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject. \r
21  */\r
22 \r
23 #include "internal.h"\r
24 #include "AbstractAttributeExtensibleXMLObject.h"\r
25 \r
26 #include <algorithm>\r
27 #include <functional>\r
28 \r
29 using namespace xmltooling;\r
30 using namespace std;\r
31 \r
32 set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;\r
33 \r
34 AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()\r
35 {\r
36     for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)\r
37         XMLString::release(&(i->second));\r
38 }\r
39 \r
40 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)\r
41     : AbstractXMLObject(src)\r
42 {\r
43     m_idAttribute = m_attributeMap.end();\r
44     for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {\r
45         m_attributeMap[i->first] = XMLString::replicate(i->second);\r
46     }\r
47     if (src.m_idAttribute != src.m_attributeMap.end()) {\r
48         m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);\r
49     }\r
50 }\r
51 \r
52 void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)\r
53 {\r
54     map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);\r
55     if (i!=m_attributeMap.end()) {\r
56         releaseThisandParentDOM();\r
57         XMLString::release(&(i->second));\r
58         if (value) {\r
59             i->second=XMLString::replicate(value);\r
60         }\r
61         else {\r
62             if (m_idAttribute==i)\r
63                 m_idAttribute=m_attributeMap.end();\r
64             m_attributeMap.erase(i);\r
65         }\r
66         \r
67         if (ID) {\r
68             m_idAttribute=i;\r
69         }\r
70     }\r
71     else if (value) {\r
72         releaseThisandParentDOM();\r
73         m_attributeMap[qualifiedName]=XMLString::replicate(value);\r
74         if (ID) {\r
75             m_idAttribute = m_attributeMap.find(qualifiedName);\r
76         } \r
77     }\r
78 }\r
79 \r
80 void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)\r
81 {\r
82     QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());\r
83     bool ID = isRegisteredIDAttribute(q); \r
84     setAttribute(q,attribute->getNodeValue(),ID);\r
85     if (ID) {\r
86         attribute->getOwnerElement()->setIdAttributeNode(attribute);\r
87     }\r
88 }\r
89 \r
90 void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const\r
91 {\r
92     for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {\r
93         DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());\r
94         if (i->first.hasPrefix())\r
95             attr->setPrefix(i->first.getPrefix());\r
96         attr->setNodeValue(i->second);\r
97         domElement->setAttributeNode(attr);\r
98         if (m_idAttribute==i)\r
99             domElement->setIdAttributeNode(attr);\r
100     }\r
101 }\r