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