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