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