summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mst@openoffice.org>2011-01-19 20:27:25 +0100
committerMichael Stahl <mst@openoffice.org>2011-01-19 20:27:25 +0100
commitdd377d72a5ef66daee850b66ab7b7308939a7626 (patch)
tree0e646ac37439bc4717bb8dd4005728d4af082271
parent46716bcf7fd75a2a293722a6a458e4138c91f394 (diff)
xmlfix3: #i113682#: unoxml: no more globals in CNode:
instead now the CDocument contains a node map member.
-rw-r--r--unoxml/source/dom/attr.cxx14
-rw-r--r--unoxml/source/dom/attr.hxx5
-rw-r--r--unoxml/source/dom/attributesmap.cxx16
-rw-r--r--unoxml/source/dom/cdatasection.hxx2
-rw-r--r--unoxml/source/dom/childlist.cxx4
-rw-r--r--unoxml/source/dom/comment.hxx3
-rw-r--r--unoxml/source/dom/document.cxx220
-rw-r--r--unoxml/source/dom/document.hxx27
-rw-r--r--unoxml/source/dom/documentbuilder.cxx12
-rw-r--r--unoxml/source/dom/documentfragment.hxx4
-rw-r--r--unoxml/source/dom/documenttype.hxx4
-rw-r--r--unoxml/source/dom/element.cxx35
-rw-r--r--unoxml/source/dom/element.hxx3
-rw-r--r--unoxml/source/dom/elementlist.cxx3
-rw-r--r--unoxml/source/dom/entity.hxx4
-rw-r--r--unoxml/source/dom/entityreference.hxx4
-rw-r--r--unoxml/source/dom/node.cxx264
-rw-r--r--unoxml/source/dom/node.hxx41
-rw-r--r--unoxml/source/dom/notation.hxx4
-rw-r--r--unoxml/source/dom/processinginstruction.hxx3
-rw-r--r--unoxml/source/dom/text.hxx3
-rw-r--r--unoxml/source/events/eventdispatcher.cxx25
-rw-r--r--unoxml/source/events/eventdispatcher.hxx9
-rw-r--r--unoxml/source/xpath/nodelist.cxx4
-rw-r--r--unoxml/source/xpath/xpathapi.cxx22
25 files changed, 400 insertions, 335 deletions
diff --git a/unoxml/source/dom/attr.cxx b/unoxml/source/dom/attr.cxx
index 6cd335c38b4d..56c19da592d6 100644
--- a/unoxml/source/dom/attr.cxx
+++ b/unoxml/source/dom/attr.cxx
@@ -25,11 +25,16 @@
*
************************************************************************/
-#include "attr.hxx"
-#include "element.hxx"
-#include <com/sun/star/xml/dom/DOMException.hdl>
+#include <attr.hxx>
+
#include <string.h>
+#include <com/sun/star/xml/dom/DOMException.hdl>
+#include <com/sun/star/xml/dom/events/XMutationEvent.hpp>
+
+#include <document.hxx>
+
+
namespace DOM
{
CAttr::CAttr(CDocument const& rDocument, xmlAttrPtr const pAttr)
@@ -81,7 +86,8 @@ namespace DOM
return 0;
}
Reference< XElement > const xRet(
- static_cast< XNode* >(CNode::getCNode(m_aAttrPtr->parent).get()),
+ static_cast< XNode* >(GetOwnerDocument().GetCNode(
+ m_aAttrPtr->parent).get()),
UNO_QUERY_THROW);
return xRet;
}
diff --git a/unoxml/source/dom/attr.hxx b/unoxml/source/dom/attr.hxx
index bff00353b7cb..489d9ee0ccca 100644
--- a/unoxml/source/dom/attr.hxx
+++ b/unoxml/source/dom/attr.hxx
@@ -49,8 +49,9 @@ namespace DOM
class CAttr
: public CAttr_Base
{
- friend class CNode;
- friend class CElement;
+ private:
+ friend class CDocument;
+
private:
xmlAttrPtr m_aAttrPtr;
diff --git a/unoxml/source/dom/attributesmap.cxx b/unoxml/source/dom/attributesmap.cxx
index 5ed65bf10bfc..cad05123bf96 100644
--- a/unoxml/source/dom/attributesmap.cxx
+++ b/unoxml/source/dom/attributesmap.cxx
@@ -30,6 +30,7 @@
#include <string.h>
#include <element.hxx>
+#include <document.hxx>
namespace DOM
@@ -75,7 +76,8 @@ namespace DOM
{
if( strcmp((char*)xName, (char*)cur->name) == 0)
{
- aNode = Reference< XNode >( CNode::getCNode(
+ aNode = Reference< XNode >(
+ m_pElement->GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(cur)).get() );
break;
}
@@ -108,7 +110,8 @@ namespace DOM
if( strcmp((char*)xName, (char*)cur->name) == 0 &&
cur->ns == pNs)
{
- aNode = Reference< XNode >( CNode::getCNode(
+ aNode = Reference< XNode >(
+ m_pElement->GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(cur)).get() );
break;
}
@@ -134,7 +137,8 @@ namespace DOM
{
if (count == index)
{
- aNode = Reference< XNode >( CNode::getCNode(
+ aNode = Reference< XNode >(
+ m_pElement->GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(cur)).get() );
break;
}
@@ -161,7 +165,8 @@ namespace DOM
while (cur != NULL)
{
if (strcmp((char*)xName, (char*)cur->name) == 0) {
- ::rtl::Reference<CNode> const pCNode = CNode::getCNode(
+ ::rtl::Reference<CNode> const pCNode =
+ m_pElement->GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(cur)).get();
// this seems to be legal...
xmlUnlinkNode(reinterpret_cast<xmlNodePtr>(cur));
@@ -196,7 +201,8 @@ namespace DOM
if (strcmp((char*)xName, (char*)cur->name) == 0 &&
cur->ns == pNs)
{
- ::rtl::Reference<CNode> const pCNode = CNode::getCNode(
+ ::rtl::Reference<CNode> const pCNode =
+ m_pElement->GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(cur)).get();
// this seems to be legal...
xmlUnlinkNode(reinterpret_cast<xmlNodePtr>(cur));
diff --git a/unoxml/source/dom/cdatasection.hxx b/unoxml/source/dom/cdatasection.hxx
index ca278319089c..446064bc137d 100644
--- a/unoxml/source/dom/cdatasection.hxx
+++ b/unoxml/source/dom/cdatasection.hxx
@@ -46,7 +46,7 @@ namespace DOM
class CCDATASection
: public CCDATASection_Base
{
- friend class CNode;
+ friend class CDocument;
protected:
CCDATASection(CDocument const& rDocument, xmlNodePtr const pNode);
diff --git a/unoxml/source/dom/childlist.cxx b/unoxml/source/dom/childlist.cxx
index fa06c1ec6bd6..f50c7b4892f7 100644
--- a/unoxml/source/dom/childlist.cxx
+++ b/unoxml/source/dom/childlist.cxx
@@ -30,6 +30,7 @@
#include <libxml/tree.h>
#include <node.hxx>
+#include <document.hxx>
namespace DOM
@@ -75,7 +76,8 @@ namespace DOM
while (cur != NULL)
{
if (index-- == 0) {
- return Reference< XNode >(CNode::getCNode(cur).get());
+ return Reference< XNode >(
+ m_pNode->GetOwnerDocument().GetCNode(cur).get());
}
cur = cur->next;
}
diff --git a/unoxml/source/dom/comment.hxx b/unoxml/source/dom/comment.hxx
index 208a075d4ea5..00f8644099d9 100644
--- a/unoxml/source/dom/comment.hxx
+++ b/unoxml/source/dom/comment.hxx
@@ -46,7 +46,8 @@ namespace DOM
class CComment
: public CComment_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
protected:
CComment(CDocument const& rDocument, xmlNodePtr const pNode);
diff --git a/unoxml/source/dom/document.cxx b/unoxml/source/dom/document.cxx
index a84358fd69d8..92b106c1ced7 100644
--- a/unoxml/source/dom/document.cxx
+++ b/unoxml/source/dom/document.cxx
@@ -40,6 +40,8 @@
#include "documenttype.hxx"
#include "elementlist.hxx"
#include "domimplementation.hxx"
+#include <entity.hxx>
+#include <notation.hxx>
#include "../events/event.hxx"
#include "../events/mutationevent.hxx"
@@ -68,20 +70,43 @@ namespace DOM
return cur;
}
- CDocument::~CDocument()
- {
- xmlFreeDoc(m_aDocPtr);
- }
-
- CDocument::CDocument(xmlDocPtr aDocPtr)
+ CDocument::CDocument(xmlDocPtr const pDoc)
: CDocument_Base(*this,
- NodeType_DOCUMENT_NODE, reinterpret_cast<xmlNodePtr>(aDocPtr))
- , m_aDocPtr(aDocPtr)
+ NodeType_DOCUMENT_NODE, reinterpret_cast<xmlNodePtr>(pDoc))
+ , m_aDocPtr(pDoc)
, m_streamListeners()
, m_pEventDispatcher(new events::CEventDispatcher())
{
}
+ ::rtl::Reference<CDocument> CDocument::CreateCDocument(xmlDocPtr const pDoc)
+ {
+ ::rtl::Reference<CDocument> const xDoc(new CDocument(pDoc));
+ // add the doc itself to its nodemap!
+ xDoc->m_NodeMap.insert(
+ nodemap_t::value_type(reinterpret_cast<xmlNodePtr>(pDoc),
+ ::std::make_pair(
+ WeakReference<XNode>(static_cast<XDocument*>(xDoc.get())),
+ xDoc.get())));
+ return xDoc;
+ }
+
+ CDocument::~CDocument()
+ {
+#ifdef DBG_UTIL
+ // node map must be empty now, otherwise CDocument must not die!
+ for (nodemap_t::iterator i = m_NodeMap.begin();
+ i != m_NodeMap.end(); ++i)
+ {
+ Reference<XNode> const xNode(i->second.first);
+ OSL_ENSURE(!xNode.is(),
+ "CDocument::~CDocument(): ERROR: live node in document node map!");
+ }
+#endif
+ xmlFreeDoc(m_aDocPtr);
+ }
+
+
events::CEventDispatcher & CDocument::GetEventDispatcher()
{
return *m_pEventDispatcher;
@@ -91,17 +116,162 @@ namespace DOM
{
xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr);
::rtl::Reference< CElement > const xRet(
- dynamic_cast<CElement*>(CNode::getCNode(pNode).get()));
+ dynamic_cast<CElement*>(GetCNode(pNode).get()));
return xRet;
}
+ namespace {
+ struct NodeMutex : public ::rtl::Static<osl::Mutex, NodeMutex> {};
+ }
+
+ void
+ CDocument::RemoveCNode(xmlNodePtr const pNode, CNode const*const pCNode)
+ {
+ ::osl::MutexGuard guard(NodeMutex::get());
+ nodemap_t::iterator const i = m_NodeMap.find(pNode);
+ if (i != m_NodeMap.end()) {
+ // #i113681# consider this scenario:
+ // T1 calls ~CNode
+ // T2 calls getCNode: lookup will find i->second->first invalid
+ // so a new CNode is created and inserted
+ // T1 calls removeCNode: i->second->second now points to a
+ // different CNode instance!
+ //
+ // check that the CNode is the right one
+ CNode *const pCurrent = i->second.second;
+ if (pCurrent == pCNode) {
+ m_NodeMap.erase(i);
+ }
+ }
+ }
+
+ ::rtl::Reference<CNode>
+ CDocument::GetCNode(xmlNodePtr const pNode, bool const bCreate)
+ {
+ if (0 == pNode) {
+ return 0;
+ }
+ //see CNode::remove
+ ::osl::MutexGuard guard(NodeMutex::get());
+ //check whether there is already an instance for this node
+ nodemap_t::const_iterator const i = m_NodeMap.find(pNode);
+ if (i != m_NodeMap.end()) {
+ // #i113681# check that the CNode is still alive
+ uno::Reference<XNode> const xNode(i->second.first);
+ if (xNode.is())
+ {
+ ::rtl::Reference<CNode> ret(i->second.second);
+ OSL_ASSERT(ret.is());
+ return ret;
+ }
+ }
+
+ if (!bCreate) { return 0; }
+
+ // there is not yet an instance wrapping this node,
+ // create it and store it in the map
+
+ ::rtl::Reference<CNode> pCNode;
+ switch (pNode->type)
+ {
+ case XML_ELEMENT_NODE:
+ // m_aNodeType = NodeType::ELEMENT_NODE;
+ pCNode = static_cast< CNode* >(new CElement(*this, pNode));
+ break;
+ case XML_TEXT_NODE:
+ // m_aNodeType = NodeType::TEXT_NODE;
+ pCNode = static_cast< CNode* >(new CText(*this, pNode));
+ break;
+ case XML_CDATA_SECTION_NODE:
+ // m_aNodeType = NodeType::CDATA_SECTION_NODE;
+ pCNode = static_cast< CNode* >(new CCDATASection(*this, pNode));
+ break;
+ case XML_ENTITY_REF_NODE:
+ // m_aNodeType = NodeType::ENTITY_REFERENCE_NODE;
+ pCNode = static_cast< CNode* >(new CEntityReference(*this,
+ pNode));
+ break;
+ case XML_ENTITY_NODE:
+ // m_aNodeType = NodeType::ENTITY_NODE;
+ pCNode = static_cast< CNode* >(new CEntity(*this,
+ reinterpret_cast<xmlEntityPtr>(pNode)));
+ break;
+ case XML_PI_NODE:
+ // m_aNodeType = NodeType::PROCESSING_INSTRUCTION_NODE;
+ pCNode = static_cast< CNode* >(
+ new CProcessingInstruction(*this, pNode));
+ break;
+ case XML_COMMENT_NODE:
+ // m_aNodeType = NodeType::COMMENT_NODE;
+ pCNode = static_cast< CNode* >(new CComment(*this, pNode));
+ break;
+ case XML_DOCUMENT_NODE:
+ // m_aNodeType = NodeType::DOCUMENT_NODE;
+ OSL_ENSURE(false, "CDocument::GetCNode is not supposed to"
+ " create a CDocument!!!");
+ pCNode = static_cast< CNode* >(new CDocument(
+ reinterpret_cast<xmlDocPtr>(pNode)));
+ break;
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DTD_NODE:
+ // m_aNodeType = NodeType::DOCUMENT_TYPE_NODE;
+ pCNode = static_cast< CNode* >(new CDocumentType(*this,
+ reinterpret_cast<xmlDtdPtr>(pNode)));
+ break;
+ case XML_DOCUMENT_FRAG_NODE:
+ // m_aNodeType = NodeType::DOCUMENT_FRAGMENT_NODE;
+ pCNode = static_cast< CNode* >(new CDocumentFragment(*this,
+ pNode));
+ break;
+ case XML_NOTATION_NODE:
+ // m_aNodeType = NodeType::NOTATION_NODE;
+ pCNode = static_cast< CNode* >(new CNotation(*this,
+ reinterpret_cast<xmlNotationPtr>(pNode)));
+ break;
+ case XML_ATTRIBUTE_NODE:
+ // m_aNodeType = NodeType::ATTRIBUTE_NODE;
+ pCNode = static_cast< CNode* >(new CAttr(*this,
+ reinterpret_cast<xmlAttrPtr>(pNode)));
+ break;
+ // unsupported node types
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_ELEMENT_DECL:
+ case XML_ATTRIBUTE_DECL:
+ case XML_ENTITY_DECL:
+ case XML_NAMESPACE_DECL:
+ default:
+ break;
+ }
+
+ if (pCNode != 0) {
+ bool const bInserted = m_NodeMap.insert(
+ nodemap_t::value_type(pNode,
+ ::std::make_pair(WeakReference<XNode>(pCNode.get()),
+ pCNode.get()))
+ ).second;
+ OSL_ASSERT(bInserted);
+ if (!bInserted) {
+ // if insertion failed, delete new instance and return null
+ return 0;
+ }
+ }
+
+ OSL_ENSURE(pCNode.is(), "no node produced during CDocument::GetCNode!");
+ return pCNode;
+ }
+
+
+ CDocument & CDocument::GetOwnerDocument()
+ {
+ return *this;
+ }
void SAL_CALL CDocument::saxify(
const Reference< XDocumentHandler >& i_xHandler) {
i_xHandler->startDocument();
for (xmlNodePtr pChild = m_aNodePtr->children;
pChild != 0; pChild = pChild->next) {
- ::rtl::Reference<CNode> const pNode = CNode::getCNode(pChild);
+ ::rtl::Reference<CNode> const pNode = GetCNode(pChild);
OSL_ENSURE(pNode != 0, "CNode::get returned 0");
pNode->saxify(i_xHandler);
}
@@ -112,7 +282,7 @@ namespace DOM
rContext.mxDocHandler->startDocument();
for (xmlNodePtr pChild = m_aNodePtr->children;
pChild != 0; pChild = pChild->next) {
- ::rtl::Reference<CNode> const pNode = CNode::getCNode(pChild);
+ ::rtl::Reference<CNode> const pNode = GetCNode(pChild);
OSL_ENSURE(pNode != 0, "CNode::get returned 0");
pNode->fastSaxify(rContext);
}
@@ -214,7 +384,7 @@ namespace DOM
xmlChar *xName = (xmlChar*)o1.getStr();
xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr, xName, NULL);
Reference< XAttr > const xRet(
- static_cast< XNode* >(CNode::getCNode(
+ static_cast< XNode* >(GetCNode(
reinterpret_cast<xmlNodePtr>(pAttr)).get()),
UNO_QUERY_THROW);
return xRet;
@@ -255,7 +425,7 @@ namespace DOM
xmlNsPtr pNs = xmlNewNs(pNode, xUri, xPrefix);
xmlAttrPtr pAttr = xmlNewNsProp(pNode, pNs, xName, NULL);
Reference< XAttr > const xRet(
- static_cast< XNode* >(CNode::getCNode(
+ static_cast< XNode* >(GetCNode(
reinterpret_cast<xmlNodePtr>(pAttr)).get()),
UNO_QUERY_THROW);
return xRet;
@@ -268,7 +438,7 @@ namespace DOM
xmlChar *xData = (xmlChar*)OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr();
xmlNodePtr pText = xmlNewCDataBlock(m_aDocPtr, xData, strlen((char*)xData));
Reference< XCDATASection > const xRet(
- static_cast< XNode* >(CNode::getCNode(pText).get()),
+ static_cast< XNode* >(GetCNode(pText).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -281,7 +451,7 @@ namespace DOM
xmlChar *xData = (xmlChar*)o1.getStr();
xmlNodePtr pComment = xmlNewDocComment(m_aDocPtr, xData);
Reference< XComment > const xRet(
- static_cast< XNode* >(CNode::getCNode(pComment).get()),
+ static_cast< XNode* >(GetCNode(pComment).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -292,7 +462,7 @@ namespace DOM
{
xmlNodePtr pFrag = xmlNewDocFragment(m_aDocPtr);
Reference< XDocumentFragment > const xRet(
- static_cast< XNode* >(CNode::getCNode(pFrag).get()),
+ static_cast< XNode* >(GetCNode(pFrag).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -305,7 +475,7 @@ namespace DOM
xmlChar *xName = (xmlChar*)o1.getStr();
xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL);
Reference< XElement > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -340,7 +510,7 @@ namespace DOM
xmlNsPtr const pNs = xmlNewNs(pNode, xUri, xPrefix);
xmlSetNs(pNode, pNs);
Reference< XElement > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -353,7 +523,7 @@ namespace DOM
xmlChar *xName = (xmlChar*)o1.getStr();
xmlNodePtr const pNode = xmlNewReference(m_aDocPtr, xName);
Reference< XEntityReference > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -371,7 +541,7 @@ namespace DOM
xmlNodePtr const pNode = xmlNewPI(xTarget, xData);
pNode->doc = m_aDocPtr;
Reference< XProcessingInstruction > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -384,7 +554,7 @@ namespace DOM
xmlChar *xData = (xmlChar*)o1.getStr();
xmlNodePtr const pNode = xmlNewDocText(m_aDocPtr, xData);
Reference< XText > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -402,7 +572,7 @@ namespace DOM
break;
}
Reference< XDocumentType > const xRet(
- static_cast< XNode* >(CNode::getCNode(cur).get()),
+ static_cast< XNode* >(GetCNode(cur).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -414,7 +584,7 @@ namespace DOM
{
xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr);
Reference< XElement > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
@@ -452,10 +622,10 @@ namespace DOM
// search the tree for an element with the given ID
OString o1 = OUStringToOString(elementId, RTL_TEXTENCODING_UTF8);
xmlChar *xId = (xmlChar*)o1.getStr();
- xmlNodePtr pStart = CNode::getNodePtr(getDocumentElement().get());
+ xmlNodePtr const pStart = lcl_getDocumentRootPtr(m_aDocPtr);
xmlNodePtr const pNode = _search_element_by_id(pStart, xId);
Reference< XElement > const xRet(
- static_cast< XNode* >(CNode::getCNode(pNode).get()),
+ static_cast< XNode* >(GetCNode(pNode).get()),
UNO_QUERY_THROW);
return xRet;
}
diff --git a/unoxml/source/dom/document.hxx b/unoxml/source/dom/document.hxx
index 8a5758bfe415..f10bf5010732 100644
--- a/unoxml/source/dom/document.hxx
+++ b/unoxml/source/dom/document.hxx
@@ -82,28 +82,43 @@ namespace DOM
class CDocument
: public CDocument_Base
{
- friend class CNode;
- typedef set< Reference< XStreamListener > > listenerlist_t;
+
private:
xmlDocPtr const m_aDocPtr;
// datacontrol/source state
+ typedef set< Reference< XStreamListener > > listenerlist_t;
listenerlist_t m_streamListeners;
Reference< XOutputStream > m_rOutputStream;
+ typedef std::map< const xmlNodePtr,
+ ::std::pair< WeakReference<XNode>, CNode* > > nodemap_t;
+ nodemap_t m_NodeMap;
+
::std::auto_ptr<events::CEventDispatcher> const m_pEventDispatcher;
- protected:
- CDocument(xmlDocPtr aDocPtr);
+ CDocument(xmlDocPtr const pDocPtr);
- events::CEventDispatcher & GetEventDispatcher();
- ::rtl::Reference< CElement > GetDocumentElement();
public:
+ /// factory: only way to create instance!
+ static ::rtl::Reference<CDocument>
+ CreateCDocument(xmlDocPtr const pDoc);
virtual ~CDocument();
+ events::CEventDispatcher & GetEventDispatcher();
+ ::rtl::Reference< CElement > GetDocumentElement();
+
+ /// get UNO wrapper instance for a libxml node
+ ::rtl::Reference<CNode> GetCNode(
+ xmlNodePtr const pNode, bool const bCreate = true);
+ /// remove a UNO wrapper instance
+ void RemoveCNode(xmlNodePtr const pNode, CNode const*const pCNode);
+
+ virtual CDocument & GetOwnerDocument();
+
virtual void SAL_CALL saxify(
const Reference< XDocumentHandler >& i_xHandler);
diff --git a/unoxml/source/dom/documentbuilder.cxx b/unoxml/source/dom/documentbuilder.cxx
index e9f10249292e..4b9cba2ec0ed 100644
--- a/unoxml/source/dom/documentbuilder.cxx
+++ b/unoxml/source/dom/documentbuilder.cxx
@@ -185,9 +185,7 @@ namespace DOM
// create a new document
xmlDocPtr pDocument = xmlNewDoc((const xmlChar*)"1.0");
Reference< XDocument > const xRet(
- static_cast< XNode* >(CNode::getCNode(
- reinterpret_cast<xmlNodePtr>(pDocument)).get()),
- UNO_QUERY_THROW);
+ CDocument::CreateCDocument(pDocument).get());
return xRet;
}
@@ -361,9 +359,7 @@ namespace DOM
}
xmlFreeParserCtxt(ctxt);
Reference< XDocument > const xRet(
- static_cast< XNode* >(CNode::getCNode(
- reinterpret_cast<xmlNodePtr>(pDoc)).get()),
- UNO_QUERY_THROW);
+ CDocument::CreateCDocument(pDoc).get());
return xRet;
}
@@ -414,9 +410,7 @@ namespace DOM
}
xmlFreeParserCtxt(ctxt);
Reference< XDocument > const xRet(
- static_cast< XNode* >(CNode::getCNode(
- reinterpret_cast<xmlNodePtr>(pDoc)).get()),
- UNO_QUERY_THROW);
+ CDocument::CreateCDocument(pDoc).get());
return xRet;
}
diff --git a/unoxml/source/dom/documentfragment.hxx b/unoxml/source/dom/documentfragment.hxx
index 56fd0b55b269..cc65524fa15b 100644
--- a/unoxml/source/dom/documentfragment.hxx
+++ b/unoxml/source/dom/documentfragment.hxx
@@ -46,7 +46,9 @@ namespace DOM
class CDocumentFragment
: public CDocumentFragment_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
+
protected:
CDocumentFragment(CDocument const& rDocument,
xmlNodePtr const pNode);
diff --git a/unoxml/source/dom/documenttype.hxx b/unoxml/source/dom/documenttype.hxx
index 654c88c3062d..925c42637e91 100644
--- a/unoxml/source/dom/documenttype.hxx
+++ b/unoxml/source/dom/documenttype.hxx
@@ -52,7 +52,9 @@ namespace DOM
class CDocumentType
: public CDocumentType_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
+
private:
xmlDtdPtr m_aDtdPtr;
diff --git a/unoxml/source/dom/element.cxx b/unoxml/source/dom/element.cxx
index 6d779599cc96..57fd65e7beec 100644
--- a/unoxml/source/dom/element.cxx
+++ b/unoxml/source/dom/element.cxx
@@ -40,6 +40,8 @@
#include "../events/mutationevent.hxx"
+#include <document.hxx>
+
namespace DOM
{
@@ -73,8 +75,8 @@ namespace DOM
// add attributes
for (xmlAttrPtr pAttr = m_aNodePtr->properties;
pAttr != 0; pAttr = pAttr->next) {
- ::rtl::Reference<CNode> const pNode =
- CNode::getCNode(reinterpret_cast<xmlNodePtr>(pAttr));
+ ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
+ reinterpret_cast<xmlNodePtr>(pAttr));
OSL_ENSURE(pNode != 0, "CNode::get returned 0");
OUString prefix = pNode->getPrefix();
OUString name = (prefix.getLength() == 0)
@@ -92,7 +94,8 @@ namespace DOM
// recurse
for (xmlNodePtr pChild = m_aNodePtr->children;
pChild != 0; pChild = pChild->next) {
- ::rtl::Reference<CNode> const pNode = CNode::getCNode(pChild);
+ ::rtl::Reference<CNode> const pNode(
+ GetOwnerDocument().GetCNode(pChild));
OSL_ENSURE(pNode != 0, "CNode::get returned 0");
pNode->saxify(i_xHandler);
}
@@ -108,8 +111,8 @@ namespace DOM
i_rContext.mxAttribList->clear();
for (xmlAttrPtr pAttr = m_aNodePtr->properties;
pAttr != 0; pAttr = pAttr->next) {
- ::rtl::Reference<CNode> const pNode =
- CNode::getCNode(reinterpret_cast<xmlNodePtr>(pAttr));
+ ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
+ reinterpret_cast<xmlNodePtr>(pAttr));
OSL_ENSURE(pNode != 0, "CNode::get returned 0");
const xmlChar* xName = pAttr->name;
@@ -172,7 +175,8 @@ namespace DOM
// recurse
for (xmlNodePtr pChild = m_aNodePtr->children;
pChild != 0; pChild = pChild->next) {
- ::rtl::Reference<CNode> const pNode = CNode::getCNode(pChild);
+ ::rtl::Reference<CNode> const pNode(
+ GetOwnerDocument().GetCNode(pChild));
OSL_ENSURE(pNode != 0, "CNode::get returned 0");
pNode->fastSaxify(i_rContext);
}
@@ -236,7 +240,7 @@ namespace DOM
return 0;
}
Reference< XAttr > const xRet(
- static_cast< XNode* >(CNode::getCNode(
+ static_cast< XNode* >(GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(pAttr)).get()),
UNO_QUERY_THROW);
return xRet;
@@ -263,7 +267,7 @@ namespace DOM
return 0;
}
Reference< XAttr > const xRet(
- static_cast< XNode* >(CNode::getCNode(
+ static_cast< XNode* >(GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(pAttr)).get()),
UNO_QUERY_THROW);
return xRet;
@@ -403,7 +407,11 @@ namespace DOM
Reference< XAttr > aAttr;
if(m_aNodePtr != NULL)
{
- xmlNodePtr const pNode = CNode::getNodePtr(oldAttr.get());
+ ::rtl::Reference<CNode> const pCNode(
+ CNode::GetImplementation(Reference<XNode>(oldAttr.get())));
+ if (!pCNode.is()) { throw RuntimeException(); }
+
+ xmlNodePtr const pNode = pCNode->GetNodePtr();
xmlAttrPtr const pAttr = (xmlAttrPtr) pNode;
if (pAttr->parent != m_aNodePtr)
@@ -426,7 +434,6 @@ namespace DOM
aAttr = oldAttr->getOwnerDocument()->createAttribute(oldAttr->getName());
aAttr->setValue(oldAttr->getValue());
xmlRemoveProp(pAttr);
- ::rtl::Reference<CNode> const pCNode( CNode::getCNode(pNode) );
pCNode->invalidate(); // freed by xmlRemoveProp
}
return aAttr;
@@ -449,7 +456,11 @@ namespace DOM
}
// get the implementation
- xmlAttrPtr pAttr = (xmlAttrPtr) CNode::getNodePtr(newAttr.get());
+ CNode *const pCNode = CNode::GetImplementation(newAttr);
+ if (!pCNode) { throw RuntimeException(); }
+ xmlAttrPtr const pAttr =
+ reinterpret_cast<xmlAttrPtr>(pCNode->GetNodePtr());
+ if (!pAttr) { throw RuntimeException(); }
// check whether the attribute is not in use by another element
xmlNsPtr pNs = NULL;
@@ -477,7 +488,7 @@ namespace DOM
// get the new attr node
aAttr = Reference< XAttr >(
- static_cast< XNode* >(CNode::getCNode(
+ static_cast< XNode* >(GetOwnerDocument().GetCNode(
reinterpret_cast<xmlNodePtr>(res)).get()),
UNO_QUERY_THROW);
}
diff --git a/unoxml/source/dom/element.hxx b/unoxml/source/dom/element.hxx
index 89ff9b349ded..bef1f0a5d8f6 100644
--- a/unoxml/source/dom/element.hxx
+++ b/unoxml/source/dom/element.hxx
@@ -50,8 +50,9 @@ namespace DOM
class CElement
: public CElement_Base
{
- friend class CNode;
private:
+ friend class CDocument;
+
Reference< XAttr > _setAttributeNode(const Reference< XAttr >& newAttr, sal_Bool bNS)
throw (RuntimeException);
diff --git a/unoxml/source/dom/elementlist.cxx b/unoxml/source/dom/elementlist.cxx
index fa496ea4d6b0..1112c16ce231 100644
--- a/unoxml/source/dom/elementlist.cxx
+++ b/unoxml/source/dom/elementlist.cxx
@@ -30,6 +30,7 @@
#include <string.h>
#include <element.hxx>
+#include <document.hxx>
namespace DOM
@@ -126,7 +127,7 @@ namespace DOM
throw RuntimeException();
}
Reference< XNode > const xRet(
- CNode::getCNode(m_nodevector[index]).get());
+ m_pElement->GetOwnerDocument().GetCNode(m_nodevector[index]).get());
return xRet;
}
diff --git a/unoxml/source/dom/entity.hxx b/unoxml/source/dom/entity.hxx
index 58e4b53dbb21..e785f9343e36 100644
--- a/unoxml/source/dom/entity.hxx
+++ b/unoxml/source/dom/entity.hxx
@@ -50,7 +50,9 @@ namespace DOM
class CEntity
: public CEntity_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
+
private:
xmlEntityPtr m_aEntityPtr;
diff --git a/unoxml/source/dom/entityreference.hxx b/unoxml/source/dom/entityreference.hxx
index 63cad5fe302e..3d1d0569b0b3 100644
--- a/unoxml/source/dom/entityreference.hxx
+++ b/unoxml/source/dom/entityreference.hxx
@@ -48,7 +48,9 @@ namespace DOM
class CEntityReference
: public CEntityReference_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
+
protected:
CEntityReference(CDocument const& rDocument, xmlNodePtr const pNode);
diff --git a/unoxml/source/dom/node.cxx b/unoxml/source/dom/node.cxx
index 85de84c71e30..f16babb3ab2f 100644
--- a/unoxml/source/dom/node.cxx
+++ b/unoxml/source/dom/node.cxx
@@ -40,19 +40,8 @@
#include <com/sun/star/xml/sax/FastToken.hpp>
-#include "element.hxx"
-#include "text.hxx"
-#include "cdatasection.hxx"
-#include "entityreference.hxx"
-#include "entity.hxx"
-#include "processinginstruction.hxx"
-#include "comment.hxx"
-#include "document.hxx"
-#include "documenttype.hxx"
-#include "documentfragment.hxx"
-#include "notation.hxx"
-#include "childlist.hxx"
-#include "attr.hxx"
+#include <document.hxx>
+#include <childlist.hxx>
#include "../events/eventdispatcher.hxx"
#include "../events/mutationevent.hxx"
@@ -63,8 +52,6 @@ using namespace ::com::sun::star;
namespace {
-//see CNode::remove
- struct NodeMutex: public ::rtl::Static<osl::Mutex, NodeMutex> {};
struct UnoTunnelId
: public ::rtl::StaticWithInit< Sequence<sal_Int8>, UnoTunnelId >
{
@@ -154,151 +141,6 @@ namespace DOM
return nNamespaceToken;
}
- typedef std::map< const xmlNodePtr,
- ::std::pair< WeakReference<XNode>, CNode* > > nodemap_t;
- static nodemap_t g_theNodeMap;
-
- void CNode::removeCNode(xmlNodePtr const pNode, CNode const*const pCNode)
- {
- ::osl::MutexGuard guard(NodeMutex::get());
- nodemap_t::iterator const i = g_theNodeMap.find(pNode);
- if (i != g_theNodeMap.end()) {
- // #i113681# consider this scenario:
- // T1 calls ~CNode
- // T2 calls getCNode: lookup will find i->second->first invalid
- // so a new CNode is created and inserted
- // T1 calls removeCNode: i->second->second now points to a
- // different CNode instance!
- //
- // check that the CNode is the right one
- CNode *const pCurrent = i->second.second;
- if (pCurrent == pCNode) {
- g_theNodeMap.erase(i);
- }
- }
- }
-
- ::rtl::Reference<CNode>
- CNode::getCNode(xmlNodePtr const pNode, bool const bCreate)
- {
- if (0 == pNode) {
- return 0;
- }
- //see CNode::remove
- ::osl::MutexGuard guard(NodeMutex::get());
- //check whether there is already an instance for this node
- nodemap_t::const_iterator const i = g_theNodeMap.find(pNode);
- if (i != g_theNodeMap.end()) {
- // #i113681# check that the CNode is still alive
- uno::Reference<XNode> const xNode(i->second.first);
- if (xNode.is())
- {
- ::rtl::Reference<CNode> ret(i->second.second);
- OSL_ASSERT(ret.is());
- return ret;
- }
- }
-
- if (!bCreate) { return 0; }
-
- // there is not yet an instance wrapping this node,
- // create it and store it in the map
-
- ::rtl::Reference<CNode> pCNode;
- switch (pNode->type)
- {
- case XML_ELEMENT_NODE:
- // m_aNodeType = NodeType::ELEMENT_NODE;
- pCNode = static_cast< CNode* >(new CElement(*(CDocument*)0, pNode));
- break;
- case XML_TEXT_NODE:
- // m_aNodeType = NodeType::TEXT_NODE;
- pCNode = static_cast< CNode* >(new CText(*(CDocument*)0, pNode));
- break;
- case XML_CDATA_SECTION_NODE:
- // m_aNodeType = NodeType::CDATA_SECTION_NODE;
- pCNode = static_cast< CNode* >(new CCDATASection(*(CDocument*)0, pNode));
- break;
- case XML_ENTITY_REF_NODE:
- // m_aNodeType = NodeType::ENTITY_REFERENCE_NODE;
- pCNode = static_cast< CNode* >(new CEntityReference(*(CDocument*)0, pNode));
- break;
- case XML_ENTITY_NODE:
- // m_aNodeType = NodeType::ENTITY_NODE;
- pCNode = static_cast< CNode* >(new CEntity(*(CDocument*)0,
- reinterpret_cast<xmlEntityPtr>(pNode)));
- break;
- case XML_PI_NODE:
- // m_aNodeType = NodeType::PROCESSING_INSTRUCTION_NODE;
- pCNode = static_cast< CNode* >(new CProcessingInstruction(*(CDocument*)0, pNode));
- break;
- case XML_COMMENT_NODE:
- // m_aNodeType = NodeType::COMMENT_NODE;
- pCNode = static_cast< CNode* >(new CComment(*(CDocument*)0, pNode));
- break;
- case XML_DOCUMENT_NODE:
- // m_aNodeType = NodeType::DOCUMENT_NODE;
- pCNode = static_cast< CNode* >(new CDocument(
- reinterpret_cast<xmlDocPtr>(pNode)));
- break;
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DTD_NODE:
- // m_aNodeType = NodeType::DOCUMENT_TYPE_NODE;
- pCNode = static_cast< CNode* >(new CDocumentType(*(CDocument*)0,
- reinterpret_cast<xmlDtdPtr>(pNode)));
- break;
- case XML_DOCUMENT_FRAG_NODE:
- // m_aNodeType = NodeType::DOCUMENT_FRAGMENT_NODE;
- pCNode = static_cast< CNode* >(new CDocumentFragment(*(CDocument*)0, pNode));
- break;
- case XML_NOTATION_NODE:
- // m_aNodeType = NodeType::NOTATION_NODE;
- pCNode = static_cast< CNode* >(new CNotation(*(CDocument*)0,
- reinterpret_cast<xmlNotationPtr>(pNode)));
- break;
- case XML_ATTRIBUTE_NODE:
- // m_aNodeType = NodeType::ATTRIBUTE_NODE;
- pCNode = static_cast< CNode* >(new CAttr(*(CDocument*)0,
- reinterpret_cast<xmlAttrPtr>(pNode)));
- break;
- // unsupported node types
- case XML_HTML_DOCUMENT_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
- default:
- break;
- }
-
- if (pCNode != 0) {
- bool const bInserted = g_theNodeMap.insert(
- nodemap_t::value_type(pNode,
- ::std::make_pair(WeakReference<XNode>(pCNode.get()),
- pCNode.get()))
- ).second;
- OSL_ASSERT(bInserted);
- if (!bInserted) {
- // if insertion failed, delete new instance and return null
- return 0;
- }
- }
-
- OSL_ENSURE(pCNode.is(), "no node produced during CNode::getCNode!");
- return pCNode;
- }
-
- xmlNodePtr CNode::getNodePtr(const Reference< XNode >& aNode)
- {
- try {
- CNode *const pNode = GetImplementation(aNode);
- if( pNode )
- return pNode->m_aNodePtr;
- }
- catch(...) {}
- return 0;
- }
-
CNode::CNode(CDocument const& rDocument,
NodeType const& reNodeType, xmlNodePtr const& rpNode)
@@ -316,8 +158,8 @@ namespace DOM
void CNode::invalidate()
{
//remove from list if this wrapper goes away
- if (m_aNodePtr != 0) {
- CNode::removeCNode(m_aNodePtr, this);
+ if (m_aNodePtr != 0 && m_xDocument.is()) {
+ m_xDocument->RemoveCNode(m_aNodePtr, this);
}
// #i113663#: unlinked nodes will not be freed by xmlFreeDoc
if (m_bUnlinked) {
@@ -342,15 +184,10 @@ namespace DOM
return pCNode;
}
- ::rtl::Reference< CDocument > CNode::GetOwnerDocument_Impl()
+ CDocument & CNode::GetOwnerDocument()
{
- if (0 == m_aNodePtr) {
- return 0;
- }
- ::rtl::Reference< CDocument > const xDoc(
- dynamic_cast<CDocument *>(CNode::getCNode(
- reinterpret_cast<xmlNodePtr>(m_aNodePtr->doc)).get()));
- return xDoc;
+ OSL_ASSERT(m_xDocument.is());
+ return *m_xDocument; // needs overriding in CDocument!
}
@@ -443,12 +280,15 @@ namespace DOM
/**
Adds the node newChild to the end of the list of children of this node.
*/
- Reference< XNode > CNode::appendChild(const Reference< XNode >& newChild)
+ Reference< XNode > CNode::appendChild(Reference< XNode > const& xNewChild)
throw (RuntimeException, DOMException)
{
::rtl::Reference<CNode> pNode;
if (m_aNodePtr != NULL) {
- xmlNodePtr cur = CNode::getNodePtr(newChild.get());
+ CNode *const pNewChild(CNode::GetImplementation(xNewChild));
+ if (!pNewChild) { throw RuntimeException(); }
+ xmlNodePtr const cur = pNewChild->GetNodePtr();
+ if (!cur) { throw RuntimeException(); }
// error checks:
// from other document
@@ -515,11 +355,7 @@ namespace DOM
// if res != cur, something was optimized and the newchild-wrapper
// should be updated
if (res && (cur != res)) {
- ::rtl::Reference<CNode> pCNode(CNode::getCNode(cur));
- OSL_ASSERT(pCNode.is());
- if (pCNode.is()) {
- pCNode->invalidate(); // cur has been freed
- }
+ pNewChild->invalidate(); // cur has been freed
}
// use custom ns cleanup instaead of
@@ -527,7 +363,7 @@ namespace DOM
// because that will not remove unneeded ns decls
_nscleanup(res, m_aNodePtr);
- pNode = CNode::getCNode(res);
+ pNode = GetOwnerDocument().GetCNode(res);
}
//XXX check for errors
@@ -542,7 +378,7 @@ namespace DOM
OUString::createFromAscii("DOMNodeInserted")), UNO_QUERY);
event->initMutationEvent(OUString::createFromAscii("DOMNodeInserted")
, sal_True, sal_False,
- Reference< XNode >(CNode::getCNode(m_aNodePtr).get()),
+ this,
OUString(), OUString(), OUString(), (AttrChangeType)0 );
dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
@@ -562,7 +398,7 @@ namespace DOM
if (0 == m_aNodePtr) {
return 0;
}
- ::rtl::Reference<CNode> const pNode = CNode::getCNode(
+ ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
xmlCopyNode(m_aNodePtr, (bDeep) ? 1 : 0));
pNode->m_bUnlinked = true; // not linked yet
//XXX check for errors
@@ -610,7 +446,7 @@ namespace DOM
return 0;
}
Reference< XNode > const xNode(
- CNode::getCNode(m_aNodePtr->children).get());
+ GetOwnerDocument().GetCNode(m_aNodePtr->children).get());
return xNode;
}
@@ -624,7 +460,7 @@ namespace DOM
return 0;
}
Reference< XNode > const xNode(
- CNode::getCNode(xmlGetLastChild(m_aNodePtr)).get());
+ GetOwnerDocument().GetCNode(xmlGetLastChild(m_aNodePtr)).get());
return xNode;
}
@@ -674,7 +510,8 @@ namespace DOM
if (0 == m_aNodePtr) {
return 0;
}
- Reference< XNode > const xNode(CNode::getCNode(m_aNodePtr->next).get());
+ Reference< XNode > const xNode(
+ GetOwnerDocument().GetCNode(m_aNodePtr->next).get());
return xNode;
}
@@ -731,7 +568,10 @@ namespace DOM
Reference< XDocument > SAL_CALL CNode::getOwnerDocument()
throw (RuntimeException)
{
- Reference< XDocument > const xDoc(GetOwnerDocument_Impl().get());
+ if (0 == m_aNodePtr) {
+ return 0;
+ }
+ Reference< XDocument > const xDoc(& GetOwnerDocument());
return xDoc;
}
@@ -745,7 +585,7 @@ namespace DOM
return 0;
}
Reference< XNode > const xNode(
- CNode::getCNode(m_aNodePtr->parent).get());
+ GetOwnerDocument().GetCNode(m_aNodePtr->parent).get());
return xNode;
}
@@ -778,7 +618,7 @@ namespace DOM
return 0;
}
Reference< XNode > const xNode(
- CNode::getCNode(m_aNodePtr->prev).get());
+ GetOwnerDocument().GetCNode(m_aNodePtr->prev).get());
return xNode;
}
@@ -819,8 +659,11 @@ namespace DOM
throw e;
}
- xmlNodePtr pRefChild = CNode::getNodePtr(refChild.get());
- xmlNodePtr pNewChild = CNode::getNodePtr(newChild.get());
+ CNode *const pNewNode(CNode::GetImplementation(newChild));
+ CNode *const pRefNode(CNode::GetImplementation(refChild));
+ if (!pNewNode || !pRefNode) { throw RuntimeException(); }
+ xmlNodePtr const pNewChild(pNewNode->GetNodePtr());
+ xmlNodePtr const pRefChild(pRefNode->GetNodePtr());
xmlNodePtr cur = m_aNodePtr->children;
//search cild before which to insert
@@ -833,8 +676,7 @@ namespace DOM
cur->prev = pNewChild;
if( pNewChild->prev != NULL)
pNewChild->prev->next = pNewChild;
- ::rtl::Reference<CNode> const pNode(CNode::getCNode(pNewChild));
- pNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
+ pNewNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
}
cur = cur->next;
}
@@ -884,8 +726,8 @@ namespace DOM
Reference<XNode> xReturn( oldChild );
- xmlNodePtr old = CNode::getNodePtr(oldChild);
- ::rtl::Reference<CNode> const pOld( CNode::getCNode(old) );
+ ::rtl::Reference<CNode> const pOld(CNode::GetImplementation(oldChild));
+ xmlNodePtr const old = pOld->GetNodePtr();
pOld->m_bUnlinked = true;
if( old->type == XML_ATTRIBUTE_NODE )
@@ -915,7 +757,7 @@ namespace DOM
OUString::createFromAscii("DOMNodeRemoved")), UNO_QUERY);
event->initMutationEvent(OUString::createFromAscii("DOMNodeRemoved"), sal_True,
sal_False,
- Reference< XNode >(CNode::getCNode(m_aNodePtr).get()),
+ this,
OUString(), OUString(), OUString(), (AttrChangeType)0 );
dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
@@ -930,15 +772,16 @@ namespace DOM
and returns the oldChild node.
*/
Reference< XNode > SAL_CALL CNode::replaceChild(
- const Reference< XNode >& newChild, const Reference< XNode >& oldChild)
+ Reference< XNode > const& xNewChild,
+ Reference< XNode > const& xOldChild)
throw (RuntimeException, DOMException)
{
- if (!oldChild.is()) {
+ if (!xOldChild.is()) {
throw RuntimeException();
}
// XXX check node types
- if (oldChild->getParentNode() != Reference< XNode >(this)) {
+ if (xOldChild->getParentNode() != Reference< XNode >(this)) {
DOMException e;
e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
throw e;
@@ -948,8 +791,12 @@ namespace DOM
Reference< XNode > aNode = removeChild(oldChild);
appendChild(newChild);
*/
- xmlNodePtr pOld = CNode::getNodePtr(oldChild);
- xmlNodePtr pNew = CNode::getNodePtr(newChild);
+ ::rtl::Reference<CNode> const pOldNode(
+ CNode::GetImplementation(xOldChild));
+ ::rtl::Reference<CNode> const pNewNode(
+ CNode::GetImplementation(xNewChild));
+ xmlNodePtr const pOld = pOldNode->GetNodePtr();
+ xmlNodePtr const pNew = pNewNode->GetNodePtr();
if( pOld->type == XML_ATTRIBUTE_NODE )
{
@@ -963,9 +810,8 @@ namespace DOM
xmlAttrPtr pAttr = (xmlAttrPtr)pOld;
xmlRemoveProp( pAttr );
- ::rtl::Reference<CNode> const pOldNode( CNode::getCNode(pOld) );
pOldNode->invalidate(); // freed by xmlRemoveProp
- appendChild( newChild );
+ appendChild(xNewChild);
}
else
{
@@ -991,9 +837,7 @@ namespace DOM
pOld->next = NULL;
pOld->prev = NULL;
pOld->parent = NULL;
- ::rtl::Reference<CNode> const pOldNode(CNode::getCNode(pOld));
pOldNode->m_bUnlinked = true;
- ::rtl::Reference<CNode> const pNewNode(CNode::getCNode(pNew));
pNewNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
}
cur = cur->next;
@@ -1002,7 +846,7 @@ namespace DOM
dispatchSubtreeModified();
- return oldChild;
+ return xOldChild;
}
void CNode::dispatchSubtreeModified()
@@ -1054,8 +898,8 @@ namespace DOM
sal_Bool useCapture)
throw (RuntimeException)
{
- events::CEventDispatcher & rDispatcher(
- m_xDocument->GetEventDispatcher());
+ CDocument & rDocument(GetOwnerDocument());
+ events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher());
rDispatcher.addListener(m_aNodePtr, eventType, listener, useCapture);
}
@@ -1064,17 +908,17 @@ namespace DOM
sal_Bool useCapture)
throw (RuntimeException)
{
- events::CEventDispatcher & rDispatcher(
- m_xDocument->GetEventDispatcher());
+ CDocument & rDocument(GetOwnerDocument());
+ events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher());
rDispatcher.removeListener(m_aNodePtr, eventType, listener, useCapture);
}
sal_Bool SAL_CALL CNode::dispatchEvent(const Reference< XEvent >& evt)
throw(RuntimeException, EventException)
{
- events::CEventDispatcher & rDispatcher(
- m_xDocument->GetEventDispatcher());
- rDispatcher.dispatchEvent(this, evt);
+ CDocument & rDocument(GetOwnerDocument());
+ events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher());
+ rDispatcher.dispatchEvent(rDocument, m_aNodePtr, this, evt);
return sal_True;
}
diff --git a/unoxml/source/dom/node.hxx b/unoxml/source/dom/node.hxx
index 5ea34f548264..d959fd49a074 100644
--- a/unoxml/source/dom/node.hxx
+++ b/unoxml/source/dom/node.hxx
@@ -28,34 +28,32 @@
#ifndef DOM_NODE_HXX
#define DOM_NODE_HXX
+#include <hash_map>
+
+#include <libxml/tree.h>
+
+#include <sal/types.h>
#include <rtl/ref.hxx>
#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
-#include <sal/types.h>
-#include <sax/fastattribs.hxx>
-#include <cppuhelper/implbase1.hxx>
+
#include <cppuhelper/implbase3.hxx>
+
+#include <sax/fastattribs.hxx>
+
#include <com/sun/star/uno/Reference.h>
-#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/xml/dom/XNode.hpp>
#include <com/sun/star/xml/dom/XNodeList.hpp>
#include <com/sun/star/xml/dom/XNamedNodeMap.hpp>
#include <com/sun/star/xml/dom/NodeType.hpp>
-#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/xml/dom/events/XEventTarget.hpp>
-#include <com/sun/star/xml/dom/events/XDocumentEvent.hpp>
#include <com/sun/star/xml/dom/events/XEvent.hpp>
-#include <com/sun/star/xml/dom/events/XMutationEvent.hpp>
-#include <com/sun/star/xml/dom/events/XUIEvent.hpp>
-#include <com/sun/star/xml/dom/events/XMouseEvent.hpp>
#include <com/sun/star/xml/dom/DOMException.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp>
-#include <libxml/tree.h>
-#include <map>
-#include <hash_map>
using ::rtl::OUString;
using ::rtl::OString;
@@ -64,9 +62,9 @@ using namespace com::sun::star::uno;
using namespace com::sun::star::xml::sax;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::dom::events;
-
using com::sun::star::lang::XUnoTunnel;
+
namespace DOM
{
struct Context
@@ -124,6 +122,7 @@ namespace DOM
friend class CElementList;
friend class CEntitiesMap;
friend class CNotationsMap;
+
private:
bool m_bUnlinked; /// node has been removed from document
@@ -141,25 +140,17 @@ namespace DOM
void dispatchSubtreeModified();
- ::rtl::Reference< CDocument > GetOwnerDocument_Impl();
-
public:
virtual ~CNode();
- /// get UNO wrapper instance for a libxml node
- static ::rtl::Reference<CNode> getCNode(
- xmlNodePtr const pNode, bool const bCreate = true);
- /// remove a UNO wrapper instance
- static void removeCNode(
- xmlNodePtr const pNode, CNode const*const pCNode);
-
- // get the libxml node implementation
- static xmlNodePtr getNodePtr(const Reference< XNode >& aNode);
-
static CNode * GetImplementation(::com::sun::star::uno::Reference<
::com::sun::star::uno::XInterface> const& xNode);
+ xmlNodePtr GetNodePtr() { return m_aNodePtr; }
+
+ virtual CDocument & GetOwnerDocument();
+
// recursively create SAX events
virtual void SAL_CALL saxify(
const Reference< XDocumentHandler >& i_xHandler);
diff --git a/unoxml/source/dom/notation.hxx b/unoxml/source/dom/notation.hxx
index 6ec98bce7212..b4fcca61602f 100644
--- a/unoxml/source/dom/notation.hxx
+++ b/unoxml/source/dom/notation.hxx
@@ -47,7 +47,9 @@ namespace DOM
class CNotation
: public CNotation_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
+
private:
xmlNotationPtr m_aNotationPtr;
diff --git a/unoxml/source/dom/processinginstruction.hxx b/unoxml/source/dom/processinginstruction.hxx
index 26f561a02e37..4c140123f13c 100644
--- a/unoxml/source/dom/processinginstruction.hxx
+++ b/unoxml/source/dom/processinginstruction.hxx
@@ -48,7 +48,8 @@ namespace DOM
class CProcessingInstruction
: public CProcessingInstruction_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
protected:
CProcessingInstruction(CDocument const& rDocument,
diff --git a/unoxml/source/dom/text.hxx b/unoxml/source/dom/text.hxx
index 6449ff8afc2e..1f0e273f5426 100644
--- a/unoxml/source/dom/text.hxx
+++ b/unoxml/source/dom/text.hxx
@@ -52,7 +52,8 @@ namespace DOM
class CText
: public CText_Base
{
- friend class CNode;
+ private:
+ friend class CDocument;
protected:
CText(CDocument const& rDocument,
diff --git a/unoxml/source/events/eventdispatcher.cxx b/unoxml/source/events/eventdispatcher.cxx
index 7c7e72bb8429..88abd8ea057e 100644
--- a/unoxml/source/events/eventdispatcher.cxx
+++ b/unoxml/source/events/eventdispatcher.cxx
@@ -25,12 +25,15 @@
*
************************************************************************/
-#include "eventdispatcher.hxx"
-#include "event.hxx"
-#include "mutationevent.hxx"
-#include "uievent.hxx"
-#include "mouseevent.hxx"
-#include "../dom/node.hxx"
+#include <eventdispatcher.hxx>
+
+#include <event.hxx>
+#include <mutationevent.hxx>
+#include <uievent.hxx>
+#include <mouseevent.hxx>
+
+#include "../dom/document.hxx"
+
namespace DOM { namespace events {
@@ -100,7 +103,8 @@ namespace DOM { namespace events {
}
}
- bool CEventDispatcher::dispatchEvent(Reference<XNode> const& xNode,
+ bool CEventDispatcher::dispatchEvent(DOM::CDocument & rDocument,
+ xmlNodePtr const pNode, Reference<XNode> const& xNode,
Reference< XEvent > const& i_xEvent) const
{
CEvent *pEvent = 0; // pointer to internal event representation
@@ -174,7 +178,7 @@ namespace DOM { namespace events {
// build the path from target node to the root
NodeVector captureVector;
- xmlNodePtr cur = DOM::CNode::getNodePtr(Reference< XNode >(xEvent->getTarget(), UNO_QUERY_THROW));
+ xmlNodePtr cur = pNode;
while (cur != NULL)
{
captureVector.push_back(cur);
@@ -196,9 +200,8 @@ namespace DOM { namespace events {
while (rinode !=
const_cast<const NodeVector&>(captureVector).rend())
{
- //pEvent->m_currentTarget = *inode;
pEvent->m_currentTarget = Reference< XEventTarget >(
- DOM::CNode::getCNode(*rinode).get());
+ rDocument.GetCNode(*rinode).get());
callListeners(*rinode, aType, xEvent, sal_True);
if (pEvent->m_canceled) return sal_True;
rinode++;
@@ -217,7 +220,7 @@ namespace DOM { namespace events {
while (inode != captureVector.end())
{
pEvent->m_currentTarget = Reference< XEventTarget >(
- DOM::CNode::getCNode(*inode).get());
+ rDocument.GetCNode(*inode).get());
callListeners(*inode, aType, xEvent, sal_False);
if (pEvent->m_canceled) return sal_True;
inode++;
diff --git a/unoxml/source/events/eventdispatcher.hxx b/unoxml/source/events/eventdispatcher.hxx
index 5160256ac493..bf85a80da8f7 100644
--- a/unoxml/source/events/eventdispatcher.hxx
+++ b/unoxml/source/events/eventdispatcher.hxx
@@ -46,8 +46,11 @@ using namespace com::sun::star::uno;
using namespace com::sun::star::xml::dom;
using namespace com::sun::star::xml::dom::events;
-namespace DOM { namespace events
-{
+namespace DOM {
+
+class CDocument;
+
+namespace events {
typedef std::vector< xmlNodePtr > NodeVector;
typedef std::multimap< xmlNodePtr, Reference< com::sun::star::xml::dom::events::XEventListener> > ListenerMap;
@@ -80,6 +83,8 @@ public:
sal_Bool const bCapture) const;
bool dispatchEvent(
+ DOM::CDocument & rDocument,
+ xmlNodePtr const pNode,
Reference<XNode> const& xNode,
Reference< XEvent > const& xEvent) const;
};
diff --git a/unoxml/source/xpath/nodelist.cxx b/unoxml/source/xpath/nodelist.cxx
index 3f24205309fb..8e37e70f5590 100644
--- a/unoxml/source/xpath/nodelist.cxx
+++ b/unoxml/source/xpath/nodelist.cxx
@@ -63,8 +63,8 @@ namespace XPath
if (0 == m_pNodeSet) {
return 0;
}
- Reference< XNode > const xNode(
- DOM::CNode::getCNode(xmlXPathNodeSetItem(m_pNodeSet, index)).get());
+ xmlNodePtr const pNode = xmlXPathNodeSetItem(m_pNodeSet, index);
+ Reference< XNode > const xNode(m_pDocument->GetCNode(pNode).get());
return xNode;
}
}
diff --git a/unoxml/source/xpath/xpathapi.cxx b/unoxml/source/xpath/xpathapi.cxx
index 2b515d0a9241..6fad00f99c8f 100644
--- a/unoxml/source/xpath/xpathapi.cxx
+++ b/unoxml/source/xpath/xpathapi.cxx
@@ -143,12 +143,13 @@ namespace XPath
}
// get all ns decls on a node (and parent nodes, if any) and register them
- static void _collectNamespaces(
- CXPathAPI* pAPI,
- const Reference< XNode >& namespaceNode)
+ static void lcl_collectNamespaces(
+ CXPathAPI *const pAPI,
+ Reference< XNode > const& xNamespaceNode)
{
// get namespace decls from node...
- xmlNodePtr pNode = DOM::CNode::getNodePtr(namespaceNode);
+ DOM::CNode *const pCNode(DOM::CNode::GetImplementation(xNamespaceNode));
+ xmlNodePtr pNode = pCNode->GetNodePtr();
while (pNode != 0) {
xmlNsPtr curDef = pNode->nsDef;
while (curDef != 0) {
@@ -214,7 +215,7 @@ namespace XPath
const Reference< XNode >& namespaceNode)
throw (RuntimeException, XPathException)
{
- _collectNamespaces(this, namespaceNode);
+ lcl_collectNamespaces(this, namespaceNode);
return selectNodeList(contextNode, expr);
}
@@ -241,7 +242,7 @@ namespace XPath
const Reference< XNode >& namespaceNode )
throw (RuntimeException, XPathException)
{
- _collectNamespaces(this, namespaceNode);
+ lcl_collectNamespaces(this, namespaceNode);
return selectSingleNode(contextNode, expr);
}
@@ -320,7 +321,9 @@ namespace XPath
xmlXPathObjectPtr xpathObj;
// get the node and document
- xmlNodePtr pNode = DOM::CNode::getNodePtr(contextNode);
+ DOM::CNode *const pCNode = DOM::CNode::GetImplementation(contextNode);
+ if (!pCNode) { throw RuntimeException(); }
+ xmlNodePtr const pNode = pCNode->GetNodePtr();
if (!pNode) { throw RuntimeException(); }
xmlDocPtr pDoc = pNode->doc;
@@ -359,8 +362,7 @@ namespace XPath
}
xmlXPathFreeContext(xpathCtx);
::rtl::Reference<DOM::CDocument> const pCDoc(
- dynamic_cast<DOM::CDocument*>(DOM::CNode::getCNode(
- reinterpret_cast<xmlNodePtr>(pDoc)).get()));
+ & pCNode->GetOwnerDocument());
OSL_ASSERT(pCDoc.is());
Reference<XXPathObject> const xObj(new CXPathObject(pCDoc, xpathObj));
return xObj;
@@ -375,7 +377,7 @@ namespace XPath
const Reference< XNode >& namespaceNode)
throw (RuntimeException, XPathException)
{
- _collectNamespaces(this, namespaceNode);
+ lcl_collectNamespaces(this, namespaceNode);
return eval(contextNode, expr);
}