Hook releaseDOM properly, correct KeyInfo handling inside Signature impl.
authorScott Cantor <cantor.2@osu.edu>
Sun, 21 May 2006 19:53:47 +0000 (19:53 +0000)
committerScott Cantor <cantor.2@osu.edu>
Sun, 21 May 2006 19:53:47 +0000 (19:53 +0000)
xmltooling/impl/UnknownElement.cpp
xmltooling/impl/UnknownElement.h
xmltooling/signature/impl/XMLSecSignatureImpl.cpp

index 27fcfd9..e8ea23e 100644 (file)
@@ -35,7 +35,7 @@ using namespace xmltooling;
 using namespace log4cpp;\r
 using namespace std;\r
 \r
-void UnknownElementImpl::releaseDOM()\r
+void UnknownElementImpl::releaseDOM() const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("releaseDOM");\r
index 18e9cab..ded9183 100644 (file)
@@ -45,7 +45,7 @@ namespace xmltooling {
         UnknownElementImpl(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
             : AbstractXMLObject(namespaceURI, elementLocalName, namespacePrefix) {}\r
     \r
-        void releaseDOM();\r
+        void releaseDOM() const;\r
 \r
         XMLObject* clone() const;\r
 \r
index d92bffd..292d771 100644 (file)
@@ -57,8 +57,8 @@ namespace xmlsignature {
             m_signature(NULL), m_c14n(NULL), m_sm(NULL), m_key(NULL), m_keyInfo(NULL), m_reference(NULL) {}\r
         virtual ~XMLSecSignatureImpl();\r
         \r
-        void releaseDOM();\r
-        void releaseChildrenDOM(bool propagateRelease=true) {\r
+        void releaseDOM() const;\r
+        void releaseChildrenDOM(bool propagateRelease=true) const {\r
             if (m_keyInfo) {\r
                 m_keyInfo->releaseDOM();\r
                 if (propagateRelease)\r
@@ -135,15 +135,17 @@ XMLSecSignatureImpl::~XMLSecSignatureImpl()
     for_each(m_validators.begin(),m_validators.end(),cleanup<Validator>());\r
 }\r
 \r
-void XMLSecSignatureImpl::releaseDOM()\r
+void XMLSecSignatureImpl::releaseDOM() const\r
 {\r
-    // This should save off the DOM\r
-    UnknownElementImpl::releaseDOM();\r
-    \r
-    // Release the associated signature.\r
-    if (m_signature) {\r
-        XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
-        m_signature=NULL;\r
+    if (getDOM()) {\r
+        // This should save off the DOM\r
+        UnknownElementImpl::releaseDOM();\r
+        \r
+        // Release the associated signature.\r
+        if (m_signature) {\r
+            XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
+            m_signature=NULL;\r
+        }\r
     }\r
 }\r
 \r
@@ -189,9 +191,6 @@ void XMLSecSignatureImpl::sign()
     try {\r
         log.debug("creating signature reference(s)");\r
         m_reference->createReferences(m_signature);\r
-        if (m_keyInfo) {\r
-            m_keyInfo->marshall(getDOM());\r
-        }\r
         \r
         log.debug("computing signature");\r
         m_signature->setSigningKey(m_key->clone());\r
@@ -225,32 +224,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
             return cachedDOM;\r
         }\r
         \r
-        // We have a DOM but it doesn't match the document we were given, so we import\r
-        // it into the new document.\r
-        cachedDOM=static_cast<DOMElement*>(document->importNode(cachedDOM, true));\r
-\r
-        try {\r
-            XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
-            m_signature=NULL;\r
-            m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
-                document, cachedDOM\r
-                );\r
-            m_signature->load();\r
-        }\r
-        catch(XSECException& e) {\r
-            auto_ptr_char temp(e.getMsg());\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());\r
-        }\r
-        catch(XSECCryptoException& e) {\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());\r
-        }\r
-\r
-        // Recache the DOM.\r
-        setDocumentElement(document, cachedDOM);\r
-        log.debug("caching imported DOM for Signature");\r
-        setDOM(cachedDOM, false);\r
-        releaseParentDOM(true);\r
-        return cachedDOM;\r
+        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
+        // Without an adoptNode option to maintain the child pointers, we have to either import the\r
+        // DOM while somehow reassigning all the nested references (which amounts to a complete\r
+        // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
+        // it back. This depends on all objects being able to preserve their DOM at all costs.\r
+        releaseChildrenDOM(true);\r
+        releaseDOM();\r
     }\r
     \r
     // If we get here, we didn't have a usable DOM.\r
@@ -306,6 +286,11 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
         }\r
     }\r
     \r
+    // Marshall KeyInfo data.\r
+    if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {\r
+        m_keyInfo->marshall(cachedDOM);\r
+    }\r
+\r
     // Recache the DOM and clear the serialized copy.\r
     setDocumentElement(document, cachedDOM);\r
     log.debug("caching DOM for Signature (document is %sbound)", bindDocument ? "" : "not ");\r
@@ -328,37 +313,20 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
     if (cachedDOM) {\r
         if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
             log.debug("Signature has a usable cached DOM, reusing it");\r
-            parentElement->appendChild(cachedDOM);\r
-            releaseParentDOM(true);\r
+            if (parentElement!=cachedDOM->getParentNode()) {\r
+                parentElement->appendChild(cachedDOM);\r
+                releaseParentDOM(true);\r
+            }\r
             return cachedDOM;\r
         }\r
         \r
-        // We have a DOM but it doesn't match the document we were given, so we import\r
-        // it into the new document.\r
-        cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(cachedDOM, true));\r
-\r
-        try {\r
-            XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
-            m_signature=NULL;\r
-            m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
-                parentElement->getOwnerDocument(), cachedDOM\r
-                );\r
-            m_signature->load();\r
-        }\r
-        catch(XSECException& e) {\r
-            auto_ptr_char temp(e.getMsg());\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());\r
-        }\r
-        catch(XSECCryptoException& e) {\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());\r
-        }\r
-\r
-        // Recache the DOM.\r
-        parentElement->appendChild(cachedDOM);\r
-        log.debug("caching imported DOM for Signature");\r
-        setDOM(cachedDOM, false);\r
-        releaseParentDOM(true);\r
-        return cachedDOM;\r
+        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
+        // Without an adoptNode option to maintain the child pointers, we have to either import the\r
+        // DOM while somehow reassigning all the nested references (which amounts to a complete\r
+        // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
+        // it back. This depends on all objects being able to preserve their DOM at all costs.\r
+        releaseChildrenDOM(true);\r
+        releaseDOM();\r
     }\r
     \r
     // If we get here, we didn't have a usable DOM.\r
@@ -397,6 +365,11 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
         }\r
     }\r
 \r
+    // Marshall KeyInfo data.\r
+    if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {\r
+        m_keyInfo->marshall(cachedDOM);\r
+    }\r
+\r
     // Recache the DOM and clear the serialized copy.\r
     parentElement->appendChild(cachedDOM);\r
     log.debug("caching DOM for Signature");\r