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