Base classes for open content models.
authorcantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Mon, 6 Mar 2006 00:25:16 +0000 (00:25 +0000)
committercantor <cantor@de75baf8-a10c-0410-a50a-987c0e22f00f>
Mon, 6 Mar 2006 00:25:16 +0000 (00:25 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/trunk@44 de75baf8-a10c-0410-a50a-987c0e22f00f

15 files changed:
xmltooling/AbstractAttributeExtensibleXMLObject.cpp [new file with mode: 0644]
xmltooling/AbstractAttributeExtensibleXMLObject.h [new file with mode: 0644]
xmltooling/AbstractDOMCachingXMLObject.cpp
xmltooling/AbstractDOMCachingXMLObject.h
xmltooling/AbstractExtensibleXMLObject.cpp [new file with mode: 0644]
xmltooling/AbstractExtensibleXMLObject.h [new file with mode: 0644]
xmltooling/AbstractXMLObject.h
xmltooling/AttributeExtensibleXMLObject.h [new file with mode: 0644]
xmltooling/ExtensibleXMLObject.h [new file with mode: 0644]
xmltooling/Makefile.am
xmltooling/util/XMLObjectChildrenList.h
xmltooling/xmltooling.vcproj
xmltoolingtest/MarshallingTest.h
xmltoolingtest/UnmarshallingTest.h
xmltoolingtest/XMLObjectBaseTestCase.h

diff --git a/xmltooling/AbstractAttributeExtensibleXMLObject.cpp b/xmltooling/AbstractAttributeExtensibleXMLObject.cpp
new file mode 100644 (file)
index 0000000..7362956
--- /dev/null
@@ -0,0 +1,61 @@
+/*\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
+ * AbstractAttributeExtensibleXMLObject.cpp\r
+ * \r
+ * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject. \r
+ */\r
+\r
+#include "internal.h"\r
+#include "AbstractAttributeExtensibleXMLObject.h"\r
+\r
+#include <algorithm>\r
+#include <functional>\r
+\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+class _release : public unary_function<XMLCh*,void> {\r
+public:\r
+    void operator()(pair<QName,XMLCh*> p) const {\r
+        XMLString::release(&(p.second));\r
+    }\r
+};\r
+\r
+AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()\r
+{\r
+    for_each(m_attributeMap.begin(),m_attributeMap.end(),_release());\r
+}\r
+\r
+void AbstractAttributeExtensibleXMLObject::setAttribute(QName& qualifiedName, const XMLCh* value)\r
+{\r
+    map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);\r
+    if (i!=m_attributeMap.end()) {\r
+        releaseThisandParentDOM();\r
+        XMLString::release(&(i->second));\r
+        if (value) {\r
+            i->second=XMLString::replicate(value);\r
+        }\r
+        else {\r
+            m_attributeMap.erase(i);\r
+        }\r
+    }\r
+    else if (value) {\r
+        releaseThisandParentDOM();\r
+        m_attributeMap[qualifiedName]=XMLString::replicate(value);\r
+    }\r
+}\r
diff --git a/xmltooling/AbstractAttributeExtensibleXMLObject.h b/xmltooling/AbstractAttributeExtensibleXMLObject.h
new file mode 100644 (file)
index 0000000..c172b50
--- /dev/null
@@ -0,0 +1,82 @@
+/*\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 AbstractAttributeExtensibleXMLObject.h\r
+ * \r
+ * An abstract implementation of a DOM-caching AttributeExtensibleXMLObject \r
+ */\r
+\r
+#if !defined(__xmltooling_absattrextxmlobj_h__)\r
+#define __xmltooling_absattrextxmlobj_h__\r
+\r
+#include <map>\r
+#include <xmltooling/AbstractDOMCachingXMLObject.h>\r
+#include <xmltooling/AttributeExtensibleXMLObject.h>\r
+\r
+using namespace xercesc;\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( push )\r
+    #pragma warning( disable : 4250 4251 )\r
+#endif\r
+\r
+namespace xmltooling {\r
+\r
+    /**\r
+     * An abstract implementation of a DOM-caching AttributeExtensibleXMLObject.\r
+     */\r
+    class XMLTOOL_API AbstractAttributeExtensibleXMLObject : public virtual AbstractDOMCachingXMLObject\r
+    {\r
+    public:\r
+        virtual ~AbstractAttributeExtensibleXMLObject();\r
+        \r
+        /**\r
+         * @see AttributeExtensibleXMLObject::getAttribute()\r
+         */\r
+        virtual const XMLCh* getAttribute(QName& qualifiedName) const {\r
+            std::map<QName,XMLCh*>::const_iterator i=m_attributeMap.find(qualifiedName);\r
+            return (i==m_attributeMap.end()) ? NULL : i->second;\r
+        }\r
+        \r
+        /**\r
+         * @see AttributeExtensibleXMLObject::setAttribute()\r
+         */\r
+        virtual void setAttribute(QName& qualifiedName, const XMLCh* value);\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
+         * @param namespacePrefix the namespace prefix to use\r
+         */\r
+        AbstractAttributeExtensibleXMLObject(\r
+            const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL\r
+            ) : AbstractDOMCachingXMLObject(namespaceURI,elementLocalName, namespacePrefix) {}\r
+\r
+    private:\r
+        std::map<QName,XMLCh*> m_attributeMap;\r
+    };\r
+    \r
+};\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( pop )\r
+#endif\r
+\r
+#endif /* __xmltooling_absattrextxmlobj_h__ */\r
index c1cd6e2..655f22d 100644 (file)
@@ -72,9 +72,9 @@ void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease)
                 propagateRelease ? "true" : "false"\r
                 );\r
             domCachingParent->releaseDOM();\r
+            if (propagateRelease)\r
+                domCachingParent->releaseParentDOM(propagateRelease);\r
         }\r
-        if (propagateRelease)\r
-            domCachingParent->releaseParentDOM(propagateRelease);\r
     }\r
 }\r
 \r
@@ -101,31 +101,6 @@ void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool 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
-\r
 DOMElement* AbstractDOMCachingXMLObject::cloneDOM(DOMDocument* doc) const\r
 {\r
     if (getDOM()) {\r
index 862f925..ce8d2c4 100644 (file)
@@ -109,6 +109,7 @@ namespace xmltooling {
          * \r
          * @param namespaceURI the namespace the element is in\r
          * @param elementLocalName the local name of the XML element this Object represents\r
+         * @param namespacePrefix the namespace prefix to use\r
          */\r
         AbstractDOMCachingXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
             : AbstractXMLObject(namespaceURI,elementLocalName, namespacePrefix), m_dom(NULL), m_document(NULL) {}\r
@@ -141,20 +142,6 @@ namespace xmltooling {
             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
     private:\r
         DOMElement* m_dom;\r
         DOMDocument* m_document;\r
diff --git a/xmltooling/AbstractExtensibleXMLObject.cpp b/xmltooling/AbstractExtensibleXMLObject.cpp
new file mode 100644 (file)
index 0000000..8afac3b
--- /dev/null
@@ -0,0 +1,37 @@
+/*\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
+ * AbstractExtensibleXMLObject.cpp\r
+ * \r
+ * Extension of AbstractDOMCachingXMLObject that implements an ExtensibleXMLObject. \r
+ */\r
+\r
+#include "internal.h"\r
+#include "AbstractExtensibleXMLObject.h"\r
+\r
+using namespace xmltooling;\r
+using namespace std;\r
+\r
+void AbstractExtensibleXMLObject::setTextContent(const XMLCh* value)\r
+{\r
+    m_value=prepareForAssignment(m_value,value);\r
+}\r
+\r
+ListOf(XMLObject) AbstractExtensibleXMLObject::getXMLObjects()\r
+{\r
+    return ListOf(XMLObject)(this,m_children,NULL,m_children.end());\r
+}\r
diff --git a/xmltooling/AbstractExtensibleXMLObject.h b/xmltooling/AbstractExtensibleXMLObject.h
new file mode 100644 (file)
index 0000000..fb96a9a
--- /dev/null
@@ -0,0 +1,86 @@
+/*\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 AbstractExtensibleXMLObject.h\r
+ * \r
+ * An abstract implementation of a DOM-caching ExtensibleXMLObject \r
+ */\r
+\r
+#if !defined(__xmltooling_absextxmlobj_h__)\r
+#define __xmltooling_absextxmlobj_h__\r
+\r
+#include <xmltooling/AbstractDOMCachingXMLObject.h>\r
+#include <xmltooling/ExtensibleXMLObject.h>\r
+\r
+using namespace xercesc;\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( push )\r
+    #pragma warning( disable : 4250 4251 )\r
+#endif\r
+\r
+namespace xmltooling {\r
+\r
+    /**\r
+     * An abstract implementation of a DOM-caching ExtensibleXMLObject.\r
+     */\r
+    class XMLTOOL_API AbstractExtensibleXMLObject : public virtual AbstractDOMCachingXMLObject\r
+    {\r
+    public:\r
+        virtual ~AbstractExtensibleXMLObject() {}\r
+        \r
+        /**\r
+         * @see ExtensibleXMLObject::getTextContent()\r
+         */\r
+        virtual const XMLCh* getTextContent() const {\r
+            return m_value;\r
+        }\r
+        \r
+        /**\r
+         * @see ExtensibleXMLObject::setTextContent()\r
+         */\r
+        virtual void setTextContent(const XMLCh* value);\r
+        \r
+\r
+        /**\r
+         * @see ExtensibleXMLObject::getXMLObjects()\r
+         */\r
+        virtual ListOf(XMLObject) getXMLObjects();\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
+         * @param namespacePrefix the namespace prefix to use\r
+         */\r
+        AbstractExtensibleXMLObject(\r
+            const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL\r
+            ) : AbstractDOMCachingXMLObject(namespaceURI,elementLocalName, namespacePrefix), m_value(NULL) {}\r
+\r
+    private:\r
+        XMLCh* m_value;\r
+    };\r
+    \r
+};\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( pop )\r
+#endif\r
+\r
+#endif /* __xmltooling_absextxmlobj_h__ */\r
index c3aa289..fd51345 100644 (file)
@@ -141,6 +141,7 @@ namespace xmltooling {
          * \r
          * @param namespaceURI the namespace the element is in\r
          * @param elementLocalName the local name of the XML element this Object represents\r
+         * @param namespacePrefix the namespace prefix to use\r
          */\r
         AbstractXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
             : m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL) {\r
diff --git a/xmltooling/AttributeExtensibleXMLObject.h b/xmltooling/AttributeExtensibleXMLObject.h
new file mode 100644 (file)
index 0000000..2d1472f
--- /dev/null
@@ -0,0 +1,60 @@
+/*\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 AttributeExtensibleXMLObject.h\r
+ * \r
+ * An XMLObject that supports arbitrary attributes \r
+ */\r
+\r
+#if !defined(__xmltooling_attrextxmlobj_h__)\r
+#define __xmltooling_attrextxmlobj_h__\r
+\r
+#include <xmltooling/XMLObject.h>\r
+\r
+using namespace xercesc;\r
+\r
+namespace xmltooling {\r
+\r
+    /**\r
+     * An XMLObject that supports arbitrary attributes.\r
+     */\r
+    class XMLTOOL_API AttributeExtensibleXMLObject : public virtual XMLObject\r
+    {\r
+    public:\r
+        AttributeExtensibleXMLObject() {}\r
+        virtual ~AttributeExtensibleXMLObject() {}\r
+        \r
+        /**\r
+         * Gets the value of an XML attribute of the object\r
+         * \r
+         * @param   qualifiedName   qualified name of the attribute   \r
+         * @return the attribute value, or NULL\r
+         */\r
+        virtual const XMLCh* getAttribute(QName& qualifiedName) const=0;\r
+        \r
+        /**\r
+         * Sets (or clears) an XML attribute of the object \r
+         * \r
+         * @param qualifiedName qualified name of the attribute   \r
+         * @param value         value to set, or NULL to clear\r
+         */\r
+        virtual void setAttribute(QName& qualifiedName, const XMLCh* value)=0;\r
+    };\r
+    \r
+};\r
+\r
+#endif /* __xmltooling_attrextxmlobj_h__ */\r
diff --git a/xmltooling/ExtensibleXMLObject.h b/xmltooling/ExtensibleXMLObject.h
new file mode 100644 (file)
index 0000000..fb31320
--- /dev/null
@@ -0,0 +1,67 @@
+/*\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 ExtensibleXMLObject.h\r
+ * \r
+ * An XMLObject with an open content model \r
+ */\r
+\r
+#if !defined(__xmltooling_extxmlobj_h__)\r
+#define __xmltooling_extxmlobj_h__\r
+\r
+#include <xmltooling/XMLObject.h>\r
+#include <xmltooling/util/XMLObjectChildrenList.h>\r
+\r
+using namespace xercesc;\r
+\r
+namespace xmltooling {\r
+\r
+    /**\r
+     * An XMLObject with an open content model.\r
+     */\r
+    class XMLTOOL_API ExtensibleXMLObject : public virtual XMLObject\r
+    {\r
+    public:\r
+        ExtensibleXMLObject() {}\r
+        virtual ~ExtensibleXMLObject() {}\r
+        \r
+        /**\r
+         * Gets the text content of the object\r
+         * \r
+         * @return the text content, or NULL\r
+         */\r
+        virtual const XMLCh* getTextContent() const=0;\r
+        \r
+        /**\r
+         * Sets (or clears) the text content of the object \r
+         * \r
+         * @param value         value to set, or NULL to clear\r
+         */\r
+        virtual void setTextContent(const XMLCh* value)=0;\r
+        \r
+\r
+        /**\r
+         * Gets a mutable list of child objects\r
+         * \r
+         * @return  mutable list of child objects\r
+         */\r
+        virtual ListOf(XMLObject) getXMLObjects()=0;\r
+    };\r
+    \r
+};\r
+\r
+#endif /* __xmltooling_extxmlobj_h__ */\r
index 7e79c2f..37f7c40 100644 (file)
@@ -3,23 +3,27 @@ AUTOMAKE_OPTIONS = foreign
 lib_LTLIBRARIES = libxmltooling.la
 
 libxmltoolingincludedir = \
-       $(includedir)/xmltooling
+    $(includedir)/xmltooling
 
 libxmltoolinginclude_HEADERS = \
-       AbstractDOMCachingXMLObject.h \
-       AbstractXMLObject.h \
-       base.h \
-       config_pub.h \
-       DOMCachingXMLObject.h \
-       exceptions.h \
-       ILockable.h \
-       Namespace.h \
-       QName.h \
-       unicode.h \
-       version.h \
-       XMLObject.h \
-       XMLObjectBuilder.h \
-       XMLToolingConfig.h
+    AbstractAttributeExtensibleXMLObject.h \
+    AbstractDOMCachingXMLObject.h \
+    AbstractExtensibleXMLObject.h \
+    AbstractXMLObject.h \
+    AttributeExtensibleXMLObject.h \
+    base.h \
+    config_pub.h \
+    DOMCachingXMLObject.h \
+    exceptions.h \
+    ExtensibleXMLObject.h \
+    ILockable.h \
+    Namespace.h \
+    QName.h \
+    unicode.h \
+    version.h \
+    XMLObject.h \
+    XMLObjectBuilder.h \
+    XMLToolingConfig.h
 
 utilincludedir = \
     $(includedir)/xmltooling/util
@@ -44,7 +48,9 @@ noinst_HEADERS = \
     impl/UnknownElement.h
 
 libxmltooling_la_SOURCES = \
+    AbstractAttributeExtensibleXMLObject.cpp \
     AbstractDOMCachingXMLObject.cpp \
+    AbstractExtensibleXMLObject.cpp \
     Namespace.cpp \
     QName.cpp \
     unicode.cpp \
index a494952..91cda64 100644 (file)
@@ -26,7 +26,9 @@
 #include <xmltooling/DOMCachingXMLObject.h>
 #include <xmltooling/exceptions.h>
 
-#define ListOf(type) xmltooling::XMLObjectChildrenList<type>
+#define VectorOf(type) xmltooling::XMLObjectChildrenList< std::vector<type*> >
+#define ListOf(type) xmltooling::XMLObjectChildrenList< std::list<type*> >
+#define DequeOf(type) xmltooling::XMLObjectChildrenList< std::deque<type*> >
 
 namespace xmltooling {
 
@@ -62,8 +64,8 @@ namespace xmltooling {
             return *m_iter;
         }
 
-        pointer operator->() const {
-            return (&**this);
+        const_reference operator->() const {
+            return *(m_iter.operator->());
         }
 
         XMLObjectChildrenIterator& operator++() {
@@ -138,113 +140,119 @@ namespace xmltooling {
 
     /**
      * STL-compatible container that mediates access to underlying lists of typed XML children.
-     * @param _Tx   the subtype to expose a container over
+     * @param _Tx   the subtype container to encapsulate
      * @param _Ty   the base type in the underlying list (defaults to XMLObject)
      */
-    template <class _Tx, class _Ty>
+    template <class Container, class _Ty>
     class XMLObjectChildrenList
     {
-        typedef typename std::vector<_Tx*> container;
-        typename XMLObjectChildrenList::container& m_vector;
-        typename std::list<_Ty*>& m_list;
+        typename Container& m_container;
+        typename std::list<_Ty*>* m_list;
         typename std::list<_Ty*>::iterator m_fence;
         XMLObject* m_parent;
 
        public:
-        typedef typename container::value_type value_type;
-        typedef typename container::reference reference;
-        typedef typename container::const_reference const_reference;
-        typedef typename container::difference_type difference_type;
-        typedef typename container::size_type size_type;
+        typedef typename Container::value_type value_type;
+        typedef typename Container::reference reference;
+        typedef typename Container::const_reference const_reference;
+        typedef typename Container::difference_type difference_type;
+        typedef typename Container::size_type size_type;
 
         // We override the iterator types with our constrained wrapper.
-        typedef XMLObjectChildrenIterator<typename XMLObjectChildrenList::container> iterator;
-        typedef const XMLObjectChildrenIterator<typename XMLObjectChildrenList::container> const_iterator;
+        typedef XMLObjectChildrenIterator<Container> iterator;
+        typedef const XMLObjectChildrenIterator<Container> const_iterator;
 
         /**
          * Constructor to expose a typed collection of children backed by a list of a base type.
          *
          * @param parent    parent object of the collection
-         * @param v         underlying vector of iterators that reference the children
-         * @param backing   backing list for children
+         * @param sublist   underlying container to expose
+         * @param backing   pointer to backing list for children, if any
          * @param ins_fence a marker designating where new children of this type should be added
          */
         XMLObjectChildrenList(
             XMLObject* parent,
-            typename XMLObjectChildrenList::container& v,
-            typename std::list<_Ty*>& backing,
+            Container& sublist,
+            typename std::list<_Ty*>* backing,
             typename std::list<_Ty*>::iterator ins_fence
-            ) : m_parent(parent), m_vector(v), m_list(backing), m_fence(ins_fence) {
+            ) : m_parent(parent), m_container(sublist), m_list(backing), m_fence(ins_fence) {
         }
 
         size_type size() const {
             // return length of sequence
-            return m_vector.size();
+            return m_container.size();
         }
 
         bool empty() const {
             // test if sequence is empty
-            return m_vector.empty();
+            return m_container.empty();
         }
 
         iterator begin() {
             // return iterator for beginning of mutable sequence
-            return m_vector.begin();
+            return m_container.begin();
         }
 
         iterator end() {
             // return iterator for end of mutable sequence
-            return m_vector.end();
+            return m_container.end();
         }
 
         const_iterator begin() const {
             // return iterator for beginning of const sequence
-            return m_vector.begin();
+            return m_container.begin();
         }
 
         const_iterator end() const {
             // return iterator for end of const sequence
-            return m_vector.end();
+            return m_container.end();
         }
 
         const_reference at(size_type _Pos) const {
             // subscript nonmutable sequence with checking
-            return m_vector.at(_Pos);
+            return m_container.at(_Pos);
         }
 
         const_reference operator[](size_type _Pos) const {
             // subscript nonmutable sequence
-            return m_vector[_Pos];
+            return m_container[_Pos];
         }
 
         const_reference front() const {
             // return first element of nonmutable sequence
-            return (*begin());
+            return m_container.front();
         }
 
         const_reference back() const {
             // return last element of nonmutable sequence
-            return *(m_vector.back());
+            return m_container.back();
         }
 
         void push_back(const_reference _Val) {
             setParent(_Val);
-            m_list.insert(m_fence,_Val);
-            m_vector.push_back(_Val);
+            if (m_list)
+                m_list->insert(m_fence,_Val);
+            m_container.push_back(_Val);
         }
 
         iterator erase(iterator _Where) {
             removeParent(*_Where);
-            removeChild(*_Where);
-            return m_vector.erase(_Where.m_iter);
+            if (m_list)
+                removeChild(*_Where);
+            return m_container.erase(_Where.m_iter);
         }
 
         iterator erase(iterator _First, iterator _Last) {
             for (iterator i=_First; i!=_Last; i++) {
                 removeParent(*i);
-                removeChild(*i);
+                if (m_list)
+                    removeChild(*i);
             }
-            return m_vector.erase(_First,_Last);
+            return m_container.erase(_First,_Last);
+        }
+
+        void clear() {
+            erase(begin(),end());
         }
 
     private:
@@ -269,9 +277,9 @@ namespace xmltooling {
         }
 
         void removeChild(const_reference _Val) {
-            for (typename std::list<_Ty*>::iterator i=m_list.begin(); i!=m_list.end(); i++) {
+            for (typename std::list<_Ty*>::iterator i=m_list->begin(); i!=m_list->end(); i++) {
                 if ((*i)==_Val) {
-                    m_list.erase(i);
+                    m_list->erase(i);
                     delete _Val;
                     return;
                 }
index c2dff62..0418077 100644 (file)
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
                        >\r
                        <File\r
+                               RelativePath=".\AbstractAttributeExtensibleXMLObject.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\AbstractDOMCachingXMLObject.cpp"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\AbstractExtensibleXMLObject.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=".\AbstractAttributeExtensibleXMLObject.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\AbstractDOMCachingXMLObject.h"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\AbstractExtensibleXMLObject.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\AbstractXMLObject.h"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\AttributeExtensibleXMLObject.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\base.h"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\ExtensibleXMLObject.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\ILockable.h"\r
                                >\r
                        </File>\r
index dd476c9..b5f0814 100644 (file)
@@ -81,7 +81,7 @@ public:
         \r
         auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
         TS_ASSERT(sxObject.get()!=NULL);\r
-        ListOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
+        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
         kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
         kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
         kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));\r
@@ -89,9 +89,10 @@ public:
         // Test some collection stuff\r
         auto_ptr_XMLCh foo("Foo");\r
         auto_ptr_XMLCh bar("Bar");\r
-        kids[0]->setId(foo.get());\r
+        kids.begin()->setId(foo.get());\r
         kids.at(2)->setValue(bar.get());\r
         kids.erase(kids.begin()+1);\r
+        TS_ASSERT_SAME_DATA(kids.back()->getValue(), bar.get(), XMLString::stringLen(bar.get()));\r
         \r
         DOMElement* rootElement = Marshaller::getMarshaller(sxObject.get())->marshall(sxObject.get());\r
 \r
index a5c87a4..f361266 100644 (file)
@@ -108,7 +108,7 @@ public:
         auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(u->unmarshall(doc->getDocumentElement(),true)));\r
         TS_ASSERT(sxObject.get()!=NULL);\r
 \r
-        ListOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
+        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
         TSM_ASSERT_EQUALS("Number of child elements was not expected value", 2, kids.size());\r
     }\r
 \r
index d69e1c0..48aa272 100644 (file)
@@ -46,7 +46,7 @@ public:
     static const XMLCh NAMESPACE_PREFIX[];\r
     static const XMLCh LOCAL_NAME[];\r
     static const XMLCh ID_ATTRIB_NAME[];\r
-    \r
+\r
     SimpleXMLObject() : AbstractDOMCachingXMLObject(NAMESPACE, LOCAL_NAME, NAMESPACE_PREFIX), m_id(NULL), m_value(NULL) {}\r
     virtual ~SimpleXMLObject() {\r
         XMLString::release(&m_id);\r
@@ -59,9 +59,8 @@ public:
     const XMLCh* getValue() const { return m_value; }\r
     void setValue(const XMLCh* value) { m_value=prepareForAssignment(m_value,value); }\r
     \r
-    // TODO: Leave non-const, but wrap STL container to intercept adds. \r
-    ListOf(SimpleXMLObject) getSimpleXMLObjects() {\r
-        return ListOf(SimpleXMLObject)(this, m_simples, m_children, m_children.end());\r
+    VectorOf(SimpleXMLObject) getSimpleXMLObjects() {\r
+        return VectorOf(SimpleXMLObject)(this, m_simples, &m_children, m_children.end());\r
     }\r
     \r
     SimpleXMLObject* clone() const {\r
@@ -83,8 +82,6 @@ private:
     XMLCh* m_id;\r
     XMLCh* m_value;\r
     vector<SimpleXMLObject*> m_simples;\r
-    \r
-    friend class SimpleXMLObjectUnmarshaller;\r
 };\r
 \r
 class SimpleXMLObjectBuilder : public XMLObjectBuilder\r
@@ -130,8 +127,7 @@ private:
 \r
         SimpleXMLObject* child = dynamic_cast<SimpleXMLObject*>(childXMLObject);\r
         if (child) {\r
-            simpleXMLObject.m_children.push_back(child);\r
-            simpleXMLObject.m_simples.push_back(child);\r
+            simpleXMLObject.getSimpleXMLObjects().push_back(child);\r
         }\r
         else {\r
             throw UnmarshallingException("Unknown child element cannot be added to parent object.");\r