Merge branch '1.x' of ssh://authdev.it.ohio-state.edu/~scantor/git/cpp-xmltooling...
[shibboleth/cpp-xmltooling.git] / xmltooling / io / AbstractXMLObjectMarshaller.cpp
index 7e2cf3c..51fc136 100644 (file)
@@ -1,17 +1,21 @@
-/*
-*  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
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ *
+ * UCAID licenses this file to you 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
+ * 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.
+ * 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.
  */
 
 /**
@@ -43,6 +47,23 @@ using namespace xmltooling;
 using namespace xercesc;
 using namespace std;
 
+AbstractXMLObjectMarshaller::AbstractXMLObjectMarshaller()
+{
+}
+
+AbstractXMLObjectMarshaller::~AbstractXMLObjectMarshaller()
+{
+}
+
+void AbstractXMLObjectMarshaller::setDocumentElement(DOMDocument* document, DOMElement* element) const
+{
+    DOMElement* documentRoot = document->getDocumentElement();
+    if (documentRoot)
+        document->replaceChild(element, documentRoot);
+    else
+        document->appendChild(element);
+}
+
 DOMElement* AbstractXMLObjectMarshaller::marshall(
     DOMDocument* document
 #ifndef XMLTOOLING_NO_XMLSEC
@@ -79,14 +100,16 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(
     }
     
     // If we get here, we didn't have a usable DOM (and/or we released the one we had).
+    prepareForMarshalling();
+
     // We may need to create our own document.
     bool bindDocument=false;
     if (!document) {
-        document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+        document=DOMImplementationRegistry::getDOMImplementation(nullptr)->createDocument();
         bindDocument=true;
     }
     
-    XercesJanitor<DOMDocument> janitor(bindDocument ? document : NULL);
+    XercesJanitor<DOMDocument> janitor(bindDocument ? document : nullptr);
 
     m_log.debug("creating root element to marshall");
     DOMElement* domElement = document->createElementNS(
@@ -144,6 +167,8 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(
     }
     
     // If we get here, we didn't have a usable DOM (and/or we released the one we had).
+    prepareForMarshalling();
+
     m_log.debug("creating root element to marshall");
     DOMElement* domElement = parentElement->getOwnerDocument()->createElementNS(
         getElementQName().getNamespaceURI(), getElementQName().getLocalPart()
@@ -186,7 +211,7 @@ void AbstractXMLObjectMarshaller::marshallInto(
             chLatin_S, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a,
             chLatin_L, chLatin_o, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull
             };
-        if (targetElement->getParentNode()==NULL || targetElement->getParentNode()->getNodeType()==DOMNode::DOCUMENT_NODE) {
+        if (targetElement->getParentNode()==nullptr || targetElement->getParentNode()->getNodeType()==DOMNode::DOCUMENT_NODE) {
             if (m_schemaLocation)
                 targetElement->setAttributeNS(XSI_NS,schemaLocation,m_schemaLocation); 
             if (m_noNamespaceSchemaLocation)
@@ -211,8 +236,8 @@ void AbstractXMLObjectMarshaller::marshallInto(
                targetElement->setAttributeNS(XSI_NS, _nil, xmlconstants::XML_ZERO);
                 break;
         }
-        m_log.debug("adding XSI namespace to list of namespaces used by XMLObject");
-        addNamespace(Namespace(XSI_NS, XSI_PREFIX));
+        m_log.debug("adding XSI namespace to list of namespaces visibly used by XMLObject");
+        addNamespace(Namespace(XSI_NS, XSI_PREFIX, false, Namespace::VisiblyUsed));
     }
 
     marshallElementType(targetElement);
@@ -258,8 +283,8 @@ void AbstractXMLObjectMarshaller::marshallElementType(DOMElement* domElement) co
         if (xsivalue != typeLocalName)
             XMLString::release(&xsivalue);
 
-        m_log.debug("adding XSI namespace to list of namespaces used by XMLObject");
-        addNamespace(Namespace(XSI_NS, XSI_PREFIX));
+        m_log.debug("adding XSI namespace to list of namespaces visibly used by XMLObject");
+        addNamespace(Namespace(XSI_NS, XSI_PREFIX, false, Namespace::VisiblyUsed));
     }
 }
 
@@ -269,6 +294,10 @@ public:
         const XMLCh* prefix=ns.getNamespacePrefix();
         const XMLCh* uri=ns.getNamespaceURI();
         
+        // Check for xmlns:xml.
+        if (XMLString::equals(prefix, XML_PREFIX) && XMLString::equals(uri, XML_NS))
+            return;
+
         // Check to see if the prefix is already declared properly above this node.
         if (!ns.alwaysDeclare()) {
             const XMLCh* declared=lookupNamespaceURI(domElement->getParentNode(),prefix);
@@ -284,7 +313,7 @@ public:
             XMLString::catString(xmlns,colon);
             XMLString::catString(xmlns,prefix);
             domElement->setAttributeNS(XMLNS_NS, xmlns, uri);
-            XMLString::release(&xmlns);
+            delete[] xmlns;
         }
         else {
             domElement->setAttributeNS(XMLNS_NS, XMLNS_PREFIX, uri);
@@ -292,12 +321,12 @@ public:
     }
 
     const XMLCh* lookupNamespaceURI(const DOMNode* n, const XMLCh* prefix) const {
-        // Return NULL if no declaration in effect. The empty string signifies the null namespace.
+        // Return nullptr if no declaration in effect. The empty string signifies the null namespace.
         if (!n || n->getNodeType()!=DOMNode::ELEMENT_NODE) {
             // At the root, the default namespace is set to the null namespace.
             if (!prefix || !*prefix)
                 return &chNull;
-            return NULL;    // we're done
+            return nullptr;    // we're done
         }
         DOMNamedNodeMap* attributes = static_cast<const DOMElement*>(n)->getAttributes();
         if (!attributes)
@@ -347,7 +376,7 @@ void AbstractXMLObjectMarshaller::marshallContent(
     for (list<XMLObject*>::const_iterator i=children.begin(); i!=children.end(); ++i) {
         if (*i) {
 #ifndef XMLTOOLING_NO_XMLSEC
-            (*i)->marshall(domElement,NULL,credential);
+            (*i)->marshall(domElement,nullptr,credential);
 #else
             (*i)->marshall(domElement);
 #endif
@@ -357,3 +386,11 @@ void AbstractXMLObjectMarshaller::marshallContent(
         }
     }
 }
+
+void AbstractXMLObjectMarshaller::marshallAttributes(DOMElement* domElement) const
+{
+}
+
+void AbstractXMLObjectMarshaller::prepareForMarshalling() const
+{
+}