From: Scott Cantor Date: Wed, 29 Mar 2006 07:46:23 +0000 (+0000) Subject: Moved DOM methods up the tree, add copy c'tors, KeyInfo sample X-Git-Tag: 1.0-alpha1~285 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-xmltooling.git;a=commitdiff_plain;h=a039baceeda19f0e5c3269332a668763c0889e90 Moved DOM methods up the tree, add copy c'tors, KeyInfo sample --- diff --git a/.cdtproject b/.cdtproject index 3d9715b..87a1045 100644 --- a/.cdtproject +++ b/.cdtproject @@ -4,7 +4,7 @@ - + diff --git a/doxyfile b/doxyfile index 035cf62..070f613 100644 --- a/doxyfile +++ b/doxyfile @@ -83,12 +83,7 @@ WARN_LOGFILE = # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = C:/cvs/cpp-xmltooling/xmltooling -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ +FILE_PATTERNS = *.d \ *.java \ *.ii \ *.ixx \ @@ -111,7 +106,7 @@ FILE_PATTERNS = *.c \ *.dox \ *.py RECURSIVE = YES -EXCLUDE = +EXCLUDE = C:/cvs/cpp-xmltooling/xmltooling/signature/impl EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = @@ -211,7 +206,7 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = C:\cvs\cpp-xmltooling diff --git a/xmltooling/AbstractAttributeExtensibleXMLObject.cpp b/xmltooling/AbstractAttributeExtensibleXMLObject.cpp index 7362956..4052b6e 100644 --- a/xmltooling/AbstractAttributeExtensibleXMLObject.cpp +++ b/xmltooling/AbstractAttributeExtensibleXMLObject.cpp @@ -41,6 +41,14 @@ AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject() for_each(m_attributeMap.begin(),m_attributeMap.end(),_release()); } +AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src) + : AbstractXMLObject(src) +{ + for (map::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) { + m_attributeMap[i->first] = XMLString::replicate(i->second); + } +} + void AbstractAttributeExtensibleXMLObject::setAttribute(QName& qualifiedName, const XMLCh* value) { map::iterator i=m_attributeMap.find(qualifiedName); diff --git a/xmltooling/AbstractAttributeExtensibleXMLObject.h b/xmltooling/AbstractAttributeExtensibleXMLObject.h index e474ff8..09bfb7c 100644 --- a/xmltooling/AbstractAttributeExtensibleXMLObject.h +++ b/xmltooling/AbstractAttributeExtensibleXMLObject.h @@ -17,10 +17,10 @@ /** * @file AbstractAttributeExtensibleXMLObject.h * - * An abstract implementation of a DOM-caching AttributeExtensibleXMLObject + * An abstract implementation of an AttributeExtensibleXMLObject */ -#if !defined(__xmltooling_absattrextxmlobj_h__) +#ifndef __xmltooling_absattrextxmlobj_h__ #define __xmltooling_absattrextxmlobj_h__ #include @@ -35,29 +35,27 @@ namespace xmltooling { /** - * An abstract implementation of a DOM-caching AttributeExtensibleXMLObject. + * An abstract implementation of an AttributeExtensibleXMLObject. */ - class XMLTOOL_API AbstractAttributeExtensibleXMLObject : public virtual AttributeExtensibleXMLObject, public virtual AbstractDOMCachingXMLObject + class XMLTOOL_API AbstractAttributeExtensibleXMLObject : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject { public: virtual ~AbstractAttributeExtensibleXMLObject(); - /** - * @see AttributeExtensibleXMLObject::getAttribute() - */ virtual const XMLCh* getAttribute(QName& qualifiedName) const { std::map::const_iterator i=m_attributeMap.find(qualifiedName); return (i==m_attributeMap.end()) ? NULL : i->second; } - /** - * @see AttributeExtensibleXMLObject::setAttribute() - */ virtual void setAttribute(QName& qualifiedName, const XMLCh* value); protected: AbstractAttributeExtensibleXMLObject() {} + /** Copy constructor. */ + AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src); + + /** Map of arbitrary attributes. */ std::map m_attributeMap; }; diff --git a/xmltooling/AbstractDOMCachingXMLObject.cpp b/xmltooling/AbstractDOMCachingXMLObject.cpp index d97301d..3eacc8a 100644 --- a/xmltooling/AbstractDOMCachingXMLObject.cpp +++ b/xmltooling/AbstractDOMCachingXMLObject.cpp @@ -64,28 +64,24 @@ void AbstractDOMCachingXMLObject::releaseDOM() const void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease) const { - DOMCachingXMLObject* domCachingParent = dynamic_cast(getParent()); - if (domCachingParent) { - if (domCachingParent->getDOM()) { - Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug( - "releasing cached DOM representation for parent object with propagation set to %s", - propagateRelease ? "true" : "false" - ); - domCachingParent->releaseDOM(); - if (propagateRelease) - domCachingParent->releaseParentDOM(propagateRelease); - } + if (getParent() && getParent()->getDOM()) { + Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug( + "releasing cached DOM representation for parent object with propagation set to %s", + propagateRelease ? "true" : "false" + ); + getParent()->releaseDOM(); + if (propagateRelease) + getParent()->releaseParentDOM(propagateRelease); } } class _release : public binary_function { public: void operator()(XMLObject* obj, bool propagate) const { - DOMCachingXMLObject* domCaching = dynamic_cast(obj); - if (domCaching) { - domCaching->releaseDOM(); + if (obj) { + obj->releaseDOM(); if (propagate) - domCaching->releaseChildrenDOM(propagate); + obj->releaseChildrenDOM(propagate); } } }; @@ -136,28 +132,3 @@ XMLObject* AbstractDOMCachingXMLObject::clone() const } return NULL; } - -XMLObject* AbstractDOMCachingXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue) { - - if (newValue && newValue->hasParent()) - throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject"); - - if (!oldValue) { - if (newValue) { - releaseThisandParentDOM(); - newValue->setParent(this); - return newValue; - } - else { - return NULL; - } - } - - if (oldValue != newValue) { - delete oldValue; - releaseThisandParentDOM(); - newValue->setParent(this); - } - - return newValue; -} diff --git a/xmltooling/AbstractDOMCachingXMLObject.h b/xmltooling/AbstractDOMCachingXMLObject.h index edfc1bf..f143695 100644 --- a/xmltooling/AbstractDOMCachingXMLObject.h +++ b/xmltooling/AbstractDOMCachingXMLObject.h @@ -17,14 +17,13 @@ /** * @file AbstractDOMCachingXMLObject.h * - * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. + * Extension of AbstractXMLObject that adds DOM caching methods */ #if !defined(__xmltooling_abstractdomxmlobj_h__) #define __xmltooling_abstractdomxmlobj_h__ #include -#include #if defined (_MSC_VER) #pragma warning( push ) @@ -34,77 +33,40 @@ namespace xmltooling { /** - * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. + * Extension of AbstractXMLObject that adds DOM caching methods */ - class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject, public virtual DOMCachingXMLObject + class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject { public: virtual ~AbstractDOMCachingXMLObject(); - /** - * @see DOMCachingXMLObject::getDOM() - */ DOMElement* getDOM() const { return m_dom; } - /** - * @see DOMCachingXMLObject::setDOM() - */ void setDOM(DOMElement* dom, bool bindDocument=false) const; - /** - * @see DOMCachingXMLObject::setDocument() - */ void setDocument(DOMDocument* doc) const { if (m_document) m_document->release(); m_document=doc; } - /** - * @see DOMCachingXMLObject::releaseDOM() - */ virtual void releaseDOM() const; - /** - * @see DOMCachingXMLObject::releaseParentDOM() - */ virtual void releaseParentDOM(bool propagateRelease=true) const; - /** - * @see DOMCachingXMLObject::releaseChildrenDOM() - */ virtual void releaseChildrenDOM(bool propagateRelease=true) const; - /** - * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true). - */ - void releaseThisandParentDOM() const { - if (m_dom) { - releaseDOM(); - releaseParentDOM(true); - } - } - - /** - * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM(). - */ - void releaseThisAndChildrenDOM() const { - if (m_dom) { - releaseChildrenDOM(true); - releaseDOM(); - } - } - - /** - * @see XMLObject::clone() - */ XMLObject* clone() const; protected: AbstractDOMCachingXMLObject() : m_dom(NULL), m_document(NULL) {} + /** Copy constructor. */ + AbstractDOMCachingXMLObject(const AbstractDOMCachingXMLObject& src) + : AbstractXMLObject(src), m_dom(NULL), m_document(NULL) {} + /** * If a DOM representation exists, this clones it into a new document. * @@ -113,43 +75,6 @@ namespace xmltooling { */ DOMElement* cloneDOM(DOMDocument* doc=NULL) const; - /** - * A helper function for derived classes. - * This 'normalizes' newString, and then if it is different from oldString, - * it invalidates the DOM, frees the old string, and return the new. - * If not different, it frees the new string and just returns the old value. - * - * @param oldValue - the current value - * @param newValue - the new value - * - * @return the value that should be assigned - */ - XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue) { - XMLCh* newString = XMLString::replicate(newValue); - XMLString::trim(newString); - if (!XMLString::equals(oldValue,newValue)) { - releaseThisandParentDOM(); - XMLString::release(&oldValue); - return newString; - } - XMLString::release(&newString); - return oldValue; - } - - /** - * A helper function for derived classes, for assignment of (singleton) XML objects. - * - * It is indifferent to whether either the old or the new version of the value is null. - * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate - * - * @param oldValue - current value - * @param newValue - proposed new value - * @return the value to assign - * - * @throws XMLObjectException if the new child already has a parent. - */ - XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue); - private: mutable DOMElement* m_dom; mutable DOMDocument* m_document; diff --git a/xmltooling/AbstractElementProxy.h b/xmltooling/AbstractElementProxy.h index a00b9df..9829410 100644 --- a/xmltooling/AbstractElementProxy.h +++ b/xmltooling/AbstractElementProxy.h @@ -17,10 +17,10 @@ /** * @file AbstractElementProxy.h * - * An abstract implementation of a DOM-caching ElementProxy + * An abstract implementation of an ElementProxy */ -#if !defined(__xmltooling_abseleproxy_h__) +#ifndef __xmltooling_abseleproxy_h__ #define __xmltooling_abseleproxy_h__ #include @@ -34,33 +34,27 @@ namespace xmltooling { /** - * An abstract implementation of a DOM-caching ExtensibleXMLObject. + * An abstract implementation of an ExtensibleXMLObject. */ - class XMLTOOL_API AbstractElementProxy : public virtual ElementProxy, public virtual AbstractDOMCachingXMLObject + class XMLTOOL_API AbstractElementProxy : public virtual ElementProxy, public virtual AbstractXMLObject { public: virtual ~AbstractElementProxy() {} - /** - * @see ElementProxy::getTextContent() - */ virtual const XMLCh* getTextContent() const { return m_value; } - /** - * @see ElementProxy::setTextContent() - */ virtual void setTextContent(const XMLCh* value); - - /** - * @see ElementProxy::getXMLObjects() - */ virtual ListOf(XMLObject) getXMLObjects(); protected: AbstractElementProxy() : m_value(NULL) {} + + /** Copy constructor. */ + AbstractElementProxy(const AbstractElementProxy& src) + : AbstractXMLObject(src), m_value(XMLString::replicate(src.m_value)) {} private: XMLCh* m_value; diff --git a/xmltooling/AbstractXMLObject.cpp b/xmltooling/AbstractXMLObject.cpp index cc9381a..4e0005b 100644 --- a/xmltooling/AbstractXMLObject.cpp +++ b/xmltooling/AbstractXMLObject.cpp @@ -22,6 +22,7 @@ #include "internal.h" #include "AbstractXMLObject.h" +#include "exceptions.h" #include #include @@ -39,3 +40,35 @@ AbstractXMLObject::AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* ele { addNamespace(Namespace(namespaceURI, namespacePrefix)); } + +AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src) + : m_namespaces(src.m_namespaces), m_log(src.m_log), m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL) +{ + if (src.m_typeQname) + m_typeQname=new QName(*src.m_typeQname); +} + +XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue) { + + if (newValue && newValue->hasParent()) + throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject"); + + if (!oldValue) { + if (newValue) { + releaseThisandParentDOM(); + newValue->setParent(this); + return newValue; + } + else { + return NULL; + } + } + + if (oldValue != newValue) { + delete oldValue; + releaseThisandParentDOM(); + newValue->setParent(this); + } + + return newValue; +} diff --git a/xmltooling/AbstractXMLObject.h b/xmltooling/AbstractXMLObject.h index 917bb22..6beecfd 100644 --- a/xmltooling/AbstractXMLObject.h +++ b/xmltooling/AbstractXMLObject.h @@ -40,46 +40,28 @@ namespace xmltooling { public: virtual ~AbstractXMLObject(); - /** - * @see XMLObject::getElementQName() - */ const QName& getElementQName() const { return m_elementQname; } - /** - * @see XMLObject::getNamespaces() - */ const std::set& getNamespaces() const { return m_namespaces; } - /** - * @see XMLObject::addNamespace() - */ void addNamespace(const Namespace& ns) const { if (ns.alwaysDeclare() || m_namespaces.find(ns)==m_namespaces.end()) { m_namespaces.insert(ns); } } - /** - * @see XMLObject::removeNamespace() - */ void removeNamespace(const Namespace& ns) { m_namespaces.erase(ns); } - /** - * @see XMLObject::getSchemaType() - */ const QName* getSchemaType() const { return m_typeQname; } - /** - * @see XMLObject::setSchemaType() - */ void setSchemaType(const QName* type) { delete m_typeQname; m_typeQname = NULL; @@ -89,37 +71,22 @@ namespace xmltooling { } } - /** - * @see XMLObject::hasParent() - */ bool hasParent() const { return m_parent != NULL; } - /** - * @see XMLObject::getParent() - */ XMLObject* getParent() const { return m_parent; } - /** - * @see XMLObject::setParent() - */ void setParent(XMLObject* parent) { m_parent = parent; } - /** - * @see XMLObject::hasChildren() - */ bool hasChildren() const { return !m_children.empty(); } - /** - * @see XMLObject::getOrderedChildren() - */ const std::list& getOrderedChildren() const { return m_children; } @@ -134,6 +101,46 @@ namespace xmltooling { */ AbstractXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL); + /** Copy constructor. */ + AbstractXMLObject(const AbstractXMLObject& src); + + /** + * A helper function for derived classes. + * This 'normalizes' newString, and then if it is different from oldString, + * it invalidates the DOM, frees the old string, and return the new. + * If not different, it frees the new string and just returns the old value. + * + * @param oldValue - the current value + * @param newValue - the new value + * + * @return the value that should be assigned + */ + XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue) { + XMLCh* newString = XMLString::replicate(newValue); + XMLString::trim(newString); + if (!XMLString::equals(oldValue,newValue)) { + releaseThisandParentDOM(); + XMLString::release(&oldValue); + return newString; + } + XMLString::release(&newString); + return oldValue; + } + + /** + * A helper function for derived classes, for assignment of (singleton) XML objects. + * + * It is indifferent to whether either the old or the new version of the value is null. + * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate + * + * @param oldValue - current value + * @param newValue - proposed new value + * @return the value to assign + * + * @throws XMLObjectException if the new child already has a parent. + */ + XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue); + /** * Underlying list of child objects. * Manages the lifetime of the children. diff --git a/xmltooling/DOMCachingXMLObject.h b/xmltooling/DOMCachingXMLObject.h deleted file mode 100644 index 895527d..0000000 --- a/xmltooling/DOMCachingXMLObject.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2001-2006 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file DOMCachingXMLObject.h - * - * An XMLObject that can cached a DOM representation of itself. - */ - -#if !defined(__xmltooling_domxmlobj_h__) -#define __xmltooling_domxmlobj_h__ - -#include -#include - -using namespace xercesc; - -namespace xmltooling { - - /** - * An XMLObject that can cached a DOM representation of itself. - */ - class XMLTOOL_API DOMCachingXMLObject : public virtual XMLObject - { - public: - DOMCachingXMLObject() {} - virtual ~DOMCachingXMLObject() {} - - /** - * Gets the DOM representation of this XMLObject, if one exists. - * - * @return the DOM representation of this XMLObject - */ - virtual DOMElement* getDOM() const=0; - - /** - * Sets the DOM representation of this XMLObject. - * - * @param dom DOM representation of this XMLObject - * @param bindDocument true if the object should take ownership of the associated Document - */ - virtual void setDOM(DOMElement* dom, bool bindDocument=false) const=0; - - /** - * Assigns ownership of a DOM document to the XMLObject. - * This binds the lifetime of the document to the lifetime of the object. - * - * @param doc DOM document bound to this object - */ - virtual void setDocument(DOMDocument* doc) const=0; - - /** - * Releases the DOM representation of this XMLObject, if there is one. - */ - virtual void releaseDOM() const=0; - - /** - * Releases the DOM representation of this XMLObject's parent. - * - * @param propagateRelease true if all ancestors of this element should release their DOM - */ - virtual void releaseParentDOM(bool propagateRelease=true) const=0; - - /** - * Releases the DOM representation of this XMLObject's children. - * - * @param propagateRelease true if all descendants of this element should release their DOM - */ - virtual void releaseChildrenDOM(bool propagateRelease=true) const=0; - }; - -}; - -#endif /* __xmltooling_domxmlobj_h__ */ diff --git a/xmltooling/Makefile.am b/xmltooling/Makefile.am index 4e89a59..d9765bb 100644 --- a/xmltooling/Makefile.am +++ b/xmltooling/Makefile.am @@ -21,7 +21,6 @@ libxmltoolinginclude_HEADERS = \ AttributeExtensibleXMLObject.h \ base.h \ config_pub.h \ - DOMCachingXMLObject.h \ ElementProxy.h \ exceptions.h \ ILockable.h \ @@ -42,6 +41,7 @@ ioinclude_HEADERS = \ io/AbstractXMLObjectUnmarshaller.h \ siginclude_HEADERS = \ + signature/KeyInfo.h \ signature/Signature.h \ signature/SigningContext.h \ signature/VerifyingContext.h @@ -58,11 +58,13 @@ valinclude_HEADERS = \ noinst_HEADERS = \ internal.h \ - signature/impl/XMLSecSignature.h + signature/impl/KeyInfoImpl.h \ + signature/impl/XMLSecSignatureImpl.h \ if BUILD_XMLSEC xmlsec_sources = \ - signature/impl/XMLSecSignature.cpp + signature/impl/KeyInfoImpl.cpp \ + signature/impl/XMLSecSignatureImpl.cpp else xmlsec_sources = endif diff --git a/xmltooling/XMLObject.h b/xmltooling/XMLObject.h index 1624b35..09e72c9 100644 --- a/xmltooling/XMLObject.h +++ b/xmltooling/XMLObject.h @@ -52,10 +52,19 @@ namespace xmltooling { { MAKE_NONCOPYABLE(MarshallingContext); public: + /** + * Default constructor. + */ MarshallingContext() {} ~MarshallingContext() {} #ifndef XMLTOOLING_NO_XMLSEC + /** + * Builds a marshalling context with an initial signature/context pair. + * + * @param sig a signature object + * @param ctx the signing context to associate with the signature + */ MarshallingContext(Signature* sig, const SigningContext* ctx) { m_signingContexts.push_back(std::make_pair(sig,ctx)); } @@ -70,7 +79,6 @@ namespace xmltooling { */ class XMLTOOL_API XMLObject { - MAKE_NONCOPYABLE(XMLObject); public: virtual ~XMLObject() {} @@ -172,6 +180,68 @@ namespace xmltooling { virtual const std::list& getOrderedChildren() const=0; /** + * Gets the DOM representation of this XMLObject, if one exists. + * + * @return the DOM representation of this XMLObject + */ + virtual DOMElement* getDOM() const=0; + + /** + * Sets the DOM representation of this XMLObject. + * + * @param dom DOM representation of this XMLObject + * @param bindDocument true if the object should take ownership of the associated Document + */ + virtual void setDOM(DOMElement* dom, bool bindDocument=false) const=0; + + /** + * Assigns ownership of a DOM document to the XMLObject. + * This binds the lifetime of the document to the lifetime of the object. + * + * @param doc DOM document bound to this object + */ + virtual void setDocument(DOMDocument* doc) const=0; + + /** + * Releases the DOM representation of this XMLObject, if there is one. + */ + virtual void releaseDOM() const=0; + + /** + * Releases the DOM representation of this XMLObject's parent. + * + * @param propagateRelease true if all ancestors of this element should release their DOM + */ + virtual void releaseParentDOM(bool propagateRelease=true) const=0; + + /** + * Releases the DOM representation of this XMLObject's children. + * + * @param propagateRelease true if all descendants of this element should release their DOM + */ + virtual void releaseChildrenDOM(bool propagateRelease=true) const=0; + + /** + * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true). + */ + void releaseThisandParentDOM() const { + if (getDOM()) { + releaseDOM(); + releaseParentDOM(true); + } + } + + /** + * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM(). + */ + void releaseThisAndChildrenDOM() const { + if (getDOM()) { + releaseChildrenDOM(true); + releaseDOM(); + } + } + + /** * Marshalls the XMLObject, and its children, into a DOM element. * If a document is supplied, then it will be used to create the resulting elements. * If the document does not have a Document Element set, then the resulting @@ -219,6 +289,8 @@ namespace xmltooling { protected: XMLObject() {} + private: + XMLObject& operator=(const XMLObject& src); }; #if defined (_MSC_VER) diff --git a/xmltooling/XMLToolingConfig.cpp b/xmltooling/XMLToolingConfig.cpp index a8680be..f4936ad 100644 --- a/xmltooling/XMLToolingConfig.cpp +++ b/xmltooling/XMLToolingConfig.cpp @@ -21,11 +21,17 @@ */ #include "internal.h" + +#define XMLTOOLING_DEFINE_CONSTANTS +#include + #include "exceptions.h" #include "XMLToolingConfig.h" #include "impl/UnknownElement.h" -#include "signature/impl/XMLSecSignature.h" +#include "signature/impl/KeyInfoImpl.h" +#include "signature/impl/XMLSecSignatureImpl.h" #include "util/NDC.h" +#include "util/XMLConstants.h" #ifdef HAVE_DLFCN_H # include @@ -54,7 +60,7 @@ DECL_EXCEPTION_FACTORY(UnknownAttributeException); DECL_EXCEPTION_FACTORY(ValidationException); DECL_EXCEPTION_FACTORY(SignatureException); -namespace { +namespace xmltooling { XMLToolingInternalConfig g_config; } @@ -150,6 +156,7 @@ bool XMLToolingInternalConfig::init() // default registrations XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder()); + XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,KeyInfo::LOCAL_NAME),new KeyInfoBuilderImpl()); #ifndef XMLTOOLING_NO_XMLSEC XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME),new XMLSecSignatureBuilder()); #endif diff --git a/xmltooling/base.h b/xmltooling/base.h index ab86bc7..9aa9bd9 100644 --- a/xmltooling/base.h +++ b/xmltooling/base.h @@ -21,7 +21,7 @@ * Must be included prior to including any other header */ -#if !defined(__xmltooling_base_h__) +#ifndef __xmltooling_base_h__ #define __xmltooling_base_h__ #if defined (_MSC_VER) || defined(__BORLANDC__) @@ -36,7 +36,6 @@ */ // Windows and GCC4 Symbol Visibility Macros - #ifdef WIN32 #define XMLTOOL_IMPORT __declspec(dllimport) #define XMLTOOL_EXPORT __declspec(dllexport) @@ -71,15 +70,131 @@ #define XMLTOOL_EXCEPTIONAPI(api) #endif -// Macro to block copy c'tor and assignment operator for a class +#ifndef NULL +#define NULL 0 +#endif + +/** + * Blocks copy c'tor and assignment operator for a class. + */ #define MAKE_NONCOPYABLE(type) \ private: \ type(const type&); \ type& operator=(const type&); -#ifndef NULL -#define NULL 0 -#endif +/** + * Begins the declaration of an XMLObject specialization. + * Basic boilerplate includes a protected constructor, empty virtual destructor, + * and Unicode constants for the default associated element's name and prefix. + * + * @param cname the name of the class to declare + * @param base the base class to derive from using public virtual inheritance + */ +#define BEGIN_XMLOBJECT(cname,base) \ + class XMLTOOL_API cname : public virtual base, public virtual ValidatingXMLObject { \ + protected: \ + cname() {} \ + public: \ + virtual ~cname() {} \ + /##** Type-specific clone method. */ \ + virtual cname* clone##cname() const=0; \ + /##** Element prefix */ \ + static const XMLCh PREFIX[]; \ + /##** Element local name */ \ + static const XMLCh LOCAL_NAME[] + +/** + * Ends the declaration of an XMLObject specialization. + */ +#define END_XMLOBJECT } + +/** + * Declares abstract get/set methods for a named XML attribute. + * + * @param proper the proper name of the attribute + * @param upcased the upcased name of the attribute + */ +#define DECL_XMLOBJECT_ATTRIB(proper,upcased) \ + /##** proper attribute name */ \ + static const XMLCh upcased##_ATTRIB_NAME[]; \ + /##** Returns the proper attribute. */ \ + virtual const XMLCh* get##proper() const=0; \ + /##** Sets the proper attribute. */ \ + virtual void set##proper(const XMLCh* proper)=0 + +/** + * Implements get/set methods and a private member for a named XML attribute. + * + * @param proper the proper name of the attribute + */ +#define IMPL_XMLOBJECT_ATTRIB(proper) \ + private: \ + XMLCh* m_##proper; \ + public: \ + const XMLCh* get##proper() const { \ + return m_##proper; \ + } \ + void set##proper(const XMLCh* proper) { \ + m_##proper = prepareForAssignment(m_##proper,proper); \ + } + +/** + * Implements cloning methods for an XMLObject specialization implementation class. + * + * @param cname the name of the XMLObject specialization + */ +#define IMPL_XMLOBJECT_CLONE(cname) \ + cname* clone##cname() const { \ + return clone(); \ + } \ + cname* clone() const { \ + auto_ptr domClone(AbstractDOMCachingXMLObject::clone()); \ + cname##Impl* ret=dynamic_cast(domClone.get()); \ + if (ret) { \ + domClone.release(); \ + return ret; \ + } \ + return new cname##Impl(*this); \ + } + +/** + * Begins the declaration of an XMLObjectBuilder specialization. + * Basic boilerplate includes an empty virtual destructor, and + * a default builder. + * + * @param cname the name of the XMLObject specialization + */ +#define BEGIN_XMLOBJECTBUILDER(cname) \ + /##** Builder for cname objects. */ \ + class XMLTOOL_API cname##Builder : public xmltooling::XMLObjectBuilder { \ + public: \ + virtual ~cname##Builder() {} \ + /##** Default builder. */ \ + virtual cname* buildObject() const=0 + +/** + * Ends the declaration of an XMLObjectBuilder specialization. + */ +#define END_XMLOBJECTBUILDER } + +/** + * Begins the declaration of an XMLObjectBuilder specialization implementation class. + * + * @param cname the name of the XMLObject specialization + * @param namespaceURI the XML namespace of the default associated element + */ +#define BEGIN_XMLOBJECTBUILDERIMPL(cname,namespaceURI) \ + class XMLTOOL_DLLLOCAL cname##BuilderImpl : public cname##Builder { \ + public: \ + cname* buildObject(const XMLCh* ns, const XMLCh* name, const XMLCh* prefix=NULL) const; \ + cname* buildObject() const { \ + return buildObject(namespaceURI,cname::LOCAL_NAME,cname::PREFIX); \ + } + +/** + * Ends the declaration of an XMLObjectBuilder specialization implementation class. + */ +#define END_XMLOBJECTBUILDERIMPL } #include @@ -102,7 +217,7 @@ namespace xmltooling { } } - /* + /** * Functor for cleaning up heap objects in containers. */ template struct cleanup @@ -122,7 +237,7 @@ namespace xmltooling { void operator()(const T* ptr) {delete const_cast(ptr);} }; - /* + /** * Functor for cleaning up heap objects in key/value containers. */ template struct cleanup_pair diff --git a/xmltooling/exceptions.h b/xmltooling/exceptions.h index 4d343e5..6e82e1e 100644 --- a/xmltooling/exceptions.h +++ b/xmltooling/exceptions.h @@ -20,7 +20,7 @@ * Exception classes */ -#if !defined(__xmltooling_exceptions_h__) +#ifndef __xmltooling_exceptions_h__ #define __xmltooling_exceptions_h__ #include @@ -34,16 +34,22 @@ * * @param name the exception class * @param base the base class + * @param desc */ -#define DECL_XMLTOOLING_EXCEPTION(name,base) \ +#define DECL_XMLTOOLING_EXCEPTION(name,base,desc) \ + /##** desc */ \ class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \ public: \ + /##** base##::##base(const char*,const xmltooling::params&) */ \ name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \ : xmltooling::base(msg,p) {} \ + /##** base##::##base(const char*,const xmltooling::namedparams&) */ \ name(const char* msg, const xmltooling::namedparams& p) \ : xmltooling::base(msg,p) {} \ + /##** base##::##base(const std::string&,const xmltooling::params&) */ \ name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \ : xmltooling::base(msg,p) {} \ + /##** base##::##base(const std::string&,const xmltooling::namedparams&) */ \ name(const std::string& msg, const xmltooling::namedparams& p) \ : xmltooling::base(msg,p) {} \ virtual ~name() {} \ @@ -102,6 +108,7 @@ namespace xmltooling { const std::vector& get() const {return v;} protected: + /** Contains the parameters being passed. */ std::vector v; }; @@ -124,14 +131,16 @@ namespace xmltooling { namedparams(int count,...); }; + class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException; + + /** A factory function that returns an empty exception object of a given type. */ + typedef XMLToolingException* ExceptionFactory(); + /** * Base exception class, supports parametrized messages and XML serialization. * Parameters are prefixed with a dollar sign ($) and can be positional ($1) * or named ($info). */ - class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException; - typedef XMLToolingException* ExceptionFactory(); - class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException { public: @@ -326,14 +335,14 @@ namespace xmltooling { static ExceptionFactoryMap m_factoryMap; }; - DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException); - DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException); + DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException,Exceptions related to XML parsing); + DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException,Exceptions in basic object usage); + DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException,Exceptions during object marshalling); + DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException,Exceptions during object unmarshalling); + DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException,Exceptions due to processing of unknown element content); + DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException,Exceptions due to processing of unknown attributes); + DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException,Exceptions during object validation); + DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException,Exceptions in signature processing); }; diff --git a/xmltooling/impl/AnyElement.cpp b/xmltooling/impl/AnyElement.cpp index a467741..8ed8a8d 100644 --- a/xmltooling/impl/AnyElement.cpp +++ b/xmltooling/impl/AnyElement.cpp @@ -15,7 +15,7 @@ */ /** - * @file AnyElement.h + * AnyElement.cpp * * Advanced anyType implementation suitable for deep processing of unknown content. */ @@ -47,13 +47,15 @@ namespace xmltooling { /** * Implements a smart wrapper around unknown DOM content. */ - class XMLTOOL_DLLLOCAL AnyElementImpl : public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject, + class XMLTOOL_DLLLOCAL AnyElementImpl : public AbstractDOMCachingXMLObject, + public AbstractElementProxy, public AbstractAttributeExtensibleXMLObject, public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller { public: + virtual ~AnyElementImpl() {} + AnyElementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix) : AbstractXMLObject(nsURI, localName, prefix) {} - virtual ~AnyElementImpl() {} AnyElementImpl* clone() const { auto_ptr domClone(AbstractDOMCachingXMLObject::clone()); @@ -63,18 +65,17 @@ namespace xmltooling { return ret; } - ret=new AnyElementImpl( - getElementQName().getNamespaceURI(),getElementQName().getLocalPart(),getElementQName().getPrefix() - ); - ret->m_namespaces=m_namespaces; - for (map::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) { - ret->m_attributeMap[i->first]=XMLString::replicate(i->second); - } - ret->setTextContent(getTextContent()); - xmltooling::clone(m_children, ret->m_children); - return ret; + return new AnyElementImpl(*this); } + protected: + AnyElementImpl(const AnyElementImpl& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), + AbstractElementProxy(src), AbstractAttributeExtensibleXMLObject(src) { + for (list::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) { + getXMLObjects().push_back((*i) ? (*i)->clone() : NULL); + } + } + void marshallAttributes(DOMElement* domElement) const { for (map::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) { DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart()); diff --git a/xmltooling/impl/AnyElement.h b/xmltooling/impl/AnyElement.h index 8fd619f..27654a0 100644 --- a/xmltooling/impl/AnyElement.h +++ b/xmltooling/impl/AnyElement.h @@ -28,19 +28,13 @@ namespace xmltooling { /** - * Implements a smart wrapper around unknown DOM content. - */ - class XMLTOOL_DLLLOCAL AnyElementImpl; - - /** * Builder for AnyElementImpl objects. + * Use as the default builder when you want to wrap each unknown element and + * process the DOM content through xmltooling interfaces. */ class XMLTOOL_API AnyElementBuilder : public XMLObjectBuilder { public: - /** - * @see XMLObjectBuilder::buildObject(const XMLCh*,const XMLCh*,const XMLCh*) - */ XMLObject* buildObject( const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL ) const; diff --git a/xmltooling/impl/UnknownElement.h b/xmltooling/impl/UnknownElement.h index 0ad445d..dd7f3be 100644 --- a/xmltooling/impl/UnknownElement.h +++ b/xmltooling/impl/UnknownElement.h @@ -37,9 +37,7 @@ namespace xmltooling { - /** - * Implements a thin wrapper around unknown DOM content. - */ + /// @cond off class XMLTOOL_DLLLOCAL UnknownElementImpl : public AbstractDOMCachingXMLObject { public: @@ -67,17 +65,16 @@ namespace xmltooling { void serialize(std::string& s) const; }; - + /// @endcond + /** * Builder for UnknownElementImpl objects. + * Use as the default builder when you want unknown DOM content treated as raw/ignored XML. */ class XMLTOOL_API UnknownElementBuilder : public XMLObjectBuilder { public: - /** - * @see XMLObjectBuilder::buildObject(const XMLCh*,const XMLCh*,const XMLCh*) - */ - UnknownElementImpl* buildObject( + XMLObject* buildObject( const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL ) const { return new UnknownElementImpl(namespaceURI,elementLocalName,namespacePrefix); diff --git a/xmltooling/internal.h b/xmltooling/internal.h index a6c87cb..0be6bdb 100644 --- a/xmltooling/internal.h +++ b/xmltooling/internal.h @@ -46,6 +46,7 @@ namespace xmltooling { + /// @cond OFF class XMLToolingInternalConfig : public xmltooling::XMLToolingConfig { public: @@ -80,6 +81,8 @@ namespace xmltooling { void* m_lock; //PlugManager m_plugMgr; }; + /// @endcond + }; #endif /* __xmltooling_internal_h__ */ diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.h b/xmltooling/io/AbstractXMLObjectMarshaller.h index e7c6647..82d1621 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.h +++ b/xmltooling/io/AbstractXMLObjectMarshaller.h @@ -35,19 +35,13 @@ namespace xmltooling { /** * A thread-safe abstract marshaller. */ - class XMLTOOL_API AbstractXMLObjectMarshaller : public virtual AbstractDOMCachingXMLObject + class XMLTOOL_API AbstractXMLObjectMarshaller : public virtual AbstractXMLObject { public: virtual ~AbstractXMLObjectMarshaller() {} - /** - * @see XMLObject::marshall(DOMDocument*,const MarshallingContext*) - */ DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const; - /** - * @see XMLObject::marshall(DOMElement*,const MarshallingContext*) - */ DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const; protected: diff --git a/xmltooling/io/AbstractXMLObjectUnmarshaller.h b/xmltooling/io/AbstractXMLObjectUnmarshaller.h index b85ce01..0853f15 100644 --- a/xmltooling/io/AbstractXMLObjectUnmarshaller.h +++ b/xmltooling/io/AbstractXMLObjectUnmarshaller.h @@ -35,14 +35,11 @@ namespace xmltooling { /** * A thread-safe abstract unmarshaller. */ - class XMLTOOL_API AbstractXMLObjectUnmarshaller : public virtual AbstractDOMCachingXMLObject + class XMLTOOL_API AbstractXMLObjectUnmarshaller : public virtual AbstractXMLObject { public: virtual ~AbstractXMLObjectUnmarshaller() {} - /** - * @see XMLObject::unmarshall() - */ XMLObject* unmarshall(DOMElement* element, bool bindDocument=false); protected: diff --git a/xmltooling/signature/KeyInfo.h b/xmltooling/signature/KeyInfo.h new file mode 100644 index 0000000..a27ca97 --- /dev/null +++ b/xmltooling/signature/KeyInfo.h @@ -0,0 +1,57 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file KeyInfo.h + * + * XMLObjects representing XML Digital Signature, version 20020212, KeyInfo element + * and related content. + */ + +#ifndef __xmltooling_keyinfo_h__ +#define __xmltooling_keyinfo_h__ + +#include +#include +#include + +namespace xmltooling { + + /** + * XMLObject representing XML Digital Signature, version 20020212, KeyInfo element. + */ + BEGIN_XMLOBJECT(KeyInfo,ElementProxy); + DECL_XMLOBJECT_ATTRIB(Id,ID); + END_XMLOBJECT; + + BEGIN_XMLOBJECTBUILDER(KeyInfo); + END_XMLOBJECTBUILDER; + +#ifdef XMLTOOLING_DEFINE_CONSTANTS + const XMLCh KeyInfo::LOCAL_NAME[] = { + chLatin_K, chLatin_e, chLatin_y, chLatin_I, chLatin_n, chLatin_f, chLatin_o, chNull + }; + const XMLCh KeyInfo::PREFIX[] = { + chLatin_d, chLatin_s, chNull + }; + const XMLCh KeyInfo::ID_ATTRIB_NAME[] = { + chLatin_I, chLatin_d, chNull + }; +#endif + +}; + +#endif /* __xmltooling_keyinfo_h__ */ diff --git a/xmltooling/signature/Signature.h b/xmltooling/signature/Signature.h index 1794722..bf886fc 100644 --- a/xmltooling/signature/Signature.h +++ b/xmltooling/signature/Signature.h @@ -79,6 +79,15 @@ namespace xmltooling { Signature() {} }; +#ifdef XMLTOOLING_DEFINE_CONSTANTS + const XMLCh Signature::LOCAL_NAME[] = { + chLatin_S, chLatin_i, chLatin_g, chLatin_n, chLatin_a, chLatin_t, chLatin_u, chLatin_r, chLatin_e, chNull + }; + const XMLCh Signature::PREFIX[] = { + chLatin_d, chLatin_s, chNull + }; +#endif + /** * Builder for Signature objects. */ @@ -88,7 +97,7 @@ namespace xmltooling { virtual ~SignatureBuilder() {} /** - * Default typed builder method. + * Default builder. */ virtual Signature* buildObject() const=0; }; diff --git a/xmltooling/signature/impl/KeyInfoImpl.cpp b/xmltooling/signature/impl/KeyInfoImpl.cpp new file mode 100644 index 0000000..d49d0ba --- /dev/null +++ b/xmltooling/signature/impl/KeyInfoImpl.cpp @@ -0,0 +1,102 @@ +/* +* Copyright 2001-2006 Internet2 + * +* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * XMLSecSignatureImpl.cpp + * + * Signature class for XMLSec-based signature-handling + */ + +#include "internal.h" +#include "AbstractElementProxy.h" +#include "exceptions.h" +#include "io/AbstractXMLObjectMarshaller.h" +#include "io/AbstractXMLObjectUnmarshaller.h" +#include "signature/impl/KeyInfoImpl.h" +#include "util/NDC.h" +#include "util/XMLHelper.h" +#include "validation/AbstractValidatingXMLObject.h" + +#include + +using namespace xmltooling; +using namespace log4cpp; +using namespace std; + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 4251 ) +#endif + +namespace xmltooling { + + class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo, public AbstractDOMCachingXMLObject, public AbstractElementProxy, + public AbstractValidatingXMLObject, public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller + { + public: + virtual ~KeyInfoImpl() {} + + KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix) + : AbstractXMLObject(nsURI, localName, prefix), m_Id(NULL) {} + + KeyInfoImpl(const KeyInfoImpl& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), + AbstractElementProxy(src), AbstractValidatingXMLObject(src), m_Id(XMLString::replicate(src.m_Id)) { + for (list::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) { + getXMLObjects().push_back((*i) ? (*i)->clone() : NULL); + } + } + + IMPL_XMLOBJECT_ATTRIB(Id); + IMPL_XMLOBJECT_CLONE(KeyInfo); + + protected: + void marshallAttributes(DOMElement* domElement) const { + if(getId()) { + domElement->setAttributeNS(NULL, ID_ATTRIB_NAME, getId()); + domElement->setIdAttributeNS(NULL, ID_ATTRIB_NAME); + } + } + + void marshallElementContent(DOMElement* domElement) const { + if(getTextContent()) { + domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent())); + } + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + getXMLObjects().push_back(childXMLObject); + } + + void processAttribute(const DOMAttr* attribute) { + if (XMLHelper::isNodeNamed(attribute, NULL, ID_ATTRIB_NAME)) + setId(attribute->getValue()); + } + + void processElementContent(const XMLCh* elementContent) { + setTextContent(elementContent); + } + }; + +}; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + +KeyInfo* KeyInfoBuilderImpl::buildObject(const XMLCh* ns, const XMLCh* name, const XMLCh* prefix) const +{ + return new KeyInfoImpl(ns,name,prefix); +} diff --git a/xmltooling/signature/impl/KeyInfoImpl.h b/xmltooling/signature/impl/KeyInfoImpl.h new file mode 100644 index 0000000..98d0ac9 --- /dev/null +++ b/xmltooling/signature/impl/KeyInfoImpl.h @@ -0,0 +1,36 @@ +/* +* Copyright 2001-2006 Internet2 + * +* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * KeyInfoImpl.h + * + * Builder class for KeyInfo + */ + +#ifndef __xmltooling_keyinfoimpl_h__ +#define __xmltooling_keyinfoimpl_h__ + +#include +#include + +namespace xmltooling { + + BEGIN_XMLOBJECTBUILDERIMPL(KeyInfo,XMLConstants::XMLSIG_NS); + END_XMLOBJECTBUILDERIMPL; + +}; + +#endif /* __xmltooling_keyinfoimpl_h__ */ diff --git a/xmltooling/signature/impl/XMLSecSignature.h b/xmltooling/signature/impl/XMLSecSignature.h deleted file mode 100644 index 276bbab..0000000 --- a/xmltooling/signature/impl/XMLSecSignature.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* Copyright 2001-2006 Internet2 - * -* Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * XMLSecSignature.h - * - * Signature classes for XMLSec-based signature-handling - */ - -#if !defined(__xmltooling_xmlsecsig_h__) && !defined(XMLTOOLING_NO_XMLSEC) -#define __xmltooling_xmlsecsig_h__ - -#include "internal.h" -#include "impl/UnknownElement.h" -#include "signature/Signature.h" -#include "util/XMLConstants.h" - -#include - -#if defined (_MSC_VER) - #pragma warning( push ) - #pragma warning( disable : 4250 4251 ) -#endif - -namespace xmltooling { - - class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature - { - public: - XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME, XMLConstants::XMLSIG_PREFIX), - m_signature(NULL), m_c14n(NULL), m_sm(NULL) {} - virtual ~XMLSecSignatureImpl(); - - void releaseDOM(); - XMLObject* clone() const; - - DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const; - DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const; - XMLObject* unmarshall(DOMElement* element, bool bindDocument=false); - - // Getters - const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; } - const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; } - - // Setters - void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); } - void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); } - - void sign(const SigningContext& ctx); - void verify(const VerifyingContext& ctx) const; - - private: - mutable DSIGSignature* m_signature; - XMLCh* m_c14n; - XMLCh* m_sm; - }; - - class XMLTOOL_DLLLOCAL XMLSecSignatureBuilder : public virtual XMLObjectBuilder - { - public: - XMLSecSignatureImpl* buildObject( - const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix=NULL - ) const { - if (!XMLString::equals(namespaceURI,XMLConstants::XMLSIG_NS) || !XMLString::equals(elementLocalName, Signature::LOCAL_NAME)) - throw XMLObjectException("XMLSecSignatureBuilder requires standard Signature element name."); - return buildObject(); - } - - XMLSecSignatureImpl* buildObject() const { - return new XMLSecSignatureImpl(); - } - }; - -}; - -#if defined (_MSC_VER) - #pragma warning( pop ) -#endif - -#endif /* __xmltooling_xmlsecsig_h__ */ diff --git a/xmltooling/signature/impl/XMLSecSignature.cpp b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp similarity index 83% rename from xmltooling/signature/impl/XMLSecSignature.cpp rename to xmltooling/signature/impl/XMLSecSignatureImpl.cpp index 7034ca3..afb65d9 100644 --- a/xmltooling/signature/impl/XMLSecSignature.cpp +++ b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp @@ -15,21 +15,22 @@ */ /** - * XMLSecSignature.cpp + * XMLSecSignatureImpl.cpp * - * Signature classes for XMLSec-based signature-handling + * Signature class for XMLSec-based signature-handling */ #include "internal.h" #include "exceptions.h" -#include "signature/impl/XMLSecSignature.h" +#include "impl/UnknownElement.h" +#include "signature/impl/XMLSecSignatureImpl.h" #include "util/NDC.h" +#include "util/XMLConstants.h" #include "util/XMLHelper.h" #include #include #include -#include #include #include #include @@ -38,13 +39,49 @@ using namespace xmltooling; using namespace log4cpp; using namespace std; -const XMLCh xmltooling::Signature::LOCAL_NAME[] = { - chLatin_S, chLatin_i, chLatin_g, chLatin_n, chLatin_a, chLatin_t, chLatin_u, chLatin_r, chLatin_e, chNull -}; +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 4251 ) +#endif + +namespace xmltooling { + + class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature + { + public: + XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME, XMLConstants::XMLSIG_PREFIX), + m_signature(NULL), m_c14n(NULL), m_sm(NULL) {} + virtual ~XMLSecSignatureImpl(); + + void releaseDOM(); + XMLObject* clone() const; -const XMLCh xmltooling::Signature::PREFIX[] = { - chLatin_d, chLatin_s, chNull -}; + DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const; + DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const; + XMLObject* unmarshall(DOMElement* element, bool bindDocument=false); + + // Getters + const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; } + const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; } + + // Setters + void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); } + void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); } + + void sign(const SigningContext& ctx); + void verify(const VerifyingContext& ctx) const; + + private: + mutable DSIGSignature* m_signature; + XMLCh* m_c14n; + XMLCh* m_sm; + }; + +}; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif XMLSecSignatureImpl::~XMLSecSignatureImpl() { @@ -363,3 +400,15 @@ XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocumen setDOM(element, bindDocument); return this; } + +Signature* XMLSecSignatureBuilder::buildObject(const XMLCh* ns, const XMLCh* name, const XMLCh* prefix) const +{ + if (!XMLString::equals(ns,XMLConstants::XMLSIG_NS) || !XMLString::equals(name,Signature::LOCAL_NAME)) + throw XMLObjectException("XMLSecSignatureBuilder requires standard Signature element name."); + return buildObject(); +} + +Signature* XMLSecSignatureBuilder::buildObject() const +{ + return new XMLSecSignatureImpl(); +} diff --git a/xmltooling/signature/impl/XMLSecSignatureImpl.h b/xmltooling/signature/impl/XMLSecSignatureImpl.h new file mode 100644 index 0000000..6bcc4eb --- /dev/null +++ b/xmltooling/signature/impl/XMLSecSignatureImpl.h @@ -0,0 +1,39 @@ +/* +* Copyright 2001-2006 Internet2 + * +* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * XMLSecSignatureImpl.h + * + * Builder class for XMLSec-based signature-handling + */ + +#if !defined(__xmltooling_xmlsecsig_h__) && !defined(XMLTOOLING_NO_XMLSEC) +#define __xmltooling_xmlsecsig_h__ + +#include + +namespace xmltooling { + + class XMLTOOL_DLLLOCAL XMLSecSignatureBuilder : public SignatureBuilder + { + public: + Signature* buildObject(const XMLCh* ns, const XMLCh* name, const XMLCh* prefix=NULL) const; + Signature* buildObject() const; + }; + +}; + +#endif /* __xmltooling_xmlsecsig_h__ */ diff --git a/xmltooling/util/ParserPool.h b/xmltooling/util/ParserPool.h index a15b6de..34fbdd9 100644 --- a/xmltooling/util/ParserPool.h +++ b/xmltooling/util/ParserPool.h @@ -94,7 +94,7 @@ namespace xmltooling { */ bool loadCatalog(const XMLCh* pathname); - /* + /** * Load a schema explicitly from a local file. * * Note that "successful processing" does not imply that the schema is valid, @@ -147,7 +147,10 @@ namespace xmltooling { * @param systemId optional system identifier to attach to the stream */ StreamInputSource(std::istream& is, const char* systemId=NULL) : InputSource(systemId), m_is(is) {} + /// @cond off virtual BinInputStream* makeStream() const { return new StreamBinInputStream(m_is); } + /// @endcond + private: std::istream& m_is; diff --git a/xmltooling/util/XMLObjectChildrenList.h b/xmltooling/util/XMLObjectChildrenList.h index 9de1579..32dd9d7 100644 --- a/xmltooling/util/XMLObjectChildrenList.h +++ b/xmltooling/util/XMLObjectChildrenList.h @@ -20,14 +20,30 @@ * STL-compatible container wrapper */ -#if !defined(__xmltooling_list_h__) +#ifndef __xmltooling_list_h__ #define __xmltooling_list_h__ -#include #include +/** + * Shorthand for an XMLObjectChildrenList wrapped around a vector + * + * @param type the type of object in the vector + */ #define VectorOf(type) xmltooling::XMLObjectChildrenList< std::vector > + +/** + * Shorthand for an XMLObjectChildrenList wrapped around a list + * + * @param type the type of object in the list + */ #define ListOf(type) xmltooling::XMLObjectChildrenList< std::list > + +/** + * Shorthand for an XMLObjectChildrenList wrapped around a deque + * + * @param type the type of object in the deque + */ #define DequeOf(type) xmltooling::XMLObjectChildrenList< std::deque > namespace xmltooling { @@ -42,6 +58,7 @@ namespace xmltooling { template class XMLObjectChildrenIterator { + /// @cond OFF typename _Ty::iterator m_iter; template friend class XMLObjectChildrenList; public: @@ -135,6 +152,7 @@ namespace xmltooling { // test for iterator inequality return (!(m_iter == _Right.m_iter)); } + /// @endcond }; /** @@ -151,6 +169,7 @@ namespace xmltooling { XMLObject* m_parent; public: + /// @cond OFF typedef typename Container::value_type value_type; typedef typename Container::reference reference; typedef typename Container::const_reference const_reference; @@ -160,6 +179,7 @@ namespace xmltooling { // We override the iterator types with our constrained wrapper. typedef XMLObjectChildrenIterator iterator; typedef XMLObjectChildrenIterator const_iterator; + /// @endcond /** * Constructor to expose a typed collection of children backed by a list of a base type. @@ -177,6 +197,8 @@ namespace xmltooling { ) : m_parent(parent), m_container(sublist), m_list(backing), m_fence(ins_fence) { } + /// @cond OFF + size_type size() const { // return length of sequence return m_container.size(); @@ -263,20 +285,14 @@ namespace xmltooling { if (_Val->getParent()) throw XMLObjectException("Child object already has a parent."); _Val->setParent(m_parent); - DOMCachingXMLObject* dc=dynamic_cast(_Val); - if (dc) { - dc->releaseParentDOM(true); - } + _Val->releaseParentDOM(true); } void removeParent(const_reference _Val) { if (_Val->getParent()!=m_parent) throw XMLObjectException("Child object not owned by this parent."); _Val->setParent(NULL); - DOMCachingXMLObject* dc=dynamic_cast(m_parent); - if (dc) { - dc->releaseParentDOM(true); - } + m_parent->releaseParentDOM(true); } void removeChild(const_reference _Val) { @@ -288,6 +304,7 @@ namespace xmltooling { } } } + /// @endcond }; }; diff --git a/xmltooling/validation/AbstractValidatingXMLObject.cpp b/xmltooling/validation/AbstractValidatingXMLObject.cpp index 78f5cbb..fb2bfde 100644 --- a/xmltooling/validation/AbstractValidatingXMLObject.cpp +++ b/xmltooling/validation/AbstractValidatingXMLObject.cpp @@ -35,6 +35,14 @@ AbstractValidatingXMLObject::ValidatorWrapper::~ValidatorWrapper() for_each(v.begin(),v.end(),cleanup()); } +AbstractValidatingXMLObject::AbstractValidatingXMLObject(const AbstractValidatingXMLObject& src) : AbstractXMLObject(src) +{ + if (src.m_validators) { + m_validators=new ValidatorWrapper(); + xmltooling::clone(src.m_validators->v,m_validators->v); + } +} + AbstractValidatingXMLObject::~AbstractValidatingXMLObject() { delete m_validators; diff --git a/xmltooling/validation/AbstractValidatingXMLObject.h b/xmltooling/validation/AbstractValidatingXMLObject.h index 2e8d27b..0eda2c6 100644 --- a/xmltooling/validation/AbstractValidatingXMLObject.h +++ b/xmltooling/validation/AbstractValidatingXMLObject.h @@ -59,6 +59,9 @@ namespace xmltooling { protected: AbstractValidatingXMLObject() : m_validators(NULL) {} + /** Copy constructor. */ + AbstractValidatingXMLObject(const AbstractValidatingXMLObject& src); + private: struct XMLTOOL_DLLLOCAL ValidatorWrapper { ~ValidatorWrapper(); diff --git a/xmltooling/validation/Validator.h b/xmltooling/validation/Validator.h index 0734030..6962bb8 100644 --- a/xmltooling/validation/Validator.h +++ b/xmltooling/validation/Validator.h @@ -55,6 +55,13 @@ namespace xmltooling { virtual void validate(const XMLObject* xmlObject) const=0; /** + * Returns a copy of the validator. + * + * @return the new validator + */ + virtual Validator* clone() const=0; + + /** * Evaluates the registered validators against the given XMLObject and it's children. * * @param xmlObject the XMLObject tree to validate diff --git a/xmltooling/version.h b/xmltooling/version.h index adf0181..21bc63b 100644 --- a/xmltooling/version.h +++ b/xmltooling/version.h @@ -15,7 +15,7 @@ */ /** - * @file version.h + * version.h * * Library version macros and constants */ diff --git a/xmltooling/xmltooling.vcproj b/xmltooling/xmltooling.vcproj index d095368..14d79d6 100644 --- a/xmltooling/xmltooling.vcproj +++ b/xmltooling/xmltooling.vcproj @@ -284,7 +284,11 @@ Name="impl" > + + @@ -324,10 +328,6 @@ > - - @@ -454,7 +454,11 @@ Name="impl" > + + diff --git a/xmltoolingtest/UnmarshallingTest.h b/xmltoolingtest/UnmarshallingTest.h index fe8487b..248671d 100644 --- a/xmltoolingtest/UnmarshallingTest.h +++ b/xmltoolingtest/UnmarshallingTest.h @@ -130,6 +130,30 @@ public: TSM_ASSERT_EQUALS("Child's schema type was not expected value", m_qtype, *(kids.back()->getSchemaType())); } + void testUnmarshallingWithClone() { + TS_TRACE("testUnmarshallingWithClone"); + + string path=data_path + "SimpleXMLObjectWithChildren.xml"; + ifstream fs(path.c_str()); + DOMDocument* doc=nonvalidatingPool->parse(fs); + TS_ASSERT(doc!=NULL); + + const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement()); + TS_ASSERT(b!=NULL); + + auto_ptr sxObject( + dynamic_cast(b->buildFromDocument(doc)) + ); + TS_ASSERT(sxObject.get()!=NULL); + + sxObject->releaseThisAndChildrenDOM(); + auto_ptr clonedObject(sxObject->clone()); + + VectorOf(SimpleXMLObject) kids=clonedObject->getSimpleXMLObjects(); + TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size()); + TSM_ASSERT_EQUALS("Child's schema type was not expected value", m_qtype, *(kids.back()->getSchemaType())); + } + void testUnmarshallingWithUnknownChild() { TS_TRACE("testUnmarshallingWithUnknownChild"); diff --git a/xmltoolingtest/XMLObjectBaseTestCase.h b/xmltoolingtest/XMLObjectBaseTestCase.h index f59c1a3..f74e9a5 100644 --- a/xmltoolingtest/XMLObjectBaseTestCase.h +++ b/xmltoolingtest/XMLObjectBaseTestCase.h @@ -43,8 +43,21 @@ extern string data_path; #pragma warning( disable : 4250 4251 ) #endif -class SimpleXMLObject : public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller +class SimpleXMLObject : public AbstractDOMCachingXMLObject, public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller { +protected: + SimpleXMLObject(const SimpleXMLObject& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), + m_id(XMLString::replicate(src.m_id)), m_value(XMLString::replicate(src.m_value)) { +#ifndef XMLTOOLING_NO_XMLSEC + m_children.push_back(NULL); + m_signature=m_children.begin(); +#endif + VectorOf(SimpleXMLObject) mine=getSimpleXMLObjects(); + for (vector::const_iterator i=src.m_simples.begin(); i!=src.m_simples.end(); i++) { + mine.push_back((*i) ? (*i)->clone() : NULL); + } + } + public: static const XMLCh NAMESPACE[]; static const XMLCh NAMESPACE_PREFIX[]; @@ -66,7 +79,18 @@ public: XMLString::release(&m_id); XMLString::release(&m_value); } - + + SimpleXMLObject* clone() const { + auto_ptr domClone(AbstractDOMCachingXMLObject::clone()); + SimpleXMLObject* ret=dynamic_cast(domClone.get()); + if (ret) { + domClone.release(); + return ret; + } + + return new SimpleXMLObject(*this); + } + const XMLCh* getId() const { return m_id; } void setId(const XMLCh* id) { m_id=prepareForAssignment(m_id,id); } @@ -86,23 +110,8 @@ public: VectorOf(SimpleXMLObject) getSimpleXMLObjects() { return VectorOf(SimpleXMLObject)(this, m_simples, &m_children, m_children.end()); } - - SimpleXMLObject* clone() const { - auto_ptr domClone(AbstractDOMCachingXMLObject::clone()); - SimpleXMLObject* ret=dynamic_cast(domClone.get()); - if (ret) { - domClone.release(); - return ret; - } - - ret=new SimpleXMLObject(); - ret->m_namespaces=m_namespaces; - ret->setId(m_id); - ret->setValue(m_value); - xmltooling::clone(m_children, ret->m_children); - return ret; - } +protected: void marshallAttributes(DOMElement* domElement) const { if(getId()) { domElement->setAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME, getId());