--- /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
+ * AbstractDOMCachingXMLObject.cpp\r
+ * \r
+ * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. \r
+ */\r
+\r
+#include "internal.h"\r
+#include "exceptions.h"\r
+#include "AbstractDOMCachingXMLObject.h"\r
+\r
+#include <algorithm>\r
+#include <functional>\r
+#include <log4cpp/Category.hh>\r
+\r
+using namespace xmltooling;\r
+using namespace log4cpp;\r
+using namespace std;\r
+\r
+AbstractDOMCachingXMLObject::~AbstractDOMCachingXMLObject()\r
+{\r
+ if (m_document)\r
+ m_document->release();\r
+}\r
+\r
+void AbstractDOMCachingXMLObject::releaseDOM()\r
+{\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
+ if (log.isDebugEnabled())\r
+ log.debug("Releasing cached DOM reprsentation for %s", getElementQName().toString().c_str());\r
+\r
+ // We don't get rid of the document we're holding, if any.\r
+ // The marshalling process deals with that.\r
+ setDOM(NULL);\r
+}\r
+\r
+void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease)\r
+{\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
+ if (log.isDebugEnabled()) {\r
+ log.debug(\r
+ "Releasing cached DOM representation for parent of %s with propagation set to %s",\r
+ getElementQName().toString().c_str(), propagateRelease ? "true" : "false"\r
+ );\r
+ }\r
+\r
+ DOMCachingXMLObject* domCachingParent = dynamic_cast<DOMCachingXMLObject*>(getParent());\r
+ if (domCachingParent) {\r
+ domCachingParent->releaseDOM();\r
+ if (propagateRelease)\r
+ domCachingParent->releaseParentDOM(propagateRelease);\r
+ }\r
+}\r
+\r
+class _release : public binary_function<XMLObject*,bool,void> {\r
+public:\r
+ void operator()(XMLObject* obj, bool propagate) const {\r
+ DOMCachingXMLObject* domCachingParent = dynamic_cast<DOMCachingXMLObject*>(obj);\r
+ if (domCachingParent) {\r
+ domCachingParent->releaseDOM();\r
+ if (propagate)\r
+ domCachingParent->releaseChildrenDOM(propagate);\r
+ }\r
+ }\r
+};\r
+\r
+void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease)\r
+{\r
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
+ if (log.isDebugEnabled()) {\r
+ log.debug(\r
+ "Releasing cached DOM representation for children of %s with propagation set to %s",\r
+ getElementQName().toString().c_str(), propagateRelease ? "true" : "false"\r
+ );\r
+ }\r
+ \r
+ vector<XMLObject*> children;\r
+ if (getOrderedChildren(children))\r
+ for_each(children.begin(),children.end(),bind2nd(_release(),propagateRelease));\r
+}\r
+\r
+XMLObject* AbstractDOMCachingXMLObject::prepareForAssignment(const XMLObject* oldValue, XMLObject* newValue) {\r
+\r
+ if (newValue && newValue->hasParent())\r
+ throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");\r
+\r
+ if (!oldValue) {\r
+ if (newValue) {\r
+ releaseThisandParentDOM();\r
+ newValue->setParent(this);\r
+ return newValue;\r
+ }\r
+ else {\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ if (oldValue != newValue) {\r
+ delete oldValue;\r
+ releaseThisandParentDOM();\r
+ newValue->setParent(this);\r
+ }\r
+\r
+ return newValue;\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 AbstractDOMCachingXMLObject.h\r
+ * \r
+ * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. \r
+ */\r
+\r
+#if !defined(__xmltooling_abstractdomxmlobj_h__)\r
+#define __xmltooling_abstractdomxmlobj_h__\r
+\r
+#include <xmltooling/AbstractXMLObject.h>\r
+#include <xmltooling/DOMCachingXMLObject.h>\r
+\r
+#pragma warning( push )\r
+#pragma warning( disable : 4250 4251 )\r
+\r
+namespace xmltooling {\r
+\r
+ /**\r
+ * Extension of AbstractXMLObject that implements a DOMCachingXMLObject.\r
+ */\r
+ class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject, public virtual DOMCachingXMLObject\r
+ {\r
+ public:\r
+ virtual ~AbstractDOMCachingXMLObject();\r
+ \r
+ /**\r
+ * @see DOMCachingXMLObject::getDOM()\r
+ */\r
+ const DOMElement* getDOM() const {\r
+ return m_dom;\r
+ }\r
+ \r
+ /**\r
+ * @see DOMCachingXMLObject::setDOM()\r
+ */\r
+ void setDOM(DOMElement* dom) {\r
+ m_dom=dom;\r
+ }\r
+ \r
+ /**\r
+ * @see DOMCachingXMLObject::setDocument()\r
+ */\r
+ DOMDocument* setDocument(DOMDocument* doc) {\r
+ DOMDocument* ret=m_document;\r
+ m_document=doc;\r
+ return ret;\r
+ }\r
+ \r
+ /**\r
+ * @see DOMCachingXMLObject::releaseDOM()\r
+ */\r
+ void releaseDOM();\r
+ \r
+ /**\r
+ * @see DOMCachingXMLObject::releaseParentDOM()\r
+ */\r
+ void releaseParentDOM(bool propagateRelease=true);\r
+ \r
+ /**\r
+ * @see DOMCachingXMLObject::releaseChildrenDOM()\r
+ */\r
+ void releaseChildrenDOM(bool propagateRelease=true);\r
+ \r
+ /**\r
+ * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).\r
+ */\r
+ void releaseThisandParentDOM() {\r
+ if (m_dom) {\r
+ releaseDOM();\r
+ releaseParentDOM(true);\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * A convenience method that is equal to calling releaseDOM() then releaseChildrenDOM(true).\r
+ */\r
+ void releaseThisAndChildrenDOM() {\r
+ if (m_dom) {\r
+ releaseDOM();\r
+ releaseChildrenDOM(true);\r
+ }\r
+ }\r
+ \r
+ protected:\r
+ /**\r
+ * A helper function for derived classes.\r
+ * This 'normalizes' newString and then if it is different from oldString\r
+ * invalidates the DOM. It returns the normalized value.\r
+ * \r
+ * @param oldValue - the current value\r
+ * @param newValue - the new value\r
+ * \r
+ * @return the value that should be assigned\r
+ */\r
+ XMLCh* prepareForAssignment(const XMLCh* oldValue, const XMLCh* newValue) {\r
+ XMLCh* newString = XMLString::replicate(newValue);\r
+ XMLString::trim(newString);\r
+\r
+ if (oldValue && !newValue || !oldValue && newValue || XMLString::compareString(oldValue,newValue))\r
+ releaseThisandParentDOM();\r
+ \r
+ return newString;\r
+ }\r
+ \r
+ /**\r
+ * A helper function for derived classes, for assignment of (singleton) XML objects.\r
+ * \r
+ * It is indifferent to whether either the old or the new version of the value is null. \r
+ * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate\r
+ * \r
+ * @param oldValue - current value\r
+ * @param newValue - proposed new value\r
+ * @return The value to assign to the saved Object.\r
+ * \r
+ * @throws IllegalArgumentException if the child already has a parent.\r
+ */\r
+ XMLObject* prepareForAssignment(const XMLObject* oldValue, XMLObject* newValue);\r
+\r
+ /**\r
+ * Constructor\r
+ * \r
+ * @param namespaceURI the namespace the element is in\r
+ * @param elementLocalName the local name of the XML element this Object represents\r
+ */\r
+ explicit AbstractDOMCachingXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName)\r
+ : AbstractXMLObject(namespaceURI,elementLocalName), m_dom(NULL), m_document(NULL) {}\r
+\r
+ private:\r
+ DOMElement* m_dom;\r
+ DOMDocument* m_document;\r
+ };\r
+ \r
+};\r
+\r
+#pragma warning( pop )\r
+\r
+#endif /* __xmltooling_abstractdomxmlobj_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
+ * @file AbstractXMLObject.h\r
+ * \r
+ * An abstract implementation of XMLObject.\r
+ */\r
+\r
+#if !defined(__xmltooling_abstractxmlobj_h__)\r
+#define __xmltooling_abstractxmlobj_h__\r
+\r
+#include <xmltooling/XMLObject.h>\r
+\r
+#pragma warning( push )\r
+#pragma warning( disable : 4250 4251 )\r
+\r
+namespace xmltooling {\r
+\r
+ /**\r
+ * An abstract implementation of XMLObject.\r
+ */\r
+ class XMLTOOL_API AbstractXMLObject : public virtual XMLObject\r
+ {\r
+ public:\r
+ virtual ~AbstractXMLObject() {\r
+ delete m_typeQname;\r
+ }\r
+\r
+ /**\r
+ * @see XMLObject::getElementQName()\r
+ */\r
+ const QName& getElementQName() const {\r
+ return m_elementQname;\r
+ }\r
+\r
+ /**\r
+ * @see XMLObject::setElementNamespacePrefix()\r
+ */\r
+ void setElementNamespacePrefix(const XMLCh* prefix) {\r
+ m_elementQname.setPrefix(prefix);\r
+ }\r
+\r
+ /**\r
+ * @see XMLObject::getNamespaces()\r
+ */\r
+ const std::set<Namespace>& getNamespaces() const {\r
+ return m_namespaces;\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::addNamespace()\r
+ */\r
+ void addNamespace(const Namespace& ns) {\r
+ m_namespaces.insert(ns);\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::removeNamespace()\r
+ */\r
+ void removeNamespace(const Namespace& ns) {\r
+ m_namespaces.erase(ns);\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::getSchemaType()\r
+ */\r
+ const QName* getSchemaType() const {\r
+ return m_typeQname;\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::setSchemaType()\r
+ */\r
+ void setSchemaType(const QName* type) {\r
+ delete m_typeQname;\r
+ m_typeQname = NULL;\r
+ if (type) {\r
+ m_typeQname = new QName(*type);\r
+ addNamespace(Namespace(type->getNamespaceURI(), type->getPrefix()));\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::hasParent()\r
+ */\r
+ bool hasParent() const {\r
+ return m_parent != NULL;\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::getParent()\r
+ */\r
+ XMLObject* getParent() const {\r
+ return m_parent;\r
+ }\r
+ \r
+ /**\r
+ * @see XMLObject::setParent()\r
+ */\r
+ void setParent(XMLObject* parent) {\r
+ m_parent = parent;\r
+ }\r
+ \r
+ protected:\r
+ /**\r
+ * Constructor\r
+ * \r
+ * @param namespaceURI the namespace the element is in\r
+ * @param elementLocalName the local name of the XML element this Object represents\r
+ */\r
+ explicit AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName)\r
+ : m_elementQname(namespaceURI,elementLocalName), m_typeQname(NULL), m_parent(NULL) {}\r
+ \r
+ private:\r
+ XMLObject* m_parent;\r
+ QName m_elementQname;\r
+ QName* m_typeQname;\r
+ std::set<Namespace> m_namespaces;\r
+ };\r
+\r
+};\r
+\r
+#pragma warning( pop )\r
+\r
+#endif /* __xmltooling_abstractxmlobj_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
+ * @file AbstractXMLObjectBuilder.h\r
+ * \r
+ * Factory interface for XMLObjects \r
+ */\r
+\r
+#if !defined(__xmltooling_abstractxmlobjbuilder_h__)\r
+#define __xmltooling_abstractxmlobjbuilder_h__\r
+\r
+#include <xmltooling/XMLObjectBuilder.h>\r
+\r
+namespace xmltooling {\r
+\r
+ /**\r
+ * Base implementation of XMLObjectBuilder that automatically \r
+ * invokes resetState() after the XMLObject is built.\r
+ */\r
+ class XMLTOOL_API AbstractXMLObjectBuilder : public virtual XMLObjectBuilder\r
+ {\r
+ public:\r
+ virtual ~AbstractXMLObjectBuilder() {}\r
+ \r
+ /**\r
+ * @see XMLObjectBuilder::buildObject()\r
+ */\r
+ XMLObject* buildObject() {\r
+ XMLObject* builtObject = doBuildObject();\r
+ resetState();\r
+ return builtObject;\r
+ }\r
+\r
+ /**\r
+ * Delegated call that builds the XMLObject prior to a state reset.\r
+ * \r
+ * @return the built XMLObject\r
+ */\r
+ virtual XMLObject* doBuildObject()=0;\r
+ };\r
+\r
+};\r
+\r
+#endif /* __xmltooling_abstractxmlobjbuilder_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
+ * @file DOMCachingXMLObject.h\r
+ * \r
+ * An XMLObject that can cached a DOM representation of itself. \r
+ */\r
+\r
+#if !defined(__xmltooling_domxmlobj_h__)\r
+#define __xmltooling_domxmlobj_h__\r
+\r
+#include <xercesc/dom/DOM.hpp>\r
+#include <xmltooling/XMLObject.h>\r
+\r
+using namespace xercesc;\r
+\r
+namespace xmltooling {\r
+\r
+ /**\r
+ * An XMLObject that can cached a DOM representation of itself.\r
+ */\r
+ class XMLTOOL_API DOMCachingXMLObject : public virtual XMLObject\r
+ {\r
+ public:\r
+ DOMCachingXMLObject() {}\r
+ virtual ~DOMCachingXMLObject() {}\r
+ \r
+ /**\r
+ * Gets the DOM representation of this XMLObject, if one exists.\r
+ * \r
+ * @return the DOM representation of this XMLObject\r
+ */\r
+ virtual const DOMElement* getDOM() const=0;\r
+ \r
+ /**\r
+ * Sets the DOM representation of this XMLObject.\r
+ * \r
+ * @param dom DOM representation of this XMLObject\r
+ */\r
+ virtual void setDOM(DOMElement* dom)=0;\r
+ \r
+ /**\r
+ * Assigns ownership of a DOM document to the XMLObject.\r
+ * This binds the lifetime of the document to the lifetime of the object.\r
+ * \r
+ * @param doc DOM document bound to this object \r
+ */\r
+ virtual DOMDocument* setDocument(DOMDocument* doc)=0;\r
+\r
+ /**\r
+ * Releases the DOM representation of this XMLObject, if there is one.\r
+ */\r
+ virtual void releaseDOM()=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
+ \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
+ };\r
+ \r
+};\r
+\r
+#endif /* __xmltooling_domxmlobj_h__ */\r
$(includedir)/xmltooling
libxmltoolinginclude_HEADERS = \
+ AbstractDOMCachingXMLObject.h \
+ AbstractXMLObject.h \
+ AbstractXMLObjectBuilder.h \
base.h \
config_pub.h \
+ DOMCachingXMLObject.h \
exceptions.h \
ILockable.h \
Namespace.h \
internal.h
libxmltooling_la_SOURCES = \
+ AbstractDOMCachingXMLObject.cpp \
Namespace.cpp \
QName.cpp \
unicode.cpp \
{\r
MAKE_NONCOPYABLE(XMLObject);\r
public:\r
+ XMLObject() {}\r
virtual ~XMLObject() {}\r
\r
/**\r
* \r
* @return the empty XMLObject\r
*/\r
- XMLObject* buildObject() const;\r
+ virtual XMLObject* buildObject()=0;\r
\r
/**\r
* Resets the state of the builder.\r
* This normally means null'ing out any properties that were\r
* needed to build an object.\r
*/\r
- void resetState();\r
+ virtual void resetState()=0;\r
};\r
\r
};\r
};\r
\r
DECL_XMLTOOLING_EXCEPTION(XMLParserException);\r
+ DECL_XMLTOOLING_EXCEPTION(XMLObjectException);\r
\r
};\r
\r
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
>\r
<File\r
+ RelativePath=".\AbstractDOMCachingXMLObject.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\Namespace.cpp"\r
>\r
</File>\r
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
>\r
<File\r
+ RelativePath=".\AbstractDOMCachingXMLObject.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\AbstractXMLObject.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\AbstractXMLObjectBuilder.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\base.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\DOMCachingXMLObject.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\exceptions.h"\r
>\r
</File>\r