SAML objects in progress.
[shibboleth/cpp-opensaml.git] / saml / saml1 / core / impl / AssertionsImpl.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  * AssertionsImpl.cpp
19  * 
20  * Implementation classes for SAML 1.x Assertions schema
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "saml1/core/Assertions.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/io/AbstractXMLObjectMarshaller.h>
32 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
33 #include <xmltooling/util/XMLHelper.h>
34 #include <xmltooling/validation/AbstractValidatingXMLObject.h>
35
36 #include <ctime>
37 #include <xercesc/util/XMLUniDefs.hpp>
38
39 using namespace opensaml::saml1;
40 using namespace opensaml;
41 using namespace xmlsignature;
42 using namespace xmltooling;
43 using namespace std;
44
45 #if defined (_MSC_VER)
46     #pragma warning( push )
47     #pragma warning( disable : 4250 4251 )
48 #endif
49
50 namespace opensaml {
51     namespace saml1 {
52     
53         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionIDReference);
54         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,Audience);
55         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,ConfirmationMethod);
56         
57         class XMLTOOL_DLLLOCAL AudienceRestrictionConditionImpl : public virtual AudienceRestrictionCondition,
58             public AbstractComplexElement,
59             public AbstractDOMCachingXMLObject,
60             public AbstractValidatingXMLObject,
61             public AbstractXMLObjectMarshaller,
62             public AbstractXMLObjectUnmarshaller
63         {
64         public:
65             virtual ~AudienceRestrictionConditionImpl() {}
66     
67             AudienceRestrictionConditionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
68                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
69             }
70                 
71             AudienceRestrictionConditionImpl(const AudienceRestrictionConditionImpl& src)
72                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
73                 VectorOf(Audience) v=getAudiences();
74                 for (vector<Audience*>::const_iterator i=src.m_Audiences.begin(); i!=src.m_Audiences.end(); i++) {
75                     if (*i) {
76                         v.push_back((*i)->cloneAudience());
77                     }
78                 }
79             }
80             
81             IMPL_XMLOBJECT_CLONE(AudienceRestrictionCondition);
82             Condition* cloneCondition() const {
83                 return cloneAudienceRestrictionCondition();
84             }
85             IMPL_TYPED_CHILDREN(Audience,m_children.end());
86     
87         protected:
88             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
89                 PROC_TYPED_CHILDREN(Audience,SAMLConstants::SAML1_NS,false);
90                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
91             }
92         };
93
94         class XMLTOOL_DLLLOCAL DoNotCacheConditionImpl : public virtual DoNotCacheCondition,
95             public AbstractChildlessElement,
96             public AbstractDOMCachingXMLObject,
97             public AbstractValidatingXMLObject,
98             public AbstractXMLObjectMarshaller,
99             public AbstractXMLObjectUnmarshaller
100         {
101         public:
102             virtual ~DoNotCacheConditionImpl() {}
103     
104             DoNotCacheConditionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
105                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
106             }
107                 
108             DoNotCacheConditionImpl(const DoNotCacheConditionImpl& src)
109                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
110             }
111             
112             IMPL_XMLOBJECT_CLONE(DoNotCacheCondition);
113             Condition* cloneCondition() const {
114                 return cloneDoNotCacheCondition();
115             }
116         };
117
118         class SAML_DLLLOCAL ConditionsImpl : public virtual Conditions,
119             public AbstractComplexElement,
120             public AbstractDOMCachingXMLObject,
121             public AbstractValidatingXMLObject,
122             public AbstractXMLObjectMarshaller,
123             public AbstractXMLObjectUnmarshaller
124         {
125         public:
126             virtual ~ConditionsImpl() {
127                 delete m_NotBefore;
128                 delete m_NotOnOrAfter;
129             }
130     
131             ConditionsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
132                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
133                 init();
134             }
135                 
136             ConditionsImpl(const ConditionsImpl& src)
137                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
138                 init();
139                 setNotBefore(src.getNotBefore());
140                 setNotOnOrAfter(src.getNotOnOrAfter());
141
142                 for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
143                     if (*i) {
144                         AudienceRestrictionCondition* arc=dynamic_cast<AudienceRestrictionCondition*>(*i);
145                         if (arc) {
146                             getAudienceRestrictionConditions().push_back(arc->cloneAudienceRestrictionCondition());
147                             continue;
148                         }
149     
150                         DoNotCacheCondition* dncc=dynamic_cast<DoNotCacheCondition*>(*i);
151                         if (dncc) {
152                             getDoNotCacheConditions().push_back(dncc->cloneDoNotCacheCondition());
153                             continue;
154                         }
155     
156                         Condition* c=dynamic_cast<Condition*>(*i);
157                         if (c) {
158                             getConditions().push_back(c->cloneCondition());
159                             continue;
160                         }
161                     }
162                 }
163             }
164             
165             void init() {
166                 m_NotBefore=m_NotOnOrAfter=NULL;
167             }
168             
169             IMPL_XMLOBJECT_CLONE(Conditions);
170             IMPL_DATETIME_ATTRIB(NotBefore);
171             IMPL_DATETIME_ATTRIB(NotOnOrAfter);
172             IMPL_TYPED_CHILDREN(AudienceRestrictionCondition, m_children.end());
173             IMPL_TYPED_CHILDREN(DoNotCacheCondition,m_children.end());
174             IMPL_TYPED_CHILDREN(Condition,m_children.end());
175     
176         protected:
177             void marshallAttributes(DOMElement* domElement) const {
178                 MARSHALL_DATETIME_ATTRIB(NotBefore,NOTBEFORE,NULL);
179                 MARSHALL_DATETIME_ATTRIB(NotOnOrAfter,NOTONORAFTER,NULL);
180             }
181     
182             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
183                 PROC_TYPED_CHILDREN(AudienceRestrictionCondition,SAMLConstants::SAML1_NS,true);
184                 PROC_TYPED_CHILDREN(DoNotCacheCondition,SAMLConstants::SAML1_NS,true);
185                 PROC_TYPED_CHILDREN(Condition,SAMLConstants::SAML1_NS,true);
186                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
187             }
188     
189             void processAttribute(const DOMAttr* attribute) {
190                 PROC_DATETIME_ATTRIB(NotBefore,NOTBEFORE,NULL);
191                 PROC_DATETIME_ATTRIB(NotOnOrAfter,NOTONORAFTER,NULL);
192             }
193         };
194
195         class SAML_DLLLOCAL NameIdentifierImpl : public virtual NameIdentifier,
196             public AbstractSimpleElement,
197             public AbstractChildlessElement,
198             public AbstractDOMCachingXMLObject,
199             public AbstractValidatingXMLObject,
200             public AbstractXMLObjectMarshaller,
201             public AbstractXMLObjectUnmarshaller
202         {
203         public:
204             virtual ~NameIdentifierImpl() {}
205     
206             NameIdentifierImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
207                     : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
208                 init();
209             }
210                 
211             NameIdentifierImpl(const NameIdentifierImpl& src)
212                     : AbstractXMLObject(src), AbstractSimpleElement(src),
213                         AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
214                 init();
215                 setFormat(src.getFormat());
216                 setNameQualifier(src.getNameQualifier());
217             }
218             
219             void init() {
220                 m_Format=m_NameQualifier=NULL;
221             }
222             
223             IMPL_XMLOBJECT_CLONE(NameIdentifier);
224             IMPL_STRING_ATTRIB(Format);
225             IMPL_STRING_ATTRIB(NameQualifier);
226             IMPL_XMLOBJECT_CONTENT;
227     
228         protected:
229             void processAttribute(const DOMAttr* attribute) {
230                 PROC_STRING_ATTRIB(Format,FORMAT,NULL);
231                 PROC_STRING_ATTRIB(NameQualifier,NAMEQUALIFIER,NULL);
232             }
233         };
234
235         class SAML_DLLLOCAL SubjectConfirmationDataImpl : public virtual SubjectConfirmationData,
236             public AbstractDOMCachingXMLObject,
237             public AbstractElementProxy,
238             public AbstractValidatingXMLObject,
239             public AbstractXMLObjectMarshaller,
240             public AbstractXMLObjectUnmarshaller
241         {
242         public:
243             virtual ~SubjectConfirmationDataImpl() {}
244     
245             SubjectConfirmationDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
246                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
247             }
248                 
249             SubjectConfirmationDataImpl(const SubjectConfirmationDataImpl& src)
250                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractElementProxy(src),
251                         AbstractValidatingXMLObject(src) {
252                 for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
253                     if (*i) {
254                         getXMLObjects().push_back((*i)->clone());
255                     }
256                 }
257             }
258             
259             IMPL_XMLOBJECT_CLONE(SubjectConfirmationData);
260             IMPL_XMLOBJECT_CONTENT;
261     
262         protected:
263             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
264                 getXMLObjects().push_back(childXMLObject);
265             }
266         };
267
268         class SAML_DLLLOCAL SubjectConfirmationImpl : public virtual SubjectConfirmation,
269             public AbstractComplexElement,
270             public AbstractDOMCachingXMLObject,
271             public AbstractValidatingXMLObject,
272             public AbstractXMLObjectMarshaller,
273             public AbstractXMLObjectUnmarshaller
274         {
275         public:
276             virtual ~SubjectConfirmationImpl() {}
277     
278             SubjectConfirmationImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
279                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
280                 init();
281             }
282                 
283             SubjectConfirmationImpl(const SubjectConfirmationImpl& src)
284                     : AbstractXMLObject(src),
285                         AbstractDOMCachingXMLObject(src),
286                         AbstractValidatingXMLObject(src) {
287                 init();
288                 if (src.getSubjectConfirmationData())
289                     setSubjectConfirmationData(src.getSubjectConfirmationData()->clone());
290                 if (src.getKeyInfo())
291                     setKeyInfo(src.getKeyInfo()->cloneKeyInfo());
292                 VectorOf(ConfirmationMethod) v=getConfirmationMethods();
293                 for (vector<ConfirmationMethod*>::const_iterator i=src.m_ConfirmationMethods.begin(); i!=src.m_ConfirmationMethods.end(); i++) {
294                     if (*i) {
295                         v.push_back((*i)->cloneConfirmationMethod());
296                     }
297                 }
298             }
299             
300             void init() {
301                 m_SubjectConfirmationData=NULL;
302                 m_KeyInfo=NULL;
303                 m_children.push_back(NULL);
304                 m_children.push_back(NULL);
305                 m_pos_SubjectConfirmationData=m_children.begin();
306                 m_pos_KeyInfo=m_pos_SubjectConfirmationData;
307                 ++m_pos_KeyInfo;
308             }
309
310             IMPL_XMLOBJECT_CLONE(SubjectConfirmation);
311             IMPL_TYPED_CHILDREN(ConfirmationMethod,m_pos_SubjectConfirmationData);
312             IMPL_XMLOBJECT_CHILD(SubjectConfirmationData);
313             IMPL_TYPED_CHILD(KeyInfo);
314     
315         protected:
316             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
317                 PROC_TYPED_CHILDREN(ConfirmationMethod,SAMLConstants::SAML1_NS,false);
318                 PROC_TYPED_CHILD(KeyInfo,XMLConstants::XMLSIG_NS,false);
319                 
320                 // Anything else we'll assume is the data.
321                 if (getSubjectConfirmationData())
322                     throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
323                 setSubjectConfirmationData(childXMLObject);
324             }
325         };
326
327         class SAML_DLLLOCAL SubjectImpl : public virtual Subject,
328             public AbstractComplexElement,
329             public AbstractDOMCachingXMLObject,
330             public AbstractValidatingXMLObject,
331             public AbstractXMLObjectMarshaller,
332             public AbstractXMLObjectUnmarshaller
333         {
334         public:
335             virtual ~SubjectImpl() {}
336     
337             SubjectImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
338                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
339                 init();
340             }
341                 
342             SubjectImpl(const SubjectImpl& src)
343                     : AbstractXMLObject(src),
344                         AbstractDOMCachingXMLObject(src),
345                         AbstractValidatingXMLObject(src) {
346                 init();
347                 if (src.getNameIdentifier())
348                     setNameIdentifier(src.getNameIdentifier()->cloneNameIdentifier());
349                 if (src.getSubjectConfirmation())
350                     setSubjectConfirmation(src.getSubjectConfirmation()->cloneSubjectConfirmation());
351             }
352             
353             void init() {
354                 m_NameIdentifier=NULL;
355                 m_SubjectConfirmation=NULL;
356                 m_children.push_back(NULL);
357                 m_children.push_back(NULL);
358                 m_pos_NameIdentifier=m_children.begin();
359                 m_pos_SubjectConfirmation=m_pos_NameIdentifier;
360                 ++m_pos_SubjectConfirmation;
361             }
362
363             IMPL_XMLOBJECT_CLONE(Subject);
364             IMPL_TYPED_CHILD(NameIdentifier);
365             IMPL_TYPED_CHILD(SubjectConfirmation);
366     
367         protected:
368             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
369                 PROC_TYPED_CHILD(NameIdentifier,SAMLConstants::SAML1_NS,true);
370                 PROC_TYPED_CHILD(SubjectConfirmation,SAMLConstants::SAML1_NS,true);
371                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
372             }
373         };
374
375         class SAML_DLLLOCAL SubjectStatementImpl : public virtual SubjectStatement,
376             public AbstractComplexElement,
377             public AbstractDOMCachingXMLObject,
378             public AbstractValidatingXMLObject,
379             public AbstractXMLObjectMarshaller,
380             public AbstractXMLObjectUnmarshaller
381         {
382         public:
383             virtual ~SubjectStatementImpl() {}
384     
385             SubjectStatementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
386                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
387                 init();
388             }
389                 
390             SubjectStatementImpl(const SubjectStatementImpl& src)
391                     : AbstractXMLObject(src),
392                         AbstractDOMCachingXMLObject(src),
393                         AbstractValidatingXMLObject(src) {
394                 init();
395                 if (src.getSubject())
396                     setSubject(src.getSubject()->cloneSubject());
397             }
398             
399             void init() {
400                 m_Subject=NULL;
401                 m_children.push_back(NULL);
402                 m_pos_Subject=m_children.begin();
403             }
404
405             IMPL_TYPED_CHILD(Subject);
406     
407         protected:
408             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
409                 PROC_TYPED_CHILD(Subject,SAMLConstants::SAML1_NS,true);
410                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
411             }
412         };
413
414         class SAML_DLLLOCAL AuthenticationStatementImpl : public virtual AuthenticationStatement, public SubjectStatementImpl
415         {
416         public:
417             virtual ~AuthenticationStatementImpl() {
418                 XMLString::release(&m_AuthenticationMethod);
419                 delete m_AuthenticationInstant;
420             }
421     
422             AuthenticationStatementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
423                 : SubjectStatementImpl(nsURI, localName, prefix, schemaType) {
424                 init();
425             }
426                 
427             AuthenticationStatementImpl(const AuthenticationStatementImpl& src) : SubjectStatementImpl(src) {
428                 init();
429                 setAuthenticationMethod(src.getAuthenticationMethod());
430                 setAuthenticationInstant(src.getAuthenticationInstant());
431                 if (src.getSubjectLocality())
432                     setSubjectLocality(src.getSubjectLocality()->cloneSubjectLocality());
433                 VectorOf(AuthorityBinding) v=getAuthorityBindings();
434                 for (vector<AuthorityBinding*>::const_iterator i=src.m_AuthorityBindings.begin(); i!=src.m_AuthorityBindings.end(); i++) {
435                     if (*i) {
436                         v.push_back((*i)->cloneAuthorityBinding());
437                     }
438                 }
439             }
440             
441             void init() {
442                 SubjectStatementImpl::init();
443                 m_AuthenticationMethod=NULL;
444                 m_AuthenticationInstant=NULL;
445                 m_SubjectLocality=NULL;
446                 m_children.push_back(NULL);
447                 m_pos_SubjectLocality=m_pos_Subject;
448                 m_pos_SubjectLocality++;
449             }
450             
451             IMPL_XMLOBJECT_CLONE(AuthenticationStatement);
452             SubjectStatement* cloneSubjectStatement() const {
453                 return cloneAuthenticationStatement();
454             }
455             Statement* cloneStatement() const {
456                 return cloneAuthenticationStatement();
457             }
458             IMPL_STRING_ATTRIB(AuthenticationMethod);
459             IMPL_DATETIME_ATTRIB(AuthenticationInstant);
460             IMPL_TYPED_CHILD(SubjectLocality);
461             IMPL_TYPED_CHILDREN(AuthorityBinding, m_children.end());
462     
463         protected:
464             void marshallAttributes(DOMElement* domElement) const {
465                 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
466                 MARSHALL_DATETIME_ATTRIB(AuthenticationInstant,AUTHENTICATIONINSTANT,NULL);
467                 SubjectStatementImpl::marshallAttributes(domElement);
468             }
469     
470             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
471                 PROC_TYPED_CHILD(SubjectLocality,SAMLConstants::SAML1_NS,false);
472                 PROC_TYPED_CHILDREN(AuthorityBinding,SAMLConstants::SAML1_NS,false);
473                 SubjectStatementImpl::processChildElement(childXMLObject,root);
474             }
475     
476             void processAttribute(const DOMAttr* attribute) {
477                 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL);
478                 PROC_DATETIME_ATTRIB(AuthenticationInstant,AUTHENTICATIONINSTANT,NULL);
479                 SubjectStatementImpl::processAttribute(attribute);
480             }
481         };
482
483         class SAML_DLLLOCAL SubjectLocalityImpl : public virtual SubjectLocality,
484             public AbstractChildlessElement,
485             public AbstractDOMCachingXMLObject,
486             public AbstractValidatingXMLObject,
487             public AbstractXMLObjectMarshaller,
488             public AbstractXMLObjectUnmarshaller
489         {
490         public:
491             virtual ~SubjectLocalityImpl() {
492                 XMLString::release(&m_IPAddress);
493                 XMLString::release(&m_DNSAddress);
494             }
495     
496             SubjectLocalityImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
497                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
498                 init();
499             }
500                 
501             SubjectLocalityImpl(const SubjectLocalityImpl& src)
502                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
503                 init();
504                 setIPAddress(src.getIPAddress());
505                 setDNSAddress(src.getDNSAddress());
506             }
507             
508             void init() {
509                 m_IPAddress=m_DNSAddress=NULL;
510             }
511             
512             IMPL_XMLOBJECT_CLONE(SubjectLocality);
513             IMPL_STRING_ATTRIB(IPAddress);
514             IMPL_STRING_ATTRIB(DNSAddress);
515     
516         protected:
517             void marshallAttributes(DOMElement* domElement) const {
518                 MARSHALL_STRING_ATTRIB(IPAddress,IPADDRESS,NULL);
519                 MARSHALL_STRING_ATTRIB(DNSAddress,DNSADDRESS,NULL);
520             }
521     
522             void processAttribute(const DOMAttr* attribute) {
523                 PROC_STRING_ATTRIB(IPAddress,IPADDRESS,NULL);
524                 PROC_STRING_ATTRIB(DNSAddress,DNSADDRESS,NULL);
525             }
526         };
527
528         class SAML_DLLLOCAL AuthorityBindingImpl : public virtual AuthorityBinding,
529             public AbstractChildlessElement,
530             public AbstractDOMCachingXMLObject,
531             public AbstractValidatingXMLObject,
532             public AbstractXMLObjectMarshaller,
533             public AbstractXMLObjectUnmarshaller
534         {
535         public:
536             virtual ~AuthorityBindingImpl() {
537                 delete m_AuthorityKind;
538                 XMLString::release(&m_Location);
539                 XMLString::release(&m_Binding);
540             }
541     
542             AuthorityBindingImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
543                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
544                 init();
545             }
546                 
547             AuthorityBindingImpl(const AuthorityBindingImpl& src)
548                     : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
549                 init();
550                 setAuthorityKind(src.getAuthorityKind());
551                 setLocation(src.getLocation());
552                 setBinding(src.getBinding());
553             }
554             
555             void init() {
556                 m_AuthorityKind=NULL;
557                 m_Location=m_Binding=NULL;
558             }
559             
560             IMPL_XMLOBJECT_CLONE(AuthorityBinding);
561             IMPL_XMLOBJECT_ATTRIB(AuthorityKind,QName);
562             IMPL_STRING_ATTRIB(Location);
563             IMPL_STRING_ATTRIB(Binding);
564     
565         protected:
566             void marshallAttributes(DOMElement* domElement) const {
567                 MARSHALL_QNAME_ATTRIB(AuthorityKind,AUTHORITYKIND,NULL);
568                 MARSHALL_STRING_ATTRIB(Location,LOCATION,NULL);
569                 MARSHALL_STRING_ATTRIB(Binding,BINDING,NULL);
570             }
571     
572             void processAttribute(const DOMAttr* attribute) {
573                 PROC_QNAME_ATTRIB(AuthorityKind,AUTHORITYKIND,NULL);
574                 PROC_STRING_ATTRIB(Location,LOCATION,NULL);
575                 PROC_STRING_ATTRIB(Binding,BINDING,NULL);
576             }
577         };
578
579         class SAML_DLLLOCAL AdviceImpl : public virtual Advice,
580             public AbstractComplexElement,
581             public AbstractDOMCachingXMLObject,
582             public AbstractValidatingXMLObject,
583             public AbstractXMLObjectMarshaller,
584             public AbstractXMLObjectUnmarshaller
585         {
586         public:
587             virtual ~AdviceImpl() {}
588     
589             AdviceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
590                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
591             }
592                 
593             AdviceImpl(const AdviceImpl& src)
594                     : AbstractXMLObject(src),
595                         AbstractDOMCachingXMLObject(src),
596                         AbstractValidatingXMLObject(src) {
597     
598                 for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
599                     if (*i) {
600                         AssertionIDReference* ref=dynamic_cast<AssertionIDReference*>(*i);
601                         if (ref) {
602                             getAssertionIDReferences().push_back(ref->cloneAssertionIDReference());
603                             continue;
604                         }
605     
606                         Assertion* assertion=dynamic_cast<Assertion*>(*i);
607                         if (assertion) {
608                             getAssertions().push_back(assertion->cloneAssertion());
609                             continue;
610                         }
611     
612                         getOthers().push_back((*i)->clone());
613                     }
614                 }
615             }
616             
617             IMPL_XMLOBJECT_CLONE(Advice);
618             IMPL_TYPED_CHILDREN(AssertionIDReference,m_children.end());
619             IMPL_TYPED_CHILDREN(Assertion,m_children.end());
620             IMPL_XMLOBJECT_CHILDREN(Other,m_children.end());
621     
622         protected:
623             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
624                 PROC_TYPED_CHILDREN(AssertionIDReference,SAMLConstants::SAML1_NS,false);
625                 PROC_TYPED_CHILDREN(Assertion,SAMLConstants::SAML1_NS,true);
626                 
627                 // Unknown child.
628                 const XMLCh* nsURI=root->getNamespaceURI();
629                 if (!XMLString::equals(nsURI,SAMLConstants::SAML1_NS) && nsURI && *nsURI)
630                     getOthers().push_back(childXMLObject);
631                 
632                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
633             }
634         };
635
636         class SAML_DLLLOCAL AssertionImpl : public virtual Assertion,
637             public AbstractComplexElement,
638             public AbstractDOMCachingXMLObject,
639             public AbstractValidatingXMLObject,
640             public AbstractXMLObjectMarshaller,
641             public AbstractXMLObjectUnmarshaller
642         {
643         public:
644             virtual ~AssertionImpl() {
645                 XMLString::release(&m_AssertionID);
646                 XMLString::release(&m_Issuer);
647                 delete m_IssueInstant;
648             }
649     
650             AssertionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
651                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
652                 init();
653             }
654                 
655             AssertionImpl(const AssertionImpl& src)                     
656                 : AbstractXMLObject(src),
657                     AbstractDOMCachingXMLObject(src),
658                     AbstractValidatingXMLObject(src) {
659                 init();
660                 setMinorVersion(src.getMinorVersion());
661                 setAssertionID(src.getAssertionID());
662                 setIssuer(src.getIssuer());
663                 setIssueInstant(src.getIssueInstant());
664                 if (src.getConditions())
665                     setConditions(src.getConditions()->cloneConditions());
666                 if (src.getAdvice())
667                     setAdvice(src.getAdvice()->cloneAdvice());
668                 if (src.getSignature())
669                     setSignature(src.getSignature()->cloneSignature());
670                 for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
671                     if (*i) {
672                         AuthenticationStatement* authst=dynamic_cast<AuthenticationStatement*>(*i);
673                         if (authst) {
674                             getAuthenticationStatements().push_back(authst->cloneAuthenticationStatement());
675                             continue;
676                         }
677     
678                         SubjectStatement* subst=dynamic_cast<SubjectStatement*>(*i);
679                         if (subst) {
680                             getSubjectStatements().push_back(subst->cloneSubjectStatement());
681                             continue;
682                         }
683     
684                         Statement* st=dynamic_cast<Statement*>(*i);
685                         if (st) {
686                             getStatements().push_back(st->cloneStatement());
687                             continue;
688                         }
689                     }
690                 }
691             }
692             
693             void init() {
694                 m_MinorVersion=1;
695                 m_AssertionID=NULL;
696                 m_Issuer=NULL;
697                 m_IssueInstant=NULL;
698                 m_children.push_back(NULL);
699                 m_children.push_back(NULL);
700                 m_children.push_back(NULL);
701                 m_Conditions=NULL;
702                 m_Advice=NULL;
703                 m_Signature=NULL;
704                 m_pos_Conditions=m_children.begin();
705                 m_pos_Advice=m_pos_Conditions;
706                 m_pos_Advice++;
707                 m_pos_Signature=m_pos_Advice;
708                 m_pos_Signature++;
709             }
710             
711             IMPL_XMLOBJECT_CLONE(Assertion);
712             IMPL_INTEGER_ATTRIB(MinorVersion);
713             IMPL_STRING_ATTRIB(AssertionID);
714             IMPL_STRING_ATTRIB(Issuer);
715             IMPL_DATETIME_ATTRIB(IssueInstant);
716             IMPL_TYPED_CHILD(Conditions);
717             IMPL_TYPED_CHILD(Advice);
718             IMPL_TYPED_CHILD(Signature);
719             IMPL_TYPED_CHILDREN(Statement, m_pos_Signature);
720             IMPL_TYPED_CHILDREN(SubjectStatement, m_pos_Signature);
721             IMPL_TYPED_CHILDREN(AuthenticationStatement, m_pos_Signature);
722     
723         protected:
724             void marshallAttributes(DOMElement* domElement) const {
725                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
726                 static const XMLCh ONE[] = { chDigit_1, chNull };
727                 domElement->setAttributeNS(NULL,MAJORVERSION,ONE);
728                 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
729                 if (!m_AssertionID)
730                     const_cast<AssertionImpl*>(this)->m_AssertionID=SAMLConfig::getConfig().generateIdentifier();
731                 MARSHALL_ID_ATTRIB(AssertionID,ASSERTIONID,NULL);
732                 MARSHALL_STRING_ATTRIB(Issuer,ISSUER,NULL);
733                 if (!m_IssueInstant)
734                     const_cast<AssertionImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
735                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
736             }
737     
738             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
739                 PROC_TYPED_CHILD(Conditions,SAMLConstants::SAML1_NS,false);
740                 PROC_TYPED_CHILD(Advice,SAMLConstants::SAML1_NS,false);
741                 PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false);
742                 PROC_TYPED_CHILDREN(AuthenticationStatement,SAMLConstants::SAML1_NS,false);
743                 PROC_TYPED_CHILDREN(SubjectStatement,SAMLConstants::SAML1_NS,true);
744                 PROC_TYPED_CHILDREN(Statement,SAMLConstants::SAML1_NS,true);
745                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
746             }
747     
748             void processAttribute(const DOMAttr* attribute) {
749                 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
750                 if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) {
751                     if (XMLString::parseInt(attribute->getValue()) != 1)
752                         throw UnmarshallingException("Assertion has invalid major version.");
753                 }
754                 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL);
755                 PROC_ID_ATTRIB(AssertionID,ASSERTIONID,NULL);
756                 PROC_STRING_ATTRIB(Issuer,ISSUER,NULL);
757                 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
758             }
759         };
760     
761     };
762 };
763
764 #if defined (_MSC_VER)
765     #pragma warning( pop )
766 #endif
767
768 // Builder Implementations
769
770 IMPL_XMLOBJECTBUILDER(Advice);
771 IMPL_XMLOBJECTBUILDER(Assertion);
772 IMPL_XMLOBJECTBUILDER(AssertionIDReference);
773 IMPL_XMLOBJECTBUILDER(Audience);
774 IMPL_XMLOBJECTBUILDER(AudienceRestrictionCondition);
775 IMPL_XMLOBJECTBUILDER(AuthenticationStatement);
776 IMPL_XMLOBJECTBUILDER(AuthorityBinding);
777 IMPL_XMLOBJECTBUILDER(Conditions);
778 IMPL_XMLOBJECTBUILDER(ConfirmationMethod);
779 IMPL_XMLOBJECTBUILDER(DoNotCacheCondition);
780 IMPL_XMLOBJECTBUILDER(NameIdentifier);
781 IMPL_XMLOBJECTBUILDER(Subject);
782 IMPL_XMLOBJECTBUILDER(SubjectConfirmation);
783 IMPL_XMLOBJECTBUILDER(SubjectConfirmationData);
784 IMPL_XMLOBJECTBUILDER(SubjectLocality);
785
786 // Unicode literals
787 const XMLCh Advice::LOCAL_NAME[] =                  UNICODE_LITERAL_6(A,d,v,i,c,e);
788 const XMLCh Advice::TYPE_NAME[] =                   UNICODE_LITERAL_10(A,d,v,i,c,e,T,y,p,e);
789 const XMLCh Assertion::LOCAL_NAME[] =               UNICODE_LITERAL_9(A,s,s,e,r,t,i,o,n);
790 const XMLCh Assertion::TYPE_NAME[] =                UNICODE_LITERAL_13(A,s,s,e,r,t,i,o,n,T,y,p,e);
791 const XMLCh Assertion::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
792 const XMLCh Assertion::ASSERTIONID_ATTRIB_NAME[] =  UNICODE_LITERAL_11(A,s,s,e,r,t,i,o,n,I,D);
793 const XMLCh Assertion::ISSUER_ATTRIB_NAME[] =       UNICODE_LITERAL_6(I,s,s,u,e,r);
794 const XMLCh Assertion::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
795 const XMLCh AssertionIDReference::LOCAL_NAME[] =    UNICODE_LITERAL_20(A,s,s,e,r,t,i,o,n,I,D,R,e,f,e,r,e,n,c,e);
796 const XMLCh Audience::LOCAL_NAME[] =                UNICODE_LITERAL_8(A,u,d,i,e,n,c,e);
797 const XMLCh AudienceRestrictionCondition::LOCAL_NAME[] =    UNICODE_LITERAL_28(A,u,d,i,e,n,c,e,R,e,s,t,r,i,c,t,i,o,n,C,o,n,d,i,t,i,o,n);
798 const XMLCh AudienceRestrictionCondition::TYPE_NAME[] =     UNICODE_LITERAL_32(A,u,d,i,e,n,c,e,R,e,s,t,r,i,c,t,i,o,n,C,o,n,d,i,t,i,o,n,T,y,p,e);
799 const XMLCh AuthenticationStatement::LOCAL_NAME[] = UNICODE_LITERAL_23(A,u,t,h,e,n,t,i,c,a,t,i,o,n,S,t,a,t,e,m,e,n,t);
800 const XMLCh AuthenticationStatement::TYPE_NAME[] =  UNICODE_LITERAL_27(A,u,t,h,e,n,t,i,c,a,t,i,o,n,S,t,a,t,e,m,e,n,t,T,y,p,e);
801 const XMLCh AuthenticationStatement::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);
802 const XMLCh AuthenticationStatement::AUTHENTICATIONINSTANT_ATTRIB_NAME[] =  UNICODE_LITERAL_21(A,u,t,h,e,n,t,i,c,a,t,i,o,n,I,n,s,t,a,n,t);
803 const XMLCh AuthorityBinding::LOCAL_NAME[] =        UNICODE_LITERAL_16(A,u,t,h,o,r,i,t,y,B,i,n,d,i,n,g);
804 const XMLCh AuthorityBinding::TYPE_NAME[] =         UNICODE_LITERAL_20(A,u,t,h,o,r,i,t,y,B,i,n,d,i,n,g,T,y,p,e);
805 const XMLCh AuthorityBinding::AUTHORITYKIND_ATTRIB_NAME[] = UNICODE_LITERAL_13(A,u,t,h,o,r,i,t,y,K,i,n,d);
806 const XMLCh AuthorityBinding::LOCATION_ATTRIB_NAME[] =      UNICODE_LITERAL_8(L,o,c,a,t,i,o,n);
807 const XMLCh AuthorityBinding::BINDING_ATTRIB_NAME[] =       UNICODE_LITERAL_7(B,i,n,d,i,n,g);
808 const XMLCh Condition::LOCAL_NAME[] =               UNICODE_LITERAL_9(C,o,n,d,i,t,i,o,n);
809 const XMLCh Conditions::LOCAL_NAME[] =              UNICODE_LITERAL_10(C,o,n,d,i,t,i,o,n,s);
810 const XMLCh Conditions::TYPE_NAME[] =               UNICODE_LITERAL_14(C,o,n,d,i,t,i,o,n,s,T,y,p,e);
811 const XMLCh Conditions::NOTBEFORE_ATTRIB_NAME[] =   UNICODE_LITERAL_9(N,o,t,B,e,f,o,r,e);
812 const XMLCh Conditions::NOTONORAFTER_ATTRIB_NAME[] =UNICODE_LITERAL_12(N,o,t,O,n,O,r,A,f,t,e,r);
813 const XMLCh ConfirmationMethod::LOCAL_NAME[] =      UNICODE_LITERAL_18(C,o,n,f,i,r,m,a,t,i,o,n,M,e,t,h,o,d);
814 const XMLCh DoNotCacheCondition::LOCAL_NAME[] =     UNICODE_LITERAL_19(D,o,N,o,t,C,a,c,h,e,C,o,n,d,i,t,i,o,n);
815 const XMLCh DoNotCacheCondition::TYPE_NAME[] =      UNICODE_LITERAL_23(D,o,N,o,t,C,a,c,h,e,C,o,n,d,i,t,i,o,n,T,y,p,e);
816 const XMLCh NameIdentifier::LOCAL_NAME[] =          UNICODE_LITERAL_14(N,a,m,e,I,d,e,n,t,i,f,i,e,r);
817 const XMLCh NameIdentifier::TYPE_NAME[] =           UNICODE_LITERAL_18(N,a,m,e,I,d,e,n,t,i,f,i,e,r,T,y,p,e);
818 const XMLCh NameIdentifier::NAMEQUALIFIER_ATTRIB_NAME[] =   UNICODE_LITERAL_13(N,a,m,e,Q,u,a,l,i,f,i,e,r);
819 const XMLCh NameIdentifier::FORMAT_ATTRIB_NAME[] =  UNICODE_LITERAL_6(F,o,r,m,a,t);
820 const XMLCh Statement::LOCAL_NAME[] =               UNICODE_LITERAL_9(S,t,a,t,e,m,e,n,t);
821 const XMLCh Subject::LOCAL_NAME[] =                 UNICODE_LITERAL_7(S,u,b,j,e,c,t);
822 const XMLCh Subject::TYPE_NAME[] =                  UNICODE_LITERAL_11(S,u,b,j,e,c,t,T,y,p,e);
823 const XMLCh SubjectConfirmation::LOCAL_NAME[] =     UNICODE_LITERAL_19(S,u,b,j,e,c,t,C,o,n,f,i,r,m,a,t,i,o,n);
824 const XMLCh SubjectConfirmation::TYPE_NAME[] =      UNICODE_LITERAL_23(S,u,b,j,e,c,t,C,o,n,f,i,r,m,a,t,i,o,n,T,y,p,e);
825 const XMLCh SubjectConfirmationData::LOCAL_NAME[] = UNICODE_LITERAL_23(S,u,b,j,e,c,t,C,o,n,f,i,r,m,a,t,i,o,n,D,a,t,a);
826 const XMLCh SubjectLocality::LOCAL_NAME[] =         UNICODE_LITERAL_15(S,u,b,j,e,c,t,L,o,c,a,l,i,t,y);
827 const XMLCh SubjectLocality::TYPE_NAME[] =          UNICODE_LITERAL_19(S,u,b,j,e,c,t,L,o,c,a,l,i,t,y,T,y,p,e);
828 const XMLCh SubjectLocality::IPADDRESS_ATTRIB_NAME[] =      UNICODE_LITERAL_9(I,P,A,d,d,r,e,s,s);
829 const XMLCh SubjectLocality::DNSADDRESS_ATTRIB_NAME[] =     UNICODE_LITERAL_10(D,N,S,A,d,d,r,e,s,s);
830
831 #define XCH(ch) chLatin_##ch
832 #define XNUM(d) chDigit_##d