2 * Copyright 2001-2010 Internet2
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * AbstractAttributeExtensibleXMLObject.cpp
20 * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject.
24 #include "AbstractAttributeExtensibleXMLObject.h"
25 #include "ElementExtensibleXMLObject.h"
26 #include "ElementProxy.h"
30 #include <xercesc/util/XMLUniDefs.hpp>
32 using namespace xmltooling;
34 using xercesc::chColon;
36 using xercesc::DOMAttr;
37 using xercesc::DOMElement;
38 using xercesc::XMLString;
40 ElementExtensibleXMLObject::ElementExtensibleXMLObject()
44 ElementExtensibleXMLObject::~ElementExtensibleXMLObject()
48 ElementProxy::ElementProxy()
52 ElementProxy::~ElementProxy()
56 set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;
58 AttributeExtensibleXMLObject::AttributeExtensibleXMLObject()
62 AttributeExtensibleXMLObject::~AttributeExtensibleXMLObject()
66 const set<QName>& AttributeExtensibleXMLObject::getRegisteredIDAttributes()
68 return m_idAttributeSet;
71 bool AttributeExtensibleXMLObject::isRegisteredIDAttribute(const QName& name)
73 return m_idAttributeSet.find(name)!=m_idAttributeSet.end();
76 void AttributeExtensibleXMLObject::registerIDAttribute(const QName& name)
78 m_idAttributeSet.insert(name);
81 void AttributeExtensibleXMLObject::deregisterIDAttribute(const QName& name)
83 m_idAttributeSet.erase(name);
86 void AttributeExtensibleXMLObject::deregisterIDAttributes()
88 m_idAttributeSet.clear();
91 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject()
93 m_idAttribute = m_attributeMap.end();
96 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)
97 : AbstractXMLObject(src)
99 m_idAttribute = m_attributeMap.end();
100 for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {
101 m_attributeMap[i->first] = XMLString::replicate(i->second);
103 if (src.m_idAttribute != src.m_attributeMap.end()) {
104 m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);
108 AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()
110 for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)
111 XMLString::release(&(i->second));
114 const XMLCh* AbstractAttributeExtensibleXMLObject::getAttribute(const QName& qualifiedName) const
116 map<QName,XMLCh*>::const_iterator i=m_attributeMap.find(qualifiedName);
117 return (i==m_attributeMap.end()) ? nullptr : i->second;
120 void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)
122 map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);
123 if (i!=m_attributeMap.end()) {
124 releaseThisandParentDOM();
125 XMLString::release(&(i->second));
126 if (value && *value) {
127 i->second=XMLString::replicate(value);
132 if (m_idAttribute==i)
133 m_idAttribute=m_attributeMap.end();
134 m_attributeMap.erase(i);
137 else if (value && *value) {
138 releaseThisandParentDOM();
139 m_attributeMap[qualifiedName]=XMLString::replicate(value);
141 m_idAttribute = m_attributeMap.find(qualifiedName);
142 Namespace newNamespace(qualifiedName.getNamespaceURI(), qualifiedName.getPrefix(), false, Namespace::VisiblyUsed);
143 addNamespace(newNamespace);
147 void AttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const QName& value)
149 if (!value.hasLocalPart())
152 if (value.hasPrefix()) {
153 xstring buf(value.getPrefix());
154 buf = buf + chColon + value.getLocalPart();
155 setAttribute(qualifiedName, buf.c_str());
158 setAttribute(qualifiedName, value.getLocalPart());
161 Namespace newNamespace(value.getNamespaceURI(), value.getPrefix(), false, Namespace::NonVisiblyUsed);
162 addNamespace(newNamespace);
165 const map<QName,XMLCh*>& AbstractAttributeExtensibleXMLObject::getExtensionAttributes() const
167 return m_attributeMap;
169 const XMLCh* AbstractAttributeExtensibleXMLObject::getXMLID() const
171 return (m_idAttribute == m_attributeMap.end()) ? nullptr : m_idAttribute->second;
174 void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)
176 QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());
177 bool ID = attribute->isId() || isRegisteredIDAttribute(q);
178 setAttribute(q,attribute->getNodeValue(),ID);
180 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
181 attribute->getOwnerElement()->setIdAttributeNode(attribute, true);
183 attribute->getOwnerElement()->setIdAttributeNode(attribute);
188 void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const
190 for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
191 DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
192 if (i->first.hasPrefix())
193 attr->setPrefix(i->first.getPrefix());
194 attr->setNodeValue(i->second);
195 domElement->setAttributeNodeNS(attr);
196 if (m_idAttribute==i) {
197 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
198 domElement->setIdAttributeNode(attr, true);
200 domElement->setIdAttributeNode(attr);