-/*\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
-#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 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
- if (ns.alwaysDeclare() || m_namespaces.find(ns)==m_namespaces.end()) {\r
- m_namespaces.insert(ns);\r
- }\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
- AbstractXMLObject(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
- : m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL) {\r
- addNamespace(Namespace(namespaceURI, namespacePrefix));\r
- }\r
- \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
-#if defined (_MSC_VER)\r
- #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_abstractxmlobj_h__ */\r
+/*
+* Copyright 2001-2007 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 xmltooling/AbstractXMLObject.h
+ *
+ * An abstract implementation of XMLObject.
+ */
+
+#ifndef __xmltooling_abstractxmlobj_h__
+#define __xmltooling_abstractxmlobj_h__
+
+#include <xmltooling/logging.h>
+#include <xmltooling/XMLObject.h>
+#include <xmltooling/util/DateTime.h>
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+ /**
+ * An abstract implementation of XMLObject.
+ * This is the primary concrete base class, and supplies basic namespace,
+ * type, and parent handling. Most implementation classes should not
+ * directly inherit from this class, but rather from the various mixins
+ * that supply the rest of the XMLObject interface, as required.
+ */
+ class XMLTOOL_API AbstractXMLObject : public virtual XMLObject
+ {
+ public:
+ virtual ~AbstractXMLObject() {
+ delete m_typeQname;
+ xercesc::XMLString::release(&m_schemaLocation);
+ xercesc::XMLString::release(&m_noNamespaceSchemaLocation);
+ }
+
+ void detach();
+
+ const QName& getElementQName() const {
+ return m_elementQname;
+ }
+
+ const std::set<Namespace>& getNamespaces() const {
+ return m_namespaces;
+ }
+
+ void addNamespace(const Namespace& ns) const {
+ std::set<Namespace>::iterator i = m_namespaces.find(ns);
+ if (i == m_namespaces.end())
+ m_namespaces.insert(ns);
+ else if (ns.alwaysDeclare())
+ const_cast<Namespace&>(*i).setAlwaysDeclare(true);
+ }
+
+ void removeNamespace(const Namespace& ns) {
+ m_namespaces.erase(ns);
+ }
+
+ const QName* getSchemaType() const {
+ return m_typeQname;
+ }
+
+ const XMLCh* getXMLID() const {
+ return NULL;
+ }
+
+ xmlconstants::xmltooling_bool_t getNil() const {
+ return m_nil;
+ }
+
+ void nil(xmlconstants::xmltooling_bool_t value) {
+ if (m_nil != value) {
+ releaseThisandParentDOM();
+ m_nil = value;
+ }
+ }
+
+ bool hasParent() const {
+ return m_parent != NULL;
+ }
+
+ XMLObject* getParent() const {
+ return m_parent;
+ }
+
+ void setParent(XMLObject* parent) {
+ m_parent = parent;
+ }
+
+ protected:
+ /**
+ * Constructor
+ *
+ * @param nsURI the namespace of the element
+ * @param localName the local name of the XML element this Object represents
+ * @param prefix the namespace prefix to use
+ * @param schemaType the xsi:type to use
+ */
+ AbstractXMLObject(
+ const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL
+ );
+
+ /** Copy constructor. */
+ AbstractXMLObject(const AbstractXMLObject& src);
+
+ /**
+ * A helper function for derived classes, for assignment of strings.
+ *
+ * This 'normalizes' newString, and then if it is different from oldString,
+ * it invalidates the DOM, frees the old string, and returns 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);
+
+ /**
+ * A helper function for derived classes, for assignment of date/time data.
+ *
+ * It invalidates the DOM, frees the old object, and returns the new.
+ *
+ * @param oldValue - the current value
+ * @param newValue - the new value
+ *
+ * @return the value that should be assigned
+ */
+ DateTime* prepareForAssignment(DateTime* oldValue, const DateTime* newValue);
+
+ /**
+ * A helper function for derived classes, for assignment of date/time data.
+ *
+ * It invalidates the DOM, frees the old object, and returns the new.
+ *
+ * @param oldValue - the current value
+ * @param newValue - the epoch to assign as the new value
+ *
+ * @return the value that should be assigned
+ */
+ DateTime* prepareForAssignment(DateTime* oldValue, time_t newValue);
+
+ /**
+ * A helper function for derived classes, for assignment of date/time data.
+ *
+ * It invalidates the DOM, frees the old object, and returns the new.
+ *
+ * @param oldValue - the current value
+ * @param newValue - the new value in string form
+ *
+ * @return the value that should be assigned
+ */
+ DateTime* prepareForAssignment(DateTime* oldValue, const XMLCh* newValue);
+
+ /**
+ * A helper function for derived classes, for assignment of QName data.
+ *
+ * It invalidates the DOM, frees the old object, and returns the new.
+ *
+ * @param oldValue - the current value
+ * @param newValue - the new value
+ *
+ * @return the value that should be assigned
+ */
+ QName* prepareForAssignment(QName* oldValue, const QName* newValue);
+
+ /**
+ * 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.
+ * Note that since the new value (even if NULL) is always returned, it may be more efficient
+ * to discard the return value and just assign independently if a dynamic cast would be involved.
+ *
+ * @param oldValue - current value
+ * @param newValue - proposed new value
+ * @return the new value
+ *
+ * @throws XMLObjectException if the new child already has a parent.
+ */
+ XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue);
+
+ /**
+ * Set of namespaces associated with the object.
+ */
+ mutable std::set<Namespace> m_namespaces;
+
+ /**
+ * Logging object.
+ */
+ logging::Category& m_log;
+
+ /**
+ * Stores off xsi:schemaLocation attribute.
+ */
+ XMLCh* m_schemaLocation;
+
+ /**
+ * Stores off xsi:noNamespaceSchemaLocation attribute.
+ */
+ XMLCh* m_noNamespaceSchemaLocation;
+
+ /**
+ * Stores off xsi:nil attribute.
+ */
+ xmlconstants::xmltooling_bool_t m_nil;
+
+ private:
+ XMLObject* m_parent;
+ QName m_elementQname;
+ QName* m_typeQname;
+ };
+
+};
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_abstractxmlobj_h__ */