Wrap importNode call in exception handler.
[shibboleth/xmltooling.git] / xmltooling / AbstractDOMCachingXMLObject.cpp
index b8d3b42..87f02a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  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.
@@ -33,12 +33,26 @@ using namespace xmltooling;
 using namespace xercesc;
 using namespace std;
 
+AbstractDOMCachingXMLObject::AbstractDOMCachingXMLObject() : m_dom(NULL), m_document(NULL)
+{
+}
+
+AbstractDOMCachingXMLObject::AbstractDOMCachingXMLObject(const AbstractDOMCachingXMLObject& src)
+    : AbstractXMLObject(src), m_dom(NULL), m_document(NULL)
+{
+}
+
 AbstractDOMCachingXMLObject::~AbstractDOMCachingXMLObject()
 {
     if (m_document)
         m_document->release();
 }
 
+DOMElement* AbstractDOMCachingXMLObject::getDOM() const
+{
+    return m_dom;
+}
+
 void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument) const
 {
     m_dom=dom;
@@ -49,6 +63,15 @@ void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument) con
     }
 }
 
+void AbstractDOMCachingXMLObject::setDocument(DOMDocument* doc) const
+{
+    if (m_document != doc) {
+        if (m_document)
+            m_document->release();
+        m_document=doc;
+    }
+}
+
 void AbstractDOMCachingXMLObject::releaseDOM() const
 {
     if (m_dom) {
@@ -73,15 +96,17 @@ void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease) const
     }
 }
 
-class _release : public binary_function<XMLObject*,bool,void> {
-public:
-    void operator()(XMLObject* obj, bool propagate) const {
-        if (obj) {
-            obj->releaseDOM();
-            if (propagate)
-                obj->releaseChildrenDOM(propagate);
+namespace {
+    class _release : public binary_function<XMLObject*,bool,void> {
+    public:
+        void operator()(XMLObject* obj, bool propagate) const {
+            if (obj) {
+                obj->releaseDOM();
+                if (propagate)
+                    obj->releaseChildrenDOM(propagate);
+            }
         }
-    }
+    };
 };
 
 void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease) const
@@ -99,9 +124,18 @@ void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease) cons
 DOMElement* AbstractDOMCachingXMLObject::cloneDOM(DOMDocument* doc) const
 {
     if (getDOM()) {
-        if (!doc)
-            doc=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
-        return static_cast<DOMElement*>(doc->importNode(getDOM(),true));
+        DOMDocument* cloneDoc = doc;
+        if (!cloneDoc)
+            cloneDoc=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+        try {
+            return static_cast<DOMElement*>(cloneDoc->importNode(getDOM(),true));
+        }
+        catch (XMLException& ex) {
+            if (!doc)
+                cloneDoc->release();
+            auto_ptr_char temp(ex.getMessage());
+            m_log.error("DOM clone failed: %s", temp.get());
+        }
     }
     return NULL;
 }