Additional macros and cleanup for cloning
[shibboleth/cpp-xmltooling.git] / xmltooling / soap / impl / SOAPImpl.cpp
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 /**
22  * SOAPImpl.cpp
23  * 
24  * Implementation classes for SOAP 1.1 schema.
25  */
26
27 #include "internal.h"
28 #include "AbstractAttributeExtensibleXMLObject.h"
29 #include "AbstractComplexElement.h"
30 #include "AbstractSimpleElement.h"
31 #include "exceptions.h"
32 #include "io/AbstractXMLObjectMarshaller.h"
33 #include "io/AbstractXMLObjectUnmarshaller.h"
34 #include "soap/SOAP.h"
35 #include "util/XMLHelper.h"
36
37 #include <boost/lambda/bind.hpp>
38 #include <boost/lambda/if.hpp>
39 #include <boost/lambda/lambda.hpp>
40 #include <xercesc/util/XMLUniDefs.hpp>
41
42 using namespace soap11;
43 using namespace xmltooling;
44 using namespace xercesc;
45 using namespace std;
46 using xmlconstants::SOAP11ENV_NS;
47 using xmlconstants::SOAP11ENV_PREFIX;
48
49 #if defined (_MSC_VER)
50     #pragma warning( push )
51     #pragma warning( disable : 4250 4251 )
52 #endif
53
54 namespace {
55
56     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Faultstring);
57     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Faultactor);
58
59     class XMLTOOL_DLLLOCAL FaultcodeImpl : public virtual Faultcode,
60         public AbstractSimpleElement,
61         public AbstractDOMCachingXMLObject,
62         public AbstractXMLObjectMarshaller,
63         public AbstractXMLObjectUnmarshaller
64     {
65         mutable xmltooling::QName* m_qname;
66     public:
67         virtual ~FaultcodeImpl() {
68             delete m_qname;
69         }
70
71         FaultcodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
72             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(nullptr) {
73         }
74             
75         FaultcodeImpl(const FaultcodeImpl& src)
76                 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_qname(nullptr) {
77             IMPL_CLONE_ATTRIB(Code);
78         }
79         
80         const xmltooling::QName* getCode() const {
81             if (!m_qname && getDOM() && getDOM()->getTextContent()) {
82                 m_qname = XMLHelper::getNodeValueAsQName(getDOM());
83             }
84             return m_qname;
85         }
86         
87         void setCode(const xmltooling::QName* qname) {
88             m_qname=prepareForAssignment(m_qname,qname);
89             if (m_qname) {
90                 auto_ptr_XMLCh temp(m_qname->toString().c_str());
91                 setTextContent(temp.get());
92             }
93             else {
94                 setTextContent(nullptr);
95             }
96         }
97         
98         IMPL_XMLOBJECT_CLONE(Faultcode);
99     };
100
101     class XMLTOOL_DLLLOCAL DetailImpl : public virtual Detail,
102         public AbstractAttributeExtensibleXMLObject,
103         public AbstractComplexElement,
104         public AbstractDOMCachingXMLObject,
105         public AbstractXMLObjectMarshaller,
106         public AbstractXMLObjectUnmarshaller
107     {
108     public:
109         virtual ~DetailImpl() {}
110
111         DetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
112             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
113         }
114             
115         DetailImpl(const DetailImpl& src)
116                 : AbstractXMLObject(src),
117                     AbstractAttributeExtensibleXMLObject(src),
118                     AbstractComplexElement(src),
119                     AbstractDOMCachingXMLObject(src) {
120             IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
121         }
122         
123         IMPL_XMLOBJECT_CLONE(Detail);
124         IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject, m_children.end());
125
126     protected:
127         void marshallAttributes(DOMElement* domElement) const {
128             marshallExtensionAttributes(domElement);
129         }
130
131         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
132             getUnknownXMLObjects().push_back(childXMLObject);
133         }
134
135         void processAttribute(const DOMAttr* attribute) {
136             unmarshallExtensionAttribute(attribute);
137         }
138     };
139
140     class XMLTOOL_DLLLOCAL FaultImpl : public virtual Fault,
141         public AbstractComplexElement,
142         public AbstractDOMCachingXMLObject,
143         public AbstractXMLObjectMarshaller,
144         public AbstractXMLObjectUnmarshaller
145     {
146         void init() {
147             m_Faultcode=nullptr;
148             m_Faultstring=nullptr;
149             m_Faultactor=nullptr;
150             m_Detail=nullptr;
151             m_children.push_back(nullptr);
152             m_children.push_back(nullptr);
153             m_children.push_back(nullptr);
154             m_children.push_back(nullptr);
155             m_pos_Faultcode=m_children.begin();
156             m_pos_Faultstring=m_pos_Faultcode;
157             ++m_pos_Faultstring;
158             m_pos_Faultactor=m_pos_Faultstring;
159             ++m_pos_Faultactor;
160             m_pos_Detail=m_pos_Faultactor;
161             ++m_pos_Detail;
162         }
163
164     protected:
165         FaultImpl() {
166             init();
167         }
168         
169     public:
170         virtual ~FaultImpl() {}
171
172         FaultImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
173                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
174             init();
175         }
176             
177         FaultImpl(const FaultImpl& src)
178                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
179             init();
180             IMPL_CLONE_TYPED_CHILD(Faultcode);
181             IMPL_CLONE_TYPED_CHILD(Faultstring);
182             IMPL_CLONE_TYPED_CHILD(Faultactor);
183             IMPL_CLONE_TYPED_CHILD(Detail);
184         }
185         
186         IMPL_XMLOBJECT_CLONE(Fault);
187         IMPL_TYPED_CHILD(Faultcode);
188         IMPL_TYPED_CHILD(Faultstring);
189         IMPL_TYPED_CHILD(Faultactor);
190         IMPL_TYPED_CHILD(Detail);
191
192     protected:
193         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
194             PROC_TYPED_CHILD(Faultcode,nullptr,false);
195             PROC_TYPED_CHILD(Faultstring,nullptr,false);
196             PROC_TYPED_CHILD(Faultactor,nullptr,false);
197             PROC_TYPED_CHILD(Detail,nullptr,false);
198             AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
199         }
200     };
201
202     class XMLTOOL_DLLLOCAL BodyImpl : public virtual Body,
203         public AbstractAttributeExtensibleXMLObject,
204         public AbstractComplexElement,
205         public AbstractDOMCachingXMLObject,
206         public AbstractXMLObjectMarshaller,
207         public AbstractXMLObjectUnmarshaller
208     {
209     public:
210         virtual ~BodyImpl() {
211         }
212
213         BodyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
214             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
215         }
216             
217         BodyImpl(const BodyImpl& src)
218                 : AbstractXMLObject(src),
219                     AbstractAttributeExtensibleXMLObject(src),
220                     AbstractComplexElement(src),
221                     AbstractDOMCachingXMLObject(src) {
222             IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
223         }
224         
225         IMPL_XMLOBJECT_CLONE(Body);
226         IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject, m_children.end());
227
228     protected:
229         void marshallAttributes(DOMElement* domElement) const {
230             marshallExtensionAttributes(domElement);
231         }
232
233         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
234             getUnknownXMLObjects().push_back(childXMLObject);
235         }
236
237         void processAttribute(const DOMAttr* attribute) {
238             unmarshallExtensionAttribute(attribute);
239         }
240     };
241
242     class XMLTOOL_DLLLOCAL HeaderImpl : public virtual Header,
243         public AbstractAttributeExtensibleXMLObject,
244         public AbstractComplexElement,
245         public AbstractDOMCachingXMLObject,
246         public AbstractXMLObjectMarshaller,
247         public AbstractXMLObjectUnmarshaller
248     {
249     public:
250         virtual ~HeaderImpl() {
251         }
252
253         HeaderImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
254             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
255         }
256             
257         HeaderImpl(const HeaderImpl& src)
258                 : AbstractXMLObject(src),
259                     AbstractAttributeExtensibleXMLObject(src),
260                     AbstractComplexElement(src),
261                     AbstractDOMCachingXMLObject(src) {
262             IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
263         }
264         
265         IMPL_XMLOBJECT_CLONE(Header);
266         IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject, m_children.end());
267
268     protected:
269         void marshallAttributes(DOMElement* domElement) const {
270             marshallExtensionAttributes(domElement);
271         }
272
273         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
274             getUnknownXMLObjects().push_back(childXMLObject);
275         }
276
277         void processAttribute(const DOMAttr* attribute) {
278             unmarshallExtensionAttribute(attribute);
279         }
280     };
281
282     class XMLTOOL_DLLLOCAL EnvelopeImpl : public virtual Envelope,
283         public AbstractAttributeExtensibleXMLObject,
284         public AbstractComplexElement,
285         public AbstractDOMCachingXMLObject,
286         public AbstractXMLObjectMarshaller,
287         public AbstractXMLObjectUnmarshaller
288     {
289         void init() {
290             m_Header=nullptr;
291             m_Body=nullptr;
292             m_children.push_back(nullptr);
293             m_children.push_back(nullptr);
294             m_pos_Header=m_children.begin();
295             m_pos_Body=m_pos_Header;
296             ++m_pos_Body;
297         }
298
299     public:
300         virtual ~EnvelopeImpl() {}
301
302         EnvelopeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
303             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
304             init();
305         }
306             
307         EnvelopeImpl(const EnvelopeImpl& src)
308                 : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
309             init();
310             IMPL_CLONE_TYPED_CHILD(Header);
311             IMPL_CLONE_TYPED_CHILD(Body);
312         }
313         
314         IMPL_XMLOBJECT_CLONE(Envelope);
315         IMPL_TYPED_CHILD(Header);
316         IMPL_TYPED_CHILD(Body);
317
318     protected:
319         void marshallAttributes(DOMElement* domElement) const {
320             marshallExtensionAttributes(domElement);
321         }
322
323         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
324             PROC_TYPED_CHILD(Header,SOAP11ENV_NS,false);
325             PROC_TYPED_CHILD(Body,SOAP11ENV_NS,false);
326             AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
327         }
328
329         void processAttribute(const DOMAttr* attribute) {
330             unmarshallExtensionAttribute(attribute);
331         }
332     };
333 };
334
335 #if defined (_MSC_VER)
336     #pragma warning( pop )
337 #endif
338
339 // Builder Implementations
340
341 IMPL_XMLOBJECTBUILDER(Body);
342 IMPL_XMLOBJECTBUILDER(Detail);
343 IMPL_XMLOBJECTBUILDER(Envelope);
344 IMPL_XMLOBJECTBUILDER(Fault);
345 IMPL_XMLOBJECTBUILDER(Faultactor);
346 IMPL_XMLOBJECTBUILDER(Faultcode);
347 IMPL_XMLOBJECTBUILDER(Faultstring);
348 IMPL_XMLOBJECTBUILDER(Header);
349
350 // Unicode literals
351
352 const XMLCh Body::LOCAL_NAME[] =                        UNICODE_LITERAL_4(B,o,d,y);
353 const XMLCh Body::TYPE_NAME[] =                         UNICODE_LITERAL_4(B,o,d,y);
354 const XMLCh Body::ENCODINGSTYLE_ATTRIB_NAME[] =         UNICODE_LITERAL_13(e,n,c,o,d,i,n,g,S,t,y,l,e);
355 const XMLCh Detail::LOCAL_NAME[] =                      UNICODE_LITERAL_6(d,e,t,a,i,l);
356 const XMLCh Detail::TYPE_NAME[] =                       UNICODE_LITERAL_6(d,e,t,a,i,l);
357 const XMLCh Envelope::LOCAL_NAME[] =                    UNICODE_LITERAL_8(E,n,v,e,l,o,p,e);
358 const XMLCh Envelope::TYPE_NAME[] =                     UNICODE_LITERAL_8(E,n,v,e,l,o,p,e);
359 const XMLCh Fault::LOCAL_NAME[] =                       UNICODE_LITERAL_5(F,a,u,l,t);
360 const XMLCh Fault::TYPE_NAME[] =                        UNICODE_LITERAL_5(F,a,u,l,t);
361 const XMLCh Faultactor::LOCAL_NAME[] =                  UNICODE_LITERAL_10(f,a,u,l,t,a,c,t,o,r);
362 const XMLCh Faultcode::LOCAL_NAME[] =                   UNICODE_LITERAL_9(f,a,u,l,t,c,o,d,e);
363 const XMLCh Faultstring::LOCAL_NAME[] =                 UNICODE_LITERAL_11(f,a,u,l,t,s,t,r,i,n,g);
364 const XMLCh Header::LOCAL_NAME[] =                      UNICODE_LITERAL_6(H,e,a,d,e,r);
365 const XMLCh Header::TYPE_NAME[] =                       UNICODE_LITERAL_6(H,e,a,d,e,r);
366 const XMLCh Header::ACTOR_ATTRIB_NAME[] =               UNICODE_LITERAL_5(a,c,t,o,r);
367 const XMLCh Header::MUSTUNDERSTAND_ATTRIB_NAME[] =      UNICODE_LITERAL_14(m,u,s,t,U,n,d,e,r,s,t,a,n,d);
368
369 static const XMLCh _CLIENT[] =                          UNICODE_LITERAL_6(C,l,i,e,n,t);
370 static const XMLCh _SERVER[] =                          UNICODE_LITERAL_6(S,e,r,v,e,r);
371 static const XMLCh _MUSTUNDERSTAND[] =                  UNICODE_LITERAL_14(M,u,s,t,U,n,d,e,r,s,t,a,n,d);
372 static const XMLCh _VERSIONMISMATCH[] =                 UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
373  
374 xmltooling::QName Faultcode::CLIENT(SOAP11ENV_NS,_CLIENT,SOAP11ENV_PREFIX);
375 xmltooling::QName Faultcode::SERVER(SOAP11ENV_NS,_SERVER,SOAP11ENV_PREFIX);
376 xmltooling::QName Faultcode::MUSTUNDERSTAND(SOAP11ENV_NS,_MUSTUNDERSTAND,SOAP11ENV_PREFIX);
377 xmltooling::QName Faultcode::VERSIONMISMATCH(SOAP11ENV_NS,_VERSIONMISMATCH,SOAP11ENV_PREFIX);