a4677415be8dd0c65306ddfb56fd0fdf3b692bf6
[shibboleth/cpp-xmltooling.git] / xmltooling / impl / AnyElement.cpp
1 /*
2  *  Copyright 2001-2006 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  * @file AnyElement.h
19  * 
20  * Advanced anyType implementation suitable for deep processing of unknown content.
21  */
22
23 #include "internal.h"
24 #include "AbstractAttributeExtensibleXMLObject.h"
25 #include "AbstractElementProxy.h"
26 #include "exceptions.h"
27 #include "impl/AnyElement.h"
28 #include "io/AbstractXMLObjectMarshaller.h"
29 #include "io/AbstractXMLObjectUnmarshaller.h"
30 #include "util/NDC.h"
31 #include "util/XMLHelper.h"
32
33 #include <log4cpp/Category.hh>
34 #include <xercesc/util/XMLUniDefs.hpp>
35
36 using namespace xmltooling;
37 using namespace log4cpp;
38 using namespace std;
39
40 #if defined (_MSC_VER)
41     #pragma warning( push )
42     #pragma warning( disable : 4250 4251 )
43 #endif
44
45 namespace xmltooling {
46
47     /**
48      * Implements a smart wrapper around unknown DOM content.
49      */
50     class XMLTOOL_DLLLOCAL AnyElementImpl : public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject,
51         public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller
52     {
53     public:
54         AnyElementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix)
55             : AbstractXMLObject(nsURI, localName, prefix) {}
56         virtual ~AnyElementImpl() {}
57         
58         AnyElementImpl* clone() const {
59             auto_ptr<XMLObject> domClone(AbstractDOMCachingXMLObject::clone());
60             AnyElementImpl* ret=dynamic_cast<AnyElementImpl*>(domClone.get());
61             if (ret) {
62                 domClone.release();
63                 return ret;
64             }
65
66             ret=new AnyElementImpl(
67                 getElementQName().getNamespaceURI(),getElementQName().getLocalPart(),getElementQName().getPrefix()
68                 );
69             ret->m_namespaces=m_namespaces;
70             for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
71                 ret->m_attributeMap[i->first]=XMLString::replicate(i->second);
72             }
73             ret->setTextContent(getTextContent());
74             xmltooling::clone(m_children, ret->m_children);
75             return ret;
76         }
77
78         void marshallAttributes(DOMElement* domElement) const {
79             for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
80                 DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
81                 if (i->first.hasPrefix())
82                     attr->setPrefix(i->first.getPrefix());
83                 attr->setNodeValue(i->second);
84                 domElement->setAttributeNode(attr);
85             }
86         }
87
88         void marshallElementContent(DOMElement* domElement) const {
89             if(getTextContent()) {
90                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
91             }
92         }
93
94         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
95             getXMLObjects().push_back(childXMLObject);
96         }
97
98         void processAttribute(const DOMAttr* attribute) {
99             QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix()); 
100             setAttribute(q,attribute->getNodeValue());
101         }
102
103         void processElementContent(const XMLCh* elementContent) {
104             setTextContent(elementContent);
105         }
106     };
107
108 };
109
110 #if defined (_MSC_VER)
111     #pragma warning( pop )
112 #endif
113
114
115 XMLObject* AnyElementBuilder::buildObject(
116     const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix
117     ) const {
118     return new AnyElementImpl(namespaceURI,elementLocalName,namespacePrefix);
119 }