Handle variant element names, merge in wildcard class, add test cases.
authorScott Cantor <cantor.2@osu.edu>
Thu, 23 Mar 2006 04:26:51 +0000 (04:26 +0000)
committerScott Cantor <cantor.2@osu.edu>
Thu, 23 Mar 2006 04:26:51 +0000 (04:26 +0000)
17 files changed:
xmltooling/AbstractXMLObject.h
xmltooling/Makefile.am
xmltooling/XMLObjectBuilder.h
xmltooling/impl/AnyElement.cpp [new file with mode: 0644]
xmltooling/impl/AnyElement.h [new file with mode: 0644]
xmltooling/impl/UnknownElement.cpp
xmltooling/impl/UnknownElement.h
xmltooling/signature/impl/XMLSecSignature.cpp
xmltooling/signature/impl/XMLSecSignature.h
xmltooling/xmltooling.vcproj
xmltoolingtest/ComplexXMLObjectTest.h
xmltoolingtest/MarshallingTest.h
xmltoolingtest/SignatureTest.h
xmltoolingtest/UnmarshallingTest.h
xmltoolingtest/XMLObjectBaseTestCase.h
xmltoolingtest/data/SimpleXMLObjectWithChildren.xml
xmltoolingtest/xmltoolingtest.h

index e72f3eb..d5ebc71 100644 (file)
@@ -52,6 +52,7 @@ namespace xmltooling {
          */\r
         void setElementNamespacePrefix(const XMLCh* prefix) {\r
             m_elementQname.setPrefix(prefix);\r
+            addNamespace(Namespace(m_elementQname.getNamespaceURI(),prefix));\r
         }\r
 \r
         /**\r
index e90aca3..bd9a7fd 100644 (file)
@@ -32,6 +32,10 @@ libxmltoolinginclude_HEADERS = \
     XMLObjectBuilder.h \
     XMLToolingConfig.h
 
+implinclude_HEADERS = \
+    impl/AnyElement.h \
+    impl/UnknownElement.h
+
 ioinclude_HEADERS = \
     io/AbstractXMLObjectUnmarshaller.h \
 
@@ -52,7 +56,6 @@ valinclude_HEADERS = \
 
 noinst_HEADERS = \
     internal.h \
-    impl/UnknownElement.h \
     signature/impl/XMLSecSignature.h
 
 if BUILD_XMLSEC
@@ -72,6 +75,7 @@ libxmltooling_la_SOURCES = \
     unicode.cpp \
     XMLObjectBuilder.cpp \
     XMLToolingConfig.cpp \
+    impl/AnyElement.cpp \
     impl/UnknownElement.cpp \
     io/AbstractXMLObjectMarshaller.cpp \
     io/AbstractXMLObjectUnmarshaller.cpp \
index 4426401..0b05e46 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file XMLObjectBuilder.h\r
- * \r
- * Factory interface for XMLObjects \r
- */\r
-\r
-#if !defined(__xmltooling_xmlobjbuilder_h__)\r
-#define __xmltooling_xmlobjbuilder_h__\r
-\r
-#include <map>\r
-#include <xmltooling/QName.h>\r
-#include <xmltooling/XMLObject.h>\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
-     * A factory interface for obtaining XMLObjects.\r
-     * Subclasses MAY supply additional factory methods.\r
-     */\r
-    class XMLTOOL_API XMLObjectBuilder\r
-    {\r
-    MAKE_NONCOPYABLE(XMLObjectBuilder);\r
-    public:\r
-        virtual ~XMLObjectBuilder() {}\r
-        \r
-        /**\r
-         * Creates an empty XMLObject.\r
-         * \r
-         * @return the empty XMLObject\r
-         */\r
-        virtual XMLObject* buildObject() const=0;\r
-\r
-        /**\r
-         * Creates an unmarshalled XMLObject from a DOM Element.\r
-         * \r
-         * @param element       the unmarshalling source\r
-         * @param bindDocument  true iff the XMLObject should take ownership of the DOM Document\r
-         * @return the unmarshalled XMLObject\r
-         */\r
-        virtual XMLObject* buildFromElement(DOMElement* element, bool bindDocument=false) const {\r
-            std::auto_ptr<XMLObject> ret(buildObject());\r
-            ret->unmarshall(element,bindDocument);\r
-            return ret.release();\r
-        }\r
-\r
-        /**\r
-         * Creates an unmarshalled XMLObject from the root of a DOM Document.\r
-         * \r
-         * @param doc           the unmarshalling source\r
-         * @param bindDocument  true iff the XMLObject should take ownership of the DOM Document\r
-         * @return the unmarshalled XMLObject\r
-         */\r
-        virtual XMLObject* buildFromDocument(DOMDocument* doc, bool bindDocument=true) const {\r
-            return buildFromElement(doc->getDocumentElement(),bindDocument);\r
-        }\r
-\r
-        /**\r
-         * Creates an empty XMLObject using the default build method, if a builder can be found.\r
-         * \r
-         * @param key   the key used to locate a builder\r
-         * @return  the empty object or NULL if no builder is available \r
-         */\r
-        static XMLObject* buildOne(const QName& key) {\r
-            const XMLObjectBuilder* b=getBuilder(key);\r
-            if (b)\r
-                return b->buildObject();\r
-            b=getDefaultBuilder();\r
-            return b ? b->buildObject() : NULL;\r
-        }\r
-\r
-        /**\r
-         * Creates an unmarshalled XMLObject using the default build method, if a builder can be found.\r
-         * \r
-         * @param element       the unmarshalling source\r
-         * @param bindDocument  true iff the new XMLObject should take ownership of the DOM Document\r
-         * @return  the unmarshalled object or NULL if no builder is available \r
-         */\r
-        static XMLObject* buildOneFromElement(DOMElement* element, bool bindDocument=false) {\r
-            const XMLObjectBuilder* b=getBuilder(element);\r
-            return b ? b->buildFromElement(element,bindDocument) : NULL;\r
-        }\r
-\r
-        /**\r
-         * Retrieves an XMLObjectBuilder using the key it was registered with.\r
-         * \r
-         * @param key the key used to register the builder\r
-         * @return the builder or NULL\r
-         */\r
-        static const XMLObjectBuilder* getBuilder(const QName& key) {\r
-            std::map<QName,XMLObjectBuilder*>::const_iterator i=m_map.find(key);\r
-            return (i==m_map.end()) ? NULL : i->second;\r
-        }\r
-\r
-        /**\r
-         * Retrieves an XMLObjectBuilder for a given DOM element.\r
-         * If no match is found, the default builder is returned, if any.\r
-         * \r
-         * @param element the element for which to locate a builder\r
-         * @return the builder or NULL\r
-         */\r
-        static const XMLObjectBuilder* getBuilder(const DOMElement* element);\r
-\r
-        /**\r
-         * Retrieves the default XMLObjectBuilder for DOM elements\r
-         * \r
-         * @return the default builder or NULL\r
-         */\r
-        static const XMLObjectBuilder* getDefaultBuilder() {\r
-            return m_default;\r
-        }\r
-\r
-        /**\r
-         * Gets an immutable list of all the builders currently registered.\r
-         * \r
-         * @return list of all the builders currently registered\r
-         */\r
-        static const std::map<QName,XMLObjectBuilder*>& getBuilders() {\r
-            return m_map;\r
-        }\r
-    \r
-        /**\r
-         * Registers a new builder for the given key.\r
-         * \r
-         * @param builderKey the key used to retrieve this builder later\r
-         * @param builder the builder\r
-         */\r
-        static void registerBuilder(const QName& builderKey, XMLObjectBuilder* builder) {\r
-            deregisterBuilder(builderKey);\r
-            m_map[builderKey]=builder;\r
-        }\r
-\r
-        /**\r
-         * Registers a default builder\r
-         * \r
-         * @param builder the default builder\r
-         */\r
-        static void registerDefaultBuilder(XMLObjectBuilder* builder) {\r
-            deregisterDefaultBuilder();\r
-            m_default=builder;\r
-        }\r
-\r
-        /**\r
-         * Deregisters a builder.\r
-         * \r
-         * @param builderKey the key for the builder to be deregistered\r
-         */\r
-        static void deregisterBuilder(const QName& builderKey) {\r
-            delete getBuilder(builderKey);\r
-            m_map.erase(builderKey);\r
-        }\r
-\r
-        /**\r
-         * Deregisters default builder.\r
-         */\r
-        static void deregisterDefaultBuilder() {\r
-            delete m_default;\r
-            m_default=NULL;\r
-        }\r
-\r
-        /**\r
-         * Unregisters and destroys all registered builders. \r
-         */\r
-        static void destroyBuilders();\r
-\r
-    protected:\r
-        XMLObjectBuilder() {}\r
-    \r
-    private:\r
-        static std::map<QName,XMLObjectBuilder*> m_map;\r
-        static XMLObjectBuilder* m_default;\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_xmlobjbuilder_h__ */\r
+/*
+ *  Copyright 2001-2006 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file XMLObjectBuilder.h
+ * 
+ * Factory interface for XMLObjects 
+ */
+
+#if !defined(__xmltooling_xmlobjbuilder_h__)
+#define __xmltooling_xmlobjbuilder_h__
+
+#include <map>
+#include <xmltooling/QName.h>
+#include <xmltooling/XMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * A factory interface for obtaining XMLObjects.
+     * Subclasses MAY supply additional factory methods.
+     */
+    class XMLTOOL_API XMLObjectBuilder
+    {
+    MAKE_NONCOPYABLE(XMLObjectBuilder);
+    public:
+        virtual ~XMLObjectBuilder() {}
+        
+        /**
+         * Creates an empty XMLObject with a particular element name.
+         * 
+         * @param namespaceURI          namespace URI for element
+         * @param elementLocalName      local name of element
+         * @param namespacePrefix       prefix of element name
+         * @return the empty XMLObject
+         */
+        virtual XMLObject* buildObject(
+            const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL
+            ) const=0;
+
+        /**
+         * Creates an empty XMLObject with a defaulted element name.
+         * 
+         * @return the empty XMLObject
+         */
+        virtual XMLObject* buildObject() const {
+            return buildObject(NULL,NULL,NULL);
+        }
+
+        /**
+         * Creates an empty XMLObject with a particular element name.
+         * 
+         * @param q     QName of element for object
+         * @return the empty XMLObject
+         */
+        virtual XMLObject* buildObject(const QName& q) const {
+            return buildObject(q.getNamespaceURI(),q.getLocalPart(),q.getPrefix());
+        }
+
+        /**
+         * Creates an unmarshalled XMLObject from a DOM Element.
+         * 
+         * @param element       the unmarshalling source
+         * @param bindDocument  true iff the XMLObject should take ownership of the DOM Document
+         * @return the unmarshalled XMLObject
+         */
+        virtual XMLObject* buildFromElement(DOMElement* element, bool bindDocument=false) const {
+            std::auto_ptr<XMLObject> ret(buildObject(element->getNamespaceURI(),element->getLocalName(),element->getPrefix()));
+            ret->unmarshall(element,bindDocument);
+            return ret.release();
+        }
+
+        /**
+         * Creates an unmarshalled XMLObject from the root of a DOM Document.
+         * 
+         * @param doc           the unmarshalling source
+         * @param bindDocument  true iff the XMLObject should take ownership of the DOM Document
+         * @return the unmarshalled XMLObject
+         */
+        virtual XMLObject* buildFromDocument(DOMDocument* doc, bool bindDocument=true) const {
+            return buildFromElement(doc->getDocumentElement(),bindDocument);
+        }
+
+        /**
+         * Creates an empty XMLObject using the default build method, if a builder can be found.
+         * 
+         * @param key   the key used to locate a builder
+         * @return  the empty object or NULL if no builder is available 
+         */
+        static XMLObject* buildOne(const QName& key) {
+            const XMLObjectBuilder* b=getBuilder(key);
+            if (b)
+                return b->buildObject();
+            b=getDefaultBuilder();
+            return b ? b->buildObject() : NULL;
+        }
+
+        /**
+         * Creates an unmarshalled XMLObject using the default build method, if a builder can be found.
+         * 
+         * @param element       the unmarshalling source
+         * @param bindDocument  true iff the new XMLObject should take ownership of the DOM Document
+         * @return  the unmarshalled object or NULL if no builder is available 
+         */
+        static XMLObject* buildOneFromElement(DOMElement* element, bool bindDocument=false) {
+            const XMLObjectBuilder* b=getBuilder(element);
+            return b ? b->buildFromElement(element,bindDocument) : NULL;
+        }
+
+        /**
+         * Retrieves an XMLObjectBuilder using the key it was registered with.
+         * 
+         * @param key the key used to register the builder
+         * @return the builder or NULL
+         */
+        static const XMLObjectBuilder* getBuilder(const QName& key) {
+            std::map<QName,XMLObjectBuilder*>::const_iterator i=m_map.find(key);
+            return (i==m_map.end()) ? NULL : i->second;
+        }
+
+        /**
+         * Retrieves an XMLObjectBuilder for a given DOM element.
+         * If no match is found, the default builder is returned, if any.
+         * 
+         * @param element the element for which to locate a builder
+         * @return the builder or NULL
+         */
+        static const XMLObjectBuilder* getBuilder(const DOMElement* element);
+
+        /**
+         * Retrieves the default XMLObjectBuilder for DOM elements
+         * 
+         * @return the default builder or NULL
+         */
+        static const XMLObjectBuilder* getDefaultBuilder() {
+            return m_default;
+        }
+
+        /**
+         * Gets an immutable list of all the builders currently registered.
+         * 
+         * @return list of all the builders currently registered
+         */
+        static const std::map<QName,XMLObjectBuilder*>& getBuilders() {
+            return m_map;
+        }
+    
+        /**
+         * Registers a new builder for the given key.
+         * 
+         * @param builderKey the key used to retrieve this builder later
+         * @param builder the builder
+         */
+        static void registerBuilder(const QName& builderKey, XMLObjectBuilder* builder) {
+            deregisterBuilder(builderKey);
+            m_map[builderKey]=builder;
+        }
+
+        /**
+         * Registers a default builder
+         * 
+         * @param builder the default builder
+         */
+        static void registerDefaultBuilder(XMLObjectBuilder* builder) {
+            deregisterDefaultBuilder();
+            m_default=builder;
+        }
+
+        /**
+         * Deregisters a builder.
+         * 
+         * @param builderKey the key for the builder to be deregistered
+         */
+        static void deregisterBuilder(const QName& builderKey) {
+            delete getBuilder(builderKey);
+            m_map.erase(builderKey);
+        }
+
+        /**
+         * Deregisters default builder.
+         */
+        static void deregisterDefaultBuilder() {
+            delete m_default;
+            m_default=NULL;
+        }
+
+        /**
+         * Unregisters and destroys all registered builders. 
+         */
+        static void destroyBuilders();
+
+    protected:
+        XMLObjectBuilder() {}
+    
+    private:
+        static std::map<QName,XMLObjectBuilder*> m_map;
+        static XMLObjectBuilder* m_default;
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_xmlobjbuilder_h__ */
diff --git a/xmltooling/impl/AnyElement.cpp b/xmltooling/impl/AnyElement.cpp
new file mode 100644 (file)
index 0000000..fea0081
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Copyright 2001-2006 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file AnyElement.h
+ * 
+ * Advanced anyType implementation suitable for deep processing of unknown content.
+ */
+
+#include "internal.h"
+#include "AbstractAttributeExtensibleXMLObject.h"
+#include "AbstractElementProxy.h"
+#include "exceptions.h"
+#include "impl/AnyElement.h"
+#include "io/AbstractXMLObjectMarshaller.h"
+#include "io/AbstractXMLObjectUnmarshaller.h"
+#include "util/NDC.h"
+#include "util/XMLHelper.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * Implements a smart wrapper around unknown DOM content.
+     */
+    class XMLTOOL_DLLLOCAL AnyElementImpl : public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject,
+        public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller
+    {
+    public:
+        AnyElementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix)
+            : AbstractDOMCachingXMLObject(nsURI, localName, prefix),
+            AbstractElementProxy(nsURI, localName, prefix),
+            AbstractAttributeExtensibleXMLObject(nsURI, localName, prefix) {}
+        virtual ~AnyElementImpl() {}
+        
+        AnyElementImpl* clone() const {
+            auto_ptr<XMLObject> domClone(AbstractDOMCachingXMLObject::clone());
+            AnyElementImpl* ret=dynamic_cast<AnyElementImpl*>(domClone.get());
+            if (ret) {
+                domClone.release();
+                return ret;
+            }
+
+            ret=new AnyElementImpl(
+                getElementQName().getNamespaceURI(),getElementQName().getLocalPart(),getElementQName().getPrefix()
+                );
+            ret->m_namespaces=m_namespaces;
+            for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
+                ret->m_attributeMap[i->first]=XMLString::replicate(i->second);
+            }
+            ret->setTextContent(getTextContent());
+            xmltooling::clone(m_children, ret->m_children);
+            return ret;
+        }
+
+        void marshallAttributes(DOMElement* domElement) const {
+            for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
+                DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
+                if (i->first.hasPrefix())
+                    attr->setPrefix(i->first.getPrefix());
+                attr->setNodeValue(i->second);
+                domElement->setAttributeNode(attr);
+            }
+        }
+
+        void marshallElementContent(DOMElement* domElement) const {
+            if(getTextContent()) {
+                domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
+            }
+        }
+
+        void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            getXMLObjects().push_back(childXMLObject);
+        }
+
+        void processAttribute(const DOMAttr* attribute) {
+            QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix()); 
+            setAttribute(q,attribute->getNodeValue());
+        }
+
+        void processElementContent(const XMLCh* elementContent) {
+            setTextContent(elementContent);
+        }
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+
+XMLObject* AnyElementBuilder::buildObject(
+    const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix
+    ) const {
+    if (XMLString::stringLen(elementLocalName)==0)
+        throw XMLObjectException("Constructing this object requires an element name.");
+    return new AnyElementImpl(namespaceURI,elementLocalName,namespacePrefix);
+}
diff --git a/xmltooling/impl/AnyElement.h b/xmltooling/impl/AnyElement.h
new file mode 100644 (file)
index 0000000..803de11
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright 2001-2006 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file AnyElement.h
+ * 
+ * Advanced anyType implementation suitable for deep processing of unknown content.
+ */
+
+#if !defined(__xmltooling_anyelement_h__)
+#define __xmltooling_anyelement_h__
+
+#include <xmltooling/XMLObjectBuilder.h>
+
+namespace xmltooling {
+
+    /**
+     * Implements a smart wrapper around unknown DOM content.
+     */
+    class XMLTOOL_DLLLOCAL AnyElementImpl;
+
+    /**
+     * Builder for AnyElementImpl objects.
+     */
+    class XMLTOOL_API AnyElementBuilder : public XMLObjectBuilder
+    {
+    public:
+        XMLObject* buildObject(
+            const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL
+            ) const;
+    };
+
+};
+
+#endif /* __xmltooling_anyelement_h__ */
index dd8e303..6759e5f 100644 (file)
@@ -17,7 +17,7 @@
 /**\r
  * UnknownElement.cpp\r
  * \r
- * Basic implementations suitable for use as defaults for unrecognized content\r
+ * Basic implementation suitable for use as default for unrecognized content\r
  */\r
 \r
 #include "internal.h"\r
index bfc5b1a..d13f22c 100644 (file)
  */\r
 \r
 /**\r
- * UnknownElement.h\r
+ * @file UnknownElement.h\r
  * \r
- * Basic implementations suitable for use as defaults for unrecognized content\r
+ * Basic implementation suitable for use as default for unrecognized content\r
  */\r
 \r
 #if !defined(__xmltooling_unkelement_h__)\r
 #define __xmltooling_unkelement_h__\r
 \r
-#include "internal.h"\r
-#include "XMLObjectBuilder.h"\r
-#include "io/AbstractXMLObjectMarshaller.h"\r
-#include "io/AbstractXMLObjectUnmarshaller.h"\r
+#include <xmltooling/XMLObjectBuilder.h>\r
+#include <xmltooling/io/AbstractXMLObjectMarshaller.h>\r
+#include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>\r
 \r
 #include <string>\r
 \r
@@ -37,6 +36,9 @@
 \r
 namespace xmltooling {\r
 \r
+    /**\r
+     * Implements a thin wrapper around unknown DOM content.\r
+     */\r
     class XMLTOOL_DLLLOCAL UnknownElementImpl : public AbstractDOMCachingXMLObject\r
     {\r
     public:\r
@@ -65,11 +67,16 @@ namespace xmltooling {
         void serialize(std::string& s) const;\r
     };\r
 \r
-    class XMLTOOL_DLLLOCAL UnknownElementBuilder : public XMLObjectBuilder\r
+    /**\r
+     * Factory for UnknownElementImpl objects.\r
+     */\r
+    class XMLTOOL_API UnknownElementBuilder : public XMLObjectBuilder\r
     {\r
     public:\r
-        UnknownElementImpl* buildObject() const {\r
-            return new UnknownElementImpl();\r
+        UnknownElementImpl* buildObject(\r
+            const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL\r
+            ) const {\r
+            return new UnknownElementImpl(namespaceURI,elementLocalName,namespacePrefix);\r
         }\r
     };\r
 \r
index eb01345..7034ca3 100644 (file)
@@ -84,11 +84,6 @@ XMLObject* XMLSecSignatureImpl::clone() const
     return ret;\r
 }\r
 \r
-DSIGKeyInfoList* XMLSecSignatureImpl::getKeyInfo() const\r
-{\r
-    return m_signature ? m_signature->getKeyInfoList() : NULL;\r
-}\r
-\r
 class _addcert : public std::binary_function<DSIGKeyInfoX509*,XSECCryptoX509*,void> {\r
 public:\r
     void operator()(DSIGKeyInfoX509* bag, XSECCryptoX509* cert) const {\r
index 635b646..e22421c 100644 (file)
@@ -40,7 +40,7 @@ namespace xmltooling {
     class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature\r
     {\r
     public:\r
-        XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME),\r
+        XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME, XMLConstants::XMLSIG_PREFIX),\r
             m_signature(NULL), m_c14n(NULL), m_sm(NULL) {}\r
         virtual ~XMLSecSignatureImpl();\r
         \r
@@ -71,7 +71,9 @@ namespace xmltooling {
     class XMLTOOL_DLLLOCAL XMLSecSignatureBuilder : public virtual XMLObjectBuilder\r
     {\r
     public:\r
-        XMLSecSignatureImpl* buildObject() const {\r
+        XMLSecSignatureImpl* buildObject(\r
+            const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL\r
+            ) const {\r
             return new XMLSecSignatureImpl();\r
         }\r
     };\r
index 11c0f60..5fc189b 100644 (file)
                                Name="impl"\r
                                >\r
                                <File\r
+                                       RelativePath=".\impl\AnyElement.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\impl\UnknownElement.cpp"\r
                                        >\r
                                </File>\r
                                Name="impl"\r
                                >\r
                                <File\r
+                                       RelativePath=".\impl\AnyElement.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\impl\UnknownElement.h"\r
                                        >\r
                                </File>\r
index de45855..847931c 100644 (file)
@@ -24,11 +24,11 @@ public:
     ComplexXMLObjectTest() {}\r
 \r
     void setUp() {\r
-        XMLObjectBuilder::registerDefaultBuilder(new WildcardXMLObjectBuilder());\r
+        XMLObjectBuilder::registerDefaultBuilder(new AnyElementBuilder());\r
     }\r
 \r
     void tearDown() {\r
-        //XMLObjectBuilder::deregisterDefaultBuilder();\r
+        XMLObjectBuilder::deregisterDefaultBuilder();\r
     }\r
 \r
     void testComplexUnmarshalling() {\r
@@ -42,16 +42,16 @@ public:
         const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
         TS_ASSERT(b!=NULL);\r
 \r
-        auto_ptr<WildcardXMLObject> wcObject(\r
-            dynamic_cast<WildcardXMLObject*>(b->buildFromDocument(doc))\r
+        auto_ptr<ElementProxy> wcObject(\r
+            dynamic_cast<ElementProxy*>(b->buildFromDocument(doc))\r
             );\r
         TS_ASSERT(wcObject.get()!=NULL);\r
 \r
         ListOf(XMLObject) kids=wcObject->getXMLObjects();\r
         TSM_ASSERT_EQUALS("Number of child elements was not expected value", 2, kids.size());\r
         \r
-        WildcardXMLObject* wc1=dynamic_cast<WildcardXMLObject*>(*(++kids.begin()));\r
-        WildcardXMLObject* wc2=dynamic_cast<WildcardXMLObject*>(*(++(wc1->getXMLObjects().begin())));\r
+        ElementProxy* wc1=dynamic_cast<ElementProxy*>(*(++kids.begin()));\r
+        ElementProxy* wc2=dynamic_cast<ElementProxy*>(*(++(wc1->getXMLObjects().begin())));\r
         TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, wc2->getXMLObjects().size());\r
 \r
         static const XMLCh html[] = {chLatin_h, chLatin_t, chLatin_m, chLatin_l, chNull};\r
index 13e07e9..af687e3 100644 (file)
 \r
 class MarshallingTest : public CxxTest::TestSuite {\r
     QName m_qname;\r
+    QName m_qtype;\r
 public:\r
-    MarshallingTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME) {}\r
+    MarshallingTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME,SimpleXMLObject::NAMESPACE_PREFIX),\r
+        m_qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX) {}\r
 \r
     void setUp() {\r
         XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
+        XMLObjectBuilder::registerBuilder(m_qtype, new SimpleXMLObjectBuilder());\r
     }\r
 \r
     void tearDown() {\r
         XMLObjectBuilder::deregisterBuilder(m_qname);\r
+        XMLObjectBuilder::deregisterBuilder(m_qtype);\r
     }\r
 \r
     void testMarshallingWithAttributes() {\r
@@ -85,11 +89,16 @@ public:
         // Test some collection stuff\r
         auto_ptr_XMLCh foo("Foo");\r
         auto_ptr_XMLCh bar("Bar");\r
+        auto_ptr_XMLCh baz("Baz");\r
         kids.begin()->setId(foo.get());\r
         kids.at(2)->setValue(bar.get());\r
         kids.erase(kids.begin()+1);\r
         TS_ASSERT_SAME_DATA(kids.back()->getValue(), bar.get(), XMLString::stringLen(bar.get()));\r
         \r
+        kids.push_back(b->buildObject(SimpleXMLObject::NAMESPACE,SimpleXMLObject::DERIVED_NAME,SimpleXMLObject::NAMESPACE_PREFIX));\r
+        kids.back()->setSchemaType(&m_qtype);\r
+        kids.back()->setValue(baz.get());\r
+        \r
         DOMElement* rootElement = sxObject->marshall();\r
 \r
         string path=data_path + "SimpleXMLObjectWithChildren.xml";\r
index 5e02520..cfd8e46 100644 (file)
@@ -85,15 +85,19 @@ public:
 \r
 class SignatureTest : public CxxTest::TestSuite {\r
     QName m_qname;\r
+    QName m_qtype;\r
 public:\r
-    SignatureTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME) {}\r
+    SignatureTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME,SimpleXMLObject::NAMESPACE_PREFIX),\r
+        m_qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX) {}\r
 \r
     void setUp() {\r
         XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
+        XMLObjectBuilder::registerBuilder(m_qtype, new SimpleXMLObjectBuilder());\r
     }\r
 \r
     void tearDown() {\r
         XMLObjectBuilder::deregisterBuilder(m_qname);\r
+        XMLObjectBuilder::deregisterBuilder(m_qtype);\r
     }\r
 \r
     void testSignature() {\r
index d4f41cc..fe8487b 100644 (file)
@@ -37,21 +37,36 @@ const XMLCh SimpleXMLObject::LOCAL_NAME[] = {
     chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chNull\r
 };\r
 \r
+const XMLCh SimpleXMLObject::DERIVED_NAME[] = {\r
+    chLatin_D, chLatin_e, chLatin_r, chLatin_i, chLatin_v, chLatin_e, chLatin_d,\r
+    chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chNull\r
+};\r
+\r
+const XMLCh SimpleXMLObject::TYPE_NAME[] = {\r
+    chLatin_S, chLatin_i, chLatin_m, chLatin_p, chLatin_l, chLatin_e,\r
+    chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, \r
+    chLatin_T, chLatin_y, chLatin_p, chLatin_e, chNull\r
+};\r
+\r
 const XMLCh SimpleXMLObject::ID_ATTRIB_NAME[] = {\r
     chLatin_I, chLatin_d, chNull\r
 };\r
 \r
 class UnmarshallingTest : public CxxTest::TestSuite {\r
     QName m_qname;\r
+    QName m_qtype;\r
 public:\r
-    UnmarshallingTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME) {}\r
+    UnmarshallingTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME,SimpleXMLObject::NAMESPACE_PREFIX),\r
+        m_qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX) {}\r
 \r
     void setUp() {\r
         XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
+        XMLObjectBuilder::registerBuilder(m_qtype, new SimpleXMLObjectBuilder());\r
     }\r
 \r
     void tearDown() {\r
         XMLObjectBuilder::deregisterBuilder(m_qname);\r
+        XMLObjectBuilder::deregisterBuilder(m_qtype);\r
     }\r
 \r
     void testUnmarshallingWithAttributes() {\r
@@ -111,7 +126,8 @@ public:
         TS_ASSERT(sxObject.get()!=NULL);\r
 \r
         VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 2, kids.size());\r
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());\r
+        TSM_ASSERT_EQUALS("Child's schema type was not expected value", m_qtype, *(kids.back()->getSchemaType()));\r
     }\r
 \r
     void testUnmarshallingWithUnknownChild() {\r
index 873f227..e9cface 100644 (file)
  */
 
 #include <cxxtest/TestSuite.h>
-#include <xmltooling/AbstractAttributeExtensibleXMLObject.h>
-#include <xmltooling/AbstractElementProxy.h>
+#include <xmltooling/ElementProxy.h>
 #include <xmltooling/exceptions.h>
 #include <xmltooling/XMLObjectBuilder.h>
 #include <xmltooling/XMLToolingConfig.h>
 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
+#include <xmltooling/impl/AnyElement.h>
+#include <xmltooling/impl/UnknownElement.h>
 #ifndef XMLTOOLING_NO_XMLSEC
     #include <xmltooling/signature/Signature.h>
 #endif
@@ -48,9 +49,13 @@ public:
     static const XMLCh NAMESPACE[];
     static const XMLCh NAMESPACE_PREFIX[];
     static const XMLCh LOCAL_NAME[];
+    static const XMLCh DERIVED_NAME[];
+    static const XMLCh TYPE_NAME[];
     static const XMLCh ID_ATTRIB_NAME[];
 
-    SimpleXMLObject() : AbstractDOMCachingXMLObject(NAMESPACE, LOCAL_NAME, NAMESPACE_PREFIX), m_id(NULL), m_value(NULL) {
+    SimpleXMLObject(
+        const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL
+        ) : AbstractDOMCachingXMLObject(namespaceURI, elementLocalName, namespacePrefix), m_id(NULL), m_value(NULL) {
 #ifndef XMLTOOLING_NO_XMLSEC
         m_children.push_back(NULL);
         m_signature=m_children.begin();
@@ -112,14 +117,21 @@ public:
     }
 
     void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-        if (XMLHelper::isNodeNamed(root, SimpleXMLObject::NAMESPACE, SimpleXMLObject::LOCAL_NAME))
-            getSimpleXMLObjects().push_back(dynamic_cast<SimpleXMLObject*>(childXMLObject));
+        SimpleXMLObject* simple=dynamic_cast<SimpleXMLObject*>(childXMLObject);
+        if (simple) {
+            getSimpleXMLObjects().push_back(simple);
+            return;
+        }
+        
 #ifndef XMLTOOLING_NO_XMLSEC
-        else if (XMLHelper::isNodeNamed(root, XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME))
-            setSignature(dynamic_cast<Signature*>(childXMLObject));
+        Signature* sig=dynamic_cast<Signature*>(childXMLObject);
+        if (sig) {
+            setSignature(sig);
+            return;
+        }
 #endif
-        else
-            throw UnmarshallingException("Unknown child element cannot be added to parent object.");
+
+        throw UnmarshallingException("Unknown child element cannot be added to parent object.");
     }
 
     void processAttribute(const DOMAttr* attribute) {
@@ -146,85 +158,13 @@ class SimpleXMLObjectBuilder : public XMLObjectBuilder
 {
 public:
     SimpleXMLObject* buildObject() const {
-        return new SimpleXMLObject();
-    }
-};
-
-class WildcardXMLObject : public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject,
-    public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller
-{
-public:
-    WildcardXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix)
-        : AbstractDOMCachingXMLObject(nsURI, localName, prefix),
-        AbstractElementProxy(nsURI, localName, prefix),
-        AbstractAttributeExtensibleXMLObject(nsURI, localName, prefix) {}
-    virtual ~WildcardXMLObject() {}
-    
-    WildcardXMLObject* clone() const {
-        auto_ptr<XMLObject> domClone(AbstractDOMCachingXMLObject::clone());
-        WildcardXMLObject* ret=dynamic_cast<WildcardXMLObject*>(domClone.get());
-        if (ret) {
-            domClone.release();
-            return ret;
-        }
-
-        ret=new WildcardXMLObject(
-            getElementQName().getNamespaceURI(),getElementQName().getLocalPart(),getElementQName().getPrefix()
-            );
-        ret->m_namespaces=m_namespaces;
-        for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
-            ret->m_attributeMap[i->first]=XMLString::replicate(i->second);
-        }
-        ret->setTextContent(getTextContent());
-        xmltooling::clone(m_children, ret->m_children);
-        return ret;
-    }
-
-    void marshallAttributes(DOMElement* domElement) const {
-        for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
-            DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
-            if (i->first.hasPrefix())
-                attr->setPrefix(i->first.getPrefix());
-            attr->setNodeValue(i->second);
-            domElement->setAttributeNode(attr);
-        }
-    }
-
-    void marshallElementContent(DOMElement* domElement) const {
-        if(getTextContent()) {
-            domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
-        }
-    }
-
-    void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-        getXMLObjects().push_back(childXMLObject);
-    }
-
-    void processAttribute(const DOMAttr* attribute) {
-        QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix()); 
-        setAttribute(q,attribute->getNodeValue());
-    }
-
-    void processElementContent(const XMLCh* elementContent) {
-        setTextContent(elementContent);
-    }
-};
-
-class WildcardXMLObjectBuilder : public XMLObjectBuilder
-{
-public:
-    WildcardXMLObject* buildObject() const {
-        throw XMLObjectException("Default build operation is unsupported.");
-    }
-
-    WildcardXMLObject* buildObject(const QName& q) const {
-        return new WildcardXMLObject(q.getNamespaceURI(),q.getLocalPart(),q.getPrefix());
+        return buildObject(SimpleXMLObject::NAMESPACE, SimpleXMLObject::LOCAL_NAME, SimpleXMLObject::NAMESPACE_PREFIX);
     }
 
-    WildcardXMLObject* buildFromElement(DOMElement* e, bool bindDocument=false) const {
-        auto_ptr<WildcardXMLObject> ret(new WildcardXMLObject(e->getNamespaceURI(),e->getLocalName(),e->getPrefix()));
-        ret->unmarshall(e,bindDocument);
-        return ret.release();
+    SimpleXMLObject* buildObject(
+        const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL
+        ) const {
+        return new SimpleXMLObject(namespaceURI,elementLocalName,namespacePrefix);
     }
 };
 
index f8a9f67..9a6769b 100644 (file)
Binary files a/xmltoolingtest/data/SimpleXMLObjectWithChildren.xml and b/xmltoolingtest/data/SimpleXMLObjectWithChildren.xml differ
index 84b52c1..fcf5a69 100644 (file)
@@ -62,6 +62,14 @@ static ToolingFixture globalFixture;
 class GlobalTest : public CxxTest::TestSuite\r
 {\r
 public:\r
+    void setUp() {\r
+        XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());\r
+    }\r
+\r
+    void tearDown() {\r
+        XMLObjectBuilder::deregisterDefaultBuilder();\r
+    }\r
+\r
     void testCatalog(void) {\r
         std::string path=data_path + "catalog.xml";\r
         auto_ptr_XMLCh temp(path.c_str());\r