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