Moved DOM methods up the tree, add copy c'tors, KeyInfo sample
[shibboleth/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  * AnyElement.cpp
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 AbstractDOMCachingXMLObject,
51         public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject,
52         public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller
53     {
54     public:
55         virtual ~AnyElementImpl() {}
56
57         AnyElementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix)
58             : AbstractXMLObject(nsURI, localName, prefix) {}
59         
60         AnyElementImpl* clone() const {
61             auto_ptr<XMLObject> domClone(AbstractDOMCachingXMLObject::clone());
62             AnyElementImpl* ret=dynamic_cast<AnyElementImpl*>(domClone.get());
63             if (ret) {
64                 domClone.release();
65                 return ret;
66             }
67
68             return new AnyElementImpl(*this);
69         }
70
71     protected:
72         AnyElementImpl(const AnyElementImpl& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src),
73             AbstractElementProxy(src), AbstractAttributeExtensibleXMLObject(src) {
74             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
75                 getXMLObjects().push_back((*i) ? (*i)->clone() : NULL);
76             }
77         }       
78         
79         void marshallAttributes(DOMElement* domElement) const {
80             for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
81                 DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
82                 if (i->first.hasPrefix())
83                     attr->setPrefix(i->first.getPrefix());
84                 attr->setNodeValue(i->second);
85                 domElement->setAttributeNode(attr);
86             }
87         }
88
89         void marshallElementContent(DOMElement* domElement) const {
90             if(getTextContent()) {
91                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
92             }
93         }
94
95         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
96             getXMLObjects().push_back(childXMLObject);
97         }
98
99         void processAttribute(const DOMAttr* attribute) {
100             QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix()); 
101             setAttribute(q,attribute->getNodeValue());
102         }
103
104         void processElementContent(const XMLCh* elementContent) {
105             setTextContent(elementContent);
106         }
107     };
108
109 };
110
111 #if defined (_MSC_VER)
112     #pragma warning( pop )
113 #endif
114
115
116 XMLObject* AnyElementBuilder::buildObject(
117     const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix
118     ) const {
119     return new AnyElementImpl(namespaceURI,elementLocalName,namespacePrefix);
120 }