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