2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
22 * AbstractAttributeExtensibleXMLObject.cpp
24 * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject.
28 #include "AbstractAttributeExtensibleXMLObject.h"
29 #include "ElementExtensibleXMLObject.h"
30 #include "ElementProxy.h"
34 #include <boost/lambda/bind.hpp>
35 #include <boost/lambda/lambda.hpp>
36 #include <xercesc/util/XMLUniDefs.hpp>
38 using namespace xmltooling;
39 using namespace xercesc;
40 using namespace boost::lambda;
41 using namespace boost;
45 ElementExtensibleXMLObject::ElementExtensibleXMLObject()
49 ElementExtensibleXMLObject::~ElementExtensibleXMLObject()
53 ElementProxy::ElementProxy()
57 ElementProxy::~ElementProxy()
61 set<xmltooling::QName> AttributeExtensibleXMLObject::m_idAttributeSet;
63 AttributeExtensibleXMLObject::AttributeExtensibleXMLObject()
67 AttributeExtensibleXMLObject::~AttributeExtensibleXMLObject()
71 const set<xmltooling::QName>& AttributeExtensibleXMLObject::getRegisteredIDAttributes()
73 return m_idAttributeSet;
76 bool AttributeExtensibleXMLObject::isRegisteredIDAttribute(const xmltooling::QName& name)
78 return m_idAttributeSet.find(name)!=m_idAttributeSet.end();
81 void AttributeExtensibleXMLObject::registerIDAttribute(const xmltooling::QName& name)
83 m_idAttributeSet.insert(name);
86 void AttributeExtensibleXMLObject::deregisterIDAttribute(const xmltooling::QName& name)
88 m_idAttributeSet.erase(name);
91 void AttributeExtensibleXMLObject::deregisterIDAttributes()
93 m_idAttributeSet.clear();
96 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject()
98 m_idAttribute = m_attributeMap.end();
101 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)
102 : AbstractXMLObject(src)
104 m_idAttribute = m_attributeMap.end();
105 for (map<xmltooling::QName,XMLCh*>::const_iterator i = src.m_attributeMap.begin(); i != src.m_attributeMap.end(); ++i) {
106 m_attributeMap[i->first] = XMLString::replicate(i->second);
108 if (src.m_idAttribute != src.m_attributeMap.end()) {
109 m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);
113 AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()
115 #ifdef XMLTOOLING_XERCESC_HAS_XMLBYTE_RELEASE
116 static void (*release)(XMLCh**) = &XMLString::release;
118 static void (*release)(XMLCh**,MemoryManager*) = &XMLString::release;
121 m_attributeMap.begin(), m_attributeMap.end(),
124 &lambda::bind(&map<xmltooling::QName,XMLCh*>::value_type::second, boost::ref(_1))
125 #ifndef XMLTOOLING_XERCESC_HAS_XMLBYTE_RELEASE
126 ,XMLPlatformUtils::fgMemoryManager
132 const XMLCh* AbstractAttributeExtensibleXMLObject::getAttribute(const xmltooling::QName& qualifiedName) const
134 map<xmltooling::QName,XMLCh*>::const_iterator i = m_attributeMap.find(qualifiedName);
135 return (i != m_attributeMap.end()) ? i->second : nullptr;
138 const XMLCh* AbstractAttributeExtensibleXMLObject::getLang() const
140 static const XMLCh _lang[] = UNICODE_LITERAL_4(l,a,n,g);
141 static xmltooling::QName qname(xmlconstants::XML_NS, _lang);
142 return getAttribute(qname);
145 void AbstractAttributeExtensibleXMLObject::setAttribute(const xmltooling::QName& qualifiedName, const XMLCh* value, bool ID)
147 map<xmltooling::QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);
148 if (i != m_attributeMap.end()) {
149 releaseThisandParentDOM();
150 XMLString::release(&(i->second));
151 if (value && *value) {
152 i->second = XMLString::replicate(value);
157 if (m_idAttribute == i)
158 m_idAttribute = m_attributeMap.end();
159 m_attributeMap.erase(i);
162 else if (value && *value) {
163 releaseThisandParentDOM();
164 m_attributeMap[qualifiedName] = XMLString::replicate(value);
166 m_idAttribute = m_attributeMap.find(qualifiedName);
167 Namespace newNamespace(qualifiedName.getNamespaceURI(), qualifiedName.getPrefix(), false, Namespace::VisiblyUsed);
168 addNamespace(newNamespace);
172 void AttributeExtensibleXMLObject::setAttribute(const xmltooling::QName& qualifiedName, const xmltooling::QName& value)
174 if (!value.hasLocalPart())
177 if (value.hasPrefix()) {
178 xstring buf(value.getPrefix());
179 buf = buf + chColon + value.getLocalPart();
180 setAttribute(qualifiedName, buf.c_str());
183 setAttribute(qualifiedName, value.getLocalPart());
186 Namespace newNamespace(value.getNamespaceURI(), value.getPrefix(), false, Namespace::NonVisiblyUsed);
187 addNamespace(newNamespace);
190 const map<xmltooling::QName,XMLCh*>& AbstractAttributeExtensibleXMLObject::getExtensionAttributes() const
192 return m_attributeMap;
194 const XMLCh* AbstractAttributeExtensibleXMLObject::getXMLID() const
196 return (m_idAttribute != m_attributeMap.end()) ? m_idAttribute->second : nullptr;
199 void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)
201 xmltooling::QName q(attribute->getNamespaceURI(), attribute->getLocalName(), attribute->getPrefix());
202 bool ID = attribute->isId() || isRegisteredIDAttribute(q);
203 setAttribute(q,attribute->getNodeValue(),ID);
205 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
206 attribute->getOwnerElement()->setIdAttributeNode(attribute, true);
208 attribute->getOwnerElement()->setIdAttributeNode(attribute);
213 void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const
215 for (map<xmltooling::QName,XMLCh*>::const_iterator i = m_attributeMap.begin(); i != m_attributeMap.end(); ++i) {
216 DOMAttr* attr = domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(), i->first.getLocalPart());
217 if (i->first.hasPrefix())
218 attr->setPrefix(i->first.getPrefix());
219 attr->setNodeValue(i->second);
220 domElement->setAttributeNodeNS(attr);
221 if (m_idAttribute == i) {
222 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
223 domElement->setIdAttributeNode(attr, true);
225 domElement->setIdAttributeNode(attr);