-/*\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
- * AbstractXMLObject.cpp\r
- * \r
- * An abstract implementation of XMLObject.\r
- */\r
-\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(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
- XMLCh* newString = XMLString::replicate(newValue);\r
- XMLString::trim(newString);\r
- if (!XMLString::equals(oldValue,newValue)) {\r
- releaseThisandParentDOM();\r
- XMLString::release(&oldValue);\r
- return newString;\r
- }\r
- XMLString::release(&newString);\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
-XMLObject* AbstractXMLObject::prepareForAssignment(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
- }\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
+/*
+* Copyright 2001-2010 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.
+ */
+
+/**
+ * AbstractXMLObject.cpp
+ *
+ * An abstract implementation of XMLObject.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "AbstractXMLObject.h"
+#include "util/DateTime.h"
+
+#include <algorithm>
+
+using namespace xmltooling;
+using std::set;
+
+using xercesc::XMLString;
+
+XMLObject::XMLObject()
+{
+}
+
+XMLObject::~XMLObject()
+{
+}
+
+void XMLObject::releaseThisandParentDOM() const
+{
+ releaseDOM();
+ releaseParentDOM(true);
+}
+
+void XMLObject::releaseThisAndChildrenDOM() const
+{
+ releaseChildrenDOM(true);
+ releaseDOM();
+}
+
+AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+ : m_log(logging::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")),
+ m_schemaLocation(nullptr), m_noNamespaceSchemaLocation(nullptr), m_nil(xmlconstants::XML_BOOL_NULL),
+ m_parent(nullptr), m_elementQname(nsURI, localName, prefix), m_typeQname(nullptr)
+{
+ addNamespace(Namespace(nsURI, prefix, false, Namespace::VisiblyUsed));
+ if (schemaType) {
+ m_typeQname = new QName(*schemaType);
+ addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix(), false, Namespace::NonVisiblyUsed));
+ }
+}
+
+AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)
+ : m_namespaces(src.m_namespaces), m_log(src.m_log), m_schemaLocation(XMLString::replicate(src.m_schemaLocation)),
+ m_noNamespaceSchemaLocation(XMLString::replicate(src.m_noNamespaceSchemaLocation)), m_nil(src.m_nil),
+ m_parent(nullptr), m_elementQname(src.m_elementQname), m_typeQname(nullptr)
+{
+ if (src.m_typeQname)
+ m_typeQname=new QName(*src.m_typeQname);
+}
+
+AbstractXMLObject::~AbstractXMLObject()
+{
+ delete m_typeQname;
+ xercesc::XMLString::release(&m_schemaLocation);
+ xercesc::XMLString::release(&m_noNamespaceSchemaLocation);
+}
+
+void AbstractXMLObject::detach()
+{
+ if (!getParent())
+ return;
+ else if (getParent()->hasParent())
+ throw XMLObjectException("Cannot detach an object whose parent is itself a child.");
+
+ // Pull ourselves out of the parent and then blast him.
+ getParent()->removeChild(this);
+ delete m_parent;
+ m_parent = nullptr;
+}
+
+const QName& AbstractXMLObject::getElementQName() const
+{
+ return m_elementQname;
+}
+
+const set<Namespace>& AbstractXMLObject::getNamespaces() const
+{
+ return m_namespaces;
+}
+
+void XMLObject::setNil(const XMLCh* value)
+{
+ if (value) {
+ switch (*value) {
+ case xercesc::chLatin_t:
+ nil(xmlconstants::XML_BOOL_TRUE);
+ break;
+ case xercesc::chLatin_f:
+ nil(xmlconstants::XML_BOOL_FALSE);
+ break;
+ case xercesc::chDigit_1:
+ nil(xmlconstants::XML_BOOL_ONE);
+ break;
+ case xercesc::chDigit_0:
+ nil(xmlconstants::XML_BOOL_ZERO);
+ break;
+ default:
+ nil(xmlconstants::XML_BOOL_NULL);
+ }
+ }
+ else {
+ nil(xmlconstants::XML_BOOL_NULL);
+ }
+}
+
+void AbstractXMLObject::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);
+ switch (ns.usage()) {
+ case Namespace::Indeterminate:
+ break;
+ case Namespace::VisiblyUsed:
+ const_cast<Namespace&>(*i).setUsage(Namespace::VisiblyUsed);
+ break;
+ case Namespace::NonVisiblyUsed:
+ if (i->usage() == Namespace::Indeterminate)
+ const_cast<Namespace&>(*i).setUsage(Namespace::NonVisiblyUsed);
+ break;
+ }
+ }
+}
+
+void AbstractXMLObject::removeNamespace(const Namespace& ns)
+{
+ m_namespaces.erase(ns);
+}
+
+const QName* AbstractXMLObject::getSchemaType() const
+{
+ return m_typeQname;
+}
+
+const XMLCh* AbstractXMLObject::getXMLID() const
+{
+ return nullptr;
+}
+
+xmlconstants::xmltooling_bool_t AbstractXMLObject::getNil() const
+{
+ return m_nil;
+}
+
+void AbstractXMLObject::nil(xmlconstants::xmltooling_bool_t value)
+{
+ if (m_nil != value) {
+ releaseThisandParentDOM();
+ m_nil = value;
+ }
+}
+
+bool AbstractXMLObject::hasParent() const
+{
+ return m_parent != nullptr;
+}
+
+XMLObject* AbstractXMLObject::getParent() const
+{
+ return m_parent;
+}
+
+void AbstractXMLObject::setParent(XMLObject* parent)
+{
+ m_parent = parent;
+}
+
+XMLCh* AbstractXMLObject::prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue)
+{
+ if (!XMLString::equals(oldValue,newValue)) {
+ releaseThisandParentDOM();
+ XMLCh* newString = XMLString::replicate(newValue);
+ XMLString::release(&oldValue);
+ return newString;
+ }
+ return oldValue;
+}
+
+QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)
+{
+ if (!oldValue) {
+ if (newValue) {
+ releaseThisandParentDOM();
+ addNamespace(Namespace(newValue->getNamespaceURI(), newValue->getPrefix(), false, Namespace::NonVisiblyUsed));
+ return new QName(*newValue);
+ }
+ return nullptr;
+ }
+
+ delete oldValue;
+ releaseThisandParentDOM();
+ if (newValue) {
+ // Attach a non-visibly used namespace.
+ addNamespace(Namespace(newValue->getNamespaceURI(), newValue->getPrefix(), false, Namespace::NonVisiblyUsed));
+ return new QName(*newValue);
+ }
+ return nullptr;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)
+{
+ if (!oldValue) {
+ if (newValue) {
+ releaseThisandParentDOM();
+ return new DateTime(*newValue);
+ }
+ return nullptr;
+ }
+
+ delete oldValue;
+ releaseThisandParentDOM();
+ return newValue ? new DateTime(*newValue) : nullptr;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue, bool duration)
+{
+ delete oldValue;
+ releaseThisandParentDOM();
+ DateTime* ret = new DateTime(newValue, duration);
+ if (duration)
+ ret->parseDuration();
+ else
+ ret->parseDateTime();
+ return ret;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue, bool duration)
+{
+ delete oldValue;
+ releaseThisandParentDOM();
+ if (!newValue || !*newValue)
+ return nullptr;
+ DateTime* ret = new DateTime(newValue);
+ if (duration)
+ ret->parseDuration();
+ else
+ ret->parseDateTime();
+ return ret;
+}
+
+XMLObject* AbstractXMLObject::prepareForAssignment(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;
+ }
+
+ if (oldValue != newValue) {
+ delete oldValue;
+ releaseThisandParentDOM();
+ if (newValue)
+ newValue->setParent(this);
+ }
+
+ return newValue;
+}