Default support for arbitrary DOM objects.
authorScott Cantor <cantor.2@osu.edu>
Fri, 24 Feb 2006 05:17:02 +0000 (05:17 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 24 Feb 2006 05:17:02 +0000 (05:17 +0000)
20 files changed:
xmltooling/AbstractDOMCachingXMLObject.cpp
xmltooling/AbstractDOMCachingXMLObject.h
xmltooling/AbstractXMLObject.h
xmltooling/Makefile.am
xmltooling/XMLObjectBuilder.cpp
xmltooling/XMLObjectBuilder.h
xmltooling/XMLToolingConfig.cpp
xmltooling/XMLToolingConfig.h
xmltooling/impl/UnknownElement.cpp [new file with mode: 0644]
xmltooling/impl/UnknownElement.h [new file with mode: 0644]
xmltooling/internal.h
xmltooling/io/AbstractXMLObjectMarshaller.cpp
xmltooling/io/AbstractXMLObjectUnmarshaller.cpp
xmltooling/io/AbstractXMLObjectUnmarshaller.h
xmltooling/io/Marshaller.cpp
xmltooling/io/Marshaller.h
xmltooling/io/Unmarshaller.cpp
xmltooling/io/Unmarshaller.h
xmltooling/unicode.cpp
xmltooling/xmltooling.vcproj

index 3a3d853..8a23062 100644 (file)
@@ -58,7 +58,7 @@ void AbstractDOMCachingXMLObject::releaseDOM()
 {\r
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
     if (log.isDebugEnabled())\r
-        log.debug("Releasing cached DOM reprsentation for %s", getElementQName().toString().c_str());\r
+        log.debug("releasing cached DOM reprsentation for %s", getElementQName().toString().c_str());\r
     setDOM(NULL);\r
 }\r
 \r
@@ -67,7 +67,7 @@ void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease)
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
     if (log.isDebugEnabled()) {\r
         log.debug(\r
-            "Releasing cached DOM representation for parent of %s with propagation set to %s",\r
+            "releasing cached DOM representation for parent of %s with propagation set to %s",\r
             getElementQName().toString().c_str(), propagateRelease ? "true" : "false"\r
             );\r
     }\r
@@ -97,7 +97,7 @@ void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease)
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
     if (log.isDebugEnabled()) {\r
         log.debug(\r
-            "Releasing cached DOM representation for children of %s with propagation set to %s",\r
+            "releasing cached DOM representation for children of %s with propagation set to %s",\r
             getElementQName().toString().c_str(), propagateRelease ? "true" : "false"\r
             );\r
     }\r
index 35bd2e1..8093fe8 100644 (file)
@@ -65,17 +65,17 @@ namespace xmltooling {
         /**\r
          * @see DOMCachingXMLObject::releaseDOM()\r
          */\r
-        void releaseDOM();\r
+        virtual void releaseDOM();\r
         \r
         /**\r
          * @see DOMCachingXMLObject::releaseParentDOM()\r
          */\r
-        void releaseParentDOM(bool propagateRelease=true);\r
+        virtual void releaseParentDOM(bool propagateRelease=true);\r
         \r
         /**\r
          * @see DOMCachingXMLObject::releaseChildrenDOM()\r
          */\r
-        void releaseChildrenDOM(bool propagateRelease=true);\r
+        virtual void releaseChildrenDOM(bool propagateRelease=true);\r
     \r
         /**\r
          * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).\r
@@ -88,7 +88,7 @@ namespace xmltooling {
         }\r
     \r
         /**\r
-         * A convenience method that is equal to calling releaseDOM() then releaseChildrenDOM(true).\r
+         * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM().\r
          */\r
         void releaseThisAndChildrenDOM() {\r
             if (m_dom) {\r
@@ -132,13 +132,15 @@ namespace xmltooling {
          */\r
         XMLObject* prepareForAssignment(const XMLObject* oldValue, XMLObject* newValue);\r
 \r
+        AbstractDOMCachingXMLObject() : m_dom(NULL), m_document(NULL) {}\r
+\r
         /**\r
          * Constructor\r
          * \r
          * @param namespaceURI the namespace the element is in\r
          * @param elementLocalName the local name of the XML element this Object represents\r
          */\r
-        explicit AbstractDOMCachingXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName)\r
+        AbstractDOMCachingXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName)\r
             : AbstractXMLObject(namespaceURI,elementLocalName), m_dom(NULL), m_document(NULL) {}\r
 \r
     private:\r
index 88fdef9..a3b5a70 100644 (file)
@@ -118,13 +118,15 @@ namespace xmltooling {
         }\r
     \r
      protected:\r
+         AbstractXMLObject() : m_typeQname(NULL), m_parent(NULL) {}\r
+\r
         /**\r
          * Constructor\r
          * \r
          * @param namespaceURI the namespace the element is in\r
          * @param elementLocalName the local name of the XML element this Object represents\r
          */\r
-        explicit AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName)\r
+        AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName)\r
             : m_elementQname(namespaceURI,elementLocalName), m_typeQname(NULL), m_parent(NULL) {}\r
         \r
     private:\r
index 1fc91c8..b9c8d94 100644 (file)
@@ -39,7 +39,8 @@ ioinclude_HEADERS = \
     io/Unmarshaller.h
 
 noinst_HEADERS = \
-       internal.h
+       internal.h \
+       impl/UnknownElement.h
 
 libxmltooling_la_SOURCES = \
        AbstractDOMCachingXMLObject.cpp \
@@ -48,6 +49,8 @@ libxmltooling_la_SOURCES = \
        unicode.cpp \
        XMLObjectBuilder.cpp \
        XMLToolingConfig.cpp \
+       impl/UnknownElement.cpp \
+       io/AbstractXMLObjectMarshaller.cpp \
        io/AbstractXMLObjectUnmarshaller.cpp \
        io/Marshaller.cpp \
        io/Unmarshaller.cpp \
index c3aa881..03b9c27 100644 (file)
@@ -45,7 +45,7 @@ const XMLObjectBuilder* XMLObjectBuilder::getBuilder(const DOMElement* domElemen
     const XMLObjectBuilder* xmlObjectBuilder = getBuilder(*(schemaType.get()));\r
     if (xmlObjectBuilder) {\r
         if (log.isDebugEnabled()) {\r
-            log.debug("Located XMLObjectBuilder for schema type: %s", schemaType->toString().c_str());\r
+            log.debug("located XMLObjectBuilder for schema type: %s", schemaType->toString().c_str());\r
         }\r
         return xmlObjectBuilder;\r
     }\r
@@ -54,13 +54,13 @@ const XMLObjectBuilder* XMLObjectBuilder::getBuilder(const DOMElement* domElemen
     xmlObjectBuilder = getBuilder(*(elementName.get()));\r
     if (xmlObjectBuilder) {\r
         if (log.isDebugEnabled()) {\r
-            log.debug("Located XMLObjectBuilder for element name: %s", elementName->toString().c_str());\r
+            log.debug("located XMLObjectBuilder for element name: %s", elementName->toString().c_str());\r
         }\r
         return xmlObjectBuilder;\r
     }\r
 \r
-    log.error("No XMLObjectBuilder was registered for element: %s", elementName->toString().c_str());\r
-    return NULL;\r
+    log.error("no XMLObjectBuilder registered for element (%s), using default", elementName->toString().c_str());\r
+    return m_default;\r
 }\r
 \r
 void XMLObjectBuilder::destroyBuilders()\r
index 43e9daa..a4c4311 100644 (file)
@@ -58,7 +58,7 @@ namespace xmltooling {
          * 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\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
@@ -66,7 +66,8 @@ namespace xmltooling {
         }\r
 \r
         /**\r
-         * Retrieves an XMLObjectBuilder for a given DOM element\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
@@ -134,6 +135,9 @@ namespace xmltooling {
          * 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
index e4e19c0..e6fe259 100644 (file)
@@ -22,6 +22,7 @@
 \r
 #include "internal.h"\r
 #include "XMLToolingConfig.h"\r
+#include "impl/UnknownElement.h"\r
 #include "util/NDC.h"\r
 \r
 #ifdef HAVE_DLFCN_H\r
@@ -49,6 +50,11 @@ XMLToolingConfig& XMLToolingConfig::getConfig()
     return g_config;\r
 }\r
 \r
+XMLToolingInternalConfig& XMLToolingInternalConfig::getInternalConfig()\r
+{\r
+    return g_config;\r
+}\r
+\r
 bool XMLToolingInternalConfig::log_config(const char* config)\r
 {\r
     try {\r
@@ -124,7 +130,13 @@ bool XMLToolingInternalConfig::init()
         //m_xsec=new XSECProvider();\r
         log.debug("XMLSec initialization complete");\r
         \r
+        m_parserPool=new ParserPool();\r
         m_lock=xercesc::XMLPlatformUtils::makeMutex();\r
+\r
+        // default registrations\r
+        XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());\r
+        Marshaller::registerDefaultMarshaller(new UnknownElementMarshaller());\r
+        Unmarshaller::registerDefaultUnmarshaller(new UnknownElementUnmarshaller());\r
     }\r
     catch (const xercesc::XMLException&) {\r
         log.fatal("caught exception while initializing Xerces");\r
@@ -154,9 +166,13 @@ void XMLToolingInternalConfig::term()
     }\r
     m_libhandles.clear();\r
     \r
+    delete m_parserPool;\r
+    m_parserPool=NULL;\r
+\r
     //delete m_xsec; m_xsec=NULL;\r
     XSECPlatformUtils::Terminate();\r
     xercesc::XMLPlatformUtils::closeMutex(m_lock);\r
+    m_lock=NULL;\r
     xercesc::XMLPlatformUtils::Terminate();\r
 \r
  #ifdef _DEBUG\r
index 406bbd0..dacf961 100644 (file)
@@ -92,18 +92,8 @@ namespace xmltooling {
          */\r
         virtual bool log_config(const char* config=NULL)=0;\r
         \r
-        /**\r
-         * Allow and capture unknown attributes during unmarshalling\r
-         */\r
-        bool ignoreUnknownAttributes;\r
-\r
-        /**\r
-         * Allow and capture unknown elements during unmarshalling \r
-         */\r
-        bool ignoreUnknownElements;\r
-\r
     protected:\r
-        XMLToolingConfig() : ignoreUnknownAttributes(true), ignoreUnknownElements(true) {}\r
+        XMLToolingConfig() {}\r
     };\r
 \r
 };\r
diff --git a/xmltooling/impl/UnknownElement.cpp b/xmltooling/impl/UnknownElement.cpp
new file mode 100644 (file)
index 0000000..0dfef21
--- /dev/null
@@ -0,0 +1,148 @@
+/*\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
+ * UnknownElement.cpp\r
+ * \r
+ * Basic implementations suitable for use as defaults for unrecognized content\r
+ */\r
+\r
+#include "internal.h"\r
+#include "exceptions.h"\r
+#include "impl/UnknownElement.h"\r
+#include "util/NDC.h"\r
+\r
+#include <log4cpp/Category.hh>\r
+#include <xercesc/framework/MemBufFormatTarget.hpp>\r
+#include <xercesc/framework/MemBufInputSource.hpp>\r
+#include <xercesc/framework/Wrapper4InputSource.hpp>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+\r
+using namespace xmltooling;\r
+using namespace log4cpp;\r
+using namespace std;\r
+\r
+void UnknownElementImpl::releaseDOM()\r
+{\r
+#ifdef _DEBUG\r
+    xmltooling::NDC ndc("releaseDOM");\r
+#endif\r
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".UnknownElementImpl");\r
+    log.debug("releasing DOM for unknown content, preserving current DOM in XML form");\r
+\r
+    // We're losing our DOM, so assuming we have one, we preserve it.\r
+    serialize(m_xml);\r
+\r
+    // This takes care of the generic housekeeping now that we've preserved things.\r
+    AbstractDOMCachingXMLObject::releaseDOM();\r
+}\r
+\r
+XMLObject* UnknownElementImpl::clone() const\r
+{\r
+    UnknownElementImpl* ret=new UnknownElementImpl();\r
+\r
+    // If there's no XML locally, serialize this object into the new one.\r
+    // Otherwise just copy it over.\r
+    if (m_xml.empty())\r
+        serialize(ret->m_xml);\r
+    else\r
+        ret->m_xml=m_xml;\r
+\r
+    return ret;\r
+}\r
+\r
+void UnknownElementImpl::serialize(string& s) const\r
+{\r
+    if (getDOM()) {\r
+        static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
+        static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
+        DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
+        DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();\r
+        serializer->setEncoding(UTF8);\r
+        try {\r
+            MemBufFormatTarget target;\r
+            if (!serializer->writeNode(&target,*(getDOM())))\r
+                throw XMLObjectException("unable to serialize XML to preserve DOM");\r
+            s.erase();\r
+            s.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());\r
+            serializer->release();\r
+        }\r
+        catch (...) {\r
+            serializer->release();\r
+            throw;\r
+        }\r
+    }\r
+}\r
+\r
+DOMElement* UnknownElementMarshaller::marshall(XMLObject* xmlObject, DOMDocument* document) const\r
+{\r
+#ifdef _DEBUG\r
+    xmltooling::NDC ndc("marshall");\r
+#endif\r
+    \r
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller");\r
+    log.debug("marshalling unknown content");\r
+\r
+    UnknownElementImpl* unk=dynamic_cast<UnknownElementImpl*>(xmlObject);\r
+    if (!unk)\r
+        throw MarshallingException("Only objects of class UnknownElementImpl can be marshalled.");\r
+    \r
+    DOMElement* cachedDOM=unk->getDOM();\r
+    if (cachedDOM) {\r
+        if (!document || document==cachedDOM->getOwnerDocument()) {\r
+            log.debug("XMLObject has a usable cached DOM, using it");\r
+            return cachedDOM;\r
+        }\r
+        \r
+        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
+        // Without an adoptNode option to maintain the child pointers, we rely on our custom\r
+        // implementation class to preserve the XML when we release the existing DOM.\r
+        unk->releaseDOM();\r
+    }\r
+    \r
+    // If we get here, we didn't have a usable DOM (and/or we flushed the one we had).\r
+    // We need to reparse the XML we saved off into a new DOM.\r
+    bool bindDocument=false;\r
+    MemBufInputSource src(reinterpret_cast<const XMLByte*>(unk->m_xml.c_str()),unk->m_xml.length(),"UnknownElementImpl");\r
+    Wrapper4InputSource dsrc(&src,false);\r
+    log.debug("parsing XML back into DOM tree");\r
+    DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc);\r
+    if (document) {\r
+        // The caller insists on using his own document, so we now have to import the damn thing\r
+        // into it. Then we're just dumping the one we built.\r
+        log.debug("reimporting new DOM into caller-supplied document");\r
+        cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));\r
+        internalDoc->release();\r
+    }\r
+    else {\r
+        // We just bind the document we built to the object as the result.\r
+        document=internalDoc;\r
+        bindDocument=true;\r
+    }\r
+\r
+    // Recache the DOM and clear the serialized copy.\r
+    log.debug("caching DOM for XMLObject");\r
+    unk->setDOM(cachedDOM, bindDocument);\r
+    unk->m_xml.erase();\r
+    return cachedDOM;\r
+}\r
+\r
+XMLObject* UnknownElementUnmarshaller::unmarshall(DOMElement* element, bool bindDocument) const\r
+{\r
+    UnknownElementImpl* ret=new UnknownElementImpl();\r
+    ret->setDOM(element, bindDocument);\r
+    return ret;\r
+}\r
diff --git a/xmltooling/impl/UnknownElement.h b/xmltooling/impl/UnknownElement.h
new file mode 100644 (file)
index 0000000..acab528
--- /dev/null
@@ -0,0 +1,140 @@
+/*\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 UnknownElement.h\r
+ * \r
+ * Basic implementations suitable for use as defaults for unrecognized content\r
+ */\r
+\r
+#if !defined(__xmltooling_unkelement_h__)\r
+#define __xmltooling_unkelement_h__\r
+\r
+#include "internal.h"\r
+#include "AbstractDOMCachingXMLObject.h"\r
+#include "XMLObjectBuilder.h"\r
+#include "io/Marshaller.h"\r
+#include "io/Unmarshaller.h"\r
+\r
+#include <string>\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
+     * Implementation class for unrecognized DOM elements.\r
+     * Purpose is to wrap the DOM and do any necessary caching/reconstruction\r
+     * when a DOM has to cross into a new document.\r
+     */\r
+    class XMLTOOL_DLLLOCAL UnknownElementImpl : public AbstractDOMCachingXMLObject\r
+    {\r
+    public:\r
+        UnknownElementImpl() {}\r
+\r
+        /**\r
+         * Overridden to ensure XML content of DOM isn't lost.\r
+         * \r
+         * @see DOMCachingXMLObject::releaseDOM()\r
+         */\r
+        void releaseDOM();\r
+\r
+        /**\r
+          * @see XMLObject::clone()\r
+          */\r
+        XMLObject* clone() const;\r
+\r
+        /**\r
+         * @see XMLObject::hasChildren()\r
+         */\r
+        bool hasChildren() const {\r
+            return false;\r
+        }\r
+\r
+        /**\r
+         * @see XMLObject::getOrderedChildren()\r
+         */\r
+        size_t getOrderedChildren(std::vector<XMLObject*>& v) const {\r
+            return 0;\r
+        }\r
+\r
+    protected:\r
+        /**\r
+         * When needed, we can serialize the DOM into XML form and preserve it here.\r
+         */\r
+        std::string m_xml;\r
+\r
+    private:\r
+        void serialize(std::string& s) const;\r
+        friend class XMLTOOL_API UnknownElementMarshaller;\r
+    };\r
+\r
+    /**\r
+     * Factory for UnknownElementImpl objects\r
+     */\r
+    class XMLTOOL_DLLLOCAL UnknownElementBuilder : public virtual XMLObjectBuilder\r
+    {\r
+    public:\r
+        UnknownElementBuilder() {}\r
+        virtual ~UnknownElementBuilder() {}\r
+    \r
+        /**\r
+         * @see XMLObjectBuilder::buildObject()\r
+         */\r
+        XMLObject* buildObject() const {\r
+            return new UnknownElementImpl();\r
+        }\r
+    };\r
+\r
+    /**\r
+     * Marshaller for UnknownElementImpl objects\r
+     */\r
+    class XMLTOOL_DLLLOCAL UnknownElementMarshaller : public virtual Marshaller\r
+    {\r
+    public:\r
+        UnknownElementMarshaller() {}\r
+        virtual ~UnknownElementMarshaller() {}\r
+    \r
+        /**\r
+         * @see Marshaller::marshall()\r
+         */\r
+        DOMElement* marshall(XMLObject* xmlObject, DOMDocument* document=NULL) const;\r
+    };\r
+\r
+    /**\r
+     * Marshaller for UnknownElementImpl objects\r
+     */\r
+    class XMLTOOL_DLLLOCAL UnknownElementUnmarshaller : public virtual Unmarshaller\r
+    {\r
+    public:\r
+        UnknownElementUnmarshaller() {}\r
+        virtual ~UnknownElementUnmarshaller() {}\r
+    \r
+        /**\r
+         * @see Unmarshaller::unmarshall()\r
+         */\r
+        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false) const;\r
+    };\r
+};\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( pop )\r
+#endif\r
+\r
+#endif /* __xmltooling_unkelement_h__ */\r
index 383fbcf..199c644 100644 (file)
 \r
 #include "base.h"\r
 #include "XMLToolingConfig.h"\r
+#include "util/ParserPool.h"\r
 \r
 #include <vector>\r
 \r
 #define XMLTOOLING_LOGCAT "XMLTooling"\r
 \r
-namespace {\r
+namespace xmltooling {\r
     \r
     class XMLToolingInternalConfig : public xmltooling::XMLToolingConfig\r
     {\r
     public:\r
-        XMLToolingInternalConfig() : m_lock(NULL) {}\r
+        XMLToolingInternalConfig() : m_lock(NULL), m_parserPool(NULL) {}\r
+\r
+        static XMLToolingInternalConfig& getInternalConfig();\r
 \r
         // global per-process setup and shutdown of runtime\r
         bool init();\r
@@ -59,6 +62,9 @@ namespace {
         bool load_library(const char* path, void* context=NULL);\r
         bool log_config(const char* config=NULL);\r
 \r
+        // internal parser pool\r
+        xmltooling::ParserPool* m_parserPool;\r
+\r
     private:\r
         std::vector<void*> m_libhandles;\r
         void* m_lock;\r
index 7fd4e50..1457d4b 100644 (file)
@@ -192,22 +192,11 @@ public:
 \r
         const Marshaller* marshaller = Marshaller::getMarshaller(obj);\r
         if (!marshaller) {\r
-            if (XMLToolingConfig::getConfig().ignoreUnknownElements) {\r
-                marshaller=Marshaller::getDefaultMarshaller();\r
-                if (marshaller)\r
-                    XT_log.debug("using default marshaller");\r
-                else {\r
-                    XT_log.error(\r
-                        "no default unmarshaller installed, unknown child object: %s",\r
-                        obj->getElementQName().toString().c_str()\r
-                        );\r
-                    throw MarshallingException("Marshaller found unknown child element, but no default marshaller was found.");\r
-                }\r
-            }\r
-            else {\r
-                XT_log.error("unknown child object: %s", obj->getElementQName().toString().c_str());\r
-                throw UnknownElementException("Marshaller found unknown child object.");\r
-            }\r
+            XT_log.error(\r
+                "no default unmarshaller installed, unknown child object: %s",\r
+                obj->getElementQName().toString().c_str()\r
+                );\r
+            throw MarshallingException("Marshaller found unknown child element, but no default marshaller was found.");\r
         }\r
         element->appendChild(marshaller->marshall(obj, element->getOwnerDocument()));\r
     }\r
index ce3f358..e6bdf7e 100644 (file)
@@ -164,27 +164,11 @@ void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* do
         if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {\r
             unmarshaller = Unmarshaller::getUnmarshaller(static_cast<DOMElement*>(childNode));\r
             if (!unmarshaller) {\r
-                if (config.ignoreUnknownElements) {\r
-                    unmarshaller=Unmarshaller::getDefaultUnmarshaller();\r
-                    if (!unmarshaller) {\r
-                        auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
-                        XT_log.error(\r
-                            "no default unmarshaller installed, found unknown child element %s",\r
-                            cname->toString().c_str()\r
-                            );\r
-                        throw UnmarshallingException(\r
-                            "Unmarshaller found unknown child element, but no default unmarshaller was found."\r
-                            );\r
-                    }\r
-                    else {\r
-                        XT_log.debug("using default unmarshaller");\r
-                    }\r
-                }\r
-                else {\r
-                    auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
-                    XT_log.error("detected unknown child element %s", cname->toString().c_str());\r
-                    throw UnknownElementException("Unmarshaller found unknown child element.");\r
-                }\r
+                auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
+                XT_log.error(\r
+                    "no default unmarshaller installed, found unknown child element %s", cname->toString().c_str()\r
+                    );\r
+                throw UnmarshallingException("Unmarshaller found unknown child element, but no default unmarshaller was found.");\r
             }\r
 \r
             if (XT_log.isDebugEnabled()) {\r
index a0ec6f4..56189c1 100644 (file)
@@ -39,8 +39,7 @@ namespace xmltooling {
          * @see Unmarshaller::unmarshall()\r
          */\r
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false) const;\r
-    \r
-        \r
+            \r
     protected:\r
         /**\r
          * Constructor.\r
index ed4e03f..5d6a82e 100644 (file)
@@ -59,8 +59,8 @@ const Marshaller* Marshaller::getMarshaller(const XMLObject* xmlObject)
         return m;\r
     }\r
 \r
-    log.error("no Marshaller registered for element: %s", xmlObject->getElementQName().toString().c_str());\r
-    return NULL;\r
+    log.error("no Marshaller registered for element (%s), returning default", xmlObject->getElementQName().toString().c_str());\r
+    return m_default;\r
 }\r
 \r
 void Marshaller::destroyMarshallers()\r
index 989796b..e9d6995 100644 (file)
@@ -64,7 +64,7 @@ namespace xmltooling {
          * Retrieves a Marshaller using the key it was registered with.\r
          * \r
          * @param key the key used to register the marshaller\r
-         * @return the marshaller\r
+         * @return the marshaller or NULL\r
          */\r
         static const Marshaller* getMarshaller(const QName& key) {\r
             std::map<QName,Marshaller*>::const_iterator i=m_map.find(key);\r
@@ -73,6 +73,7 @@ namespace xmltooling {
 \r
         /**\r
          * Retrieves a Marshaller for an XML object\r
+         * If no match is found, the default marshaller is returned, if any.\r
          * \r
          * @param xmlObject the object for which to return a marshaller\r
          * @return the marshaller or NULL\r
index 1bc92d3..d0bba16 100644 (file)
@@ -46,7 +46,7 @@ const Unmarshaller* Unmarshaller::getUnmarshaller(const DOMElement* domElement)
     const Unmarshaller* m = getUnmarshaller(*(schemaType.get()));\r
     if (m) {\r
         if (log.isDebugEnabled()) {\r
-            log.debug("Located Unmarshaller for schema type: %s", schemaType->toString().c_str());\r
+            log.debug("located Unmarshaller for schema type: %s", schemaType->toString().c_str());\r
         }\r
         return m;\r
     }\r
@@ -55,16 +55,13 @@ const Unmarshaller* Unmarshaller::getUnmarshaller(const DOMElement* domElement)
     m = getUnmarshaller(*(elementName.get()));\r
     if (m) {\r
         if (log.isDebugEnabled()) {\r
-            log.debug("Located Unmarshaller for element name: %s", elementName->toString().c_str());\r
+            log.debug("located Unmarshaller for element name: %s", elementName->toString().c_str());\r
         }\r
         return m;\r
     }\r
 \r
-    log.error("No Unmarshaller was registered for element: %s", elementName->toString().c_str());\r
-    if (XMLToolingConfig::getConfig().ignoreUnknownElements) {\r
-    }\r
-    \r
-    return NULL;\r
+    log.error("no Unmarshaller registered for element (%s), using default", elementName->toString().c_str());\r
+    return m_default;\r
 }\r
 \r
 void Unmarshaller::destroyUnmarshallers()\r
index e65f49f..0f99c6e 100644 (file)
@@ -72,7 +72,8 @@ namespace xmltooling {
         }\r
     \r
         /**\r
-         * Retrieves an Unmarshaller for a DOM element\r
+         * Retrieves an Unmarshaller for a DOM element.\r
+         * If no match is found, the default unmarshaller is returned, if any.\r
          * \r
          * @param element the element for which to return an unmarshaller\r
          * @return the unmarshaller or NULL\r
index 42fc020..1d95fb7 100644 (file)
@@ -26,7 +26,7 @@
 #include <xercesc/util/XMLUTF8Transcoder.hpp>\r
 #include <xercesc/util/XMLUniDefs.hpp>\r
 \r
-static XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
+static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
 \r
 char* xmltooling::toUTF8(const XMLCh* src)\r
 {\r
index 230a8fc..6a651d8 100644 (file)
                                        >\r
                                </File>\r
                        </Filter>\r
+                       <Filter\r
+                               Name="impl"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\impl\UnknownElement.cpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
                </Filter>\r
                <Filter\r
                        Name="Header Files"\r
                                        >\r
                                </File>\r
                        </Filter>\r
+                       <Filter\r
+                               Name="impl"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\impl\UnknownElement.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
                </Filter>\r
                <Filter\r
                        Name="Resource Files"\r