Added built-in ID attribute support to base classes.
authorScott Cantor <cantor.2@osu.edu>
Fri, 8 Sep 2006 01:59:23 +0000 (01:59 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 8 Sep 2006 01:59:23 +0000 (01:59 +0000)
xmltooling/AbstractAttributeExtensibleXMLObject.cpp
xmltooling/AbstractAttributeExtensibleXMLObject.h
xmltooling/AbstractXMLObject.h
xmltooling/AttributeExtensibleXMLObject.h
xmltooling/XMLObject.h
xmltooling/XMLToolingConfig.cpp
xmltooling/base.h
xmltooling/signature/impl/KeyInfoImpl.cpp
xmltoolingtest/XMLObjectBaseTestCase.h

index 781b722..7b7fd32 100644 (file)
@@ -29,6 +29,8 @@
 using namespace xmltooling;\r
 using namespace std;\r
 \r
+set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;\r
+\r
 AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()\r
 {\r
     for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)\r
@@ -38,12 +40,16 @@ AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()
 AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)\r
     : AbstractXMLObject(src)\r
 {\r
+    m_idAttribute = m_attributeMap.end();\r
     for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {\r
         m_attributeMap[i->first] = XMLString::replicate(i->second);\r
     }\r
+    if (src.m_idAttribute != src.m_attributeMap.end()) {\r
+        m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);\r
+    }\r
 }\r
 \r
-void AbstractAttributeExtensibleXMLObject::setAttribute(QName& qualifiedName, const XMLCh* value)\r
+void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)\r
 {\r
     map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);\r
     if (i!=m_attributeMap.end()) {\r
@@ -53,11 +59,20 @@ void AbstractAttributeExtensibleXMLObject::setAttribute(QName& qualifiedName, co
             i->second=XMLString::replicate(value);\r
         }\r
         else {\r
+            if (m_idAttribute==i)\r
+                m_idAttribute=m_attributeMap.end();\r
             m_attributeMap.erase(i);\r
         }\r
+        \r
+        if (ID) {\r
+            m_idAttribute=i;\r
+        }\r
     }\r
     else if (value) {\r
         releaseThisandParentDOM();\r
         m_attributeMap[qualifiedName]=XMLString::replicate(value);\r
+        if (ID) {\r
+            m_idAttribute = m_attributeMap.find(qualifiedName);\r
+        } \r
     }\r
 }\r
index ca2b390..e2e65ea 100644 (file)
@@ -38,26 +38,40 @@ namespace xmltooling {
      * AbstractXMLObject mixin that implements AttributeExtensibleXMLObject.\r
      * Inherit from this class to add support for attribute wildcarding.\r
      */\r
-    class XMLTOOL_API AbstractAttributeExtensibleXMLObject : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject\r
+    class XMLTOOL_API AbstractAttributeExtensibleXMLObject\r
+        : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject\r
     {\r
     public:\r
         virtual ~AbstractAttributeExtensibleXMLObject();\r
         \r
-        virtual const XMLCh* getAttribute(QName& qualifiedName) const {\r
+        const XMLCh* getAttribute(const QName& qualifiedName) const {\r
             std::map<QName,XMLCh*>::const_iterator i=m_attributeMap.find(qualifiedName);\r
             return (i==m_attributeMap.end()) ? NULL : i->second;\r
         }\r
         \r
-        virtual void setAttribute(QName& qualifiedName, const XMLCh* value);\r
+        void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false);\r
+    \r
+        const std::map<QName,XMLCh*>& getExtensionAttributes() const {\r
+            return m_attributeMap;\r
+        }\r
+        \r
+        const XMLCh* getXMLID() const {\r
+            return (m_idAttribute == m_attributeMap.end()) ? NULL : m_idAttribute->second;\r
+        }\r
     \r
      protected:\r
-        AbstractAttributeExtensibleXMLObject() {}\r
+        AbstractAttributeExtensibleXMLObject() {\r
+            m_idAttribute = m_attributeMap.end();\r
+        }\r
 \r
         /** Copy constructor. */\r
         AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src);\r
 \r
         /** Map of arbitrary attributes. */\r
         std::map<QName,XMLCh*> m_attributeMap;\r
+        \r
+        /** Points to the last attribute designated as an XML ID. */\r
+        std::map<QName,XMLCh*>::const_iterator m_idAttribute;\r
     };\r
     \r
 };\r
index e159df1..dee54be 100644 (file)
@@ -69,6 +69,10 @@ namespace xmltooling {
         const QName* getSchemaType() const {\r
             return m_typeQname;\r
         }\r
+        \r
+        const XMLCh* getXMLID() const {\r
+            return NULL;\r
+        }\r
     \r
         bool hasParent() const {\r
             return m_parent != NULL;\r
index 2d1472f..8ba087b 100644 (file)
 \r
 using namespace xercesc;\r
 \r
+#if defined (_MSC_VER)\r
+    #pragma warning( push )\r
+    #pragma warning( disable : 4250 4251 )\r
+#endif\r
+\r
 namespace xmltooling {\r
 \r
     /**\r
@@ -34,27 +39,80 @@ namespace xmltooling {
      */\r
     class XMLTOOL_API AttributeExtensibleXMLObject : public virtual XMLObject\r
     {\r
-    public:\r
+    protected:\r
         AttributeExtensibleXMLObject() {}\r
+        \r
+    public:\r
         virtual ~AttributeExtensibleXMLObject() {}\r
         \r
         /**\r
-         * Gets the value of an XML attribute of the object\r
+         * Gets the value of an XML attribute of the object.\r
          * \r
          * @param   qualifiedName   qualified name of the attribute   \r
          * @return the attribute value, or NULL\r
          */\r
-        virtual const XMLCh* getAttribute(QName& qualifiedName) const=0;\r
+        virtual const XMLCh* getAttribute(const QName& qualifiedName) const=0;\r
         \r
         /**\r
-         * Sets (or clears) an XML attribute of the object \r
+         * Sets (or clears) an XML attribute of the object.\r
          * \r
          * @param qualifiedName qualified name of the attribute   \r
          * @param value         value to set, or NULL to clear\r
+         * @param ID            true iff the attribute is an XML ID\r
          */\r
-        virtual void setAttribute(QName& qualifiedName, const XMLCh* value)=0;\r
+        virtual void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false)=0;\r
+\r
+        /**\r
+         * Gets an immutable map of the extended XML attributes of the object.\r
+         * \r
+         * This set is not guaranteed to (and generally will not) include\r
+         * attributes defined directly on the object's "type".\r
+         */\r
+        virtual const std::map<QName,XMLCh*>& getExtensionAttributes() const=0;\r
+        \r
+        /**\r
+         * Gets an immutable list of all the ID attributes currently registered.\r
+         * \r
+         * @return list of all the ID attributes currently registered\r
+         */\r
+        static const std::set<QName>& getRegisteredIDAttributes() {\r
+            return m_idAttributeSet;\r
+        }\r
+    \r
+        /**\r
+         * Registers a new attribute as being of XML ID type.\r
+         * \r
+         * @param name the qualified attribute name\r
+         */\r
+        static void registerIDAttribute(const QName& name) {\r
+            m_idAttributeSet.insert(name);\r
+        }\r
+\r
+        /**\r
+         * Deregisters an ID attribute.\r
+         * \r
+         * @param name the qualified attribute name\r
+         */\r
+        static void deregisterIDAttribute(const QName& name) {\r
+            m_idAttributeSet.erase(name);\r
+        }\r
+        \r
+        /**\r
+         * Deregisters all ID attributes.\r
+         */\r
+        static void deregisterIDAttributes() {\r
+            m_idAttributeSet.clear();\r
+        }\r
+\r
+    private:\r
+        /** Set of attributes to treat as XML IDs. */\r
+        static std::set<QName> m_idAttributeSet;\r
     };\r
     \r
 };\r
 \r
+#if defined (_MSC_VER)\r
+    #pragma warning( pop )\r
+#endif\r
+\r
 #endif /* __xmltooling_attrextxmlobj_h__ */\r
index ed750ce..21715e9 100644 (file)
@@ -104,6 +104,13 @@ namespace xmltooling {
         virtual const QName* getSchemaType() const=0;\r
         \r
         /**\r
+         * Gets the value of the ID attribute set on this object, if any.\r
+         * \r
+         * @return an ID value or NULL \r
+         */\r
+        virtual const XMLCh* getXMLID() const=0;\r
+        \r
+        /**\r
          * Checks to see if this object has a parent.\r
          * \r
          * @return true if the object has a parent, false if not\r
index 9477479..e248f6a 100644 (file)
@@ -184,6 +184,10 @@ bool XMLToolingInternalConfig::init()
         registerCredentialResolvers();
         registerTrustEngines();
 #endif
+
+        // Register xml:id as an ID attribute.        
+        static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d);
+        AttributeExtensibleXMLObject::registerIDAttribute(QName(XMLConstants::XML_NS, xmlid)); 
     }
     catch (const xercesc::XMLException&) {
         log.fatal("caught exception while initializing Xerces");
@@ -200,6 +204,7 @@ void XMLToolingInternalConfig::term()
     KeyInfoSchemaValidators.destroyValidators();
     EncryptionSchemaValidators.destroyValidators();
     XMLToolingException::deregisterFactories();
+    AttributeExtensibleXMLObject::deregisterIDAttributes();
 
 #ifndef XMLTOOLING_NO_XMLSEC
     TrustEngineManager.deregisterFactories();
index fe281c5..228640d 100644 (file)
     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
 
 /**
+ * Implements get/set methods and a private member for a string XML attribute,
+ * plus a getXMLID override.
+ * 
+ * @param proper    the proper name of the attribute
+ */
+#define IMPL_ID_ATTRIB(proper) \
+    IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
+    const XMLCh* getXMLID() const { \
+        return m_##proper; \
+    }
+
+/**
  * Implements get/set methods and a private member for a DateTime XML attribute.
  * 
  * @param proper    the proper name of the attribute
index 9a92069..922d583 100644 (file)
@@ -694,7 +694,7 @@ namespace xmlsignature {
         }
         
         IMPL_XMLOBJECT_CLONE(KeyInfo);
-        IMPL_STRING_ATTRIB(Id);
+        IMPL_ID_ATTRIB(Id);
         IMPL_TYPED_CHILDREN(KeyName,m_children.end());
         IMPL_TYPED_CHILDREN(KeyValue,m_children.end());
         IMPL_TYPED_CHILDREN(RetrievalMethod,m_children.end());
index d2d56c0..a90b1fc 100644 (file)
@@ -96,6 +96,7 @@ public:
         return new SimpleXMLObject(*this);
     }
 
+    const XMLCh* getXMLID() const { return getId(); }
     const XMLCh* getId() const { return m_id; }
     void setId(const XMLCh* id) { m_id=prepareForAssignment(m_id,id); }