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