Add implicit support for a "null" protocol.
[shibboleth/cpp-opensaml.git] / saml / saml2 / metadata / impl / MetadataImpl.cpp
index f8eab77..91615d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2006 Internet2
+ *  Copyright 2001-2007 Internet2
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,9 +24,7 @@
 #include "exceptions.h"
 #include "saml2/metadata/Metadata.h"
 
-#include <xmltooling/AbstractChildlessElement.h>
 #include <xmltooling/AbstractComplexElement.h>
-#include <xmltooling/AbstractElementProxy.h>
 #include <xmltooling/AbstractSimpleElement.h>
 #include <xmltooling/impl/AnyElement.h>
 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
@@ -36,6 +34,7 @@
 #include <ctime>
 #include <xercesc/util/XMLUniDefs.hpp>
 
+using namespace samlconstants;
 using namespace opensaml::saml2md;
 using namespace opensaml::saml2;
 using namespace opensaml;
@@ -43,6 +42,8 @@ using namespace xmlencryption;
 using namespace xmlsignature;
 using namespace xmltooling;
 using namespace std;
+using xmlconstants::XMLSIG_NS;
+using xmlconstants::XML_BOOL_NULL;
 
 #if defined (_MSC_VER)
     #pragma warning( push )
@@ -66,7 +67,6 @@ namespace opensaml {
 
         class SAML_DLLLOCAL localizedNameTypeImpl : public virtual localizedNameType,
             public AbstractSimpleElement,
-            public AbstractChildlessElement,
             public AbstractDOMCachingXMLObject,
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
@@ -97,23 +97,21 @@ namespace opensaml {
             }
             
             IMPL_XMLOBJECT_CLONE(localizedNameType);
-            IMPL_XMLOBJECT_CONTENT;
             IMPL_STRING_ATTRIB(Lang);
     
         protected:
             void marshallAttributes(DOMElement* domElement) const {
-                MARSHALL_STRING_ATTRIB(Lang,LANG,XMLConstants::XML_NS);
+                MARSHALL_STRING_ATTRIB(Lang,LANG,xmlconstants::XML_NS);
             }
 
             void processAttribute(const DOMAttr* attribute) {
-                PROC_STRING_ATTRIB(Lang,LANG,XMLConstants::XML_NS);
+                PROC_STRING_ATTRIB(Lang,LANG,xmlconstants::XML_NS);
                 AbstractXMLObjectUnmarshaller::processAttribute(attribute);
             }
         };
 
         class SAML_DLLLOCAL localizedURITypeImpl : public virtual localizedURIType,
             public AbstractSimpleElement,
-            public AbstractChildlessElement,
             public AbstractDOMCachingXMLObject,
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
@@ -144,16 +142,15 @@ namespace opensaml {
             }
             
             IMPL_XMLOBJECT_CLONE(localizedURIType);
-            IMPL_XMLOBJECT_CONTENT;
             IMPL_STRING_ATTRIB(Lang);
     
         protected:
             void marshallAttributes(DOMElement* domElement) const {
-                MARSHALL_STRING_ATTRIB(Lang,LANG,XMLConstants::XML_NS);
+                MARSHALL_STRING_ATTRIB(Lang,LANG,xmlconstants::XML_NS);
             }
 
             void processAttribute(const DOMAttr* attribute) {
-                PROC_STRING_ATTRIB(Lang,LANG,XMLConstants::XML_NS);
+                PROC_STRING_ATTRIB(Lang,LANG,xmlconstants::XML_NS);
                 AbstractXMLObjectUnmarshaller::processAttribute(attribute);
             }
         };
@@ -239,7 +236,7 @@ namespace opensaml {
         };
 
         class SAML_DLLLOCAL ExtensionsImpl : public virtual Extensions,
-            public AbstractElementProxy,
+            public AbstractComplexElement,
             public AbstractDOMCachingXMLObject,
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
@@ -252,22 +249,21 @@ namespace opensaml {
             }
                 
             ExtensionsImpl(const ExtensionsImpl& src)
-                    : AbstractXMLObject(src), AbstractElementProxy(src), AbstractDOMCachingXMLObject(src) {
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        getXMLObjects().push_back((*i)->clone());
-                    }
-                }
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+                VectorOf(XMLObject) v=getUnknownXMLObjects();
+                for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
+                    v.push_back((*i)->clone());
             }
             
             IMPL_XMLOBJECT_CLONE(Extensions);
+            IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
     
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
                 // Unknown child.
                 const XMLCh* nsURI=root->getNamespaceURI();
-                if (!XMLString::equals(nsURI,SAMLConstants::SAML20MD_NS) && nsURI && *nsURI) {
-                    getXMLObjects().push_back(childXMLObject);
+                if (!XMLString::equals(nsURI,SAML20MD_NS) && nsURI && *nsURI) {
+                    getUnknownXMLObjects().push_back(childXMLObject);
                     return;
                 }
                 
@@ -305,7 +301,8 @@ namespace opensaml {
             }
                 
             OrganizationImpl(const OrganizationImpl& src)
-                    : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src),
+                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 if (src.getExtensions())
                     setExtensions(src.getExtensions()->cloneExtensions());
@@ -341,10 +338,10 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILD(Extensions,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(OrganizationName,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(OrganizationDisplayName,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(OrganizationURL,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILD(Extensions,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(OrganizationName,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(OrganizationDisplayName,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(OrganizationURL,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -392,7 +389,8 @@ namespace opensaml {
             }
                 
             ContactPersonImpl(const ContactPersonImpl& src)
-                    : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src),
+                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 if (src.getExtensions())
                     setExtensions(src.getExtensions()->cloneExtensions());
@@ -443,12 +441,12 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILD(Extensions,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILD(Company,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILD(GivenName,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILD(SurName,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(EmailAddress,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(TelephoneNumber,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILD(Extensions,SAML20MD_NS,false);
+                PROC_TYPED_CHILD(Company,SAML20MD_NS,false);
+                PROC_TYPED_CHILD(GivenName,SAML20MD_NS,false);
+                PROC_TYPED_CHILD(SurName,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(EmailAddress,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(TelephoneNumber,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -459,7 +457,6 @@ namespace opensaml {
 
         class SAML_DLLLOCAL AdditionalMetadataLocationImpl : public virtual AdditionalMetadataLocation,
             public AbstractSimpleElement,
-            public AbstractChildlessElement,
             public AbstractDOMCachingXMLObject,
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
@@ -484,7 +481,6 @@ namespace opensaml {
             }
             
             IMPL_XMLOBJECT_CLONE(AdditionalMetadataLocation);
-            IMPL_XMLOBJECT_CONTENT;
             IMPL_STRING_ATTRIB(Namespace);
     
         protected:
@@ -520,7 +516,8 @@ namespace opensaml {
                 init();
             }
                 
-            KeyDescriptorImpl(const KeyDescriptorImpl& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src) {
+            KeyDescriptorImpl(const KeyDescriptorImpl& src)
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setUse(src.getUse());
                 if (src.getKeyInfo())
@@ -544,8 +541,8 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_FOREIGN_CHILD(KeyInfo,xmlsignature,XMLConstants::XMLSIG_NS,false);
-                PROC_TYPED_FOREIGN_CHILDREN(EncryptionMethod,xmlencryption,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILD(KeyInfo,xmlsignature,XMLSIG_NS,false);
+                PROC_TYPED_FOREIGN_CHILDREN(EncryptionMethod,xmlencryption,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -556,8 +553,8 @@ namespace opensaml {
         };
 
         class SAML_DLLLOCAL EndpointTypeImpl : public virtual EndpointType,
-            public AbstractElementProxy,
             public AbstractAttributeExtensibleXMLObject,
+            public AbstractComplexElement,
             public AbstractDOMCachingXMLObject,
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
@@ -583,22 +580,23 @@ namespace opensaml {
             }
                 
             EndpointTypeImpl(const EndpointTypeImpl& src)
-                    : AbstractXMLObject(src), AbstractElementProxy(src),
-                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src),
+                        AbstractAttributeExtensibleXMLObject(src),
+                        AbstractComplexElement(src),
+                        AbstractDOMCachingXMLObject(src) {
                 setBinding(src.getBinding());
                 setLocation(src.getLocation());
                 setResponseLocation(src.getResponseLocation());
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        getXMLObjects().push_back((*i)->clone());
-                    }
-                }
+                VectorOf(XMLObject) v=getUnknownXMLObjects();
+                for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
+                    v.push_back((*i)->clone());
             }
             
             IMPL_XMLOBJECT_CLONE(EndpointType);
             IMPL_STRING_ATTRIB(Binding);
             IMPL_STRING_ATTRIB(Location);
             IMPL_STRING_ATTRIB(ResponseLocation);
+            IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
     
             void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false) {
                 if (!qualifiedName.hasNamespaceURI()) {
@@ -628,8 +626,8 @@ namespace opensaml {
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
                 // Unknown child.
                 const XMLCh* nsURI=root->getNamespaceURI();
-                if (!XMLString::equals(nsURI,SAMLConstants::SAML20MD_NS) && nsURI && *nsURI) {
-                    getXMLObjects().push_back(childXMLObject);
+                if (!XMLString::equals(nsURI,SAML20MD_NS) && nsURI && *nsURI) {
+                    getUnknownXMLObjects().push_back(childXMLObject);
                     return;
                 }
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
@@ -644,7 +642,7 @@ namespace opensaml {
         {
             void init() {
                 m_Index=NULL;
-                m_isDefault=XMLConstants::XML_BOOL_NULL;
+                m_isDefault=XML_BOOL_NULL;
             }
         
         protected:
@@ -909,7 +907,8 @@ namespace opensaml {
             }
                 
             RoleDescriptorImpl(const RoleDescriptorImpl& src)
-                    : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src),
+                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setID(src.getID());
                 setProtocolSupportEnumeration(src.getProtocolSupportEnumeration());
@@ -966,6 +965,8 @@ namespace opensaml {
             IMPL_TYPED_CHILDREN(ContactPerson,m_pos_ContactPerson);
 
             bool hasSupport(const XMLCh* protocol) const {
+                if (!protocol || !*protocol)
+                    return true;
                 if (m_ProtocolSupportEnumeration) {
                     // Look for first character.
                     unsigned int len=XMLString::stringLen(protocol);
@@ -996,6 +997,28 @@ namespace opensaml {
                 }
                 return false;
             }
+
+            void addSupport(const XMLCh* protocol) {
+                if (hasSupport(protocol))
+                    return;
+                if (m_ProtocolSupportEnumeration && *m_ProtocolSupportEnumeration) {
+#ifdef HAVE_GOOD_STL
+                    xstring pse(m_ProtocolSupportEnumeration);
+                    pse = pse + chSpace + protocol;
+                    setProtocolSupportEnumeration(pse.c_str());
+#else
+                    auto_ptr_char temp(m_ProtocolSupportEnumeration);
+                    auto_ptr_char temp2(protocol);
+                    string pse(temp.get());
+                    pse = pse + ' ' + temp2.get();
+                    auto_ptr_XMLCh temp3(pse.c_str());
+                    setProtocolSupportEnumeration(temp3.get());
+#endif
+                }
+                else {
+                    setProtocolSupportEnumeration(protocol);
+                }
+            }
     
             void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false) {
                 if (!qualifiedName.hasNamespaceURI()) {
@@ -1034,11 +1057,11 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLConstants::XMLSIG_NS,false);
-                PROC_TYPED_CHILD(Extensions,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(KeyDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILD(Organization,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(ContactPerson,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
+                PROC_TYPED_CHILD(Extensions,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(KeyDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILD(Organization,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(ContactPerson,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -1118,10 +1141,10 @@ namespace opensaml {
 
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(ArtifactResolutionService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(SingleLogoutService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(ManageNameIDService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(NameIDFormat,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(ArtifactResolutionService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(SingleLogoutService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(ManageNameIDService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(NameIDFormat,SAML20MD_NS,false);
                 RoleDescriptorImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1134,7 +1157,7 @@ namespace opensaml {
             list<XMLObject*>::iterator m_pos_AttributeProfile;
             
             void init() {
-                m_WantAuthnRequestsSigned=XMLConstants::XML_BOOL_NULL;
+                m_WantAuthnRequestsSigned=XML_BOOL_NULL;
                 m_children.push_back(NULL);
                 m_children.push_back(NULL);
                 m_children.push_back(NULL);
@@ -1224,11 +1247,11 @@ namespace opensaml {
             }
             
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(SingleSignOnService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(NameIDMappingService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AttributeProfile,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_FOREIGN_CHILDREN(Attribute,saml2,SAMLConstants::SAML20_NS,false);
+                PROC_TYPED_CHILDREN(SingleSignOnService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(NameIDMappingService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AttributeProfile,SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILDREN(Attribute,saml2,SAML20_NS,false);
                 SSODescriptorTypeImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1242,7 +1265,7 @@ namespace opensaml {
         {
             void init() {
                 m_Name=m_NameFormat=m_FriendlyName=NULL;
-                m_isRequired=XMLConstants::XML_BOOL_NULL;
+                m_isRequired=XML_BOOL_NULL;
             }
         public:
             virtual ~RequestedAttributeImpl() {
@@ -1257,7 +1280,8 @@ namespace opensaml {
             }
                 
             RequestedAttributeImpl(const RequestedAttributeImpl& src)
-                    : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src),
+                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setName(src.getName());
                 setNameFormat(src.getNameFormat());
@@ -1333,7 +1357,7 @@ namespace opensaml {
             
                void init() {
                 m_Index=NULL;
-                m_isDefault=XMLConstants::XML_BOOL_NULL;
+                m_isDefault=XML_BOOL_NULL;
                 m_children.push_back(NULL);
                 m_children.push_back(NULL);
                 m_pos_ServiceDescription=m_children.begin();
@@ -1352,7 +1376,7 @@ namespace opensaml {
             }
                 
             AttributeConsumingServiceImpl(const AttributeConsumingServiceImpl& src)
-                    : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setIndex(src.m_Index);
                 isDefault(src.m_isDefault);
@@ -1390,9 +1414,9 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(ServiceName,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(ServiceDescription,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(RequestedAttribute,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(ServiceName,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(ServiceDescription,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(RequestedAttribute,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -1408,8 +1432,8 @@ namespace opensaml {
             list<XMLObject*>::iterator m_pos_AssertionConsumerService;
             
             void init() {
-                m_AuthnRequestsSigned=XMLConstants::XML_BOOL_NULL;
-                m_WantAssertionsSigned=XMLConstants::XML_BOOL_NULL;
+                m_AuthnRequestsSigned=XML_BOOL_NULL;
+                m_WantAssertionsSigned=XML_BOOL_NULL;
                 m_children.push_back(NULL);
                 m_pos_AssertionConsumerService=m_pos_NameIDFormat;
                 ++m_pos_AssertionConsumerService;
@@ -1476,8 +1500,8 @@ namespace opensaml {
             }
             
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(AssertionConsumerService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AttributeConsumingService,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AssertionConsumerService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AttributeConsumingService,SAML20MD_NS,false);
                 SSODescriptorTypeImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1537,9 +1561,9 @@ namespace opensaml {
 
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(AuthnQueryService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(NameIDFormat,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AuthnQueryService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(NameIDFormat,SAML20MD_NS,false);
                 RoleDescriptorImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1599,9 +1623,9 @@ namespace opensaml {
 
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(AuthzService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(NameIDFormat,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AuthzService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(NameIDFormat,SAML20MD_NS,false);
                 RoleDescriptorImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1683,11 +1707,11 @@ namespace opensaml {
 
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(AttributeService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(NameIDFormat,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AttributeProfile,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_FOREIGN_CHILDREN(Attribute,saml2,SAMLConstants::SAML20_NS,false);
+                PROC_TYPED_CHILDREN(AttributeService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AssertionIDRequestService,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(NameIDFormat,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AttributeProfile,SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILDREN(Attribute,saml2,SAML20_NS,false);
                 RoleDescriptorImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1695,7 +1719,7 @@ namespace opensaml {
         class SAML_DLLLOCAL QueryDescriptorTypeImpl : public virtual QueryDescriptorType, public RoleDescriptorImpl
         {
             void init() {
-                m_WantAssertionsSigned=XMLConstants::XML_BOOL_NULL;
+                m_WantAssertionsSigned=XML_BOOL_NULL;
                 m_children.push_back(NULL);
                 m_pos_NameIDFormat=m_pos_ContactPerson;
                 ++m_pos_NameIDFormat;
@@ -1747,7 +1771,7 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(NameIDFormat,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(NameIDFormat,SAML20MD_NS,false);
                 RoleDescriptorImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1801,7 +1825,7 @@ namespace opensaml {
 
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(AttributeConsumingService,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AttributeConsumingService,SAML20MD_NS,false);
                 QueryDescriptorTypeImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1836,7 +1860,7 @@ namespace opensaml {
 
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(ActionNamespace,SAMLConstants::SAML20MD_QUERY_EXT_NS,false);
+                PROC_TYPED_CHILDREN(ActionNamespace,samlconstants::SAML20MD_QUERY_EXT_NS,false);
                 QueryDescriptorTypeImpl::processChildElement(childXMLObject,root);
             }
         };
@@ -1880,7 +1904,8 @@ namespace opensaml {
             }
                 
             AffiliationDescriptorImpl(const AffiliationDescriptorImpl& src)
-                    : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src),
+                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setID(src.getID());
                 setAffiliationOwnerID(src.getAffiliationOwnerID());
@@ -1965,10 +1990,10 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLConstants::XMLSIG_NS,false);
-                PROC_TYPED_CHILD(Extensions,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AffiliateMember,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(KeyDescriptor,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
+                PROC_TYPED_CHILD(Extensions,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AffiliateMember,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(KeyDescriptor,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -2025,7 +2050,8 @@ namespace opensaml {
             }
                 
             EntityDescriptorImpl(const EntityDescriptorImpl& src)
-                    : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                    : AbstractXMLObject(src), AbstractComplexElement(src),
+                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setID(src.getID());
                 setEntityID(src.getEntityID());
@@ -2173,105 +2199,28 @@ namespace opensaml {
                 AbstractAttributeExtensibleXMLObject::setAttribute(qualifiedName, value, ID);
             }
 
-            const IDPSSODescriptor* getIDPSSODescriptor(const XMLCh* protocol) const {
-                for (vector<IDPSSODescriptor*>::const_iterator i=m_IDPSSODescriptors.begin(); i!=m_IDPSSODescriptors.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-            
-            const SPSSODescriptor* getSPSSODescriptor(const XMLCh* protocol) const {
-                for (vector<SPSSODescriptor*>::const_iterator i=m_SPSSODescriptors.begin(); i!=m_SPSSODescriptors.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-            
-            const AuthnAuthorityDescriptor* getAuthnAuthorityDescriptor(const XMLCh* protocol) const {
-                for (vector<AuthnAuthorityDescriptor*>::const_iterator i=m_AuthnAuthorityDescriptors.begin(); i!=m_AuthnAuthorityDescriptors.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-            
-            const AttributeAuthorityDescriptor* getAttributeAuthorityDescriptor(const XMLCh* protocol) const {
-                for (vector<AttributeAuthorityDescriptor*>::const_iterator i=m_AttributeAuthorityDescriptors.begin(); i!=m_AttributeAuthorityDescriptors.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-            
-            const PDPDescriptor* getPDPDescriptor(const XMLCh* protocol) const {
-                for (vector<PDPDescriptor*>::const_iterator i=m_PDPDescriptors.begin(); i!=m_PDPDescriptors.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-
-            const AuthnQueryDescriptorType* getAuthnQueryDescriptorType(const XMLCh* protocol) const {
-                for (vector<AuthnQueryDescriptorType*>::const_iterator i=m_AuthnQueryDescriptorTypes.begin(); i!=m_AuthnQueryDescriptorTypes.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-
-            const AttributeQueryDescriptorType* getAttributeQueryDescriptorType(const XMLCh* protocol) const {
-                for (vector<AttributeQueryDescriptorType*>::const_iterator i=m_AttributeQueryDescriptorTypes.begin(); i!=m_AttributeQueryDescriptorTypes.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-            
-            const AuthzDecisionQueryDescriptorType* getAuthzDecisionQueryDescriptorType(const XMLCh* protocol) const {
-                for (vector<AuthzDecisionQueryDescriptorType*>::const_iterator i=m_AuthzDecisionQueryDescriptorTypes.begin(); i!=m_AuthzDecisionQueryDescriptorTypes.end(); i++) {
-                    if ((*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
-            }
-
             const RoleDescriptor* getRoleDescriptor(const xmltooling::QName& qname, const XMLCh* protocol) const {
                 // Check for "known" elements/types.
-                QName q;
-                q.setNamespaceURI(SAMLConstants::SAML20MD_NS);
-                q.setLocalPart(IDPSSODescriptor::LOCAL_NAME);
-                if (q == qname)
-                    return getIDPSSODescriptor(protocol);
-                q.setLocalPart(SPSSODescriptor::LOCAL_NAME);
-                if (q == qname)
-                    return getSPSSODescriptor(protocol);
-                q.setLocalPart(AuthnAuthorityDescriptor::LOCAL_NAME);
-                if (q == qname)
-                    return getAuthnAuthorityDescriptor(protocol);
-                q.setLocalPart(AttributeAuthorityDescriptor::LOCAL_NAME);
-                if (q == qname)
-                    return getAttributeAuthorityDescriptor(protocol);
-                q.setLocalPart(PDPDescriptor::LOCAL_NAME);
-                if (q == qname)
-                    return getPDPDescriptor(protocol);
-                q.setNamespaceURI(SAMLConstants::SAML20MD_QUERY_EXT_NS);
-                q.setLocalPart(AuthnQueryDescriptorType::TYPE_NAME);
-                if (q == qname)
-                    return getAuthnQueryDescriptorType(protocol);
-                q.setLocalPart(AttributeQueryDescriptorType::TYPE_NAME);
-                if (q == qname)
-                    return getAttributeQueryDescriptorType(protocol);
-                q.setLocalPart(AuthzDecisionQueryDescriptorType::TYPE_NAME);
-                if (q == qname)
-                    return getAuthzDecisionQueryDescriptorType(protocol);
+                if (qname == IDPSSODescriptor::ELEMENT_QNAME)
+                    return find_if(m_IDPSSODescriptors, isValidForProtocol(protocol));
+                if (qname == SPSSODescriptor::ELEMENT_QNAME)
+                    return find_if(m_SPSSODescriptors, isValidForProtocol(protocol));
+                if (qname == AuthnAuthorityDescriptor::ELEMENT_QNAME)
+                    return find_if(m_AuthnAuthorityDescriptors, isValidForProtocol(protocol));
+                if (qname == AttributeAuthorityDescriptor::ELEMENT_QNAME)
+                    return find_if(m_AttributeAuthorityDescriptors, isValidForProtocol(protocol));
+                if (qname == PDPDescriptor::ELEMENT_QNAME)
+                    return find_if(m_PDPDescriptors, isValidForProtocol(protocol));
+                if (qname == AuthnQueryDescriptorType::TYPE_QNAME)
+                    return find_if(m_AuthnQueryDescriptorTypes, isValidForProtocol(protocol));
+                if (qname == AttributeQueryDescriptorType::TYPE_QNAME)
+                    return find_if(m_AttributeQueryDescriptorTypes, isValidForProtocol(protocol));
+                if (qname == AuthzDecisionQueryDescriptorType::TYPE_QNAME)
+                    return find_if(m_AuthzDecisionQueryDescriptorTypes, isValidForProtocol(protocol));
                 
-                for (vector<RoleDescriptor*>::const_iterator i=m_RoleDescriptors.begin(); i!=m_RoleDescriptors.end(); i++) {
-                    if ((*i)->getSchemaType() && qname==(*((*i)->getSchemaType())) && (*i)->hasSupport(protocol) && (*i)->isValid())
-                        return (*i);
-                }
-                return NULL;
+                vector<RoleDescriptor*>::const_iterator i =
+                    find_if(m_RoleDescriptors.begin(), m_RoleDescriptors.end(), ofTypeValidForProtocol(qname,protocol));
+                return (i!=m_RoleDescriptors.end()) ? *i : NULL;
             }
 
         protected:
@@ -2284,21 +2233,21 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLConstants::XMLSIG_NS,false);
-                PROC_TYPED_CHILD(Extensions,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(IDPSSODescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(SPSSODescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AuthnAuthorityDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AttributeAuthorityDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(PDPDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AuthnQueryDescriptorType,SAMLConstants::SAML20MD_QUERY_EXT_NS,false);
-                PROC_TYPED_CHILDREN(AttributeQueryDescriptorType,SAMLConstants::SAML20MD_QUERY_EXT_NS,false);
-                PROC_TYPED_CHILDREN(AuthzDecisionQueryDescriptorType,SAMLConstants::SAML20MD_QUERY_EXT_NS,false);
-                PROC_TYPED_CHILDREN(RoleDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILD(AffiliationDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILD(Organization,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(ContactPerson,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(AdditionalMetadataLocation,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
+                PROC_TYPED_CHILD(Extensions,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(IDPSSODescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(SPSSODescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AuthnAuthorityDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AttributeAuthorityDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(PDPDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AuthnQueryDescriptorType,samlconstants::SAML20MD_QUERY_EXT_NS,false);
+                PROC_TYPED_CHILDREN(AttributeQueryDescriptorType,samlconstants::SAML20MD_QUERY_EXT_NS,false);
+                PROC_TYPED_CHILDREN(AuthzDecisionQueryDescriptorType,samlconstants::SAML20MD_QUERY_EXT_NS,false);
+                PROC_TYPED_CHILDREN(RoleDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILD(AffiliationDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILD(Organization,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(ContactPerson,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(AdditionalMetadataLocation,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -2340,7 +2289,8 @@ namespace opensaml {
                 init();
             }
                 
-            EntitiesDescriptorImpl(const EntitiesDescriptorImpl& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src) {
+            EntitiesDescriptorImpl(const EntitiesDescriptorImpl& src)
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
                 setID(src.getID());
                 setName(src.getName());
@@ -2405,10 +2355,10 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLConstants::XMLSIG_NS,false);
-                PROC_TYPED_CHILD(Extensions,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(EntityDescriptor,SAMLConstants::SAML20MD_NS,false);
-                PROC_TYPED_CHILDREN(EntitiesDescriptor,SAMLConstants::SAML20MD_NS,false);
+                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
+                PROC_TYPED_CHILD(Extensions,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(EntityDescriptor,SAML20MD_NS,false);
+                PROC_TYPED_CHILDREN(EntitiesDescriptor,SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -2427,6 +2377,15 @@ namespace opensaml {
     #pragma warning( pop )
 #endif
 
+IMPL_ELEMENT_QNAME(IDPSSODescriptor, SAML20MD_NS, SAML20MD_PREFIX);
+IMPL_ELEMENT_QNAME(SPSSODescriptor, SAML20MD_NS, SAML20MD_PREFIX);
+IMPL_ELEMENT_QNAME(AuthnAuthorityDescriptor, SAML20MD_NS, SAML20MD_PREFIX);
+IMPL_ELEMENT_QNAME(AttributeAuthorityDescriptor, SAML20MD_NS, SAML20MD_PREFIX);
+IMPL_ELEMENT_QNAME(PDPDescriptor, SAML20MD_NS, SAML20MD_PREFIX);
+IMPL_TYPE_QNAME(AuthnQueryDescriptorType, SAML20MD_QUERY_EXT_NS, SAML20MD_QUERY_EXT_PREFIX);
+IMPL_TYPE_QNAME(AttributeQueryDescriptorType, SAML20MD_QUERY_EXT_NS, SAML20MD_QUERY_EXT_PREFIX);
+IMPL_TYPE_QNAME(AuthzDecisionQueryDescriptorType, SAML20MD_QUERY_EXT_NS, SAML20MD_QUERY_EXT_PREFIX);
+
 // Builder Implementations
 
 IMPL_XMLOBJECTBUILDER(AdditionalMetadataLocation);