\r
#include "internal.h"\r
#include "AbstractXMLObject.h"\r
+#include "exceptions.h"\r
\r
#include <algorithm>\r
#include <log4cpp/Category.hh>\r
\r
using namespace xmltooling;\r
\r
-AbstractXMLObject::~AbstractXMLObject() {\r
- delete m_typeQname;\r
- std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());\r
+AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
+ : m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")), m_schemaLocation(NULL),\r
+ m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)\r
+{\r
+ addNamespace(Namespace(nsURI, prefix));\r
+ if (schemaType) {\r
+ m_typeQname = new QName(*schemaType);\r
+ addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));\r
+ }\r
+}\r
+\r
+AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)\r
+ : m_namespaces(src.m_namespaces), m_log(src.m_log), m_schemaLocation(XMLString::replicate(src.m_schemaLocation)),\r
+ m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)\r
+{\r
+ if (src.m_typeQname)\r
+ m_typeQname=new QName(*src.m_typeQname);\r
+}\r
+\r
+XMLCh* AbstractXMLObject::prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue)\r
+{\r
+ if (!XMLString::equals(oldValue,newValue)) {\r
+ releaseThisandParentDOM();\r
+ XMLCh* newString = XMLString::replicate(newValue);\r
+ XMLString::release(&oldValue);\r
+ return newString;\r
+ }\r
+ return oldValue;\r
+}\r
+\r
+QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)\r
+{\r
+ if (!oldValue) {\r
+ if (newValue) {\r
+ releaseThisandParentDOM();\r
+ Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
+ addNamespace(newNamespace);\r
+ return new QName(*newValue);\r
+ }\r
+ return NULL;\r
+ }\r
+\r
+ delete oldValue;\r
+ releaseThisandParentDOM();\r
+ if (newValue) {\r
+ Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
+ addNamespace(newNamespace);\r
+ return new QName(*newValue);\r
+ }\r
+ return NULL;\r
+}\r
+\r
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)\r
+{\r
+ if (!oldValue) {\r
+ if (newValue) {\r
+ releaseThisandParentDOM();\r
+ return new DateTime(*newValue);\r
+ }\r
+ return NULL;\r
+ }\r
+\r
+ delete oldValue;\r
+ releaseThisandParentDOM();\r
+ return newValue ? new DateTime(*newValue) : NULL;\r
+}\r
+\r
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue)\r
+{\r
+ delete oldValue;\r
+ releaseThisandParentDOM();\r
+ DateTime* ret = new DateTime(newValue);\r
+ ret->parseDateTime();\r
+ return ret;\r
+}\r
+\r
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue)\r
+{\r
+ delete oldValue;\r
+ releaseThisandParentDOM();\r
+ DateTime* ret = new DateTime(newValue);\r
+ ret->parseDateTime();\r
+ return ret;\r
}\r
\r
-AbstractXMLObject::AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix)\r
- : m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL),\r
- m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject"))\r
+XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue)\r
{\r
- addNamespace(Namespace(namespaceURI, namespacePrefix));\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
+ }\r
+ return newValue;\r
+ }\r
+\r
+ if (oldValue != newValue) {\r
+ delete oldValue;\r
+ releaseThisandParentDOM();\r
+ if (newValue)\r
+ newValue->setParent(this);\r
+ }\r
+\r
+ return newValue;\r
+}\r
+\r
+void AbstractXMLObject::detach()\r
+{\r
+ if (!getParent())\r
+ return;\r
+ else if (getParent()->hasParent())\r
+ throw XMLObjectException("Cannot detach an object whose parent is itself a child.");\r
+\r
+ // Pull ourselves out of the parent and then blast him.\r
+ getParent()->removeChild(this);\r
+ delete m_parent;\r
+ m_parent = NULL;\r
}\r