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
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
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
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
}\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
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
}\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