diff options
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); } |