From: cantor Date: Mon, 20 Feb 2006 04:30:32 +0000 (+0000) Subject: Initial DOM handling interfaces. X-Git-Tag: 1.4.1~809 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fxmltooling.git;a=commitdiff_plain;h=979cfca4c3a64aa447576146aea4b62ca4c35182 Initial DOM handling interfaces. git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/trunk@14 de75baf8-a10c-0410-a50a-987c0e22f00f --- diff --git a/xmltooling/AbstractDOMCachingXMLObject.cpp b/xmltooling/AbstractDOMCachingXMLObject.cpp new file mode 100644 index 0000000..0b9f064 --- /dev/null +++ b/xmltooling/AbstractDOMCachingXMLObject.cpp @@ -0,0 +1,120 @@ +/* + * 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. + */ + +/** + * AbstractDOMCachingXMLObject.cpp + * + * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. + */ + +#include "internal.h" +#include "exceptions.h" +#include "AbstractDOMCachingXMLObject.h" + +#include +#include +#include + +using namespace xmltooling; +using namespace log4cpp; +using namespace std; + +AbstractDOMCachingXMLObject::~AbstractDOMCachingXMLObject() +{ + if (m_document) + m_document->release(); +} + +void AbstractDOMCachingXMLObject::releaseDOM() +{ + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM"); + if (log.isDebugEnabled()) + log.debug("Releasing cached DOM reprsentation for %s", getElementQName().toString().c_str()); + + // We don't get rid of the document we're holding, if any. + // The marshalling process deals with that. + setDOM(NULL); +} + +void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease) +{ + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM"); + if (log.isDebugEnabled()) { + log.debug( + "Releasing cached DOM representation for parent of %s with propagation set to %s", + getElementQName().toString().c_str(), propagateRelease ? "true" : "false" + ); + } + + DOMCachingXMLObject* domCachingParent = dynamic_cast(getParent()); + if (domCachingParent) { + domCachingParent->releaseDOM(); + if (propagateRelease) + domCachingParent->releaseParentDOM(propagateRelease); + } +} + +class _release : public binary_function { +public: + void operator()(XMLObject* obj, bool propagate) const { + DOMCachingXMLObject* domCachingParent = dynamic_cast(obj); + if (domCachingParent) { + domCachingParent->releaseDOM(); + if (propagate) + domCachingParent->releaseChildrenDOM(propagate); + } + } +}; + +void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease) +{ + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM"); + if (log.isDebugEnabled()) { + log.debug( + "Releasing cached DOM representation for children of %s with propagation set to %s", + getElementQName().toString().c_str(), propagateRelease ? "true" : "false" + ); + } + + vector children; + if (getOrderedChildren(children)) + for_each(children.begin(),children.end(),bind2nd(_release(),propagateRelease)); +} + +XMLObject* AbstractDOMCachingXMLObject::prepareForAssignment(const 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 new file mode 100644 index 0000000..dc57831 --- /dev/null +++ b/xmltooling/AbstractDOMCachingXMLObject.h @@ -0,0 +1,153 @@ +/* + * 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 AbstractDOMCachingXMLObject.h + * + * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. + */ + +#if !defined(__xmltooling_abstractdomxmlobj_h__) +#define __xmltooling_abstractdomxmlobj_h__ + +#include +#include + +#pragma warning( push ) +#pragma warning( disable : 4250 4251 ) + +namespace xmltooling { + + /** + * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. + */ + class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject, public virtual DOMCachingXMLObject + { + public: + virtual ~AbstractDOMCachingXMLObject(); + + /** + * @see DOMCachingXMLObject::getDOM() + */ + const DOMElement* getDOM() const { + return m_dom; + } + + /** + * @see DOMCachingXMLObject::setDOM() + */ + void setDOM(DOMElement* dom) { + m_dom=dom; + } + + /** + * @see DOMCachingXMLObject::setDocument() + */ + DOMDocument* setDocument(DOMDocument* doc) { + DOMDocument* ret=m_document; + m_document=doc; + return ret; + } + + /** + * @see DOMCachingXMLObject::releaseDOM() + */ + void releaseDOM(); + + /** + * @see DOMCachingXMLObject::releaseParentDOM() + */ + void releaseParentDOM(bool propagateRelease=true); + + /** + * @see DOMCachingXMLObject::releaseChildrenDOM() + */ + void releaseChildrenDOM(bool propagateRelease=true); + + /** + * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true). + */ + void releaseThisandParentDOM() { + if (m_dom) { + releaseDOM(); + releaseParentDOM(true); + } + } + + /** + * A convenience method that is equal to calling releaseDOM() then releaseChildrenDOM(true). + */ + void releaseThisAndChildrenDOM() { + if (m_dom) { + releaseDOM(); + releaseChildrenDOM(true); + } + } + + protected: + /** + * A helper function for derived classes. + * This 'normalizes' newString and then if it is different from oldString + * invalidates the DOM. It returns the normalized value. + * + * @param oldValue - the current value + * @param newValue - the new value + * + * @return the value that should be assigned + */ + XMLCh* prepareForAssignment(const XMLCh* oldValue, const XMLCh* newValue) { + XMLCh* newString = XMLString::replicate(newValue); + XMLString::trim(newString); + + if (oldValue && !newValue || !oldValue && newValue || XMLString::compareString(oldValue,newValue)) + releaseThisandParentDOM(); + + return newString; + } + + /** + * 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 to the saved Object. + * + * @throws IllegalArgumentException if the child already has a parent. + */ + XMLObject* prepareForAssignment(const XMLObject* oldValue, XMLObject* newValue); + + /** + * Constructor + * + * @param namespaceURI the namespace the element is in + * @param elementLocalName the local name of the XML element this Object represents + */ + explicit AbstractDOMCachingXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName) + : AbstractXMLObject(namespaceURI,elementLocalName), m_dom(NULL), m_document(NULL) {} + + private: + DOMElement* m_dom; + DOMDocument* m_document; + }; + +}; + +#pragma warning( pop ) + +#endif /* __xmltooling_abstractdomxmlobj_h__ */ diff --git a/xmltooling/AbstractXMLObject.h b/xmltooling/AbstractXMLObject.h new file mode 100644 index 0000000..b4f7788 --- /dev/null +++ b/xmltooling/AbstractXMLObject.h @@ -0,0 +1,139 @@ +/* +* 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 AbstractXMLObject.h + * + * An abstract implementation of XMLObject. + */ + +#if !defined(__xmltooling_abstractxmlobj_h__) +#define __xmltooling_abstractxmlobj_h__ + +#include + +#pragma warning( push ) +#pragma warning( disable : 4250 4251 ) + +namespace xmltooling { + + /** + * An abstract implementation of XMLObject. + */ + class XMLTOOL_API AbstractXMLObject : public virtual XMLObject + { + public: + virtual ~AbstractXMLObject() { + delete m_typeQname; + } + + /** + * @see XMLObject::getElementQName() + */ + const QName& getElementQName() const { + return m_elementQname; + } + + /** + * @see XMLObject::setElementNamespacePrefix() + */ + void setElementNamespacePrefix(const XMLCh* prefix) { + m_elementQname.setPrefix(prefix); + } + + /** + * @see XMLObject::getNamespaces() + */ + const std::set& getNamespaces() const { + return m_namespaces; + } + + /** + * @see XMLObject::addNamespace() + */ + void addNamespace(const Namespace& ns) { + 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; + if (type) { + m_typeQname = new QName(*type); + addNamespace(Namespace(type->getNamespaceURI(), type->getPrefix())); + } + } + + /** + * @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; + } + + protected: + /** + * Constructor + * + * @param namespaceURI the namespace the element is in + * @param elementLocalName the local name of the XML element this Object represents + */ + explicit AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName) + : m_elementQname(namespaceURI,elementLocalName), m_typeQname(NULL), m_parent(NULL) {} + + private: + XMLObject* m_parent; + QName m_elementQname; + QName* m_typeQname; + std::set m_namespaces; + }; + +}; + +#pragma warning( pop ) + +#endif /* __xmltooling_abstractxmlobj_h__ */ diff --git a/xmltooling/AbstractXMLObjectBuilder.h b/xmltooling/AbstractXMLObjectBuilder.h new file mode 100644 index 0000000..f5aba64 --- /dev/null +++ b/xmltooling/AbstractXMLObjectBuilder.h @@ -0,0 +1,58 @@ +/* + * 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 AbstractXMLObjectBuilder.h + * + * Factory interface for XMLObjects + */ + +#if !defined(__xmltooling_abstractxmlobjbuilder_h__) +#define __xmltooling_abstractxmlobjbuilder_h__ + +#include + +namespace xmltooling { + + /** + * Base implementation of XMLObjectBuilder that automatically + * invokes resetState() after the XMLObject is built. + */ + class XMLTOOL_API AbstractXMLObjectBuilder : public virtual XMLObjectBuilder + { + public: + virtual ~AbstractXMLObjectBuilder() {} + + /** + * @see XMLObjectBuilder::buildObject() + */ + XMLObject* buildObject() { + XMLObject* builtObject = doBuildObject(); + resetState(); + return builtObject; + } + + /** + * Delegated call that builds the XMLObject prior to a state reset. + * + * @return the built XMLObject + */ + virtual XMLObject* doBuildObject()=0; + }; + +}; + +#endif /* __xmltooling_abstractxmlobjbuilder_h__ */ diff --git a/xmltooling/DOMCachingXMLObject.h b/xmltooling/DOMCachingXMLObject.h new file mode 100644 index 0000000..b850531 --- /dev/null +++ b/xmltooling/DOMCachingXMLObject.h @@ -0,0 +1,86 @@ +/* + * 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 const DOMElement* getDOM() const=0; + + /** + * Sets the DOM representation of this XMLObject. + * + * @param dom DOM representation of this XMLObject + */ + virtual void setDOM(DOMElement* dom)=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 DOMDocument* setDocument(DOMDocument* doc)=0; + + /** + * Releases the DOM representation of this XMLObject, if there is one. + */ + virtual void releaseDOM()=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)=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)=0; + }; + +}; + +#endif /* __xmltooling_domxmlobj_h__ */ diff --git a/xmltooling/Makefile.am b/xmltooling/Makefile.am index 7d896fa..d949703 100644 --- a/xmltooling/Makefile.am +++ b/xmltooling/Makefile.am @@ -6,8 +6,12 @@ libxmltoolingincludedir = \ $(includedir)/xmltooling libxmltoolinginclude_HEADERS = \ + AbstractDOMCachingXMLObject.h \ + AbstractXMLObject.h \ + AbstractXMLObjectBuilder.h \ base.h \ config_pub.h \ + DOMCachingXMLObject.h \ exceptions.h \ ILockable.h \ Namespace.h \ @@ -31,6 +35,7 @@ noinst_HEADERS = \ internal.h libxmltooling_la_SOURCES = \ + AbstractDOMCachingXMLObject.cpp \ Namespace.cpp \ QName.cpp \ unicode.cpp \ diff --git a/xmltooling/XMLObject.h b/xmltooling/XMLObject.h index a16b325..5ed3363 100644 --- a/xmltooling/XMLObject.h +++ b/xmltooling/XMLObject.h @@ -37,6 +37,7 @@ namespace xmltooling { { MAKE_NONCOPYABLE(XMLObject); public: + XMLObject() {} virtual ~XMLObject() {} /** diff --git a/xmltooling/XMLObjectBuilder.h b/xmltooling/XMLObjectBuilder.h index c562cf4..50842b7 100644 --- a/xmltooling/XMLObjectBuilder.h +++ b/xmltooling/XMLObjectBuilder.h @@ -42,7 +42,7 @@ namespace xmltooling { * * @return the empty XMLObject */ - XMLObject* buildObject() const; + virtual XMLObject* buildObject()=0; /** * Resets the state of the builder. @@ -50,7 +50,7 @@ namespace xmltooling { * This normally means null'ing out any properties that were * needed to build an object. */ - void resetState(); + virtual void resetState()=0; }; }; diff --git a/xmltooling/exceptions.h b/xmltooling/exceptions.h index 79a06f7..dcfc84e 100644 --- a/xmltooling/exceptions.h +++ b/xmltooling/exceptions.h @@ -54,6 +54,7 @@ namespace xmltooling { }; DECL_XMLTOOLING_EXCEPTION(XMLParserException); + DECL_XMLTOOLING_EXCEPTION(XMLObjectException); }; diff --git a/xmltooling/xmltooling.vcproj b/xmltooling/xmltooling.vcproj index 4cbaf0c..c5c9826 100644 --- a/xmltooling/xmltooling.vcproj +++ b/xmltooling/xmltooling.vcproj @@ -182,6 +182,10 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -224,6 +228,18 @@ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + + + + + @@ -232,6 +248,10 @@ > + +