*/\r
\r
#include "internal.h"\r
-#include "exceptions.h"\r
#include "AbstractDOMCachingXMLObject.h"\r
-#include "io/Unmarshaller.h"\r
+#include "exceptions.h"\r
+#include "XMLObjectBuilder.h"\r
#include "util/XMLHelper.h"\r
\r
#include <algorithm>\r
m_document->release();\r
}\r
\r
-void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument)\r
+void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument) const\r
{\r
m_dom=dom;\r
if (dom) {\r
}\r
}\r
\r
-void AbstractDOMCachingXMLObject::releaseDOM()\r
+void AbstractDOMCachingXMLObject::releaseDOM() const\r
{\r
if (m_dom) {\r
Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
}\r
}\r
\r
-void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease)\r
+void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease) const\r
{\r
DOMCachingXMLObject* domCachingParent = dynamic_cast<DOMCachingXMLObject*>(getParent());\r
if (domCachingParent) {\r
}\r
};\r
\r
-void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease)\r
+void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease) const\r
{\r
if (hasChildren()) {\r
Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug(\r
DOMElement* domCopy=cloneDOM();\r
if (domCopy) {\r
// Seemed to work, so now we unmarshall the DOM to produce the clone.\r
- const Unmarshaller* u=Unmarshaller::getUnmarshaller(domCopy);\r
- if (!u) {\r
+ const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(domCopy);\r
+ if (!b) {\r
auto_ptr<QName> q(XMLHelper::getNodeQName(domCopy));\r
Category::getInstance(XMLTOOLING_LOGCAT".DOM").error(\r
- "DOM clone failed, unable to locate unmarshaller for element (%s)", q->toString().c_str()\r
+ "DOM clone failed, unable to locate builder for element (%s)", q->toString().c_str()\r
);\r
domCopy->getOwnerDocument()->release();\r
- throw UnmarshallingException("Unable to locate unmarshaller for cloned element.");\r
+ throw UnmarshallingException("Unable to locate builder for cloned element.");\r
}\r
try {\r
- return u->unmarshall(domCopy, true); // bind document\r
+ auto_ptr<XMLObject> objCopy(b->buildObject(domCopy));\r
+ objCopy->unmarshall(domCopy, true); // bind document\r
+ return objCopy.release();\r
}\r
catch (...) {\r
domCopy->getOwnerDocument()->release();\r
+ throw;\r
}\r
}\r
return NULL;\r
* Extension of AbstractXMLObject that implements a DOMCachingXMLObject.\r
* This is the primary base class for XMLObject implementation classes to use.\r
*/\r
- class XMLTOOL_API AbstractDOMCachingXMLObject : public AbstractXMLObject, public DOMCachingXMLObject\r
+ class XMLTOOL_API AbstractDOMCachingXMLObject : public AbstractXMLObject, public virtual DOMCachingXMLObject\r
{\r
public:\r
virtual ~AbstractDOMCachingXMLObject();\r
/**\r
* @see DOMCachingXMLObject::setDOM()\r
*/\r
- void setDOM(DOMElement* dom, bool bindDocument=false);\r
+ void setDOM(DOMElement* dom, bool bindDocument=false) const;\r
\r
/**\r
* @see DOMCachingXMLObject::setDocument()\r
*/\r
- void setDocument(DOMDocument* doc) {\r
+ void setDocument(DOMDocument* doc) const {\r
if (m_document)\r
m_document->release();\r
m_document=doc;\r
/**\r
* @see DOMCachingXMLObject::releaseDOM()\r
*/\r
- virtual void releaseDOM();\r
+ virtual void releaseDOM() const;\r
\r
/**\r
* @see DOMCachingXMLObject::releaseParentDOM()\r
*/\r
- virtual void releaseParentDOM(bool propagateRelease=true);\r
+ virtual void releaseParentDOM(bool propagateRelease=true) const;\r
\r
/**\r
* @see DOMCachingXMLObject::releaseChildrenDOM()\r
*/\r
- virtual void releaseChildrenDOM(bool propagateRelease=true);\r
+ virtual void releaseChildrenDOM(bool propagateRelease=true) const;\r
\r
/**\r
* A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).\r
*/\r
- void releaseThisandParentDOM() {\r
+ void releaseThisandParentDOM() const {\r
if (m_dom) {\r
releaseDOM();\r
releaseParentDOM(true);\r
/**\r
* A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM().\r
*/\r
- void releaseThisAndChildrenDOM() {\r
+ void releaseThisAndChildrenDOM() const {\r
if (m_dom) {\r
releaseChildrenDOM(true);\r
releaseDOM();\r
* @param elementLocalName the local name of the XML element this Object represents\r
* @param namespacePrefix the namespace prefix to use\r
*/\r
- AbstractDOMCachingXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
- : AbstractXMLObject(namespaceURI,elementLocalName, namespacePrefix), m_dom(NULL), m_document(NULL) {}\r
+ AbstractDOMCachingXMLObject(\r
+ const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL\r
+ ) : AbstractXMLObject(namespaceURI,elementLocalName, namespacePrefix), m_dom(NULL), m_document(NULL) {}\r
\r
/**\r
* If a DOM representation exists, this clones it into a new document.\r
XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue);\r
\r
private:\r
- DOMElement* m_dom;\r
- DOMDocument* m_document;\r
+ mutable DOMElement* m_dom;\r
+ mutable DOMDocument* m_document;\r
};\r
\r
};\r
--- /dev/null
+/*\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
+ * AbstractXMLObject.cpp\r
+ * \r
+ * An abstract implementation of XMLObject.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "AbstractXMLObject.h"\r
+\r
+#include <algorithm>\r
+#include <log4cpp/Category.hh>\r
+\r
+using namespace xmltooling;\r
+\r
+AbstractXMLObject::~AbstractXMLObject() {\r
+ delete m_typeQname;\r
+ std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());\r
+}\r
+\r
+AbstractXMLObject::AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix)\r
+ : m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL),\r
+ m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject"))\r
+{\r
+ addNamespace(Namespace(namespaceURI, namespacePrefix));\r
+}\r
#if !defined(__xmltooling_abstractxmlobj_h__)\r
#define __xmltooling_abstractxmlobj_h__\r
\r
-#include <algorithm>\r
#include <xmltooling/XMLObject.h>\r
\r
#if defined (_MSC_VER)\r
class XMLTOOL_API AbstractXMLObject : public virtual XMLObject\r
{\r
public:\r
- virtual ~AbstractXMLObject() {\r
- delete m_typeQname;\r
- std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());\r
- }\r
+ virtual ~AbstractXMLObject();\r
\r
/**\r
* @see XMLObject::getElementQName()\r
/**\r
* @see XMLObject::addNamespace()\r
*/\r
- void addNamespace(const Namespace& ns) {\r
+ void addNamespace(const Namespace& ns) const {\r
if (ns.alwaysDeclare() || m_namespaces.find(ns)==m_namespaces.end()) {\r
m_namespaces.insert(ns);\r
}\r
* @param elementLocalName the local name of the XML element this Object represents\r
* @param namespacePrefix the namespace prefix to use\r
*/\r
- AbstractXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
- : m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL) {\r
- addNamespace(Namespace(namespaceURI, namespacePrefix));\r
- }\r
+ AbstractXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL);\r
\r
/**\r
* Underlying list of child objects.\r
/**\r
* Set of namespaces associated with the object.\r
*/\r
- std::set<Namespace> m_namespaces;\r
- \r
+ mutable std::set<Namespace> m_namespaces;\r
+\r
+ /**\r
+ * Logging object.\r
+ */\r
+ void* m_log;\r
+\r
private:\r
XMLObject* m_parent;\r
QName m_elementQname;\r
* @param dom DOM representation of this XMLObject\r
* @param bindDocument true if the object should take ownership of the associated Document\r
*/\r
- virtual void setDOM(DOMElement* dom, bool bindDocument=false)=0;\r
+ virtual void setDOM(DOMElement* dom, bool bindDocument=false) const=0;\r
\r
/**\r
* Assigns ownership of a DOM document to the XMLObject.\r
* \r
* @param doc DOM document bound to this object \r
*/\r
- virtual void setDocument(DOMDocument* doc)=0;\r
+ virtual void setDocument(DOMDocument* doc) const=0;\r
\r
/**\r
* Releases the DOM representation of this XMLObject, if there is one.\r
*/\r
- virtual void releaseDOM()=0;\r
+ virtual void releaseDOM() const=0;\r
\r
/**\r
* Releases the DOM representation of this XMLObject's parent.\r
* \r
* @param propagateRelease true if all ancestors of this element should release their DOM\r
*/\r
- virtual void releaseParentDOM(bool propagateRelease=true)=0;\r
+ virtual void releaseParentDOM(bool propagateRelease=true) const=0;\r
\r
/**\r
* Releases the DOM representation of this XMLObject's children.\r
* \r
* @param propagateRelease true if all descendants of this element should release their DOM\r
*/\r
- virtual void releaseChildrenDOM(bool propagateRelease=true)=0;\r
+ virtual void releaseChildrenDOM(bool propagateRelease=true) const=0;\r
};\r
\r
};\r
ioinclude_HEADERS = \
io/AbstractXMLObjectUnmarshaller.h \
- io/Marshaller.h \
- io/Unmarshaller.h
siginclude_HEADERS = \
signature/Signature.h \
- signature/SigningContext.h
+ signature/SigningContext.h \
+ signature/VerifyingContext.h
utilinclude_HEADERS = \
util/NDC.h \
AbstractAttributeExtensibleXMLObject.cpp \
AbstractDOMCachingXMLObject.cpp \
AbstractElementProxy.cpp \
+ AbstractXMLObject.cpp \
Namespace.cpp \
QName.cpp \
unicode.cpp \
impl/UnknownElement.cpp \
io/AbstractXMLObjectMarshaller.cpp \
io/AbstractXMLObjectUnmarshaller.cpp \
- io/Marshaller.cpp \
- io/Unmarshaller.cpp \
util/NDC.cpp \
util/ParserPool.cpp \
util/XMLConstants.cpp \
\r
#include <set>\r
#include <list>\r
+#include <vector>\r
+#include <xercesc/dom/DOM.hpp>\r
#include <xmltooling/QName.h>\r
#include <xmltooling/Namespace.h>\r
\r
+using namespace xercesc;\r
+\r
+#if defined (_MSC_VER)\r
+ #pragma warning( push )\r
+ #pragma warning( disable : 4250 4251 )\r
+#endif\r
+\r
namespace xmltooling {\r
\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+ class XMLTOOL_API Signature;\r
+ class XMLTOOL_API SigningContext;\r
+#endif\r
+\r
+ /**\r
+ * Supplies additional information to the marshalling process.\r
+ * Currently this only consists of signature related information.\r
+ */\r
+ class XMLTOOL_API MarshallingContext\r
+ {\r
+ MAKE_NONCOPYABLE(MarshallingContext);\r
+ public:\r
+ MarshallingContext() {}\r
+ ~MarshallingContext() {}\r
+\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+ MarshallingContext(Signature* sig, const SigningContext* ctx) {\r
+ m_signingContexts.push_back(std::make_pair(sig,ctx));\r
+ }\r
+ \r
+ /** Array of signing contexts, keyed off of the associated Signature */\r
+ std::vector< std::pair<Signature*,const SigningContext*> > m_signingContexts;\r
+#endif\r
+ };\r
+\r
/**\r
* Object that represents an XML Element that has been unmarshalled into this C++ object.\r
*/\r
* \r
* @param ns the namespace to add\r
*/\r
- virtual void addNamespace(const Namespace& ns)=0;\r
+ virtual void addNamespace(const Namespace& ns) const=0;\r
\r
/**\r
* Removes a namespace from this element\r
*/\r
virtual const std::list<XMLObject*>& getOrderedChildren() const=0;\r
\r
+ /**\r
+ * Marshalls the XMLObject, and its children, into a DOM element.\r
+ * If a document is supplied, then it will be used to create the resulting elements.\r
+ * If the document does not have a Document Element set, then the resulting\r
+ * element will be set as the Document Element. If no document is supplied, then\r
+ * a new document will be created and bound to the lifetime of the root object being\r
+ * marshalled, unless an existing DOM can be reused without creating a new document. \r
+ * \r
+ * @param document the DOM document the marshalled element will be placed in, or NULL\r
+ * @param ctx optional marshalling context\r
+ * @return the DOM element representing this XMLObject\r
+ * \r
+ * @throws MarshallingException thrown if there is a problem marshalling the given object\r
+ * @throws SignatureException thrown if a problem occurs during signature creation \r
+ */\r
+ virtual DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const=0;\r
+ \r
+ /**\r
+ * Marshalls the XMLObject and appends it as a child of the given parent element.\r
+ * \r
+ * <strong>NOTE:</strong> The given Element must be within a DOM tree rooted in \r
+ * the Document owning the given Element.\r
+ * \r
+ * @param parentElement the parent element to append the resulting DOM tree\r
+ * @param ctx optional marshalling context\r
+ * @return the marshalled element tree\r
+\r
+ * @throws MarshallingException thrown if the given XMLObject can not be marshalled.\r
+ * @throws SignatureException thrown if a problem occurs during signature creation \r
+ */\r
+ virtual DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const=0;\r
+\r
+ /**\r
+ * Unmarshalls the given W3C DOM element into the XMLObject.\r
+ * The root of a given XML construct should be unmarshalled with the bindDocument parameter\r
+ * set to true.\r
+ * \r
+ * @param element the DOM element to unmarshall\r
+ * @param bindDocument true iff the resulting XMLObject should take ownership of the DOM's Document \r
+ * \r
+ * @return the unmarshalled XMLObject\r
+ * \r
+ * @throws UnmarshallingException thrown if an error occurs unmarshalling the DOM element into the XMLObject\r
+ */\r
+ virtual XMLObject* unmarshall(DOMElement* element, bool bindDocument=false)=0;\r
+\r
protected:\r
XMLObject() {}\r
};\r
\r
+#if defined (_MSC_VER)\r
+ #pragma warning( pop )\r
+#endif\r
+\r
};\r
\r
#endif /* __xmltooling_xmlobj_h__ */\r
/**\r
* Creates an empty XMLObject.\r
* \r
+ * @param e a construction hint based on the eventual unmarshalling source\r
* @return the empty XMLObject\r
*/\r
- virtual XMLObject* buildObject() const=0;\r
+ virtual XMLObject* buildObject(const DOMElement* e=NULL) const=0;\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
+ * @param e a construction hint based on the eventual unmarshalling source\r
* @return the empty object or NULL if no builder is available \r
*/\r
- static XMLObject* buildObject(const QName& key) {\r
+ static XMLObject* buildObject(const QName& key, const DOMElement* e=NULL) {\r
const XMLObjectBuilder* b=getBuilder(key);\r
- return b ? b->buildObject() : NULL;\r
+ return b ? b->buildObject(e) : NULL;\r
}\r
\r
/**\r
// default registrations
XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());
- Marshaller::registerDefaultMarshaller(new UnknownElementMarshaller());
- Unmarshaller::registerDefaultUnmarshaller(new UnknownElementUnmarshaller());
#ifndef XMLTOOLING_NO_XMLSEC
- QName dsig(XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME);
- XMLObjectBuilder::registerBuilder(dsig,new XMLSecSignatureBuilder());
- Marshaller::registerMarshaller(dsig,new XMLSecSignatureMarshaller());
- Unmarshaller::registerUnmarshaller(dsig,new XMLSecSignatureUnmarshaller());
+ XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME),new XMLSecSignatureBuilder());
#endif
}
catch (const xercesc::XMLException&) {
void XMLToolingInternalConfig::term()
{
XMLObjectBuilder::destroyBuilders();
- Marshaller::destroyMarshallers();
- Unmarshaller::destroyUnmarshallers();
for (vector<void*>::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) {
#if defined(WIN32)
XMLHelper::serialize(getDOM(),s);\r
}\r
\r
-DOMElement* UnknownElementMarshaller::marshall(XMLObject* xmlObject, DOMDocument* document, MarshallingContext* ctx) const\r
+DOMElement* UnknownElementImpl::marshall(DOMDocument* document, MarshallingContext* ctx) const\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("marshall");\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
+ DOMElement* cachedDOM=getDOM();\r
if (cachedDOM) {\r
if (!document || document==cachedDOM->getOwnerDocument()) {\r
log.debug("XMLObject has a usable cached DOM, reusing it");\r
if (document)\r
setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
- unk->releaseParentDOM(true);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
// Recache the DOM.\r
setDocumentElement(document, cachedDOM);\r
log.debug("caching imported DOM for XMLObject");\r
- unk->setDOM(cachedDOM, false);\r
- unk->releaseParentDOM(true);\r
+ setDOM(cachedDOM, false);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
// If we get here, we didn't have a usable DOM.\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
+ MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),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
// Recache the DOM and clear the serialized copy.\r
setDocumentElement(document, cachedDOM);\r
log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");\r
- unk->setDOM(cachedDOM, bindDocument);\r
- unk->releaseParentDOM(true);\r
- unk->m_xml.erase();\r
+ setDOM(cachedDOM, bindDocument);\r
+ releaseParentDOM(true);\r
+ m_xml.erase();\r
return cachedDOM;\r
}\r
\r
-DOMElement* UnknownElementMarshaller::marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx) const\r
+DOMElement* UnknownElementImpl::marshall(DOMElement* parentElement, MarshallingContext* ctx) const\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("marshall");\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
+ DOMElement* cachedDOM=getDOM();\r
if (cachedDOM) {\r
if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
log.debug("XMLObject has a usable cached DOM, reusing it");\r
parentElement->appendChild(cachedDOM);\r
- unk->releaseParentDOM(true);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
// Recache the DOM.\r
parentElement->appendChild(cachedDOM);\r
log.debug("caching imported DOM for XMLObject");\r
- unk->setDOM(cachedDOM, false);\r
- unk->releaseParentDOM(true);\r
+ setDOM(cachedDOM, false);\r
+ releaseParentDOM(true);\r
return cachedDOM;\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
- MemBufInputSource src(reinterpret_cast<const XMLByte*>(unk->m_xml.c_str()),unk->m_xml.length(),"UnknownElementImpl");\r
+ MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),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
// Recache the DOM and clear the serialized copy.\r
parentElement->appendChild(cachedDOM);\r
log.debug("caching DOM for XMLObject");\r
- unk->setDOM(cachedDOM, false);\r
- unk->releaseParentDOM(true);\r
- unk->m_xml.erase();\r
+ setDOM(cachedDOM, false);\r
+ releaseParentDOM(true);\r
+ m_xml.erase();\r
return cachedDOM;\r
}\r
\r
-XMLObject* UnknownElementUnmarshaller::unmarshall(DOMElement* element, bool bindDocument) const\r
+XMLObject* UnknownElementImpl::unmarshall(DOMElement* element, bool bindDocument)\r
{\r
- UnknownElementImpl* ret=new UnknownElementImpl();\r
- ret->setDOM(element, bindDocument);\r
- return ret;\r
+ setDOM(element, bindDocument);\r
+ return this;\r
}\r
*/\r
\r
/**\r
- * @file UnknownElement.h\r
+ * UnknownElement.h\r
* \r
* Basic implementations suitable for use as defaults for unrecognized content\r
*/\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
+#include "io/AbstractXMLObjectMarshaller.h"\r
+#include "io/AbstractXMLObjectUnmarshaller.h"\r
\r
#include <string>\r
\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(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
: AbstractDOMCachingXMLObject(namespaceURI, elementLocalName, namespacePrefix) {}\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
- 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
- void serialize(std::string& s) const;\r
- private:\r
- friend class XMLTOOL_DLLLOCAL UnknownElementMarshaller;\r
- };\r
-\r
- /**\r
- * Factory for UnknownElementImpl objects\r
- */\r
- class XMLTOOL_DLLLOCAL UnknownElementBuilder : public virtual XMLObjectBuilder\r
- {\r
- public:\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
- /**\r
- * @see Marshaller::marshall(XMLObject*,DOMDocument*, const MarshallingContext*)\r
- */\r
- DOMElement* marshall(XMLObject* xmlObject, DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
-\r
- /**\r
- * @see Marshaller::marshall(XMLObject*,DOMElement*, const MarshallingContext* ctx)\r
- */\r
- DOMElement* marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
+ DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
+ DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
+ XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
\r
protected:\r
void setDocumentElement(DOMDocument* document, DOMElement* element) const {\r
else\r
document->appendChild(element);\r
}\r
+\r
+ mutable std::string m_xml;\r
+\r
+ void serialize(std::string& s) const;\r
};\r
\r
- /**\r
- * Unmarshaller for UnknownElementImpl objects\r
- */\r
- class XMLTOOL_DLLLOCAL UnknownElementUnmarshaller : public virtual Unmarshaller\r
+ class XMLTOOL_DLLLOCAL UnknownElementBuilder : public XMLObjectBuilder\r
{\r
public:\r
- /**\r
- * @see Unmarshaller::unmarshall()\r
- */\r
- XMLObject* unmarshall(DOMElement* element, bool bindDocument=false) const;\r
+ XMLObject* buildObject(const DOMElement* e=NULL) const {\r
+ return new UnknownElementImpl();\r
+ }\r
};\r
+\r
};\r
\r
#if defined (_MSC_VER)\r
*/\r
\r
#include "internal.h"\r
-#include "DOMCachingXMLObject.h"\r
#include "exceptions.h"\r
#include "io/AbstractXMLObjectMarshaller.h"\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+ #include "signature/Signature.h"\r
+#endif\r
#include "util/NDC.h"\r
#include "util/XMLConstants.h"\r
#include "util/XMLHelper.h"\r
\r
#define XT_log (*static_cast<Category*>(m_log))\r
\r
-AbstractXMLObjectMarshaller::AbstractXMLObjectMarshaller()\r
- : m_log(&Category::getInstance(XMLTOOLING_LOGCAT".Marshaller")) {}\r
-\r
-DOMElement* AbstractXMLObjectMarshaller::marshall(XMLObject* xmlObject, DOMDocument* document, MarshallingContext* ctx) const\r
+DOMElement* AbstractXMLObjectMarshaller::marshall(DOMDocument* document, MarshallingContext* ctx) const\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("marshall");\r
#endif\r
\r
if (XT_log.isDebugEnabled()) {\r
- XT_log.debug("starting to marshalling %s", xmlObject->getElementQName().toString().c_str());\r
+ XT_log.debug("starting to marshal %s", getElementQName().toString().c_str());\r
}\r
\r
- DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(xmlObject);\r
- if (dc) {\r
- DOMElement* cachedDOM=dc->getDOM();\r
- if (cachedDOM) {\r
- if (!document || document==cachedDOM->getOwnerDocument()) {\r
- XT_log.debug("XMLObject has a usable cached DOM, reusing it");\r
- if (document)\r
- setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
- dc->releaseParentDOM(true);\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 have to either import the\r
- // DOM while somehow reassigning all the nested references (which amounts to a complete\r
- // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
- // it back. This depends on all objects being able to preserve their DOM at all costs.\r
- dc->releaseChildrenDOM(true);\r
- dc->releaseDOM();\r
+ DOMElement* cachedDOM=getDOM();\r
+ if (cachedDOM) {\r
+ if (!document || document==cachedDOM->getOwnerDocument()) {\r
+ XT_log.debug("XMLObject has a usable cached DOM, reusing it");\r
+ if (document)\r
+ setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
+ releaseParentDOM(true);\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 have to either import the\r
+ // DOM while somehow reassigning all the nested references (which amounts to a complete\r
+ // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
+ // it back. This depends on all objects being able to preserve their DOM at all costs.\r
+ releaseChildrenDOM(true);\r
+ releaseDOM();\r
}\r
\r
// If we get here, we didn't have a usable DOM (and/or we released the one we had).\r
try {\r
XT_log.debug("creating root element to marshall");\r
DOMElement* domElement = document->createElementNS(\r
- xmlObject->getElementQName().getNamespaceURI(), xmlObject->getElementQName().getLocalPart()\r
+ getElementQName().getNamespaceURI(), getElementQName().getLocalPart()\r
);\r
setDocumentElement(document, domElement);\r
- marshallInto(*xmlObject, domElement, ctx);\r
+ marshallInto(domElement, ctx);\r
\r
//Recache the DOM.\r
- if (dc) {\r
- XT_log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");\r
- dc->setDOM(domElement, bindDocument);\r
- dc->releaseParentDOM(true);\r
- }\r
+ XT_log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");\r
+ setDOM(domElement, bindDocument);\r
+ releaseParentDOM(true);\r
\r
return domElement;\r
}\r
}\r
}\r
\r
-DOMElement* AbstractXMLObjectMarshaller::marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx) const\r
+DOMElement* AbstractXMLObjectMarshaller::marshall(DOMElement* parentElement, MarshallingContext* ctx) const\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("marshall");\r
#endif\r
\r
if (XT_log.isDebugEnabled()) {\r
- XT_log.debug("starting to marshalling %s", xmlObject->getElementQName().toString().c_str());\r
+ XT_log.debug("starting to marshalling %s", getElementQName().toString().c_str());\r
}\r
\r
- DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(xmlObject);\r
- if (dc) {\r
- DOMElement* cachedDOM=dc->getDOM();\r
- if (cachedDOM) {\r
- if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
- XT_log.debug("XMLObject has a usable cached DOM, reusing it");\r
- if (parentElement!=cachedDOM->getParentNode()) {\r
- parentElement->appendChild(cachedDOM);\r
- dc->releaseParentDOM(true);\r
- }\r
- return cachedDOM;\r
+ DOMElement* cachedDOM=getDOM();\r
+ if (cachedDOM) {\r
+ if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
+ XT_log.debug("XMLObject has a usable cached DOM, reusing it");\r
+ if (parentElement!=cachedDOM->getParentNode()) {\r
+ parentElement->appendChild(cachedDOM);\r
+ releaseParentDOM(true);\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 have to either import the\r
- // DOM while somehow reassigning all the nested references (which amounts to a complete\r
- // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
- // it back. This depends on all objects being able to preserve their DOM at all costs.\r
- dc->releaseChildrenDOM(true);\r
- dc->releaseDOM();\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 have to either import the\r
+ // DOM while somehow reassigning all the nested references (which amounts to a complete\r
+ // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
+ // it back. This depends on all objects being able to preserve their DOM at all costs.\r
+ releaseChildrenDOM(true);\r
+ releaseDOM();\r
}\r
\r
// If we get here, we didn't have a usable DOM (and/or we released the one we had).\r
XT_log.debug("creating root element to marshall");\r
DOMElement* domElement = parentElement->getOwnerDocument()->createElementNS(\r
- xmlObject->getElementQName().getNamespaceURI(), xmlObject->getElementQName().getLocalPart()\r
+ getElementQName().getNamespaceURI(), getElementQName().getLocalPart()\r
);\r
parentElement->appendChild(domElement);\r
- marshallInto(*xmlObject, domElement, ctx);\r
+ marshallInto(domElement, ctx);\r
\r
//Recache the DOM.\r
- if (dc) {\r
- XT_log.debug("caching DOM for XMLObject");\r
- dc->setDOM(domElement, false);\r
- dc->releaseParentDOM(true);\r
- }\r
+ XT_log.debug("caching DOM for XMLObject");\r
+ setDOM(domElement, false);\r
+ releaseParentDOM(true);\r
\r
return domElement;\r
}\r
class _signit : public unary_function<const pair<Signature*,const SigningContext*>&, void> {\r
public:\r
void operator()(const pair<Signature*,const SigningContext*>& p) const {\r
- p.first->sign(p.second);\r
+ p.first->sign(*(p.second));\r
}\r
};\r
#endif\r
\r
-void AbstractXMLObjectMarshaller::marshallInto(\r
- XMLObject& xmlObject, DOMElement* targetElement, MarshallingContext* ctx\r
- ) const\r
+void AbstractXMLObjectMarshaller::marshallInto(DOMElement* targetElement, MarshallingContext* ctx) const\r
{\r
- if (xmlObject.getElementQName().hasPrefix())\r
- targetElement->setPrefix(xmlObject.getElementQName().getPrefix());\r
- marshallElementType(xmlObject, targetElement);\r
- marshallNamespaces(xmlObject, targetElement);\r
- marshallAttributes(xmlObject, targetElement);\r
- marshallChildElements(xmlObject, targetElement);\r
- marshallElementContent(xmlObject, targetElement);\r
+ if (getElementQName().hasPrefix())\r
+ targetElement->setPrefix(getElementQName().getPrefix());\r
+ marshallElementType(targetElement);\r
+ marshallNamespaces(targetElement);\r
+ marshallAttributes(targetElement);\r
+ marshallChildElements(targetElement);\r
+ marshallElementContent(targetElement);\r
\r
#ifndef XMLTOOLING_NO_XMLSEC\r
if (ctx) {\r
#endif\r
}\r
\r
-void AbstractXMLObjectMarshaller::marshallElementType(XMLObject& xmlObject, DOMElement* domElement) const\r
+void AbstractXMLObjectMarshaller::marshallElementType(DOMElement* domElement) const\r
{\r
- const QName* type = xmlObject.getSchemaType();\r
+ const QName* type = getSchemaType();\r
if (type) {\r
XT_log.debug("setting xsi:type attribute for XMLObject");\r
\r
XMLString::release(&xsivalue);\r
\r
XT_log.debug("Adding XSI namespace to list of namespaces used by XMLObject");\r
- xmlObject.addNamespace(Namespace(XMLConstants::XSI_NS, XMLConstants::XSI_PREFIX));\r
+ addNamespace(Namespace(XMLConstants::XSI_NS, XMLConstants::XSI_PREFIX));\r
}\r
}\r
\r
}\r
};\r
\r
-void AbstractXMLObjectMarshaller::marshallNamespaces(const XMLObject& xmlObject, DOMElement* domElement) const\r
+void AbstractXMLObjectMarshaller::marshallNamespaces(DOMElement* domElement) const\r
{\r
XT_log.debug("marshalling namespace attributes for XMLObject");\r
- const set<Namespace>& namespaces = xmlObject.getNamespaces();\r
+ const set<Namespace>& namespaces = getNamespaces();\r
for_each(namespaces.begin(),namespaces.end(),bind1st(_addns(),domElement));\r
}\r
\r
-class _marshallchild : public binary_function<XMLObject*,DOMElement*,void> {\r
- void* m_log;\r
+class _marshallit : public binary_function<const XMLObject*,DOMElement*,void> {\r
public:\r
- _marshallchild(void* log) : m_log(log) {}\r
- void operator()(XMLObject* obj, DOMElement* element) const {\r
- if (!obj)\r
- return;\r
- if (XT_log.isDebugEnabled()) {\r
- XT_log.debug("getting marshaller for child XMLObject: %s", obj->getElementQName().toString().c_str());\r
- }\r
-\r
- const Marshaller* marshaller = Marshaller::getMarshaller(obj);\r
- if (!marshaller) {\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
- marshaller->marshall(obj, element);\r
+ void operator()(const XMLObject* xo, DOMElement* e) const {\r
+ if (xo) xo->marshall(e);\r
}\r
};\r
\r
-void AbstractXMLObjectMarshaller::marshallChildElements(const XMLObject& xmlObject, DOMElement* domElement) const\r
+void AbstractXMLObjectMarshaller::marshallChildElements(DOMElement* domElement) const\r
{\r
XT_log.debug("marshalling child elements for XMLObject");\r
\r
- const list<XMLObject*>& children=xmlObject.getOrderedChildren();\r
- for_each(children.begin(),children.end(),bind2nd(_marshallchild(m_log),domElement));\r
+ const list<XMLObject*>& children=getOrderedChildren();\r
+ for_each(children.begin(),children.end(),bind2nd(_marshallit(),domElement));\r
}\r
#if !defined(__xmltooling_xmlmarshaller_h__)\r
#define __xmltooling_xmlmarshaller_h__\r
\r
-#include <xmltooling/io/Marshaller.h>\r
+#include <xmltooling/AbstractDOMCachingXMLObject.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 thread-safe abstract marshaller.\r
*/\r
- class XMLTOOL_API AbstractXMLObjectMarshaller : public virtual Marshaller\r
+ class XMLTOOL_API AbstractXMLObjectMarshaller : public virtual AbstractDOMCachingXMLObject\r
{\r
public:\r
virtual ~AbstractXMLObjectMarshaller() {}\r
\r
/**\r
- * @see Marshaller::marshall(XMLObject*,DOMDocument*,const MarshallingContext*)\r
+ * @see XMLObject::marshall(DOMDocument*,const MarshallingContext*)\r
*/\r
- DOMElement* marshall(XMLObject* xmlObject, DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
+ DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
\r
/**\r
- * @see Marshaller::marshall(XMLObject*,DOMElement*,const MarshallingContext*)\r
+ * @see XMLObject::marshall(DOMElement*,const MarshallingContext*)\r
*/\r
- DOMElement* marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
+ DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
\r
protected:\r
- AbstractXMLObjectMarshaller();\r
+ AbstractXMLObjectMarshaller() {}\r
\r
/**\r
* Sets the given element as the Document Element of the given Document.\r
}\r
\r
/**\r
- * Marshalls the given XMLObject into the given DOM Element.\r
+ * Marshalls the XMLObject into the given DOM Element.\r
* The DOM Element must be within a DOM tree rooted in the owning Document.\r
* \r
- * @param xmlObject the XMLObject to marshall\r
* @param targetElement the Element into which the XMLObject is marshalled into\r
* @param ctx optional marshalling context\r
* \r
* @throws MarshallingException thrown if there is a problem marshalling the object\r
* @throws SignatureException thrown if a problem occurs during signature creation \r
*/\r
- void marshallInto(XMLObject& xmlObject, DOMElement* targetElement, MarshallingContext* ctx) const;\r
+ void marshallInto(DOMElement* targetElement, MarshallingContext* ctx) const;\r
\r
/**\r
* Creates an xsi:type attribute, corresponding to the given type of the XMLObject, on the DOM element.\r
* \r
- * @param xmlObject the XMLObject\r
* @param domElement the DOM element\r
* \r
* @throws MarshallingException thrown if the type on the XMLObject is doesn't contain\r
* a local name, prefix, and namespace URI\r
*/\r
- void marshallElementType(XMLObject& xmlObject, DOMElement* domElement) const;\r
+ void marshallElementType(DOMElement* domElement) const;\r
\r
/**\r
- * Creates the xmlns attributes for any namespaces set on the given XMLObject.\r
+ * Creates the xmlns attributes for any namespaces set on the XMLObject.\r
* \r
- * @param xmlObject the XMLObject\r
* @param domElement the DOM element the namespaces will be added to\r
*/\r
- void marshallNamespaces(const XMLObject& xmlObject, DOMElement* domElement) const;\r
+ void marshallNamespaces(DOMElement* domElement) const;\r
\r
/**\r
- * Marshalls the child elements of the given XMLObject.\r
+ * Marshalls the child elements of the XMLObject.\r
* \r
- * @param xmlObject the XMLObject whose children will be marshalled\r
* @param domElement the DOM element that will recieved the marshalled children\r
* \r
* @throws MarshallingException thrown if there is a problem marshalling a child element\r
*/\r
- void marshallChildElements(const XMLObject& xmlObject, DOMElement* domElement) const;\r
+ void marshallChildElements(DOMElement* domElement) const;\r
\r
/**\r
- * Marshalls the attributes from the given XMLObject into the given DOM element.\r
- * The XMLObject passed to this method is guaranteed to be of the target name\r
- * specified during this marshaller's construction.\r
+ * Marshalls the attributes from the XMLObject into the given DOM element.\r
* \r
- * @param xmlObject the XMLObject being marshalled\r
* @param domElement the DOM Element into which attributes will be marshalled\r
* \r
- * @throws UnmarshallingException thrown if there is a problem unmarshalling an attribute\r
+ * @throws MarshallingException thrown if there is a problem marshalling an attribute\r
*/\r
- virtual void marshallAttributes(const XMLObject& xmlObject, DOMElement* domElement) const=0;\r
+ virtual void marshallAttributes(DOMElement* domElement) const=0;\r
\r
/**\r
* Marshalls data from the XMLObject into content of the DOM Element.\r
* \r
- * @param xmlObject the XMLObject\r
* @param domElement the DOM element recieving the content\r
*/\r
- virtual void marshallElementContent(const XMLObject& xmlObject, DOMElement* domElement) const=0;\r
-\r
- void* m_log;\r
+ virtual void marshallElementContent(DOMElement* domElement) const=0;\r
};\r
\r
};\r
\r
+#if defined (_MSC_VER)\r
+ #pragma warning( pop )\r
+#endif\r
+\r
#endif /* __xmltooling_xmlmarshaller_h__ */\r
*/\r
\r
#include "internal.h"\r
-#include "DOMCachingXMLObject.h"\r
#include "exceptions.h"\r
#include "XMLObjectBuilder.h"\r
#include "io/AbstractXMLObjectUnmarshaller.h"\r
\r
#define XT_log (*static_cast<Category*>(m_log))\r
\r
-AbstractXMLObjectUnmarshaller::AbstractXMLObjectUnmarshaller()\r
- : m_log(&Category::getInstance(XMLTOOLING_LOGCAT".Unmarshaller")) {}\r
-\r
-XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool bindDocument) const\r
+XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool bindDocument)\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("unmarshall");\r
XT_log.debug("unmarshalling DOM element (%s)", dname.get());\r
}\r
\r
- auto_ptr<XMLObject> xmlObject(buildXMLObject(element));\r
-\r
if (element->hasAttributes()) {\r
- unmarshallAttributes(element, *(xmlObject.get()));\r
+ unmarshallAttributes(element);\r
}\r
\r
- unmarshallChildElements(element, *(xmlObject.get()));\r
+ unmarshallChildElements(element);\r
\r
/* TODO: Signing\r
if (xmlObject instanceof SignableXMLObject) {\r
}\r
*/\r
\r
- DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(xmlObject.get());\r
- if (dc)\r
- dc->setDOM(element,bindDocument);\r
- else if (bindDocument)\r
- throw UnmarshallingException("Unable to bind document to non-DOM caching XMLObject instance.");\r
- \r
- return xmlObject.release();\r
-}\r
-\r
-XMLObject* AbstractXMLObjectUnmarshaller::buildXMLObject(const DOMElement* domElement) const\r
-{\r
- const XMLObjectBuilder* xmlObjectBuilder = XMLObjectBuilder::getBuilder(domElement);\r
- if (xmlObjectBuilder)\r
- return xmlObjectBuilder->buildObject();\r
- throw UnmarshallingException("Failed to locate XMLObjectBuilder for element.");\r
+ setDOM(element,bindDocument);\r
+ return this;\r
}\r
\r
-void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement, XMLObject& xmlObject) const\r
+void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement)\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("unmarshallAttributes");\r
if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) {\r
if (XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX)) {\r
XT_log.debug("found default namespace declaration, adding it to the list of namespaces on the XMLObject");\r
- xmlObject.addNamespace(Namespace(attribute->getValue(), NULL, true));\r
+ addNamespace(Namespace(attribute->getValue(), NULL, true));\r
continue;\r
}\r
else {\r
XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");\r
- xmlObject.addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));\r
+ addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));\r
continue;\r
}\r
}\r
else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) {\r
XT_log.debug("found xsi:type declaration, setting the schema type of the XMLObject");\r
auto_ptr<QName> xsitype(XMLHelper::getAttributeValueAsQName(attribute));\r
- xmlObject.setSchemaType(xsitype.get());\r
+ setSchemaType(xsitype.get());\r
continue;\r
}\r
else if (nsuri && !XMLString::equals(nsuri,XMLConstants::XML_NS)) {\r
XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject");\r
- xmlObject.addNamespace(Namespace(nsuri, attribute->getPrefix()));\r
+ addNamespace(Namespace(nsuri, attribute->getPrefix()));\r
}\r
\r
XT_log.debug("processing generic attribute");\r
- processAttribute(xmlObject, attribute);\r
+ processAttribute(attribute);\r
}\r
}\r
\r
-void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement, XMLObject& xmlObject) const\r
+void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement)\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("unmarshallChildElements");\r
\r
DOMNodeList* childNodes = domElement->getChildNodes();\r
DOMNode* childNode;\r
- const Unmarshaller* unmarshaller;\r
if (!childNodes || childNodes->getLength()==0) {\r
XT_log.debug("element had no children");\r
return;\r
for (XMLSize_t i = 0; i < childNodes->getLength(); i++) {\r
childNode = childNodes->item(i);\r
if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {\r
- unmarshaller = Unmarshaller::getUnmarshaller(static_cast<DOMElement*>(childNode));\r
- if (!unmarshaller) {\r
+ const XMLObjectBuilder* builder = XMLObjectBuilder::getBuilder(static_cast<DOMElement*>(childNode));\r
+ if (!builder) {\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
+ XT_log.error("no default builder installed, found unknown child element (%s)", cname->toString().c_str());\r
+ throw UnmarshallingException("Unmarshaller found unknown child element, but no default builder was found.");\r
}\r
\r
if (XT_log.isDebugEnabled()) {\r
}\r
\r
// Retain ownership of the unmarshalled child until it's processed by the parent.\r
- auto_ptr<XMLObject> childObject(unmarshaller->unmarshall(static_cast<DOMElement*>(childNode)));\r
- processChildElement(xmlObject, childObject.get(), static_cast<DOMElement*>(childNode));\r
+ auto_ptr<XMLObject> childObject(builder->buildObject(static_cast<DOMElement*>(childNode)));\r
+ childObject->unmarshall(static_cast<DOMElement*>(childNode));\r
+ processChildElement(childObject.get(), static_cast<DOMElement*>(childNode));\r
childObject.release();\r
}\r
else if (childNode->getNodeType() == DOMNode::TEXT_NODE) {\r
XT_log.debug("processing element content");\r
- processElementContent(xmlObject, childNode->getNodeValue());\r
+ processElementContent(childNode->getNodeValue());\r
}\r
}\r
}\r
#if !defined(__xmltooling_xmlunmarshaller_h__)\r
#define __xmltooling_xmlunmarshaller_h__\r
\r
-#include <xmltooling/io/Unmarshaller.h>\r
+#include <xmltooling/AbstractDOMCachingXMLObject.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 thread-safe abstract unmarshaller.\r
*/\r
- class XMLTOOL_API AbstractXMLObjectUnmarshaller : public virtual Unmarshaller\r
+ class XMLTOOL_API AbstractXMLObjectUnmarshaller : public virtual AbstractDOMCachingXMLObject\r
{\r
public:\r
virtual ~AbstractXMLObjectUnmarshaller() {}\r
\r
/**\r
- * @see Unmarshaller::unmarshall()\r
+ * @see XMLObject::unmarshall()\r
*/\r
- XMLObject* unmarshall(DOMElement* element, bool bindDocument=false) const;\r
+ XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
\r
protected:\r
- AbstractXMLObjectUnmarshaller();\r
+ AbstractXMLObjectUnmarshaller() {}\r
\r
/**\r
- * Constructs the XMLObject that the given DOM Element will be unmarshalled into. If the DOM element has an XML\r
- * Schema type defined this method will attempt to retrieve an XMLObjectBuilder using the schema type. If no\r
- * schema type is present or no builder is registered for the schema type, the element's QName is used. Once\r
- * the builder is found the XMLObject is created by invoking XMLObjectBuilder::buildObject().\r
- * Extending classes may wish to override this logic if more than just schema type or element name\r
- * (e.g. element attributes or content) need to be used to determine how to create the XMLObject.\r
- * \r
- * @param domElement the DOM Element the created XMLObject will represent\r
- * @return the empty XMLObject that DOM Element can be unmarshalled into\r
- * \r
- * @throws UnmarshallingException thrown if there is now XMLObjectBuilder registered for the given DOM Element\r
- */\r
- virtual XMLObject* buildXMLObject(const DOMElement* domElement) const;\r
- \r
- /**\r
- * Unmarshalls the attributes from the given DOM Element into the given XMLObject. If the attribute is an XML\r
- * namespace declaration the namespace is added to the given element via XMLObject::addNamespace().\r
- * If it is a schema type (xsi:type) the schema type is added to the element via XMLObject::setSchemaType().\r
+ * Unmarshalls the attributes from the given DOM Element into the XMLObject. If the attribute\r
+ * is an XML namespace declaration the namespace is added via XMLObject::addNamespace().\r
+ * If it is a schema type (xsi:type) the schema type is added via XMLObject::setSchemaType().\r
* All other attributes are passed to the processAttribute hook.\r
* \r
* @param domElement the DOM Element whose attributes will be unmarshalled\r
- * @param xmlObject the XMLObject that will recieve information from the DOM attribute\r
* \r
* @throws UnmarshallingException thrown if there is a problem unmarshalling an attribute\r
*/\r
- virtual void unmarshallAttributes(const DOMElement* domElement, XMLObject& xmlObject) const;\r
+ virtual void unmarshallAttributes(const DOMElement* domElement);\r
\r
/**\r
- * Unmarshalls a given Element's children. For each child an unmarshaller is retrieved using\r
- * getUnmarshaller(). The unmarshaller is then used to unmarshall the child element and the\r
- * resulting XMLObject is passed to processChildElement() for further processing.\r
+ * Unmarshalls a given Element's children. The resulting XMLObject child is passed to\r
+ * processChildElement() for further processing.\r
* \r
* @param domElement the DOM Element whose children will be unmarshalled\r
- * @param xmlObject the parent object of the unmarshalled children\r
* \r
* @throws UnmarshallingException thrown if an error occurs unmarshalling the child elements\r
*/\r
- virtual void unmarshallChildElements(const DOMElement* domElement, XMLObject& xmlObject) const;\r
+ virtual void unmarshallChildElements(const DOMElement* domElement);\r
\r
/**\r
* Called after a child element has been unmarshalled so that it can be added to the parent XMLObject.\r
* \r
- * @param parent the parent XMLObject\r
* @param child pointer to the child XMLObject\r
* @param childRoot root element of the child (must not be stored, just a hint)\r
* \r
* @throws UnmarshallingException thrown if there is a problem adding the child to the parent\r
*/\r
- virtual void processChildElement(XMLObject& parent, XMLObject* child, const DOMElement* childRoot) const=0;\r
+ virtual void processChildElement(XMLObject* child, const DOMElement* childRoot)=0;\r
\r
/**\r
* Called after an attribute has been unmarshalled so that it can be added to the XMLObject.\r
* \r
- * @param xmlObject the XMLObject\r
* @param attribute the attribute being unmarshalled\r
* \r
* @throws UnmarshallingException thrown if there is a problem adding the attribute to the XMLObject\r
*/\r
- virtual void processAttribute(XMLObject& xmlObject, const DOMAttr* attribute) const=0;\r
+ virtual void processAttribute(const DOMAttr* attribute)=0;\r
\r
/**\r
* Called if the element being unmarshalled contained textual content so that it can be added to the XMLObject.\r
* \r
- * @param xmlObject XMLObject the content will be given to\r
* @param elementContent the Element's text content\r
*/\r
- virtual void processElementContent(XMLObject& xmlObject, const XMLCh* elementContent) const=0;\r
-\r
- void* m_log;\r
+ virtual void processElementContent(const XMLCh* elementContent)=0;\r
};\r
\r
};\r
\r
+#if defined (_MSC_VER)\r
+ #pragma warning( pop )\r
+#endif\r
+\r
#endif /* __xmltooling_xmlunmarshaller_h__ */\r
+++ /dev/null
-/*\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
- * Marshaller.cpp\r
- * \r
- * Transforms XMLObjects into DOM trees \r
- */\r
-\r
-#include "internal.h"\r
-#include "Marshaller.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-map<QName,Marshaller*> Marshaller::m_map;\r
-\r
-Marshaller* Marshaller::m_default=NULL;\r
-\r
-const Marshaller* Marshaller::getMarshaller(const XMLObject* xmlObject)\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("getMarshaller");\r
-#endif\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller");\r
- \r
- const QName* type=xmlObject->getSchemaType();\r
- const Marshaller* m = type ? getMarshaller(*type) : NULL;\r
- if (m) {\r
- if (log.isDebugEnabled()) {\r
- log.debug("located Marshaller for schema type: %s", type->toString().c_str());\r
- }\r
- return m;\r
- }\r
- \r
- m = getMarshaller(xmlObject->getElementQName());\r
- if (m) {\r
- if (log.isDebugEnabled()) {\r
- log.debug("located Marshaller for element name: %s", xmlObject->getElementQName().toString().c_str());\r
- }\r
- return m;\r
- }\r
- if (log.isDebugEnabled()) {\r
- string qname=xmlObject->getElementQName().toString().c_str();\r
- log.debug("no Marshaller registered for element (%s), returning default", qname.empty() ? "unknown" : qname.c_str());\r
- }\r
- return m_default;\r
-}\r
-\r
-void Marshaller::destroyMarshallers()\r
-{\r
- for_each(m_map.begin(),m_map.end(),cleanup_pair<QName,Marshaller>());\r
- m_map.clear();\r
- deregisterDefaultMarshaller();\r
-}\r
+++ /dev/null
-/*\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 Marshaller.h\r
- * \r
- * Transforms XMLObjects into DOM trees\r
- */\r
-\r
-#if !defined(__xmltooling_marshaller_h__)\r
-#define __xmltooling_marshaller_h__\r
-\r
-#include <map>\r
-#include <vector>\r
-#include <xercesc/dom/DOM.hpp>\r
-#include <xmltooling/XMLObject.h>\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
- #include <xmltooling/signature/Signature.h>\r
-#endif\r
-\r
-using namespace xercesc;\r
-\r
-#if defined (_MSC_VER)\r
- #pragma warning( push )\r
- #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
- /**\r
- * Supplies additional information to the marshalling process.\r
- * Currently this only consists of signature related information.\r
- */\r
- class XMLTOOL_API MarshallingContext\r
- {\r
- MAKE_NONCOPYABLE(MarshallingContext);\r
- public:\r
- MarshallingContext() {}\r
- ~MarshallingContext() {}\r
-\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
- MarshallingContext(Signature* sig, const SigningContext* ctx) {\r
- m_signingContexts.push_back(std::make_pair(sig,ctx));\r
- }\r
- \r
- /** Array of signing contexts, keyed off of the associated Signature */\r
- std::vector< std::pair<Signature*,const SigningContext*> > m_signingContexts;\r
-#endif\r
- };\r
-\r
- /**\r
- * Marshallers are used to marshall an XMLObject into a W3C DOM element.\r
- */\r
- class XMLTOOL_API Marshaller\r
- {\r
- MAKE_NONCOPYABLE(Marshaller);\r
- public:\r
- Marshaller() {}\r
- virtual ~Marshaller() {}\r
- \r
- /**\r
- * Marshalls an object, and its children, into a DOM element.\r
- * If a document is supplied, then it will be used to create the resulting elements.\r
- * If the document does not have a Document Element set, then the resulting\r
- * element will be set as the Document Element. If no document is supplied, then\r
- * a new document will be created and bound to the lifetime of the root object being\r
- * marshalled, unless an existing DOM can be reused without creating a new document. \r
- * \r
- * @param xmlObject the object to marshall\r
- * @param document the DOM document the marshalled element will be placed in, or NULL\r
- * @param ctx optional marshalling context\r
- * @return the DOM element representing this XMLObject\r
- * \r
- * @throws MarshallingException thrown if there is a problem marshalling the given object\r
- * @throws SignatureException thrown if a problem occurs during signature creation \r
- */\r
- virtual DOMElement* marshall(XMLObject* xmlObject, DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const=0;\r
- \r
- /**\r
- * Marshall the given XMLObject and append it as a child of the given parent element.\r
- * \r
- * <strong>NOTE:</strong> The given Element must be within a DOM tree rooted in \r
- * the Document owning the given Element.\r
- * \r
- * @param xmlObject the XMLObject to be marshalled\r
- * @param parentElement the parent element to append the resulting DOM tree\r
- * @param ctx optional marshalling context\r
- * @return the marshalled element tree\r
-\r
- * @throws MarshallingException thrown if the given XMLObject can not be marshalled.\r
- * @throws SignatureException thrown if a problem occurs during signature creation \r
- */\r
- virtual DOMElement* marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx=NULL) const=0;\r
-\r
- /**\r
- * 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 or NULL\r
- */\r
- static const Marshaller* getMarshaller(const QName& key) {\r
- std::map<QName,Marshaller*>::const_iterator i=m_map.find(key);\r
- return (i==m_map.end()) ? NULL : i->second;\r
- }\r
-\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
- */\r
- static const Marshaller* getMarshaller(const XMLObject* xmlObject);\r
-\r
- /**\r
- * Retrieves default Marshaller for DOM elements\r
- * \r
- * @return the default marshaller or NULL\r
- */\r
- static const Marshaller* getDefaultMarshaller() {\r
- return m_default;\r
- }\r
- \r
- /**\r
- * Gets an immutable list of all the marshallers currently registered.\r
- * \r
- * @return list of all the marshallers currently registered\r
- */\r
- static const std::map<QName,Marshaller*>& getMarshallers() {\r
- return m_map;\r
- }\r
- \r
- /**\r
- * Registers a new marshaller for the given key.\r
- * \r
- * @param key the key used to retrieve this marshaller later\r
- * @param marshaller the marshaller\r
- */\r
- static void registerMarshaller(const QName& key, Marshaller* marshaller) {\r
- deregisterMarshaller(key);\r
- m_map[key]=marshaller;\r
- }\r
-\r
- /**\r
- * Registers default marshaller\r
- * \r
- * @param marshaller the default marshaller\r
- */\r
- static void registerDefaultMarshaller(Marshaller* marshaller) {\r
- deregisterDefaultMarshaller();\r
- m_default=marshaller;\r
- }\r
-\r
- /**\r
- * Deregisters a marshaller.\r
- * \r
- * @param key the key for the marshaller to be deregistered\r
- */\r
- static void deregisterMarshaller(const QName& key) {\r
- delete getMarshaller(key);\r
- m_map.erase(key);\r
- }\r
-\r
- /**\r
- * Deregisters default marshaller.\r
- */\r
- static void deregisterDefaultMarshaller() {\r
- delete m_default;\r
- m_default=NULL;\r
- }\r
-\r
- /**\r
- * Unregisters and destroys all registered marshallers. \r
- */\r
- static void destroyMarshallers();\r
- \r
- private:\r
- static std::map<QName,Marshaller*> m_map;\r
- static Marshaller* m_default;\r
- };\r
- \r
-};\r
-\r
-#if defined (_MSC_VER)\r
- #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_marshaller_h__ */\r
+++ /dev/null
-/*\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
- * Unmarshaller.cpp\r
- * \r
- * Transforms DOM trees into XMLObjects \r
- */\r
-\r
-#include "internal.h"\r
-#include "Unmarshaller.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-map<QName,Unmarshaller*> Unmarshaller::m_map;\r
-\r
-Unmarshaller* Unmarshaller::m_default=NULL;\r
-\r
-const Unmarshaller* Unmarshaller::getUnmarshaller(const DOMElement* domElement)\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("getUnmarshaller");\r
-#endif\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Unmarshaller");\r
- \r
- auto_ptr<QName> schemaType(XMLHelper::getXSIType(domElement));\r
- const Unmarshaller* m = schemaType.get() ? getUnmarshaller(*(schemaType.get())) : NULL;\r
- if (m) {\r
- if (log.isDebugEnabled()) {\r
- log.debug("located Unmarshaller for schema type: %s", schemaType->toString().c_str());\r
- }\r
- return m;\r
- }\r
- \r
- auto_ptr<QName> elementName(XMLHelper::getNodeQName(domElement));\r
- 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
- }\r
- return m;\r
- }\r
-\r
- if (log.isDebugEnabled()) {\r
- log.debug("no Unmarshaller registered for element (%s), returning default", elementName->toString().c_str());\r
- }\r
- return m_default;\r
-}\r
-\r
-void Unmarshaller::destroyUnmarshallers()\r
-{\r
- for_each(m_map.begin(),m_map.end(),cleanup_pair<QName,Unmarshaller>());\r
- m_map.clear();\r
- deregisterDefaultUnmarshaller();\r
-}\r
+++ /dev/null
-/*\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 Unmarshaller.h\r
- * \r
- * Transforms DOM trees into XMLObjects\r
- */\r
-\r
-#if !defined(__xmltooling_unmarshaller_h__)\r
-#define __xmltooling_unmarshaller_h__\r
-\r
-#include <map>\r
-#include <xercesc/dom/DOM.hpp>\r
-#include <xmltooling/XMLObject.h>\r
-\r
-using namespace xercesc;\r
-\r
-#if defined (_MSC_VER)\r
- #pragma warning( push )\r
- #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
- /**\r
- * Unmarshallers are used to unmarshall a W3C DOM element into an XMLObject.\r
- */\r
- class XMLTOOL_API Unmarshaller\r
- {\r
- MAKE_NONCOPYABLE(Unmarshaller);\r
- public:\r
- Unmarshaller() {}\r
- virtual ~Unmarshaller() {}\r
- \r
- /**\r
- * Unmarshalls the given W3C DOM element into an XMLObject.\r
- * The root of a given XML construct should be unmarshalled with the bindDocument parameter\r
- * set to true.\r
- * \r
- * @param element the DOM element to unmarshall\r
- * @param bindDocument true iff the resulting XMLObject should take ownership of the DOM's Document \r
- * \r
- * @return the unmarshalled XMLObject\r
- * \r
- * @throws UnmarshallingException thrown if an error occurs unmarshalling the DOM element into the XMLObject\r
- */\r
- virtual XMLObject* unmarshall(DOMElement* element, bool bindDocument=false) const=0;\r
-\r
- /**\r
- * Retrieves an unmarshaller using the key it was registered with.\r
- * \r
- * @param key the key used to register the unmarshaller\r
- * @return the unmarshaller\r
- */\r
- static const Unmarshaller* getUnmarshaller(const QName& key) {\r
- std::map<QName,Unmarshaller*>::const_iterator i=m_map.find(key);\r
- return (i==m_map.end()) ? NULL : i->second;\r
- }\r
- \r
- /**\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
- */\r
- static const Unmarshaller* getUnmarshaller(const DOMElement* element);\r
-\r
- /**\r
- * Retrieves the default Unmarshaller for an unknown DOM element\r
- * \r
- * @return the default unmarshaller or NULL\r
- */\r
- static const Unmarshaller* getDefaultUnmarshaller() {\r
- return m_default;\r
- }\r
-\r
- /**\r
- * Gets an immutable list of all the unmarshallers currently registered.\r
- * \r
- * @return list of all the unmarshallers currently registered\r
- */\r
- static const std::map<QName,Unmarshaller*>& getUnmarshallers() {\r
- return m_map;\r
- }\r
- \r
- /**\r
- * Registers a new unmarshaller for the given key.\r
- * \r
- * @param key the key used to retrieve this unmarshaller later\r
- * @param unmarshaller the unmarshaller\r
- */\r
- static void registerUnmarshaller(const QName& key, Unmarshaller* unmarshaller) {\r
- deregisterUnmarshaller(key);\r
- m_map[key]=unmarshaller;\r
- }\r
-\r
- /**\r
- * Registers a new default unmarshaller\r
- * \r
- * @param unmarshaller the default unmarshaller\r
- */\r
- static void registerDefaultUnmarshaller(Unmarshaller* unmarshaller) {\r
- deregisterDefaultUnmarshaller();\r
- m_default=unmarshaller;\r
- }\r
- \r
- /**\r
- * Deregisters a unmarshaller.\r
- * \r
- * @param key the key for the unmarshaller to be deregistered\r
- */\r
- static void deregisterUnmarshaller(const QName& key) {\r
- delete getUnmarshaller(key);\r
- m_map.erase(key);\r
- }\r
-\r
- /**\r
- * Deregisters the default unmarshaller.\r
- */\r
- static void deregisterDefaultUnmarshaller() {\r
- delete m_default;\r
- m_default=NULL;\r
- }\r
- \r
- /**\r
- * Unregisters and destroys all registered unmarshallers. \r
- */\r
- static void destroyUnmarshallers();\r
- \r
- private:\r
- static std::map<QName,Unmarshaller*> m_map;\r
- static Unmarshaller* m_default;\r
- };\r
- \r
-};\r
-\r
-#if defined (_MSC_VER)\r
- #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_unmarshaller_h__ */\r
\r
#include <xmltooling/XMLObject.h>\r
#include <xmltooling/signature/SigningContext.h>\r
+#include <xmltooling/signature/VerifyingContext.h>\r
\r
namespace xmltooling {\r
\r
static const XMLCh LOCAL_NAME[];\r
\r
/**\r
- * Gets the canonicalization method for the ds:SignedInfo element.\r
- * \r
- * @return the canonicalization method\r
- */\r
- virtual const XMLCh* getCanonicalizationMethod() const=0;\r
- \r
- /**\r
- * Gets the signing algorithm for the signature.\r
- * \r
- * @return the signature algorithm\r
- */\r
- virtual const XMLCh* getSignatureAlgorithm() const=0;\r
-\r
- /**\r
- * Returns the ds:KeyInfo information attached to the signature.\r
- * The Signature object must be marshalled before this will return anything.\r
- * The caller MUST NOT mutate the information through the provided pointer.\r
- * \r
- * @return the ds:KeyInfo information\r
- */\r
- virtual DSIGKeyInfoList* getKeyInfo() const=0; \r
-\r
- /**\r
* Sets the canonicalization method for the ds:SignedInfo element\r
* \r
* @param c14n the canonicalization method\r
* @param ctx the signing context that determines the signature's content\r
* @throws SignatureException thrown if the signing operation fails\r
*/\r
- virtual void sign(const SigningContext* ctx)=0;\r
+ virtual void sign(const SigningContext& ctx)=0;\r
\r
+ /**\r
+ * Verifies an XML signature based on the supplied context.\r
+ * \r
+ * @param ctx the verifying context that validates the signature's content\r
+ * @throws SignatureException thrown if the verifying operation fails\r
+ */\r
+ virtual void verify(const VerifyingContext& ctx) const=0;\r
+\r
protected:\r
Signature() {}\r
};\r
* appropriate signature transforms, references, etc.\r
* This method MAY attach ds:KeyInfo information, or a set of X.509\r
* certificates can be returned from the SigningContext::getX509Certificates()\r
- * method instead. \r
+ * method instead.\r
+ * \r
+ * @param sig native signature interface\r
*/\r
virtual void createSignature(DSIGSignature* sig) const=0;\r
\r
* the ds:KeyInfo element in a ds:X509Data chain.\r
* The certificate corresponding to the signing key SHOULD be\r
* first, followed by any additional intermediates to append. \r
+ * \r
+ * @return an immutable collection of certificates to embed\r
*/\r
virtual const std::vector<XSECCryptoX509*>& getX509Certificates() const=0;\r
\r
* Gets the signing key to use.\r
* Must be compatible with the intended signature algorithm. Ownership of the key\r
* MUST be transferred to the caller.\r
+ * \r
+ * @return pointer to a signing key, will be freed by caller\r
*/\r
virtual XSECCryptoKey* getSigningKey() const=0;\r
\r
}\r
};\r
\r
-void XMLSecSignatureImpl::sign(const SigningContext* ctx)\r
+void XMLSecSignatureImpl::sign(const SigningContext& ctx)\r
{\r
Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
log.debug("applying signature");\r
\r
try {\r
log.debug("creating signature content");\r
- ctx->createSignature(m_signature);\r
- const std::vector<XSECCryptoX509*>& certs=ctx->getX509Certificates();\r
+ ctx.createSignature(m_signature);\r
+ const std::vector<XSECCryptoX509*>& certs=ctx.getX509Certificates();\r
if (!certs.empty()) {\r
DSIGKeyInfoX509* x509Data=m_signature->appendX509Data();\r
for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data));\r
}\r
\r
log.debug("computing signature");\r
- m_signature->setSigningKey(ctx->getSigningKey());\r
+ m_signature->setSigningKey(ctx.getSigningKey());\r
m_signature->sign();\r
}\r
catch(XSECException& e) {\r
}\r
}\r
\r
-DOMElement* XMLSecSignatureMarshaller::marshall(XMLObject* xmlObject, DOMDocument* document, MarshallingContext* ctx) const\r
+void XMLSecSignatureImpl::verify(const VerifyingContext& ctx) const\r
+{\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
+ log.debug("verifying signature");\r
+\r
+ if (!m_signature)\r
+ throw SignatureException("Only a marshalled Signature object can be verified.");\r
+\r
+ try {\r
+ ctx.verifySignature(m_signature);\r
+ }\r
+ catch(XSECException& e) {\r
+ auto_ptr_char temp(e.getMsg());\r
+ throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());\r
+ }\r
+ catch(XSECCryptoException& e) {\r
+ throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());\r
+ }\r
+}\r
+\r
+DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, MarshallingContext* ctx) const\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("marshall");\r
#endif\r
\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller");\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
log.debug("marshalling ds:Signature");\r
\r
- XMLSecSignatureImpl* sig=dynamic_cast<XMLSecSignatureImpl*>(xmlObject);\r
- if (!sig)\r
- throw MarshallingException("Only objects of class XMLSecSignatureImpl can be marshalled.");\r
- \r
- DOMElement* cachedDOM=sig->getDOM();\r
+ DOMElement* cachedDOM=getDOM();\r
if (cachedDOM) {\r
if (!document || document==cachedDOM->getOwnerDocument()) {\r
log.debug("Signature has a usable cached DOM, reusing it");\r
if (document)\r
setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
- sig->releaseParentDOM(true);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
cachedDOM=static_cast<DOMElement*>(document->importNode(cachedDOM, true));\r
\r
try {\r
- XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(sig->m_signature);\r
- sig->m_signature=NULL;\r
- sig->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
+ XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
+ m_signature=NULL;\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
document, cachedDOM\r
);\r
+ m_signature->load();\r
}\r
catch(XSECException& e) {\r
auto_ptr_char temp(e.getMsg());\r
// Recache the DOM.\r
setDocumentElement(document, cachedDOM);\r
log.debug("caching imported DOM for Signature");\r
- sig->setDOM(cachedDOM, false);\r
- sig->releaseParentDOM(true);\r
+ setDOM(cachedDOM, false);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
// If we get here, we didn't have a usable DOM.\r
bool bindDocument=false;\r
- if (sig->m_xml.empty()) {\r
+ if (m_xml.empty()) {\r
// Fresh signature, so we just create an empty one.\r
log.debug("creating empty Signature element");\r
if (!document) {\r
document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();\r
bindDocument=true;\r
}\r
- sig->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
- sig->m_signature->setDSIGNSPrefix(Signature::PREFIX);\r
- cachedDOM=sig->m_signature->createBlankSignature(\r
- document, sig->getCanonicalizationMethod(), sig->getSignatureAlgorithm()\r
- );\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
+ m_signature->setDSIGNSPrefix(Signature::PREFIX);\r
+ cachedDOM=m_signature->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());\r
}\r
else {\r
// We need to reparse the XML we saved off into a new DOM.\r
- MemBufInputSource src(reinterpret_cast<const XMLByte*>(sig->m_xml.c_str()),sig->m_xml.length(),"XMLSecSignatureImpl");\r
+ MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");\r
Wrapper4InputSource dsrc(&src,false);\r
log.debug("parsing Signature XML back into DOM tree");\r
DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc);\r
\r
// Now reload the signature from the DOM.\r
try {\r
- sig->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
document, cachedDOM\r
);\r
+ m_signature->load();\r
}\r
catch(XSECException& e) {\r
if (bindDocument)\r
// Recache the DOM and clear the serialized copy.\r
setDocumentElement(document, cachedDOM);\r
log.debug("caching DOM for Signature (document is %sbound)", bindDocument ? "" : "not ");\r
- sig->setDOM(cachedDOM, bindDocument);\r
- sig->releaseParentDOM(true);\r
- sig->m_xml.erase();\r
+ setDOM(cachedDOM, bindDocument);\r
+ releaseParentDOM(true);\r
+ m_xml.erase();\r
return cachedDOM;\r
}\r
\r
-DOMElement* XMLSecSignatureMarshaller::marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx) const\r
+DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, MarshallingContext* ctx) const\r
{\r
#ifdef _DEBUG\r
xmltooling::NDC ndc("marshall");\r
#endif\r
\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller");\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
log.debug("marshalling ds:Signature");\r
\r
- XMLSecSignatureImpl* sig=dynamic_cast<XMLSecSignatureImpl*>(xmlObject);\r
- if (!sig)\r
- throw MarshallingException("Only objects of class XMLSecSignatureImpl can be marshalled.");\r
- \r
- DOMElement* cachedDOM=sig->getDOM();\r
+ DOMElement* cachedDOM=getDOM();\r
if (cachedDOM) {\r
if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
log.debug("Signature has a usable cached DOM, reusing it");\r
parentElement->appendChild(cachedDOM);\r
- sig->releaseParentDOM(true);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(cachedDOM, true));\r
\r
try {\r
- XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(sig->m_signature);\r
- sig->m_signature=NULL;\r
- sig->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
+ XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
+ m_signature=NULL;\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
parentElement->getOwnerDocument(), cachedDOM\r
);\r
+ m_signature->load();\r
}\r
catch(XSECException& e) {\r
auto_ptr_char temp(e.getMsg());\r
// Recache the DOM.\r
parentElement->appendChild(cachedDOM);\r
log.debug("caching imported DOM for Signature");\r
- sig->setDOM(cachedDOM, false);\r
- sig->releaseParentDOM(true);\r
+ setDOM(cachedDOM, false);\r
+ releaseParentDOM(true);\r
return cachedDOM;\r
}\r
\r
// If we get here, we didn't have a usable DOM.\r
- if (sig->m_xml.empty()) {\r
+ if (m_xml.empty()) {\r
// Fresh signature, so we just create an empty one.\r
log.debug("creating empty Signature element");\r
- sig->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
- sig->m_signature->setDSIGNSPrefix(Signature::PREFIX);\r
- cachedDOM=sig->m_signature->createBlankSignature(\r
- parentElement->getOwnerDocument(), sig->getCanonicalizationMethod(), sig->getSignatureAlgorithm()\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
+ m_signature->setDSIGNSPrefix(Signature::PREFIX);\r
+ cachedDOM=m_signature->createBlankSignature(\r
+ parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm()\r
);\r
}\r
else {\r
- MemBufInputSource src(reinterpret_cast<const XMLByte*>(sig->m_xml.c_str()),sig->m_xml.length(),"XMLSecSignatureImpl");\r
+ MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");\r
Wrapper4InputSource dsrc(&src,false);\r
log.debug("parsing XML back into DOM tree");\r
DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc);\r
\r
log.debug("reimporting new DOM into caller-supplied document");\r
- cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(), true));\r
+ cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(),true));\r
internalDoc->release();\r
\r
// Now reload the signature from the DOM.\r
try {\r
- sig->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
parentElement->getOwnerDocument(), cachedDOM\r
);\r
+ m_signature->load();\r
}\r
catch(XSECException& e) {\r
auto_ptr_char temp(e.getMsg());\r
// Recache the DOM and clear the serialized copy.\r
parentElement->appendChild(cachedDOM);\r
log.debug("caching DOM for Signature");\r
- sig->setDOM(cachedDOM, false);\r
- sig->releaseParentDOM(true);\r
- sig->m_xml.erase();\r
+ setDOM(cachedDOM, false);\r
+ releaseParentDOM(true);\r
+ m_xml.erase();\r
return cachedDOM;\r
}\r
\r
-XMLObject* XMLSecSignatureUnmarshaller::unmarshall(DOMElement* element, bool bindDocument) const\r
+XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocument)\r
{\r
- Category::getInstance(XMLTOOLING_LOGCAT".Unmarshaller").debug("unmarshalling ds:Signature");\r
+ Category::getInstance(XMLTOOLING_LOGCAT".Signature").debug("unmarshalling ds:Signature");\r
\r
- auto_ptr<XMLSecSignatureImpl> ret(new XMLSecSignatureImpl());\r
try {\r
- ret->m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
+ m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
element->getOwnerDocument(), element\r
);\r
+ m_signature->load();\r
}\r
catch(XSECException& e) {\r
auto_ptr_char temp(e.getMsg());\r
throw UnmarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());\r
}\r
\r
- ret->setDOM(element, bindDocument);\r
- return ret.release();\r
+ setDOM(element, bindDocument);\r
+ return this;\r
}\r
*/\r
\r
/**\r
- * @file XMLSecSignature.h\r
+ * XMLSecSignature.h\r
* \r
* Signature classes for XMLSec-based signature-handling\r
*/\r
\r
namespace xmltooling {\r
\r
- /**\r
- * XMLObject representing XML Digital Signature, version 20020212, Signature element.\r
- * Manages an Apache XML Signature object and the associated DOM. \r
- */\r
class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature\r
{\r
public:\r
void releaseDOM();\r
XMLObject* clone() const;\r
\r
+ DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
+ DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
+ XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
+ \r
// Getters\r
const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; }\r
const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; }\r
void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); }\r
void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); }\r
\r
- void sign(const SigningContext* ctx);\r
+ void sign(const SigningContext& ctx);\r
+ void verify(const VerifyingContext& ctx) const;\r
\r
private:\r
- DSIGSignature* m_signature;\r
+ mutable DSIGSignature* m_signature;\r
XMLCh* m_c14n;\r
XMLCh* m_sm;\r
-\r
- friend class XMLTOOL_DLLLOCAL XMLSecSignatureMarshaller;\r
- friend class XMLTOOL_DLLLOCAL XMLSecSignatureUnmarshaller;\r
};\r
\r
- /**\r
- * Factory for XMLSecSignatureImpl objects\r
- */\r
class XMLTOOL_DLLLOCAL XMLSecSignatureBuilder : public virtual XMLObjectBuilder\r
{\r
public:\r
- /**\r
- * @see XMLObjectBuilder::buildObject()\r
- */\r
- XMLObject* buildObject() const {\r
+ XMLObject* buildObject(const DOMElement* e=NULL) const {\r
return new XMLSecSignatureImpl();\r
}\r
};\r
\r
- /**\r
- * Marshaller for XMLSecSignatureImpl objects\r
- */\r
- class XMLTOOL_DLLLOCAL XMLSecSignatureMarshaller : public virtual Marshaller\r
- {\r
- public:\r
- /**\r
- * @see Marshaller::marshall(XMLObject*,DOMDocument*, const MarshallingContext*)\r
- */\r
- DOMElement* marshall(XMLObject* xmlObject, DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
-\r
- /**\r
- * @see Marshaller::marshall(XMLObject*,DOMElement*, const MarshallingContext* ctx)\r
- */\r
- DOMElement* marshall(XMLObject* xmlObject, DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
- \r
- protected:\r
- void setDocumentElement(DOMDocument* document, DOMElement* element) const {\r
- DOMElement* documentRoot = document->getDocumentElement();\r
- if (documentRoot)\r
- document->replaceChild(documentRoot, element);\r
- else\r
- document->appendChild(element);\r
- }\r
- };\r
-\r
- /**\r
- * Unmarshaller for XMLSecSignatureImpl objects\r
- */\r
- class XMLTOOL_DLLLOCAL XMLSecSignatureUnmarshaller : public virtual Unmarshaller\r
- {\r
- public:\r
- /**\r
- * @see Unmarshaller::unmarshall()\r
- */\r
- XMLObject* unmarshall(DOMElement* element, bool bindDocument=false) const;\r
- };\r
-\r
};\r
\r
#if defined (_MSC_VER)\r
>\r
</File>\r
<File\r
+ RelativePath=".\AbstractXMLObject.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\Namespace.cpp"\r
>\r
</File>\r
RelativePath=".\io\AbstractXMLObjectUnmarshaller.cpp"\r
>\r
</File>\r
- <File\r
- RelativePath=".\io\Marshaller.cpp"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\io\Unmarshaller.cpp"\r
- >\r
- </File>\r
</Filter>\r
<Filter\r
Name="impl"\r
RelativePath=".\io\AbstractXMLObjectUnmarshaller.h"\r
>\r
</File>\r
- <File\r
- RelativePath=".\io\Marshaller.h"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\io\Unmarshaller.h"\r
- >\r
- </File>\r
</Filter>\r
<Filter\r
Name="impl"\r
\r
void setUp() {\r
XMLObjectBuilder::registerDefaultBuilder(new WildcardXMLObjectBuilder());\r
- Marshaller::registerDefaultMarshaller(new WildcardXMLObjectMarshaller());\r
- Unmarshaller::registerDefaultUnmarshaller(new WildcardXMLObjectUnmarshaller());\r
}\r
\r
void tearDown() {\r
//XMLObjectBuilder::deregisterDefaultBuilder();\r
- //Marshaller::deregisterDefaultMarshaller();\r
- //Unmarshaller::deregisterDefaultUnmarshaller();\r
}\r
\r
void testComplexUnmarshalling() {\r
DOMDocument* doc=nonvalidatingPool->parse(fs);\r
TS_ASSERT(doc!=NULL);\r
\r
- const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
\r
- auto_ptr<WildcardXMLObject> wcObject(dynamic_cast<WildcardXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ auto_ptr<WildcardXMLObject> wcObject(\r
+ dynamic_cast<WildcardXMLObject*>(b->buildObject(doc->getDocumentElement())->unmarshall(doc->getDocumentElement(),true))\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
-\r
WildcardXMLObject* wc1=dynamic_cast<WildcardXMLObject*>(*(++kids.begin()));\r
WildcardXMLObject* wc2=dynamic_cast<WildcardXMLObject*>(*(++(wc1->getXMLObjects().begin())));\r
TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, wc2->getXMLObjects().size());\r
xmltoolingtest_h = \
ComplexXMLObjectTest.h \
MarshallingTest.h \
- UnknownTest.h \
UnmarshallingTest.h \
xmltoolingtest.h \
${xmlsec_sources}
\r
void setUp() {\r
XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
- Marshaller::registerMarshaller(m_qname, new SimpleXMLObjectMarshaller());\r
- Unmarshaller::registerUnmarshaller(m_qname, new SimpleXMLObjectUnmarshaller());\r
}\r
\r
void tearDown() {\r
XMLObjectBuilder::deregisterBuilder(m_qname);\r
- Marshaller::deregisterMarshaller(m_qname);\r
- Unmarshaller::deregisterUnmarshaller(m_qname);\r
}\r
\r
void testMarshallingWithAttributes() {\r
TS_ASSERT(sxObject.get()!=NULL);\r
sxObject->setId(expected.get());\r
\r
- DOMElement* rootElement = Marshaller::getMarshaller(sxObject.get())->marshall(sxObject.get());\r
+ DOMElement* rootElement = sxObject->marshall();\r
\r
string path=data_path + "SimpleXMLObjectWithAttribute.xml";\r
ifstream fs(path.c_str());\r
TS_ASSERT(sxObject.get()!=NULL);\r
sxObject->setValue(expected.get());\r
\r
- DOMElement* rootElement = Marshaller::getMarshaller(sxObject.get())->marshall(sxObject.get());\r
+ DOMElement* rootElement = sxObject->marshall();\r
\r
string path=data_path + "SimpleXMLObjectWithContent.xml";\r
ifstream fs(path.c_str());\r
void testMarshallingWithChildElements() {\r
TS_TRACE("testMarshallingWithChildElements");\r
\r
- const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(m_qname);\r
+ const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(m_qname));\r
TS_ASSERT(b!=NULL);\r
\r
- auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
+ auto_ptr<SimpleXMLObject> sxObject(b->buildObject());\r
TS_ASSERT(sxObject.get()!=NULL);\r
VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
- kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
- kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
- kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
+ kids.push_back(b->buildObject());\r
+ kids.push_back(b->buildObject());\r
+ kids.push_back(b->buildObject());\r
\r
// Test some collection stuff\r
auto_ptr_XMLCh foo("Foo");\r
kids.erase(kids.begin()+1);\r
TS_ASSERT_SAME_DATA(kids.back()->getValue(), bar.get(), XMLString::stringLen(bar.get()));\r
\r
- DOMElement* rootElement = Marshaller::getMarshaller(sxObject.get())->marshall(sxObject.get());\r
+ DOMElement* rootElement = sxObject->marshall();\r
\r
string path=data_path + "SimpleXMLObjectWithChildren.xml";\r
ifstream fs(path.c_str());\r
#include <openssl/pem.h>\r
#include <xercesc/util/XMLUniDefs.hpp>\r
#include <xsec/dsig/DSIGReference.hpp>\r
+#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
\r
-class TestContext : public SigningContext\r
+class TestContext : public SigningContext, public VerifyingContext\r
{\r
XSECCryptoKey* m_key;\r
vector<XSECCryptoX509*> m_certs;\r
ref->appendEnvelopedSignatureTransform();\r
ref->appendCanonicalizationTransform(CANON_C14NE_NOC);\r
}\r
+\r
+ void verifySignature(DSIGSignature* sig) const {\r
+ const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();\r
+ TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));\r
+ XSECKeyInfoResolverDefault resolver;\r
+ sig->setKeyInfoResolver(&resolver); // It will clone the resolver for us.\r
+ sig->verify();\r
+ }\r
\r
const std::vector<XSECCryptoX509*>& getX509Certificates() const { return m_certs; }\r
XSECCryptoKey* getSigningKey() const { return m_key->clone(); }\r
\r
void setUp() {\r
XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
- Marshaller::registerMarshaller(m_qname, new SimpleXMLObjectMarshaller());\r
- Unmarshaller::registerUnmarshaller(m_qname, new SimpleXMLObjectUnmarshaller());\r
}\r
\r
void tearDown() {\r
XMLObjectBuilder::deregisterBuilder(m_qname);\r
- Marshaller::deregisterMarshaller(m_qname);\r
- Unmarshaller::deregisterUnmarshaller(m_qname);\r
}\r
\r
void testSignature() {\r
TS_TRACE("testSignature");\r
\r
- const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(m_qname);\r
+ const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(m_qname));\r
TS_ASSERT(b!=NULL);\r
\r
- auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
+ auto_ptr<SimpleXMLObject> sxObject(b->buildObject());\r
TS_ASSERT(sxObject.get()!=NULL);\r
VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
- kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
- kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
+ kids.push_back(b->buildObject());\r
+ kids.push_back(b->buildObject());\r
\r
// Test some collection stuff\r
auto_ptr_XMLCh foo("Foo");\r
// Signing context for the whole document.\r
TestContext tc(&chNull);\r
MarshallingContext mctx(sig,&tc);\r
- DOMElement* rootElement = Marshaller::getMarshaller(sxObject.get())->marshall(sxObject.get(),(DOMDocument*)NULL,&mctx);\r
+ DOMElement* rootElement = sxObject->marshall((DOMDocument*)NULL,&mctx);\r
\r
string buf;\r
XMLHelper::serialize(rootElement, buf);\r
\r
istringstream in(buf);\r
DOMDocument* doc=nonvalidatingPool->parse(in);\r
- const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildObject()->unmarshall(doc->getDocumentElement(),true)));\r
TS_ASSERT(sxObject2.get()!=NULL);\r
TS_ASSERT(sxObject2->getSignature()!=NULL);\r
+ \r
+ try {\r
+ sxObject2->getSignature()->verify(tc);\r
+ }\r
+ catch (SignatureException& e) {\r
+ TS_TRACE(e.what());\r
+ throw;\r
+ }\r
}\r
\r
};\r
+++ /dev/null
-/*\r
- * Copyright 2001-2005 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
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-\r
-\r
-class UnknownTest : public CxxTest::TestSuite {\r
-public:\r
-\r
- void testUnknown() {\r
- ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");\r
- DOMDocument* doc=nonvalidatingPool->parse(fs);\r
- TS_ASSERT(doc!=NULL);\r
-\r
- string buf1;\r
- XMLHelper::serialize(doc->getDocumentElement(), buf1);\r
-\r
- const Unmarshaller* u=Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
-\r
- auto_ptr<XMLObject> xmlObject(u->unmarshall(doc->getDocumentElement(),true)); // bind document\r
- TS_ASSERT(xmlObject.get()!=NULL);\r
-\r
- auto_ptr<XMLObject> clonedObject(xmlObject->clone());\r
- TS_ASSERT(clonedObject.get()!=NULL);\r
-\r
- const Marshaller* m=Marshaller::getMarshaller(clonedObject.get());\r
- TS_ASSERT(m!=NULL);\r
-\r
- DOMElement* rootElement=m->marshall(clonedObject.get());\r
- TS_ASSERT(rootElement!=NULL);\r
-\r
- rootElement=m->marshall(clonedObject.get()); // should reuse DOM\r
- TS_ASSERT(rootElement!=NULL);\r
-\r
- string buf2;\r
- XMLHelper::serialize(rootElement, buf2);\r
- TS_ASSERT_EQUALS(buf1,buf2);\r
- }\r
-\r
- void testUnknownWithDocChange() {\r
- ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");\r
- DOMDocument* doc=nonvalidatingPool->parse(fs);\r
- TS_ASSERT(doc!=NULL);\r
-\r
- string buf1;\r
- XMLHelper::serialize(doc->getDocumentElement(), buf1);\r
-\r
- const Unmarshaller* u=Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
-\r
- auto_ptr<XMLObject> xmlObject(u->unmarshall(doc->getDocumentElement(),true)); // bind document\r
- TS_ASSERT(xmlObject.get()!=NULL);\r
-\r
- const Marshaller* m=Marshaller::getMarshaller(xmlObject.get());\r
- TS_ASSERT(m!=NULL);\r
-\r
- DOMDocument* newDoc=nonvalidatingPool->newDocument();\r
- DOMElement* rootElement=m->marshall(xmlObject.get(), newDoc);\r
- TS_ASSERT(rootElement!=NULL);\r
-\r
- string buf2;\r
- XMLHelper::serialize(rootElement, buf2);\r
- TS_ASSERT_EQUALS(buf1,buf2);\r
-\r
- newDoc->release();\r
- }\r
-};\r
\r
void setUp() {\r
XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder());\r
- Marshaller::registerMarshaller(m_qname, new SimpleXMLObjectMarshaller());\r
- Unmarshaller::registerUnmarshaller(m_qname, new SimpleXMLObjectUnmarshaller());\r
}\r
\r
void tearDown() {\r
XMLObjectBuilder::deregisterBuilder(m_qname);\r
- Marshaller::deregisterMarshaller(m_qname);\r
- Unmarshaller::deregisterUnmarshaller(m_qname);\r
}\r
\r
void testUnmarshallingWithAttributes() {\r
DOMDocument* doc=nonvalidatingPool->parse(fs);\r
TS_ASSERT(doc!=NULL);\r
\r
- const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
\r
- auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ auto_ptr<SimpleXMLObject> sxObject(\r
+ dynamic_cast<SimpleXMLObject*>(b->buildObject()->unmarshall(doc->getDocumentElement(),true))\r
+ );\r
TS_ASSERT(sxObject.get()!=NULL);\r
\r
auto_ptr_XMLCh expected("Firefly");\r
DOMDocument* doc=nonvalidatingPool->parse(fs);\r
TS_ASSERT(doc!=NULL);\r
\r
- const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
\r
- auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ auto_ptr<SimpleXMLObject> sxObject(\r
+ dynamic_cast<SimpleXMLObject*>(b->buildObject()->unmarshall(doc->getDocumentElement(),true))\r
+ );\r
TS_ASSERT(sxObject.get()!=NULL);\r
\r
auto_ptr_XMLCh expected("Sample Content");\r
DOMDocument* doc=nonvalidatingPool->parse(fs);\r
TS_ASSERT(doc!=NULL);\r
\r
- const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
\r
- auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
+ auto_ptr<SimpleXMLObject> sxObject(\r
+ dynamic_cast<SimpleXMLObject*>(b->buildObject()->unmarshall(doc->getDocumentElement(),true))\r
+ );\r
TS_ASSERT(sxObject.get()!=NULL);\r
\r
VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
DOMDocument* doc=nonvalidatingPool->parse(fs);\r
TS_ASSERT(doc!=NULL);\r
\r
- const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement());\r
- TS_ASSERT(u!=NULL);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
\r
- TS_ASSERT_THROWS(u->unmarshall(doc->getDocumentElement(),true),UnmarshallingException);\r
+ auto_ptr<XMLObject> sxObject(b->buildObject());\r
+ TS_ASSERT_THROWS(sxObject->unmarshall(doc->getDocumentElement(),true),UnmarshallingException);\r
doc->release();\r
}\r
};\r
#include <cxxtest/TestSuite.h>
#include <xmltooling/AbstractAttributeExtensibleXMLObject.h>
-#include <xmltooling/AbstractDOMCachingXMLObject.h>
#include <xmltooling/AbstractElementProxy.h>
#include <xmltooling/exceptions.h>
#include <xmltooling/XMLObjectBuilder.h>
#pragma warning( disable : 4250 4251 )
#endif
-class SimpleXMLObject : public AbstractDOMCachingXMLObject
+class SimpleXMLObject : public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller
{
public:
static const XMLCh NAMESPACE[];
return ret;
}
-private:
- XMLCh* m_id;
- XMLCh* m_value;
- vector<SimpleXMLObject*> m_simples;
-#ifndef XMLTOOLING_NO_XMLSEC
- list<XMLObject*>::iterator m_signature;
-#endif
-};
-
-class SimpleXMLObjectBuilder : public XMLObjectBuilder
-{
-public:
- SimpleXMLObject* buildObject() const {
- return new SimpleXMLObject();
- }
-};
-
-class SimpleXMLObjectMarshaller : public AbstractXMLObjectMarshaller
-{
-public:
- SimpleXMLObjectMarshaller() {}
-
-private:
- void marshallAttributes(const XMLObject& xmlObject, DOMElement* domElement) const {
- const SimpleXMLObject& simpleXMLObject = dynamic_cast<const SimpleXMLObject&>(xmlObject);
-
- if(simpleXMLObject.getId()) {
- domElement->setAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME, simpleXMLObject.getId());
+ void marshallAttributes(DOMElement* domElement) const {
+ if(getId()) {
+ domElement->setAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME, getId());
domElement->setIdAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME);
}
}
- void marshallElementContent(const XMLObject& xmlObject, DOMElement* domElement) const {
- const SimpleXMLObject& simpleXMLObject = dynamic_cast<const SimpleXMLObject&>(xmlObject);
-
- if(simpleXMLObject.getValue()) {
- domElement->setTextContent(simpleXMLObject.getValue());
+ void marshallElementContent(DOMElement* domElement) const {
+ if(getValue()) {
+ domElement->setTextContent(getValue());
}
}
-};
-
-class SimpleXMLObjectUnmarshaller : public AbstractXMLObjectUnmarshaller
-{
-public:
- SimpleXMLObjectUnmarshaller() {}
-
-private:
- void processChildElement(XMLObject& parentXMLObject, XMLObject* childXMLObject, const DOMElement* root) const {
- SimpleXMLObject& simpleXMLObject = dynamic_cast<SimpleXMLObject&>(parentXMLObject);
+ void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
if (XMLHelper::isNodeNamed(root, SimpleXMLObject::NAMESPACE, SimpleXMLObject::LOCAL_NAME))
- simpleXMLObject.getSimpleXMLObjects().push_back(dynamic_cast<SimpleXMLObject*>(childXMLObject));
+ getSimpleXMLObjects().push_back(dynamic_cast<SimpleXMLObject*>(childXMLObject));
#ifndef XMLTOOLING_NO_XMLSEC
else if (XMLHelper::isNodeNamed(root, XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME))
- simpleXMLObject.setSignature(dynamic_cast<Signature*>(childXMLObject));
+ setSignature(dynamic_cast<Signature*>(childXMLObject));
#endif
else
throw UnmarshallingException("Unknown child element cannot be added to parent object.");
}
- void processAttribute(XMLObject& xmlObject, const DOMAttr* attribute) const {
- SimpleXMLObject& simpleXMLObject = dynamic_cast<SimpleXMLObject&>(xmlObject);
-
+ void processAttribute(const DOMAttr* attribute) {
if (XMLHelper::isNodeNamed(attribute, NULL, SimpleXMLObject::ID_ATTRIB_NAME))
- simpleXMLObject.setId(attribute->getValue());
+ setId(attribute->getValue());
else
throw UnmarshallingException("Unknown attribute cannot be processed by parent object.");
}
- void processElementContent(XMLObject& xmlObject, const XMLCh* elementContent) const {
- SimpleXMLObject& simpleXMLObject = dynamic_cast<SimpleXMLObject&>(xmlObject);
-
- simpleXMLObject.setValue(elementContent);
+ void processElementContent(const XMLCh* elementContent) {
+ setValue(elementContent);
}
+private:
+ XMLCh* m_id;
+ XMLCh* m_value;
+ vector<SimpleXMLObject*> m_simples;
+#ifndef XMLTOOLING_NO_XMLSEC
+ list<XMLObject*>::iterator m_signature;
+#endif
};
-class WildcardXMLObjectMarshaller;
+class SimpleXMLObjectBuilder : public XMLObjectBuilder
+{
+public:
+ SimpleXMLObject* buildObject(const DOMElement* e=NULL) const {
+ return new SimpleXMLObject();
+ }
+};
-class WildcardXMLObject : public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject
+class WildcardXMLObject : public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject,
+ public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller
{
- friend class WildcardXMLObjectMarshaller;
public:
WildcardXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix)
: AbstractDOMCachingXMLObject(nsURI, localName, prefix),
xmltooling::clone(m_children, ret->m_children);
return ret;
}
-};
-
-class WildcardXMLObjectBuilder : public XMLObjectBuilder
-{
-public:
- XMLObject* buildObject() const {
- throw XMLObjectException("No default builder available.");
- }
-
- WildcardXMLObject* buildObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix) const {
- return new WildcardXMLObject(nsURI,localName,prefix);
- }
-};
-
-class WildcardXMLObjectMarshaller : public AbstractXMLObjectMarshaller
-{
-public:
- WildcardXMLObjectMarshaller() : AbstractXMLObjectMarshaller() {}
-private:
- void marshallAttributes(const XMLObject& xmlObject, DOMElement* domElement) const {
- const WildcardXMLObject& wcXMLObject = dynamic_cast<const WildcardXMLObject&>(xmlObject);
-
- for (map<QName,XMLCh*>::const_iterator i=wcXMLObject.m_attributeMap.begin(); i!=wcXMLObject.m_attributeMap.end(); i++) {
+ 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());
}
}
- void marshallElementContent(const XMLObject& xmlObject, DOMElement* domElement) const {
- const WildcardXMLObject& wcXMLObject = dynamic_cast<const WildcardXMLObject&>(xmlObject);
-
- if(wcXMLObject.getTextContent()) {
- domElement->appendChild(domElement->getOwnerDocument()->createTextNode(wcXMLObject.getTextContent()));
+ void marshallElementContent(DOMElement* domElement) const {
+ if(getTextContent()) {
+ domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent()));
}
}
-};
-class WildcardXMLObjectUnmarshaller : public AbstractXMLObjectUnmarshaller
-{
-public:
- WildcardXMLObjectUnmarshaller() {}
-
-private:
- XMLObject* buildXMLObject(const DOMElement* domElement) const {
- const WildcardXMLObjectBuilder* builder =
- dynamic_cast<const WildcardXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(domElement));
- if (builder)
- return builder->buildObject(domElement->getNamespaceURI(),domElement->getLocalName(),domElement->getPrefix());
- throw UnmarshallingException("Failed to locate WildcardObjectBuilder for element.");
+ void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+ getXMLObjects().push_back(childXMLObject);
}
- void processChildElement(XMLObject& parentXMLObject, XMLObject* childXMLObject, const DOMElement* root) const {
- WildcardXMLObject& wcXMLObject = dynamic_cast<WildcardXMLObject&>(parentXMLObject);
-
- wcXMLObject.getXMLObjects().push_back(childXMLObject);
- }
-
- void processAttribute(XMLObject& xmlObject, const DOMAttr* attribute) const {
- WildcardXMLObject& wcXMLObject = dynamic_cast<WildcardXMLObject&>(xmlObject);
-
+ void processAttribute(const DOMAttr* attribute) {
QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());
- wcXMLObject.setAttribute(q,attribute->getNodeValue());
+ setAttribute(q,attribute->getNodeValue());
}
- void processElementContent(XMLObject& xmlObject, const XMLCh* elementContent) const {
- WildcardXMLObject& wcXMLObject = dynamic_cast<WildcardXMLObject&>(xmlObject);
-
- wcXMLObject.setTextContent(elementContent);
+ void processElementContent(const XMLCh* elementContent) {
+ setTextContent(elementContent);
}
+};
+class WildcardXMLObjectBuilder : public XMLObjectBuilder
+{
+public:
+ WildcardXMLObject* buildObject(const DOMElement* e=NULL) const {
+ return new WildcardXMLObject(e->getNamespaceURI(),e->getLocalName(),e->getPrefix());
+ }
};
#if defined (_MSC_VER)
* limitations under the License.\r
*/\r
\r
-#include <cxxtest/TestSuite.h>\r
-#include <cxxtest/GlobalFixture.h>\r
+#include "XMLObjectBaseTestCase.h"\r
\r
+#include <fstream>\r
+#include <cxxtest/GlobalFixture.h>\r
#include <xmltooling/XMLToolingConfig.h>\r
#include <xmltooling/util/ParserPool.h>\r
\r
-using namespace xmltooling;\r
-\r
ParserPool* validatingPool=NULL;\r
ParserPool* nonvalidatingPool=NULL;\r
std::string data_path = "../xmltoolingtest/data/";\r
\r
static ToolingFixture globalFixture;\r
\r
-class CatalogTest : public CxxTest::TestSuite\r
+class GlobalTest : public CxxTest::TestSuite\r
{\r
public:\r
void testCatalog(void) {\r
auto_ptr_XMLCh temp(path.c_str());\r
TS_ASSERT(validatingPool->loadCatalog(temp.get()));\r
}\r
+\r
+ void testUnknown() {\r
+ ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");\r
+ DOMDocument* doc=nonvalidatingPool->parse(fs);\r
+ TS_ASSERT(doc!=NULL);\r
+\r
+ string buf1;\r
+ XMLHelper::serialize(doc->getDocumentElement(), buf1);\r
+\r
+ const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
+\r
+ auto_ptr<XMLObject> xmlObject(b->buildObject(doc->getDocumentElement())->unmarshall(doc->getDocumentElement(),true)); // bind document\r
+ TS_ASSERT(xmlObject.get()!=NULL);\r
+\r
+ auto_ptr<XMLObject> clonedObject(xmlObject->clone());\r
+ TS_ASSERT(clonedObject.get()!=NULL);\r
+\r
+ DOMElement* rootElement=clonedObject->marshall();\r
+ TS_ASSERT(rootElement!=NULL);\r
+\r
+ // should reuse DOM\r
+ TS_ASSERT(rootElement==clonedObject->marshall());\r
+\r
+ string buf2;\r
+ XMLHelper::serialize(rootElement, buf2);\r
+ TS_ASSERT_EQUALS(buf1,buf2);\r
+ }\r
+\r
+ void testUnknownWithDocChange() {\r
+ ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");\r
+ DOMDocument* doc=nonvalidatingPool->parse(fs);\r
+ TS_ASSERT(doc!=NULL);\r
+\r
+ string buf1;\r
+ XMLHelper::serialize(doc->getDocumentElement(), buf1);\r
+\r
+ const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ TS_ASSERT(b!=NULL);\r
+\r
+ auto_ptr<XMLObject> xmlObject(b->buildObject(doc->getDocumentElement())->unmarshall(doc->getDocumentElement(),true)); // bind document\r
+ TS_ASSERT(xmlObject.get()!=NULL);\r
+\r
+ DOMDocument* newDoc=nonvalidatingPool->newDocument();\r
+ DOMElement* rootElement=xmlObject->marshall(newDoc);\r
+ TS_ASSERT(rootElement!=NULL);\r
+\r
+ string buf2;\r
+ XMLHelper::serialize(rootElement, buf2);\r
+ TS_ASSERT_EQUALS(buf1,buf2);\r
+\r
+ newDoc->release();\r
+ }\r
};\r
+\r
>\r
</File>\r
<File\r
- RelativePath=".\UnknownTest.cpp"\r
- >\r
- </File>\r
- <File\r
RelativePath=".\UnmarshallingTest.cpp"\r
>\r
</File>\r
</FileConfiguration>\r
</File>\r
<File\r
- RelativePath=".\UnknownTest.h"\r
- >\r
- <FileConfiguration\r
- Name="Debug|Win32"\r
- >\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputName)".cpp "$(InputPath)""\r
- Outputs=""$(InputName)".cpp"\r
- />\r
- </FileConfiguration>\r
- <FileConfiguration\r
- Name="Release|Win32"\r
- >\r
- <Tool\r
- Name="VCCustomBuildTool"\r
- CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputName)".cpp "$(InputPath)""\r
- Outputs=""$(InputName)".cpp"\r
- />\r
- </FileConfiguration>\r
- </File>\r
- <File\r
RelativePath=".\UnmarshallingTest.h"\r
>\r
<FileConfiguration\r