Reworked int/bool attribute handling.
[shibboleth/cpp-opensaml.git] / saml / saml1 / core / impl / ProtocolsImpl.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  * ProtocolsImpl.cpp
19  * 
20  * Implementation classes for SAML 1.x Protocols schema
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "saml1/core/Protocols.h"
26
27 #include <xmltooling/AbstractChildlessElement.h>
28 #include <xmltooling/AbstractComplexElement.h>
29 #include <xmltooling/AbstractElementProxy.h>
30 #include <xmltooling/AbstractSimpleElement.h>
31 #include <xmltooling/impl/AnyElement.h>
32 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
33 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
34 #include <xmltooling/util/XMLHelper.h>
35 #include <xmltooling/validation/AbstractValidatingXMLObject.h>
36
37 #include <ctime>
38 #include <xercesc/util/XMLUniDefs.hpp>
39
40 using namespace opensaml::saml1p;
41 using namespace opensaml::saml1;
42 using namespace opensaml;
43 using namespace xmlsignature;
44 using namespace xmltooling;
45 using namespace std;
46
47 #if defined (_MSC_VER)
48     #pragma warning( push )
49     #pragma warning( disable : 4250 4251 )
50 #endif
51
52 namespace opensaml {
53     namespace saml1p {
54     
55         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
56         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
57
58         class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
59             protected AbstractSimpleElement,
60             public AbstractChildlessElement,
61             public AbstractDOMCachingXMLObject,
62             public AbstractValidatingXMLObject,
63             public AbstractXMLObjectMarshaller,
64             public AbstractXMLObjectUnmarshaller
65         {
66             QName* m_qname;
67         public:
68             virtual ~RespondWithImpl() {
69                 delete m_qname;
70             }
71     
72             RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
73                 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(NULL) {
74             }
75                 
76             RespondWithImpl(const RespondWithImpl& src)
77                     : AbstractXMLObject(src),
78                         AbstractSimpleElement(src),
79                         AbstractDOMCachingXMLObject(src),
80                         AbstractValidatingXMLObject(src), m_qname(NULL) {
81                 setQName(src.getQName());
82             }
83             
84             QName* getQName() const {
85                 return m_qname;
86             }
87             
88             void setQName(const QName* qname) {
89                 m_qname=prepareForAssignment(m_qname,qname);
90                 if (m_qname) {
91                     auto_ptr_XMLCh temp(m_qname->toString().c_str());
92                     setTextContent(temp.get());
93                 }
94                 else
95                     setTextContent(NULL);
96             }
97             
98             IMPL_XMLOBJECT_CLONE(RespondWith);
99             IMPL_XMLOBJECT_CONTENT;
100         };
101
102         class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
103             public AbstractComplexElement,
104             public AbstractDOMCachingXMLObject,
105             public AbstractValidatingXMLObject,
106             public AbstractXMLObjectMarshaller,
107             public AbstractXMLObjectUnmarshaller
108         {
109             void init() {
110                 m_Subject=NULL;
111                 m_children.push_back(NULL);
112                 m_pos_Subject=m_children.begin();
113             }
114         protected:
115             SubjectQueryImpl() {
116                 init();
117             }
118         public:
119             virtual ~SubjectQueryImpl() {}
120     
121             SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
122                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
123                 init();
124             }
125                 
126             SubjectQueryImpl(const SubjectQueryImpl& src)
127                     : AbstractXMLObject(src),
128                         AbstractDOMCachingXMLObject(src),
129                         AbstractValidatingXMLObject(src) {
130                 init();
131                 if (src.getSubject())
132                     setSubject(src.getSubject()->cloneSubject());
133             }
134             
135             IMPL_TYPED_CHILD(Subject);
136     
137         protected:
138             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
139                 PROC_TYPED_CHILD(Subject,SAMLConstants::SAML1_NS,true);
140                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
141             }
142         };
143
144         class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
145         {
146             void init() {
147                 m_AuthenticationMethod=NULL;
148             }
149         public:
150             virtual ~AuthenticationQueryImpl() {
151                 XMLString::release(&m_AuthenticationMethod);
152             }
153     
154             AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
155                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
156                 init();
157             }
158                 
159             AuthenticationQueryImpl(const AuthenticationQueryImpl& src)
160                     : AbstractXMLObject(src), SubjectQueryImpl(src) {
161                 init();
162                 setAuthenticationMethod(src.getAuthenticationMethod());
163             }
164             
165             IMPL_XMLOBJECT_CLONE(AuthenticationQuery);
166             SubjectQuery* cloneSubjectQuery() const {
167                 return cloneAuthenticationQuery();
168             }
169             Query* cloneQuery() const {
170                 return cloneAuthenticationQuery();
171             }
172             IMPL_STRING_ATTRIB(AuthenticationMethod);
173     
174         protected:
175             void marshallAttributes(DOMElement* domElement) const {
176                 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
177                 SubjectQueryImpl::marshallAttributes(domElement);
178             }
179     
180             void processAttribute(const DOMAttr* attribute) {
181                 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
182                 SubjectQueryImpl::processAttribute(attribute);
183             }
184         };
185
186         class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
187         {
188             void init() {
189                 m_Resource=NULL;
190             }
191         public:
192             virtual ~AttributeQueryImpl() {
193                 XMLString::release(&m_Resource);
194             }
195     
196             AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
197                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
198                 init();
199             }
200                 
201             AttributeQueryImpl(const AttributeQueryImpl& src)
202                     : AbstractXMLObject(src), SubjectQueryImpl(src) {
203                 init();
204                 setResource(src.getResource());
205                 VectorOf(AttributeDesignator) v=getAttributeDesignators();
206                 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
207                     if (*i) {
208                         v.push_back((*i)->cloneAttributeDesignator());
209                     }
210                 }
211             }
212             
213             IMPL_XMLOBJECT_CLONE(AttributeQuery);
214             SubjectQuery* cloneSubjectQuery() const {
215                 return cloneAttributeQuery();
216             }
217             Query* cloneQuery() const {
218                 return cloneAttributeQuery();
219             }
220             IMPL_STRING_ATTRIB(Resource);
221             IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
222     
223         protected:
224             void marshallAttributes(DOMElement* domElement) const {
225                 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
226                 SubjectQueryImpl::marshallAttributes(domElement);
227             }
228     
229             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
230                 PROC_TYPED_CHILDREN(AttributeDesignator,SAMLConstants::SAML1_NS,true);
231                 SubjectQueryImpl::processChildElement(childXMLObject,root);
232             }
233     
234             void processAttribute(const DOMAttr* attribute) {
235                 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
236                 SubjectQueryImpl::processAttribute(attribute);
237             }
238         };
239
240         class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
241         {
242             void init() {
243                 m_Resource=NULL;
244                 m_Evidence=NULL;
245                 m_children.push_back(NULL);
246                 m_pos_Evidence=m_pos_Subject;
247                 ++m_pos_Evidence;
248             }
249         public:
250             virtual ~AuthorizationDecisionQueryImpl() {
251                 XMLString::release(&m_Resource);
252             }
253     
254             AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
255                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
256                 init();
257             }
258                 
259             AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src)
260                     : AbstractXMLObject(src), SubjectQueryImpl(src) {
261                 init();
262                 setResource(src.getResource());
263                 if (src.getEvidence())
264                     setEvidence(src.getEvidence()->cloneEvidence());
265                 VectorOf(Action) v=getActions();
266                 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
267                     if (*i) {
268                         v.push_back((*i)->cloneAction());
269                     }
270                 }
271             }
272             
273             IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery);
274             SubjectQuery* cloneSubjectQuery() const {
275                 return cloneAuthorizationDecisionQuery();
276             }
277             Query* cloneQuery() const {
278                 return cloneAuthorizationDecisionQuery();
279             }
280             IMPL_STRING_ATTRIB(Resource);
281             IMPL_TYPED_CHILD(Evidence);
282             IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
283     
284         protected:
285             void marshallAttributes(DOMElement* domElement) const {
286                 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL);
287                 SubjectQueryImpl::marshallAttributes(domElement);
288             }
289     
290             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
291                 PROC_TYPED_CHILD(Evidence,SAMLConstants::SAML1_NS,false);
292                 PROC_TYPED_CHILDREN(Action,SAMLConstants::SAML1_NS,false);
293                 SubjectQueryImpl::processChildElement(childXMLObject,root);
294             }
295     
296             void processAttribute(const DOMAttr* attribute) {
297                 PROC_STRING_ATTRIB(Resource,RESOURCE,NULL);
298                 SubjectQueryImpl::processAttribute(attribute);
299             }
300         };
301
302         class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
303             public AbstractComplexElement,
304             public AbstractDOMCachingXMLObject,
305             public AbstractValidatingXMLObject,
306             public AbstractXMLObjectMarshaller,
307             public AbstractXMLObjectUnmarshaller
308         {
309             void init() {
310                 m_MinorVersion=NULL;
311                 m_RequestID=NULL;
312                 m_IssueInstant=NULL;
313                 m_children.push_back(NULL);
314                 m_Signature=NULL;
315                 m_pos_Signature=m_children.begin();
316             }
317         protected:
318             RequestAbstractTypeImpl() {
319                 init();
320             }
321         public:
322             virtual ~RequestAbstractTypeImpl() {
323                 XMLString::release(&m_MinorVersion);
324                 XMLString::release(&m_RequestID);
325                 delete m_IssueInstant;
326             }
327     
328             RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
329                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
330                 init();
331             }
332                 
333             RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
334                     : AbstractXMLObject(src),
335                         AbstractDOMCachingXMLObject(src),
336                         AbstractValidatingXMLObject(src) {
337                 init();
338                 setMinorVersion(src.m_MinorVersion);
339                 setRequestID(src.getRequestID());
340                 setIssueInstant(src.getIssueInstant());
341                 if (src.getSignature())
342                     setSignature(src.getSignature()->cloneSignature());
343                 VectorOf(RespondWith) v=getRespondWiths();
344                 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
345                     if (*i) {
346                         v.push_back((*i)->cloneRespondWith());
347                     }
348                 }
349             }
350             
351             const XMLCh* getId() const {
352                 return getRequestID();
353             }
354
355             //IMPL_TYPED_CHILD(Signature);
356             // Need customized setter.
357         protected:
358             Signature* m_Signature;
359             list<XMLObject*>::iterator m_pos_Signature;
360         public:
361             Signature* getSignature() const {
362                 return m_Signature;
363             }
364             
365             void setSignature(Signature* sig) {
366                 prepareForAssignment(m_Signature,sig);
367                 *m_pos_Signature=m_Signature=sig;
368                 // Sync content reference back up.
369                 if (m_Signature)
370                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
371             }
372
373             IMPL_INTEGER_ATTRIB(MinorVersion);
374             IMPL_STRING_ATTRIB(RequestID);
375             IMPL_DATETIME_ATTRIB(IssueInstant);
376             IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
377     
378         protected:
379             void marshallAttributes(DOMElement* domElement) const {
380                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
381                 domElement->setAttributeNS(NULL,MAJORVERSION,XMLConstants::XML_ONE);
382                 if (!m_MinorVersion)
383                     const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XMLConstants::XML_ONE);
384                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
385                 if (!m_RequestID)
386                     const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
387                 MARSHALL_ID_ATTRIB(RequestID,REQUESTID,NULL);
388                 if (!m_IssueInstant)
389                     const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
390                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
391             }
392
393             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
394                 PROC_TYPED_CHILDREN(RespondWith,SAMLConstants::SAML1P_NS,false);
395                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
396                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
397             }
398
399             void processAttribute(const DOMAttr* attribute) {
400                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
401                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
402                     if (!XMLString::equals(attribute->getValue(),XMLConstants::XML_ONE))
403                         throw UnmarshallingException("Request has invalid major version.");
404                 }
405                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
406                 PROC_ID_ATTRIB(RequestID,REQUESTID,NULL);
407                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
408             }
409         };
410
411         class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
412         {
413             void init() {
414                 m_children.push_back(NULL);
415                 m_Query=NULL;
416                 m_pos_Query=m_pos_Signature;
417                 ++m_pos_Query;
418             }
419         public:
420             virtual ~RequestImpl() {}
421     
422             RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
423                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
424                 init();
425             }
426                 
427             RequestImpl(const RequestImpl& src)
428                     : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
429                 init();
430                 if (src.getQuery())
431                     setQuery(src.getQuery()->cloneQuery());
432                 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
433                 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
434                     if (*i) {
435                         v.push_back((*i)->cloneAssertionIDReference());
436                     }
437                 }
438                 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
439                 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
440                     if (*i) {
441                         v2.push_back((*i)->cloneAssertionArtifact());
442                     }
443                 }
444             }
445             
446             IMPL_XMLOBJECT_CLONE(Request);
447             RequestAbstractType* cloneRequestAbstractType() const {
448                 return cloneRequest();
449             }
450             IMPL_TYPED_CHILD(Query);
451             
452             SubjectQuery* getSubjectQuery() const {
453                 return dynamic_cast<SubjectQuery*>(getQuery());
454             }
455             AuthenticationQuery* getAuthenticationQuery() const {
456                 return dynamic_cast<AuthenticationQuery*>(getQuery());
457             }
458             AttributeQuery* getAttributeQuery() const {
459                 return dynamic_cast<AttributeQuery*>(getQuery());
460             }
461             AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
462                 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
463             }
464
465             void setSubjectQuery(SubjectQuery* q) {
466                 setQuery(q);
467             }
468             void setAuthenticationQuery(AuthenticationQuery* q) {
469                 setQuery(q);
470             }
471             void setAttributeQuery(AttributeQuery* q) {
472                 setQuery(q);
473             }
474             void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
475                 setQuery(q);
476             }
477             
478             IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
479             IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
480     
481         protected:
482             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
483                 PROC_TYPED_CHILD(Query,SAMLConstants::SAML1P_NS,true);
484                 PROC_TYPED_CHILDREN(AssertionIDReference,SAMLConstants::SAML1_NS,false);
485                 PROC_TYPED_CHILDREN(AssertionArtifact,SAMLConstants::SAML1P_NS,false);
486                 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
487             }
488         };
489
490         class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
491             public AbstractComplexElement,
492             public AbstractDOMCachingXMLObject,
493             public AbstractValidatingXMLObject,
494             public AbstractXMLObjectMarshaller,
495             public AbstractXMLObjectUnmarshaller
496         {
497             void init() {
498                 m_Value=NULL;
499                 m_children.push_back(NULL);
500                 m_StatusCode=NULL;
501                 m_pos_StatusCode=m_children.begin();
502             }
503         public:
504             virtual ~StatusCodeImpl() {
505                 delete m_Value;
506             }
507     
508             StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
509                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
510                 init();
511             }
512                 
513             StatusCodeImpl(const StatusCodeImpl& src)
514                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
515                 init();
516                 setValue(src.getValue());
517                 if (src.getStatusCode())
518                     setStatusCode(src.getStatusCode()->cloneStatusCode());
519             }
520             
521             IMPL_XMLOBJECT_CLONE(StatusCode);
522             IMPL_XMLOBJECT_ATTRIB(Value,QName);
523             IMPL_TYPED_CHILD(StatusCode);
524     
525         protected:
526             void marshallAttributes(DOMElement* domElement) const {
527                 MARSHALL_QNAME_ATTRIB(Value,VALUE,NULL);
528             }
529
530             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
531                 PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,true);
532                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
533             }
534
535             void processAttribute(const DOMAttr* attribute) {
536                 PROC_QNAME_ATTRIB(Value,VALUE,NULL);
537             }
538         };
539
540         class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
541             public AbstractComplexElement,
542             public AbstractDOMCachingXMLObject,
543             public AbstractValidatingXMLObject,
544             public AbstractXMLObjectMarshaller,
545             public AbstractXMLObjectUnmarshaller
546         {
547         public:
548             virtual ~StatusDetailImpl() {}
549     
550             StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
551                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
552             }
553                 
554             StatusDetailImpl(const StatusDetailImpl& src)
555                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
556                 VectorOf(XMLObject) v=getDetails();
557                 for (vector<XMLObject*>::const_iterator i=src.m_Details.begin(); i!=src.m_Details.end(); i++) {
558                     if (*i) {
559                         v.push_back((*i)->clone());
560                     }
561                 }
562             }
563             
564             IMPL_XMLOBJECT_CLONE(StatusDetail);
565             IMPL_XMLOBJECT_CHILDREN(Detail,m_children.end());
566     
567         protected:
568             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
569                 getDetails().push_back(childXMLObject);
570             }
571         };
572
573         class SAML_DLLLOCAL StatusImpl : public virtual Status,
574             public AbstractComplexElement,
575             public AbstractDOMCachingXMLObject,
576             public AbstractValidatingXMLObject,
577             public AbstractXMLObjectMarshaller,
578             public AbstractXMLObjectUnmarshaller
579         {
580             void init() {
581                 m_children.push_back(NULL);
582                 m_children.push_back(NULL);
583                 m_children.push_back(NULL);
584                 m_StatusCode=NULL;
585                 m_pos_StatusCode=m_children.begin();
586                 m_StatusMessage=NULL;
587                 m_pos_StatusMessage=m_pos_StatusCode;
588                 ++m_pos_StatusMessage;
589                 m_StatusDetail=NULL;
590                 m_pos_StatusDetail=m_pos_StatusMessage;
591                 ++m_pos_StatusDetail;
592             }
593         public:
594             virtual ~StatusImpl() {}
595     
596             StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
597                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
598                 init();
599             }
600                 
601             StatusImpl(const StatusImpl& src)
602                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
603                 init();
604                 if (src.getStatusCode())
605                     setStatusCode(src.getStatusCode()->cloneStatusCode());
606                 if (src.getStatusMessage())
607                     setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
608                 if (src.getStatusDetail())
609                     setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
610             }
611             
612             IMPL_XMLOBJECT_CLONE(Status);
613             IMPL_TYPED_CHILD(StatusCode);
614             IMPL_TYPED_CHILD(StatusMessage);
615             IMPL_TYPED_CHILD(StatusDetail);
616     
617         protected:
618             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
619                 PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,false);
620                 PROC_TYPED_CHILD(StatusMessage,SAMLConstants::SAML1P_NS,false);
621                 PROC_TYPED_CHILD(StatusDetail,SAMLConstants::SAML1P_NS,false);
622                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
623             }
624         };
625
626         class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
627             public AbstractComplexElement,
628             public AbstractDOMCachingXMLObject,
629             public AbstractValidatingXMLObject,
630             public AbstractXMLObjectMarshaller,
631             public AbstractXMLObjectUnmarshaller
632         {
633             void init() {
634                 m_MinorVersion=NULL;
635                 m_ResponseID=NULL;
636                 m_InResponseTo=NULL;
637                 m_IssueInstant=NULL;
638                 m_Recipient=NULL;
639                 m_children.push_back(NULL);
640                 m_Signature=NULL;
641                 m_pos_Signature=m_children.begin();
642             }
643         protected:
644             ResponseAbstractTypeImpl() {
645                 init();
646             }
647         public:
648             virtual ~ResponseAbstractTypeImpl() {
649                 XMLString::release(&m_MinorVersion);
650                 XMLString::release(&m_ResponseID);
651                 XMLString::release(&m_InResponseTo);
652                 XMLString::release(&m_Recipient);
653                 delete m_IssueInstant;
654             }
655     
656             ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
657                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
658                 init();
659             }
660                 
661             ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
662                     : AbstractXMLObject(src),
663                         AbstractDOMCachingXMLObject(src),
664                         AbstractValidatingXMLObject(src) {
665                 init();
666                 setMinorVersion(src.m_MinorVersion);
667                 setResponseID(src.getResponseID());
668                 setInResponseTo(src.getInResponseTo());
669                 setIssueInstant(src.getIssueInstant());
670                 setRecipient(src.getRecipient());
671                 if (src.getSignature())
672                     setSignature(src.getSignature()->cloneSignature());
673             }
674
675             const XMLCh* getId() const {
676                 return getResponseID();
677             }
678
679             //IMPL_TYPED_CHILD(Signature);
680             // Need customized setter.
681         protected:
682             Signature* m_Signature;
683             list<XMLObject*>::iterator m_pos_Signature;
684         public:
685             Signature* getSignature() const {
686                 return m_Signature;
687             }
688             
689             void setSignature(Signature* sig) {
690                 prepareForAssignment(m_Signature,sig);
691                 *m_pos_Signature=m_Signature=sig;
692                 // Sync content reference back up.
693                 if (m_Signature)
694                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
695             }
696
697             IMPL_INTEGER_ATTRIB(MinorVersion);
698             IMPL_STRING_ATTRIB(ResponseID);
699             IMPL_STRING_ATTRIB(InResponseTo);
700             IMPL_DATETIME_ATTRIB(IssueInstant);
701             IMPL_STRING_ATTRIB(Recipient);
702     
703         protected:
704             void marshallAttributes(DOMElement* domElement) const {
705                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
706                 domElement->setAttributeNS(NULL,MAJORVERSION,XMLConstants::XML_ONE);
707                 if (!m_MinorVersion)
708                     const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XMLConstants::XML_ONE);
709                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
710                 if (!m_ResponseID)
711                     const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
712                 MARSHALL_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
713                 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
714                 if (!m_IssueInstant)
715                     const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
716                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
717                 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
718             }
719
720             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
721                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
722                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
723             }
724
725             void processAttribute(const DOMAttr* attribute) {
726                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
727                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
728                     if (!XMLString::equals(attribute->getValue(),XMLConstants::XML_ONE))
729                         throw UnmarshallingException("Response has invalid major version.");
730                 }
731                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
732                 PROC_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
733                 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
734                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
735                 PROC_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
736             }
737         };
738
739         class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
740         {
741             void init() {
742                 m_children.push_back(NULL);
743                 m_Status=NULL;
744                 m_pos_Status=m_pos_Signature;
745                 ++m_pos_Status;
746             }
747         public:
748             virtual ~ResponseImpl() {}
749     
750             ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
751                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
752                 init();
753             }
754                 
755             ResponseImpl(const ResponseImpl& src)
756                     : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
757                 init();
758                 if (src.getStatus())
759                     setStatus(src.getStatus()->cloneStatus());
760                 VectorOf(Assertion) v=getAssertions();
761                 for (vector<Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
762                     if (*i) {
763                         v.push_back((*i)->cloneAssertion());
764                     }
765                 }
766             }
767             
768             IMPL_XMLOBJECT_CLONE(Response);
769             ResponseAbstractType* cloneResponseAbstractType() const {
770                 return cloneResponse();
771             }
772             IMPL_TYPED_CHILD(Status);
773             IMPL_TYPED_CHILDREN(Assertion, m_children.end());
774     
775         protected:
776             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
777                 PROC_TYPED_CHILD(Status,SAMLConstants::SAML1P_NS,false);
778                 PROC_TYPED_CHILDREN(Assertion,SAMLConstants::SAML1_NS,true);
779                 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
780             }
781         };
782
783     };
784 };
785
786 #if defined (_MSC_VER)
787     #pragma warning( pop )
788 #endif
789
790 // Builder Implementations
791
792 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
793 IMPL_XMLOBJECTBUILDER(AttributeQuery);
794 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
795 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
796 IMPL_XMLOBJECTBUILDER(Request);
797 IMPL_XMLOBJECTBUILDER(RespondWith);
798 IMPL_XMLOBJECTBUILDER(Response);
799 IMPL_XMLOBJECTBUILDER(Status);
800 IMPL_XMLOBJECTBUILDER(StatusCode);
801 IMPL_XMLOBJECTBUILDER(StatusDetail);
802 IMPL_XMLOBJECTBUILDER(StatusMessage);
803
804 // Unicode literals
805 const XMLCh RequestAbstractType::LOCAL_NAME[] =             {chNull};
806 const XMLCh RequestAbstractType::TYPE_NAME[] =              UNICODE_LITERAL_19(R,e,q,u,e,s,t,A,b,s,t,r,a,c,t,T,y,p,e);
807 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] =   UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
808 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] =      UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
809 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] =   UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
810 const XMLCh ResponseAbstractType::LOCAL_NAME[] =            {chNull};
811 const XMLCh ResponseAbstractType::TYPE_NAME[] =             UNICODE_LITERAL_20(R,e,s,p,o,n,s,e,A,b,s,t,r,a,c,t,T,y,p,e);
812 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] =  UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
813 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] =    UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
814 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] =  UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
815 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] =  UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
816 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] =     UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
817 const XMLCh AssertionArtifact::LOCAL_NAME[] =               UNICODE_LITERAL_17(A,s,s,e,r,t,i,o,n,A,r,t,i,f,a,c,t);
818 const XMLCh AttributeQuery::LOCAL_NAME[] =                  UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
819 const XMLCh AttributeQuery::TYPE_NAME[] =                   UNICODE_LITERAL_18(A,t,t,r,i,b,u,t,e,Q,u,e,r,y,T,y,p,e);
820 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] =        UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
821 const XMLCh AuthenticationQuery::LOCAL_NAME[] =             UNICODE_LITERAL_19(A,u,t,h,e,n,t,i,c,a,t,i,o,n,Q,u,e,r,y);
822 const XMLCh AuthenticationQuery::TYPE_NAME[] =              UNICODE_LITERAL_23(A,u,t,h,e,n,t,i,c,a,t,i,o,n,Q,u,e,r,y,T,y,p,e);
823 const XMLCh AuthenticationQuery::AUTHENTICATIONMETHOD_ATTRIB_NAME[] =   UNICODE_LITERAL_20(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d);
824 const XMLCh AuthorizationDecisionQuery::LOCAL_NAME[] =      UNICODE_LITERAL_26(A,u,t,h,o,r,i,z,a,t,i,o,n,D,e,c,i,s,i,o,n,Q,u,e,r,y);
825 const XMLCh AuthorizationDecisionQuery::TYPE_NAME[] =       UNICODE_LITERAL_30(A,u,t,h,o,r,i,z,a,t,i,o,n,D,e,c,i,s,i,o,n,Q,u,e,r,y,T,y,p,e);
826 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] =        UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
827 const XMLCh Query::LOCAL_NAME[] =                           UNICODE_LITERAL_5(Q,u,e,r,y);
828 const XMLCh Request::LOCAL_NAME[] =                         UNICODE_LITERAL_7(R,e,q,u,e,s,t);
829 const XMLCh Request::TYPE_NAME[] =                          UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
830 const XMLCh RespondWith::LOCAL_NAME[] =                     UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
831 const XMLCh Response::LOCAL_NAME[] =                        UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
832 const XMLCh Response::TYPE_NAME[] =                         UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
833 const XMLCh Status::LOCAL_NAME[] =                          UNICODE_LITERAL_6(S,t,a,t,u,s);
834 const XMLCh Status::TYPE_NAME[] =                           UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
835 const XMLCh StatusCode::LOCAL_NAME[] =                      UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
836 const XMLCh StatusCode::TYPE_NAME[] =                       UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
837 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] =               UNICODE_LITERAL_5(V,a,l,u,e);
838 const XMLCh StatusDetail::LOCAL_NAME[] =                    UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
839 const XMLCh StatusDetail::TYPE_NAME[] =                     UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
840 const XMLCh StatusMessage::LOCAL_NAME[] =                   UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
841 const XMLCh SubjectQuery::LOCAL_NAME[] =                    UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
842
843 #define XCH(ch) chLatin_##ch
844 #define XNUM(d) chDigit_##d
845
846 const XMLCh _SUCCESS[] =                                    UNICODE_LITERAL_7(S,u,c,c,e,s,s);
847 const XMLCh _REQUESTER[] =                                  UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
848 const XMLCh _RESPONDER[] =                                  UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
849 const XMLCh _VERSIONMISMATCH[] =                            UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
850  
851 QName StatusCode::SUCCESS(SAMLConstants::SAML1P_NS,_SUCCESS,SAMLConstants::SAML1P_PREFIX);
852 QName StatusCode::REQUESTER(SAMLConstants::SAML1P_NS,_REQUESTER,SAMLConstants::SAML1P_PREFIX);
853 QName StatusCode::RESPONDER(SAMLConstants::SAML1P_NS,_RESPONDER,SAMLConstants::SAML1P_PREFIX);
854 QName StatusCode::VERSIONMISMATCH(SAMLConstants::SAML1P_NS,_VERSIONMISMATCH,SAMLConstants::SAML1P_PREFIX);