Set fourth file version digit to signify rebuild.
[shibboleth/cpp-xmltooling.git] / xmltoolingtest / XMLObjectBaseTestCase.h
1 /**
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.
6  *
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
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  */
20
21 #include <cxxtest/TestSuite.h>
22 #include <xmltooling/AbstractAttributeExtensibleXMLObject.h>
23 #include <xmltooling/AbstractComplexElement.h>
24 #include <xmltooling/ElementProxy.h>
25 #include <xmltooling/exceptions.h>
26 #include <xmltooling/XMLObjectBuilder.h>
27 #include <xmltooling/XMLToolingConfig.h>
28 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
29 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
30 #include <xmltooling/impl/AnyElement.h>
31 #include <xmltooling/impl/UnknownElement.h>
32 #include <xmltooling/util/ParserPool.h>
33 #include <xmltooling/util/XMLConstants.h>
34 #include <xmltooling/util/XMLHelper.h>
35 #include <xmltooling/util/XMLObjectChildrenList.h>
36
37 #ifndef XMLTOOLING_NO_XMLSEC
38     #include <xmltooling/signature/Signature.h>
39     using namespace xmlsignature;
40 #endif
41
42 using namespace xmltooling;
43 using namespace xercesc;
44 using namespace std;
45
46 extern string data_path;
47
48 #if defined (_MSC_VER)
49     #pragma warning( push )
50     #pragma warning( disable : 4250 4251 )
51 #endif
52
53 class SimpleXMLObject
54     : public AbstractAttributeExtensibleXMLObject,
55         public AbstractComplexElement,
56         public AbstractDOMCachingXMLObject,
57         public AbstractXMLObjectMarshaller,
58         public AbstractXMLObjectUnmarshaller
59 {
60 protected:
61     SimpleXMLObject(const SimpleXMLObject& src)
62             : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src),
63                 m_id(XMLString::replicate(src.m_id)) {
64 #ifndef XMLTOOLING_NO_XMLSEC
65         m_children.push_back(nullptr);
66         m_signature=m_children.begin();
67 #endif
68         VectorOf(SimpleXMLObject) mine=getSimpleXMLObjects();
69         for (vector<SimpleXMLObject*>::const_iterator i=src.m_simples.begin(); i!=src.m_simples.end(); i++) {
70             mine.push_back(dynamic_cast<SimpleXMLObject*>((*i)->clone()));
71         }
72     }
73
74 public:
75     static const XMLCh NAMESPACE[];
76     static const XMLCh NAMESPACE_PREFIX[];
77     static const XMLCh LOCAL_NAME[];
78     static const XMLCh DERIVED_NAME[];
79     static const XMLCh TYPE_NAME[];
80     static const XMLCh ID_ATTRIB_NAME[];
81
82     SimpleXMLObject(
83         const XMLCh* nsURI=nullptr, const XMLCh* localName=nullptr, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr
84         ) : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_id(nullptr) {
85 #ifndef XMLTOOLING_NO_XMLSEC
86         m_children.push_back(nullptr);
87         m_signature=m_children.begin();
88 #endif
89     }
90
91     virtual ~SimpleXMLObject() {
92         XMLString::release(&m_id);
93     }
94
95     XMLObject* clone() const {
96         auto_ptr<XMLObject> domClone(AbstractDOMCachingXMLObject::clone());
97         SimpleXMLObject* ret=dynamic_cast<SimpleXMLObject*>(domClone.get());
98         if (ret) {
99             domClone.release();
100             return ret;
101         }
102
103         return new SimpleXMLObject(*this);
104     }
105
106     const XMLCh* getXMLID() const { return getId(); }
107     const XMLCh* getId() const { return m_id; }
108     void setId(const XMLCh* id) { m_id=prepareForAssignment(m_id,id); }
109
110     const XMLCh* getValue() const { return getTextContent(); }
111     void setValue(const XMLCh* value) { setTextContent(value); }
112
113 #ifndef XMLTOOLING_NO_XMLSEC    
114     Signature* getSignature() const {
115         return dynamic_cast<Signature*>(*m_signature);
116     }
117
118     void setSignature(Signature* sig) {
119         *m_signature=prepareForAssignment(*m_signature,sig);
120     }
121 #endif
122
123     VectorOf(SimpleXMLObject) getSimpleXMLObjects() {
124         return VectorOf(SimpleXMLObject)(this, m_simples, &m_children, m_children.end());
125     }
126     
127     const std::vector<SimpleXMLObject*>& getSimpleXMLObjects() const {
128         return m_simples;
129     }
130
131 protected:
132     void marshallAttributes(xercesc::DOMElement* domElement) const {
133         if(getId()) {
134             domElement->setAttributeNS(nullptr, SimpleXMLObject::ID_ATTRIB_NAME, getId());
135 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
136             domElement->setIdAttributeNS(nullptr, SimpleXMLObject::ID_ATTRIB_NAME, true);
137 #else
138             domElement->setIdAttributeNS(nullptr, SimpleXMLObject::ID_ATTRIB_NAME);
139 #endif
140         }
141         marshallExtensionAttributes(domElement);
142     }
143
144     void processChildElement(XMLObject* childXMLObject, const xercesc::DOMElement* root) {
145         SimpleXMLObject* simple=dynamic_cast<SimpleXMLObject*>(childXMLObject);
146         if (simple) {
147             getSimpleXMLObjects().push_back(simple);
148             return;
149         }
150         
151 #ifndef XMLTOOLING_NO_XMLSEC
152         Signature* sig=dynamic_cast<Signature*>(childXMLObject);
153         if (sig) {
154             setSignature(sig);
155             return;
156         }
157 #endif
158
159         throw UnmarshallingException("Unknown child element cannot be added to parent object.");
160     }
161
162     void processAttribute(const xercesc::DOMAttr* attribute) {
163         if (XMLHelper::isNodeNamed(attribute, nullptr, SimpleXMLObject::ID_ATTRIB_NAME)) {
164             setId(attribute->getValue());
165             return;
166         }
167         unmarshallExtensionAttribute(attribute);
168     }
169
170 private:
171     XMLCh* m_id;
172     vector<SimpleXMLObject*> m_simples;
173 #ifndef XMLTOOLING_NO_XMLSEC
174     list<XMLObject*>::iterator m_signature;
175 #endif
176 };
177
178 class SimpleXMLObjectBuilder : public XMLObjectBuilder
179 {
180 public:
181     XMLObject* buildObject() const {
182         return buildObject(SimpleXMLObject::NAMESPACE, SimpleXMLObject::LOCAL_NAME, SimpleXMLObject::NAMESPACE_PREFIX);
183     }
184
185     XMLObject* buildObject(
186         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr
187         ) const {
188         return new SimpleXMLObject(nsURI, localName, prefix, schemaType);
189     }
190
191     static SimpleXMLObject* buildSimpleXMLObject() {
192         const SimpleXMLObjectBuilder* b = dynamic_cast<const SimpleXMLObjectBuilder*>(
193             XMLObjectBuilder::getBuilder(xmltooling::QName(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME))
194             );
195         if (b)
196             return dynamic_cast<SimpleXMLObject*>(b->buildObject());
197         throw XMLObjectException("Unable to obtain typed builder for SimpleXMLObject.");
198     }
199 };
200
201 #if defined (_MSC_VER)
202     #pragma warning( pop )
203 #endif