Add XML objects for DelegationRestriction and EntityAttributes extensions.
[shibboleth/cpp-opensaml.git] / saml / saml2 / metadata / Metadata.h
index c8167a2..5d16df0 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2006 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -16,7 +16,7 @@
 
 /**
  * @file saml/saml2/metadata/Metadata.h
- * 
+ *
  * XMLObjects representing the SAML 2.0 Metadata schema
  */
 
 #define __saml2_metadata_h__
 
 #include <saml/saml2/core/Assertions.h>
-#include <saml/util/SAMLConstants.h>
+#include <xmltooling/util/Predicates.h>
 
 #include <ctime>
-#include <xmltooling/AttributeExtensibleXMLObject.h>
-#include <xmltooling/ElementProxy.h>
-#include <xmltooling/SimpleElement.h>
-#include <xmltooling/XMLObjectBuilder.h>
-#include <xmltooling/encryption/Encryption.h>
-#include <xmltooling/signature/KeyInfo.h>
-#include <xmltooling/signature/Signature.h>
-#include <xmltooling/util/DateTime.h>
 
 #define DECL_SAML2MDOBJECTBUILDER(cname) \
-    DECL_XMLOBJECTBUILDER(SAML_API,cname,opensaml::SAMLConstants::SAML20MD_NS,opensaml::SAMLConstants::SAML20MD_PREFIX)
+    DECL_XMLOBJECTBUILDER(SAML_API,cname,samlconstants::SAML20MD_NS,samlconstants::SAML20MD_PREFIX)
 
 namespace opensaml {
 
@@ -46,7 +38,7 @@ namespace opensaml {
      * SAML 2.0 metadata namespace
      */
     namespace saml2md {
-        
+
         /**
          * Base class for metadata objects that feature a cacheDuration attribute.
          */
@@ -73,6 +65,10 @@ namespace opensaml {
             bool isValid() const {
                 return time(NULL) <= getValidUntilEpoch();
             }
+            /** Returns true iff the object is valid at the supplied time. */
+            bool isValid(time_t t) const {
+                return t <= getValidUntilEpoch();
+            }
         };
 
         DECL_XMLOBJECT_SIMPLE(SAML_API,AffiliateMember,ID,SAML 2.0 AffiliateMember element);
@@ -83,35 +79,35 @@ namespace opensaml {
         DECL_XMLOBJECT_SIMPLE(SAML_API,NameIDFormat,Format,SAML 2.0 NameIDFormat element);
         DECL_XMLOBJECT_SIMPLE(SAML_API,SurName,Name,SAML 2.0 SurName element);
         DECL_XMLOBJECT_SIMPLE(SAML_API,TelephoneNumber,Number,SAML 2.0 TelephoneNumber element);
-        
+
         DECL_XMLOBJECT_SIMPLE(SAML_API,ActionNamespace,Namespace,SAML 2.0 Metadata Extension ActionNamespace element);
         DECL_XMLOBJECT_SIMPLE(SAML_API,SourceID,ID,SAML 1.x Metadata Profile SourceID element);
 
-        BEGIN_XMLOBJECT(SAML_API,localizedNameType,xmltooling::SimpleElement,SAML 2.0 localizedNameType type);
+        BEGIN_XMLOBJECT(SAML_API,localizedNameType,xmltooling::XMLObject,SAML 2.0 localizedNameType type);
             DECL_STRING_ATTRIB(Lang,LANG);
             /** localizedNameType local name */
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT(SAML_API,localizedURIType,xmltooling::SimpleElement,SAML 2.0 localizedURIType type);
+        BEGIN_XMLOBJECT(SAML_API,localizedURIType,xmltooling::XMLObject,SAML 2.0 localizedURIType type);
             DECL_STRING_ATTRIB(Lang,LANG);
             /** localizedURIType local name */
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,OrganizationName,localizedNameType,SAML 2.0 OrganizationName element);
-            DECL_XMLOBJECT_CONTENT(Name);
+            DECL_SIMPLE_CONTENT(Name);
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,OrganizationDisplayName,localizedNameType,SAML 2.0 OrganizationDisplayName element);
-            DECL_XMLOBJECT_CONTENT(Name);
+            DECL_SIMPLE_CONTENT(Name);
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,OrganizationURL,localizedURIType,SAML 2.0 OrganizationURL element);
-            DECL_XMLOBJECT_CONTENT(URL);
+            DECL_SIMPLE_CONTENT(URL);
         END_XMLOBJECT;
-        
-        BEGIN_XMLOBJECT(SAML_API,Extensions,xmltooling::ElementProxy,SAML 2.0 Extensions element);
+
+        BEGIN_XMLOBJECT(SAML_API,Extensions,xmltooling::ElementExtensibleXMLObject,SAML 2.0 Extensions element);
             /** ExtensionsType local name */
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
@@ -147,9 +143,9 @@ namespace opensaml {
             static const XMLCh CONTACT_OTHER[];
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT(SAML_API,AdditionalMetadataLocation,xmltooling::SimpleElement,SAML 2.0 AdditionalMetadataLocation element);
+        BEGIN_XMLOBJECT(SAML_API,AdditionalMetadataLocation,xmltooling::XMLObject,SAML 2.0 AdditionalMetadataLocation element);
             DECL_STRING_ATTRIB(Namespace,NAMESPACE);
-            DECL_XMLOBJECT_CONTENT(Location);
+            DECL_SIMPLE_CONTENT(Location);
             /** AdditionalMetadataLocationType local name */
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
@@ -172,15 +168,19 @@ namespace opensaml {
             DECL_STRING_ATTRIB(ProtocolSupportEnumeration,PROTOCOLSUPPORTENUMERATION);
             /** Searches the ProtocolSupportEnumeration attribute for the indicated protocol. */
             virtual bool hasSupport(const XMLCh* protocol) const=0;
+            /** Adds the indicated protocol to the ProtocolSupportEnumeration attribute. */
+            virtual void addSupport(const XMLCh* protocol)=0;
             DECL_STRING_ATTRIB(ErrorURL,ERRORURL);
-            DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILDREN(KeyDescriptor);
             DECL_TYPED_CHILD(Organization);
             DECL_TYPED_CHILDREN(ContactPerson);
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT2(SAML_API,EndpointType,xmltooling::ElementProxy,xmltooling::AttributeExtensibleXMLObject,SAML 2.0 EndpointType type);
+        BEGIN_XMLOBJECT2(SAML_API,RoleDescriptorType,RoleDescriptor,xmltooling::ElementExtensibleXMLObject,SAML 2.0 RoleDescriptor extension);
+        END_XMLOBJECT;
+
+        BEGIN_XMLOBJECT(SAML_API,EndpointType,xmltooling::ElementProxy,SAML 2.0 EndpointType type);
             DECL_STRING_ATTRIB(Binding,BINDING);
             DECL_STRING_ATTRIB(Location,LOCATION);
             DECL_STRING_ATTRIB(ResponseLocation,RESPONSELOCATION);
@@ -231,14 +231,15 @@ namespace opensaml {
             DECL_TYPED_FOREIGN_CHILDREN(Attribute,saml2);
             /** IDPSSODescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_ELEMENT_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,ServiceName,localizedNameType,SAML 2.0 ServiceName element);
-            DECL_XMLOBJECT_CONTENT(Name);
+            DECL_SIMPLE_CONTENT(Name);
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,ServiceDescription,localizedNameType,SAML 2.0 ServiceDescription element);
-            DECL_XMLOBJECT_CONTENT(Description);
+            DECL_SIMPLE_CONTENT(Description);
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,RequestedAttribute,saml2::Attribute,SAML 2.0 RequestedAttribute element);
@@ -267,6 +268,7 @@ namespace opensaml {
             DECL_TYPED_CHILDREN(AttributeConsumingService);
             /** SPSSODescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_ELEMENT_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,AuthnQueryService,EndpointType,SAML 2.0 AuthnQueryService element);
@@ -278,6 +280,7 @@ namespace opensaml {
             DECL_TYPED_CHILDREN(NameIDFormat);
             /** AuthnAuthorityDescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_ELEMENT_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,AuthzService,EndpointType,SAML 2.0 AuthzService element);
@@ -289,6 +292,7 @@ namespace opensaml {
             DECL_TYPED_CHILDREN(NameIDFormat);
             /** PDPDescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_ELEMENT_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,AttributeService,EndpointType,SAML 2.0 AttributeService element);
@@ -302,6 +306,7 @@ namespace opensaml {
             DECL_TYPED_FOREIGN_CHILDREN(Attribute,saml2);
             /** AttributeAuthorityDescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_ELEMENT_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,QueryDescriptorType,RoleDescriptor,SAML 2.0 QueryDescriptorType abstract type);
@@ -314,25 +319,27 @@ namespace opensaml {
         BEGIN_XMLOBJECT(SAML_API,AuthnQueryDescriptorType,QueryDescriptorType,SAML 2.0 AuthnQueryDescriptorType extension type);
             /** AuthnQueryDescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_TYPE_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,AttributeQueryDescriptorType,QueryDescriptorType,SAML 2.0 AttributeQueryDescriptorType extension type);
             DECL_TYPED_CHILDREN(AttributeConsumingService);
             /** AttributeQueryDescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_TYPE_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT(SAML_API,AuthzDecisionQueryDescriptorType,QueryDescriptorType,SAML 2.0 AuthzDecisionQueryDescriptorType extension type);
             DECL_TYPED_CHILDREN(ActionNamespace);
             /** AuthzDecisionQueryDescriptorType local name */
             static const XMLCh TYPE_NAME[];
+            DECL_TYPE_QNAME;
         END_XMLOBJECT;
 
         BEGIN_XMLOBJECT4(SAML_API,AffiliationDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,
                 CacheableSAMLObject,TimeBoundSAMLObject,SAML 2.0 AffiliationDescriptor element);
             DECL_STRING_ATTRIB(ID,ID);
             DECL_STRING_ATTRIB(AffiliationOwnerID,AFFILIATIONOWNERID);
-            DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILDREN(AffiliateMember);
             DECL_TYPED_CHILDREN(KeyDescriptor);
@@ -344,7 +351,6 @@ namespace opensaml {
                 CacheableSAMLObject,TimeBoundSAMLObject,SAML 2.0 EntityDescriptor element);
             DECL_STRING_ATTRIB(ID,ID);
             DECL_STRING_ATTRIB(EntityID,ENTITYID);
-            DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILD(AffiliationDescriptor);
             DECL_TYPED_CHILDREN(RoleDescriptor);
@@ -356,23 +362,10 @@ namespace opensaml {
             DECL_TYPED_CHILDREN(AuthnQueryDescriptorType);
             DECL_TYPED_CHILDREN(AttributeQueryDescriptorType);
             DECL_TYPED_CHILDREN(AuthzDecisionQueryDescriptorType);
-            /** Finds an IDP role supporting a given protocol. */
-            virtual const IDPSSODescriptor* getIDPSSODescriptor(const XMLCh* protocol) const=0;
-            /** Finds an SP role supporting a given protocol. */
-            virtual const SPSSODescriptor* getSPSSODescriptor(const XMLCh* protocol) const=0;
-            /** Finds an Authn Authority role supporting a given protocol. */
-            virtual const AuthnAuthorityDescriptor* getAuthnAuthorityDescriptor(const XMLCh* protocol) const=0;
-            /** Finds an Attribute Authority role supporting a given protocol. */
-            virtual const AttributeAuthorityDescriptor* getAttributeAuthorityDescriptor(const XMLCh* protocol) const=0;
-            /** Finds a PDP role supporting a given protocol. */
-            virtual const PDPDescriptor* getPDPDescriptor(const XMLCh* protocol) const=0;
-            /** Finds an AuthnQuery role supporting a given protocol. */
-            virtual const AuthnQueryDescriptorType* getAuthnQueryDescriptorType(const XMLCh* protocol) const=0;
-            /** Finds an AttributeQuery role supporting a given protocol. */
-            virtual const AttributeQueryDescriptorType* getAttributeQueryDescriptorType(const XMLCh* protocol) const=0;
-            /** Finds an AuthzDecisionQuery role supporting a given protocol. */
-            virtual const AuthzDecisionQueryDescriptorType* getAuthzDecisionQueryDescriptorType(const XMLCh* protocol) const=0;
-            /** Finds an extension role supporting a given protocol. */
+            DECL_TYPED_CHILD(Organization);
+            DECL_TYPED_CHILDREN(ContactPerson);
+            DECL_TYPED_CHILDREN(AdditionalMetadataLocation);
+            /** Finds an arbitrary role type supporting a given protocol. */
             virtual const RoleDescriptor* getRoleDescriptor(const xmltooling::QName& qname, const XMLCh* protocol) const=0;
             /** EntityDescriptorType local name */
             static const XMLCh TYPE_NAME[];
@@ -382,7 +375,6 @@ namespace opensaml {
                 TimeBoundSAMLObject,SAML 2.0 EntitiesDescriptor element);
             DECL_STRING_ATTRIB(ID,ID);
             DECL_STRING_ATTRIB(Name,NAME);
-            DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILDREN(EntityDescriptor);
             DECL_TYPED_CHILDREN(EntitiesDescriptor);
@@ -390,6 +382,69 @@ namespace opensaml {
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
 
+        BEGIN_XMLOBJECT(SAML_API,EntityAttributes,xmltooling::XMLObject,SAML Metadata Extension for Entity Attributes element);
+            DECL_TYPED_FOREIGN_CHILDREN(Attribute,saml2);
+            DECL_TYPED_FOREIGN_CHILDREN(Assertion,saml2);
+            /** EntityAttributesType local name */
+            static const XMLCh TYPE_NAME[];
+        END_XMLOBJECT;
+
+        /**
+         * Predicate to test a role for validity and protocol support.
+         */
+        class isValidForProtocol
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param protocol  support constant to test for
+             */
+            isValidForProtocol(const XMLCh* protocol) : m_time(time(NULL)), m_protocol(protocol) {
+            }
+
+            /**
+             * Returns true iff the supplied role is valid now and supports the right protocol.
+             *
+             * @param role  role to test
+             * @return  result of predicate
+             */
+            bool operator()(const RoleDescriptor* role) const {
+                return role ? (role->isValid(m_time) && role->hasSupport(m_protocol)) : false;
+            }
+
+        private:
+            time_t m_time;
+            const XMLCh* m_protocol;
+        };
+
+        /**
+         * Predicate to test a role for type equivalence, validity, and protocol support.
+         */
+        class ofTypeValidForProtocol : public isValidForProtocol, public xmltooling::hasSchemaType
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param q         schema type to test for
+             * @param protocol  support constant to test for
+             */
+            ofTypeValidForProtocol(const xmltooling::QName& q, const XMLCh* protocol)
+                : isValidForProtocol(protocol), xmltooling::hasSchemaType(q)  {
+            }
+
+            /**
+             * Returns true iff the supplied role is of the right type, valid now, and supports the right protocol.
+             *
+             * @param role  role to test
+             * @return  result of predicate
+             */
+            bool operator()(const RoleDescriptor* role) const {
+                return xmltooling::hasSchemaType::operator()(role) && isValidForProtocol::operator()(role);
+            }
+        };
+
         DECL_SAML2MDOBJECTBUILDER(AdditionalMetadataLocation);
         DECL_SAML2MDOBJECTBUILDER(AffiliateMember);
         DECL_SAML2MDOBJECTBUILDER(AffiliationDescriptor);
@@ -428,31 +483,40 @@ namespace opensaml {
         DECL_SAML2MDOBJECTBUILDER(SPSSODescriptor);
         DECL_SAML2MDOBJECTBUILDER(SurName);
         DECL_SAML2MDOBJECTBUILDER(TelephoneNumber);
-        
-        DECL_XMLOBJECTBUILDER(SAML_API,ActionNamespace,opensaml::SAMLConstants::SAML20MD_QUERY_EXT_NS,opensaml::SAMLConstants::SAML20MD_QUERY_EXT_PREFIX);
-        DECL_XMLOBJECTBUILDER(SAML_API,SourceID,opensaml::SAMLConstants::SAML1MD_NS,opensaml::SAMLConstants::SAML1MD_PREFIX);
+
+        DECL_XMLOBJECTBUILDER(SAML_API,ActionNamespace,samlconstants::SAML20MD_QUERY_EXT_NS,samlconstants::SAML20MD_QUERY_EXT_PREFIX);
+        DECL_XMLOBJECTBUILDER(SAML_API,SourceID,samlconstants::SAML1MD_NS,samlconstants::SAML1MD_PREFIX);
+        DECL_XMLOBJECTBUILDER(SAML_API,EntityAttributes,samlconstants::SAML20MD_ENTITY_ATTRIBUTE_NS,samlconstants::SAML20MD_ENTITY_ATTRIBUTE_PREFIX);
 
         /**
          * Builder for localizedNameType objects.
-         * 
+         *
          * This is customized to force the element name to be specified.
          */
         class SAML_API localizedNameTypeBuilder : public xmltooling::XMLObjectBuilder {
         public:
             virtual ~localizedNameTypeBuilder() {}
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual localizedNameType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static localizedNameType* buildlocalizedNameType(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL) {
                 const localizedNameTypeBuilder* b = dynamic_cast<const localizedNameTypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_NS,localizedNameType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS,localizedNameType::TYPE_NAME))
                     );
                 if (b) {
-                    xmltooling::QName schemaType(SAMLConstants::SAML20MD_NS,localizedNameType::TYPE_NAME,SAMLConstants::SAML20MD_PREFIX);
+                    xmltooling::QName schemaType(samlconstants::SAML20MD_NS,localizedNameType::TYPE_NAME,samlconstants::SAML20MD_PREFIX);
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject(nsURI, localName, prefix, &schemaType);
+#else
+                    return dynamic_cast<localizedNameType*>(b->buildObject(nsURI, localName, prefix, &schemaType));
+#endif
                 }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for localizedNameType.");
             }
@@ -460,25 +524,33 @@ namespace opensaml {
 
         /**
          * Builder for localizedURIType objects.
-         * 
+         *
          * This is customized to force the element name to be specified.
          */
         class SAML_API localizedURITypeBuilder : public xmltooling::XMLObjectBuilder {
         public:
             virtual ~localizedURITypeBuilder() {}
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual localizedURIType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static localizedURIType* buildlocalizedURIType(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL) {
                 const localizedURITypeBuilder* b = dynamic_cast<const localizedURITypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_NS,localizedURIType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS,localizedURIType::TYPE_NAME))
                     );
                 if (b) {
-                    xmltooling::QName schemaType(SAMLConstants::SAML20MD_NS,localizedURIType::TYPE_NAME,SAMLConstants::SAML20MD_PREFIX);
+                    xmltooling::QName schemaType(samlconstants::SAML20MD_NS,localizedURIType::TYPE_NAME,samlconstants::SAML20MD_PREFIX);
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject(nsURI, localName, prefix, &schemaType);
+#else
+                    return dynamic_cast<localizedURIType*>(b->buildObject(nsURI, localName, prefix, &schemaType));
+#endif
                 }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for localizedURIType.");
             }
@@ -486,25 +558,33 @@ namespace opensaml {
 
         /**
          * Builder for EndpointType objects.
-         * 
+         *
          * This is customized to force the element name to be specified.
          */
         class SAML_API EndpointTypeBuilder : public xmltooling::XMLObjectBuilder {
         public:
             virtual ~EndpointTypeBuilder() {}
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual EndpointType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static EndpointType* buildEndpointType(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL) {
                 const EndpointTypeBuilder* b = dynamic_cast<const EndpointTypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_NS,EndpointType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS,EndpointType::TYPE_NAME))
                     );
                 if (b) {
-                    xmltooling::QName schemaType(SAMLConstants::SAML20MD_NS,EndpointType::TYPE_NAME,SAMLConstants::SAML20MD_PREFIX);
+                    xmltooling::QName schemaType(samlconstants::SAML20MD_NS,EndpointType::TYPE_NAME,samlconstants::SAML20MD_PREFIX);
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject(nsURI, localName, prefix, &schemaType);
+#else
+                    return dynamic_cast<EndpointType*>(b->buildObject(nsURI, localName, prefix, &schemaType));
+#endif
                 }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for EndpointType.");
             }
@@ -512,128 +592,208 @@ namespace opensaml {
 
         /**
          * Builder for IndexedEndpointType objects.
-         * 
+         *
          * This is customized to force the element name to be specified.
          */
         class SAML_API IndexedEndpointTypeBuilder : public xmltooling::XMLObjectBuilder {
         public:
             virtual ~IndexedEndpointTypeBuilder() {}
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual IndexedEndpointType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static IndexedEndpointType* buildIndexedEndpointType(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL) {
                 const IndexedEndpointTypeBuilder* b = dynamic_cast<const IndexedEndpointTypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_NS,IndexedEndpointType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS,IndexedEndpointType::TYPE_NAME))
                     );
                 if (b) {
-                    xmltooling::QName schemaType(SAMLConstants::SAML20MD_NS,IndexedEndpointType::TYPE_NAME,SAMLConstants::SAML20MD_PREFIX);
+                    xmltooling::QName schemaType(samlconstants::SAML20MD_NS,IndexedEndpointType::TYPE_NAME,samlconstants::SAML20MD_PREFIX);
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject(nsURI, localName, prefix, &schemaType);
+#else
+                    return dynamic_cast<IndexedEndpointType*>(b->buildObject(nsURI, localName, prefix, &schemaType));
+#endif
                 }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for IndexedEndpointType.");
             }
         };
 
         /**
+         * Builder for RoleDescriptor extension objects.
+         *
+         * This is customized to force the schema type to be specified.
+         */
+        class SAML_API RoleDescriptorBuilder : public xmltooling::XMLObjectBuilder {
+        public:
+            virtual ~RoleDescriptorBuilder() {}
+            /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
+            virtual RoleDescriptor* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
+                const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
+                ) const;
+
+            /** Singleton builder. */
+            static RoleDescriptor* buildRoleDescriptor(const xmltooling::QName& schemaType) {
+                const RoleDescriptorBuilder* b = dynamic_cast<const RoleDescriptorBuilder*>(
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS,RoleDescriptor::LOCAL_NAME))
+                    );
+                if (b) {
+#ifdef HAVE_COVARIANT_RETURNS
+                    return b->buildObject(samlconstants::SAML20MD_NS, RoleDescriptor::LOCAL_NAME, samlconstants::SAML20MD_PREFIX, &schemaType);
+#else
+                    return dynamic_cast<RoleDescriptor*>(b->buildObject(samlconstants::SAML20MD_NS, RoleDescriptor::LOCAL_NAME, samlconstants::SAML20MD_PREFIX, &schemaType));
+#endif
+                }
+                throw xmltooling::XMLObjectException("Unable to obtain typed builder for RoleDescriptor.");
+            }
+        };
+
+        /**
          * Builder for AuthnQueryDescriptorType objects.
-         * 
+         *
          * This is customized to return a RoleDescriptor element with an
          * xsi:type of AuthnQueryDescriptorType.
          */
-        class SAML_API AuthnQueryDescriptorTypeBuilder : public xmltooling::XMLObjectBuilder {
+        class SAML_API AuthnQueryDescriptorTypeBuilder : public xmltooling::ConcreteXMLObjectBuilder {
         public:
             virtual ~AuthnQueryDescriptorTypeBuilder() {}
             /** Default builder. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual AuthnQueryDescriptorType* buildObject() const {
+#else
+            virtual xmltooling::XMLObject* buildObject() const {
+#endif
                 xmltooling::QName schemaType(
-                    SAMLConstants::SAML20_NS,AuthnQueryDescriptorType::TYPE_NAME,SAMLConstants::SAML20MD_QUERY_EXT_PREFIX
+                    samlconstants::SAML20MD_QUERY_EXT_NS,AuthnQueryDescriptorType::TYPE_NAME,samlconstants::SAML20MD_QUERY_EXT_PREFIX
                     );
                 return buildObject(
-                    SAMLConstants::SAML20_NS,AuthnQueryDescriptorType::LOCAL_NAME,SAMLConstants::SAML20_PREFIX,&schemaType
+                    samlconstants::SAML20MD_NS,AuthnQueryDescriptorType::LOCAL_NAME,samlconstants::SAML20MD_PREFIX,&schemaType
                     );
             }
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual AuthnQueryDescriptorType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static AuthnQueryDescriptorType* buildAuthnQueryDescriptorType() {
                 const AuthnQueryDescriptorTypeBuilder* b = dynamic_cast<const AuthnQueryDescriptorTypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_QUERY_EXT_NS,AuthnQueryDescriptorType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_QUERY_EXT_NS,AuthnQueryDescriptorType::TYPE_NAME))
                     );
-                if (b)
+                if (b) {
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject();
+#else
+                    return dynamic_cast<AuthnQueryDescriptorType*>(b->buildObject());
+#endif
+                }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for AuthnQueryDescriptorType.");
             }
         };
 
         /**
          * Builder for AttributeQueryDescriptorType objects.
-         * 
+         *
          * This is customized to return a RoleDescriptor element with an
          * xsi:type of AttributeQueryDescriptorType.
          */
-        class SAML_API AttributeQueryDescriptorTypeBuilder : public xmltooling::XMLObjectBuilder {
+        class SAML_API AttributeQueryDescriptorTypeBuilder : public xmltooling::ConcreteXMLObjectBuilder {
         public:
             virtual ~AttributeQueryDescriptorTypeBuilder() {}
             /** Default builder. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual AttributeQueryDescriptorType* buildObject() const {
+#else
+            virtual xmltooling::XMLObject* buildObject() const {
+#endif
                 xmltooling::QName schemaType(
-                    SAMLConstants::SAML20_NS,AttributeQueryDescriptorType::TYPE_NAME,SAMLConstants::SAML20MD_QUERY_EXT_PREFIX
+                    samlconstants::SAML20MD_QUERY_EXT_NS,AttributeQueryDescriptorType::TYPE_NAME,samlconstants::SAML20MD_QUERY_EXT_PREFIX
                     );
                 return buildObject(
-                    SAMLConstants::SAML20_NS,AttributeQueryDescriptorType::LOCAL_NAME,SAMLConstants::SAML20_PREFIX,&schemaType
+                    samlconstants::SAML20MD_NS,AttributeQueryDescriptorType::LOCAL_NAME,samlconstants::SAML20MD_PREFIX,&schemaType
                     );
             }
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual AttributeQueryDescriptorType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static AttributeQueryDescriptorType* buildAttributeQueryDescriptorType() {
                 const AttributeQueryDescriptorTypeBuilder* b = dynamic_cast<const AttributeQueryDescriptorTypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_QUERY_EXT_NS,AttributeQueryDescriptorType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_QUERY_EXT_NS,AttributeQueryDescriptorType::TYPE_NAME))
                     );
-                if (b)
+                if (b) {
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject();
+#else
+                    return dynamic_cast<AttributeQueryDescriptorType*>(b->buildObject());
+#endif
+                }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for AttributeQueryDescriptorType.");
             }
         };
 
         /**
          * Builder for AuthzDecisionQueryDescriptorType objects.
-         * 
+         *
          * This is customized to return a RoleDescriptor element with an
          * xsi:type of AuthzDecisionQueryDescriptorType.
          */
-        class SAML_API AuthzDecisionQueryDescriptorTypeBuilder : public xmltooling::XMLObjectBuilder {
+        class SAML_API AuthzDecisionQueryDescriptorTypeBuilder : public xmltooling::ConcreteXMLObjectBuilder {
         public:
             virtual ~AuthzDecisionQueryDescriptorTypeBuilder() {}
             /** Default builder. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual AuthzDecisionQueryDescriptorType* buildObject() const {
+#else
+            virtual xmltooling::XMLObject* buildObject() const {
+#endif
                 xmltooling::QName schemaType(
-                    SAMLConstants::SAML20_NS,AuthzDecisionQueryDescriptorType::TYPE_NAME,SAMLConstants::SAML20MD_QUERY_EXT_PREFIX
+                    samlconstants::SAML20MD_QUERY_EXT_NS,AuthzDecisionQueryDescriptorType::TYPE_NAME,samlconstants::SAML20MD_QUERY_EXT_PREFIX
                     );
                 return buildObject(
-                    SAMLConstants::SAML20_NS,AuthzDecisionQueryDescriptorType::LOCAL_NAME,SAMLConstants::SAML20_PREFIX,&schemaType
+                    samlconstants::SAML20MD_NS,AuthzDecisionQueryDescriptorType::LOCAL_NAME,samlconstants::SAML20MD_PREFIX,&schemaType
                     );
             }
             /** Builder that allows element/type override. */
+#ifdef HAVE_COVARIANT_RETURNS
             virtual AuthzDecisionQueryDescriptorType* buildObject(
+#else
+            virtual xmltooling::XMLObject* buildObject(
+#endif
                 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
                 ) const;
-        
+
             /** Singleton builder. */
             static AuthzDecisionQueryDescriptorType* buildAuthzDecisionQueryDescriptorType() {
                 const AuthzDecisionQueryDescriptorTypeBuilder* b = dynamic_cast<const AuthzDecisionQueryDescriptorTypeBuilder*>(
-                    XMLObjectBuilder::getBuilder(xmltooling::QName(SAMLConstants::SAML20MD_QUERY_EXT_NS,AuthzDecisionQueryDescriptorType::TYPE_NAME))
+                    XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_QUERY_EXT_NS,AuthzDecisionQueryDescriptorType::TYPE_NAME))
                     );
-                if (b)
+                if (b) {
+#ifdef HAVE_COVARIANT_RETURNS
                     return b->buildObject();
+#else
+                    return dynamic_cast<AuthzDecisionQueryDescriptorType*>(b->buildObject());
+#endif
+                }
                 throw xmltooling::XMLObjectException("Unable to obtain typed builder for AuthzDecisionQueryDescriptorType.");
             }
         };