diff options
author | Michael Stahl <mst@openoffice.org> | 2011-01-19 20:27:26 +0100 |
---|---|---|
committer | Michael Stahl <mst@openoffice.org> | 2011-01-19 20:27:26 +0100 |
commit | 12de6d548b19e4d016e7a7be0980c2d78fe20d17 (patch) | |
tree | 7bcb92fea0b218f7589d7008dbc9aebe3518a4a6 /unoxml/source | |
parent | dd377d72a5ef66daee850b66ab7b7308939a7626 (diff) |
xmlfix3: #i113682#: unoxml: CDocument gets a member mutex:
use it to lock all CNode and derived classes' UNO methods.
Diffstat (limited to 'unoxml/source')
30 files changed, 491 insertions, 207 deletions
diff --git a/unoxml/source/dom/attr.cxx b/unoxml/source/dom/attr.cxx index 56c19da592d6..cfbcdce01d7b 100644 --- a/unoxml/source/dom/attr.cxx +++ b/unoxml/source/dom/attr.cxx @@ -37,8 +37,9 @@ namespace DOM { - CAttr::CAttr(CDocument const& rDocument, xmlAttrPtr const pAttr) - : CAttr_Base(rDocument, + CAttr::CAttr(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlAttrPtr const pAttr) + : CAttr_Base(rDocument, rMutex, NodeType_ATTRIBUTE_NODE, reinterpret_cast<xmlNodePtr>(pAttr)) , m_aAttrPtr(pAttr) { @@ -66,6 +67,8 @@ namespace DOM */ OUString SAL_CALL CAttr::getName() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aAttrPtr != NULL) { @@ -81,6 +84,8 @@ namespace DOM Reference< XElement > SAL_CALL CAttr::getOwnerElement() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if ((m_aAttrPtr == 0) || (m_aAttrPtr->parent == 0)) { return 0; @@ -109,6 +114,8 @@ namespace DOM OUString SAL_CALL CAttr::getValue() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aAttrPtr != NULL && m_aAttrPtr->children != NULL) { @@ -124,6 +131,8 @@ namespace DOM void SAL_CALL CAttr::setValue(const OUString& value) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + // remember old value (for mutation event) OUString sOldValue = getValue(); @@ -153,6 +162,9 @@ namespace DOM sEventName, sal_True, sal_False, Reference<XNode>( static_cast<XAttr*>( this ) ), sOldValue, value, getName(), AttrChangeType_MODIFICATION ); + + guard.clear(); // release mutex before calling event handlers + dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); dispatchSubtreeModified(); xmlFree(buffer); diff --git a/unoxml/source/dom/attr.hxx b/unoxml/source/dom/attr.hxx index 489d9ee0ccca..609a97a35c49 100644 --- a/unoxml/source/dom/attr.hxx +++ b/unoxml/source/dom/attr.hxx @@ -56,7 +56,8 @@ namespace DOM xmlAttrPtr m_aAttrPtr; protected: - CAttr(CDocument const& rDocument, xmlAttrPtr const pAttr); + CAttr(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlAttrPtr const pAttr); public: /** diff --git a/unoxml/source/dom/cdatasection.cxx b/unoxml/source/dom/cdatasection.cxx index 8579988a7b89..6f8035a793b3 100644 --- a/unoxml/source/dom/cdatasection.cxx +++ b/unoxml/source/dom/cdatasection.cxx @@ -31,14 +31,16 @@ namespace DOM { - CCDATASection::CCDATASection(CDocument const& rDocument, + CCDATASection::CCDATASection( + CDocument const& rDocument, ::osl::Mutex const& rMutex, xmlNodePtr const pNode) - : CCDATASection_Base(rDocument, NodeType_CDATA_SECTION_NODE, pNode) + : CCDATASection_Base(rDocument, rMutex, + NodeType_CDATA_SECTION_NODE, pNode) { } - void SAL_CALL CCDATASection::saxify( - const Reference< XDocumentHandler >& i_xHandler) { + void CCDATASection::saxify(const Reference< XDocumentHandler >& i_xHandler) + { if (!i_xHandler.is()) throw RuntimeException(); Reference< XExtendedDocumentHandler > xExtended(i_xHandler, UNO_QUERY); if (xExtended.is()) { diff --git a/unoxml/source/dom/cdatasection.hxx b/unoxml/source/dom/cdatasection.hxx index 446064bc137d..3d7512995357 100644 --- a/unoxml/source/dom/cdatasection.hxx +++ b/unoxml/source/dom/cdatasection.hxx @@ -49,12 +49,12 @@ namespace DOM friend class CDocument; protected: - CCDATASection(CDocument const& rDocument, xmlNodePtr const pNode); + CCDATASection(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode); public: - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); virtual Reference< XText > SAL_CALL splitText(sal_Int32 offset) throw (RuntimeException) diff --git a/unoxml/source/dom/characterdata.cxx b/unoxml/source/dom/characterdata.cxx index aa7abaf1561a..237d5eae21c5 100644 --- a/unoxml/source/dom/characterdata.cxx +++ b/unoxml/source/dom/characterdata.cxx @@ -37,13 +37,15 @@ namespace DOM { - CCharacterData::CCharacterData(CDocument const& rDocument, + CCharacterData::CCharacterData( + CDocument const& rDocument, ::osl::Mutex const& rMutex, NodeType const& reNodeType, xmlNodePtr const& rpNode) - : CCharacterData_Base(rDocument, reNodeType, rpNode) + : CCharacterData_Base(rDocument, rMutex, reNodeType, rpNode) { } - void CCharacterData::_dispatchEvent(const OUString& prevValue, const OUString& newValue) + void CCharacterData::dispatchEvent_Impl( + OUString const& prevValue, OUString const& newValue) { Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); Reference< XMutationEvent > event(docevent->createEvent( @@ -62,12 +64,16 @@ namespace DOM void SAL_CALL CCharacterData::appendData(const OUString& arg) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + if (m_aNodePtr != NULL) { OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); xmlNodeAddContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr())); OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); - _dispatchEvent(oldValue, newValue); + + guard.clear(); // release mutex before calling event handlers + dispatchEvent_Impl(oldValue, newValue); } } @@ -77,6 +83,8 @@ namespace DOM void SAL_CALL CCharacterData::deleteData(sal_Int32 offset, sal_Int32 count) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + if (m_aNodePtr != NULL) { // get current data @@ -95,8 +103,9 @@ namespace DOM OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); - _dispatchEvent(oldValue, newValue); + guard.clear(); // release mutex before calling event handlers + dispatchEvent_Impl(oldValue, newValue); } } @@ -106,6 +115,8 @@ namespace DOM */ OUString SAL_CALL CCharacterData::getData() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aData; if (m_aNodePtr != NULL) { @@ -122,8 +133,10 @@ namespace DOM The number of 16-bit units that are available through data and the substringData method below. */ - sal_Int32 CCharacterData::getLength() throw (RuntimeException) + sal_Int32 SAL_CALL CCharacterData::getLength() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + sal_Int32 length = 0; if (m_aNodePtr != NULL) { @@ -139,6 +152,8 @@ namespace DOM void SAL_CALL CCharacterData::insertData(sal_Int32 offset, const OUString& arg) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + if (m_aNodePtr != NULL) { // get current data @@ -156,8 +171,9 @@ namespace DOM OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); - _dispatchEvent(oldValue, newValue); + guard.clear(); // release mutex before calling event handlers + dispatchEvent_Impl(oldValue, newValue); } } @@ -169,6 +185,8 @@ namespace DOM void SAL_CALL CCharacterData::replaceData(sal_Int32 offset, sal_Int32 count, const OUString& arg) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + if (m_aNodePtr != NULL) { // get current data @@ -188,7 +206,9 @@ namespace DOM OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); - _dispatchEvent(oldValue, newValue); + + guard.clear(); // release mutex before calling event handlers + dispatchEvent_Impl(oldValue, newValue); } } @@ -198,13 +218,16 @@ namespace DOM void SAL_CALL CCharacterData::setData(const OUString& data) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + if (m_aNodePtr != NULL) { OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr())); OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); - _dispatchEvent(oldValue, newValue); + guard.clear(); // release mutex before calling event handlers + dispatchEvent_Impl(oldValue, newValue); } } @@ -214,6 +237,8 @@ namespace DOM OUString SAL_CALL CCharacterData::subStringData(sal_Int32 offset, sal_Int32 count) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aStr; if (m_aNodePtr != NULL) { diff --git a/unoxml/source/dom/characterdata.hxx b/unoxml/source/dom/characterdata.hxx index 906fa929832f..9639108f1e85 100644 --- a/unoxml/source/dom/characterdata.hxx +++ b/unoxml/source/dom/characterdata.hxx @@ -55,9 +55,11 @@ namespace DOM { protected: - CCharacterData(CDocument const& rDocument, + CCharacterData(CDocument const& rDocument, ::osl::Mutex const& rMutex, NodeType const& reNodeType, xmlNodePtr const& rpNode); - void _dispatchEvent(const OUString& prevValue, const OUString& newValue); + + void dispatchEvent_Impl( + OUString const& prevValue, OUString const& newValue); public: /** diff --git a/unoxml/source/dom/comment.cxx b/unoxml/source/dom/comment.cxx index 605796523b88..d1ea6d83e3e9 100644 --- a/unoxml/source/dom/comment.cxx +++ b/unoxml/source/dom/comment.cxx @@ -32,12 +32,13 @@ namespace DOM { - CComment::CComment(CDocument const& rDocument, xmlNodePtr const pNode) - : CComment_Base(rDocument, NodeType_COMMENT_NODE, pNode) + CComment::CComment(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode) + : CComment_Base(rDocument, rMutex, NodeType_COMMENT_NODE, pNode) { } - void SAL_CALL CComment::saxify( + void CComment::saxify( const Reference< XDocumentHandler >& i_xHandler) { if (!i_xHandler.is()) throw RuntimeException(); Reference< XExtendedDocumentHandler > xExtended(i_xHandler, UNO_QUERY); diff --git a/unoxml/source/dom/comment.hxx b/unoxml/source/dom/comment.hxx index 00f8644099d9..0aed0cf6a09b 100644 --- a/unoxml/source/dom/comment.hxx +++ b/unoxml/source/dom/comment.hxx @@ -50,12 +50,12 @@ namespace DOM friend class CDocument; protected: - CComment(CDocument const& rDocument, xmlNodePtr const pNode); + CComment(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode); public: - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); // --- delegations for XCharacterData virtual void SAL_CALL appendData(const OUString& arg) diff --git a/unoxml/source/dom/document.cxx b/unoxml/source/dom/document.cxx index 92b106c1ced7..b37a3b98aab9 100644 --- a/unoxml/source/dom/document.cxx +++ b/unoxml/source/dom/document.cxx @@ -71,7 +71,7 @@ namespace DOM } CDocument::CDocument(xmlDocPtr const pDoc) - : CDocument_Base(*this, + : CDocument_Base(*this, m_Mutex, NodeType_DOCUMENT_NODE, reinterpret_cast<xmlNodePtr>(pDoc)) , m_aDocPtr(pDoc) , m_streamListeners() @@ -93,6 +93,7 @@ namespace DOM CDocument::~CDocument() { + ::osl::MutexGuard const g(m_Mutex); #ifdef DBG_UTIL // node map must be empty now, otherwise CDocument must not die! for (nodemap_t::iterator i = m_NodeMap.begin(); @@ -120,14 +121,9 @@ namespace DOM 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: @@ -145,14 +141,16 @@ namespace DOM } } + /** NB: this is the CNode factory. + it is the only place where CNodes may be instantiated. + all CNodes must be registered at the m_NodeMap. + */ ::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()) { @@ -176,34 +174,38 @@ namespace DOM { case XML_ELEMENT_NODE: // m_aNodeType = NodeType::ELEMENT_NODE; - pCNode = static_cast< CNode* >(new CElement(*this, pNode)); + pCNode = static_cast< CNode* >( + new CElement(*this, m_Mutex, pNode)); break; case XML_TEXT_NODE: // m_aNodeType = NodeType::TEXT_NODE; - pCNode = static_cast< CNode* >(new CText(*this, pNode)); + pCNode = static_cast< CNode* >( + new CText(*this, m_Mutex, pNode)); break; case XML_CDATA_SECTION_NODE: // m_aNodeType = NodeType::CDATA_SECTION_NODE; - pCNode = static_cast< CNode* >(new CCDATASection(*this, pNode)); + pCNode = static_cast< CNode* >( + new CCDATASection(*this, m_Mutex, pNode)); break; case XML_ENTITY_REF_NODE: // m_aNodeType = NodeType::ENTITY_REFERENCE_NODE; - pCNode = static_cast< CNode* >(new CEntityReference(*this, - pNode)); + pCNode = static_cast< CNode* >( + new CEntityReference(*this, m_Mutex, pNode)); break; case XML_ENTITY_NODE: // m_aNodeType = NodeType::ENTITY_NODE; - pCNode = static_cast< CNode* >(new CEntity(*this, + pCNode = static_cast< CNode* >(new CEntity(*this, m_Mutex, reinterpret_cast<xmlEntityPtr>(pNode))); break; case XML_PI_NODE: // m_aNodeType = NodeType::PROCESSING_INSTRUCTION_NODE; pCNode = static_cast< CNode* >( - new CProcessingInstruction(*this, pNode)); + new CProcessingInstruction(*this, m_Mutex, pNode)); break; case XML_COMMENT_NODE: // m_aNodeType = NodeType::COMMENT_NODE; - pCNode = static_cast< CNode* >(new CComment(*this, pNode)); + pCNode = static_cast< CNode* >( + new CComment(*this, m_Mutex, pNode)); break; case XML_DOCUMENT_NODE: // m_aNodeType = NodeType::DOCUMENT_NODE; @@ -215,22 +217,22 @@ namespace DOM case XML_DOCUMENT_TYPE_NODE: case XML_DTD_NODE: // m_aNodeType = NodeType::DOCUMENT_TYPE_NODE; - pCNode = static_cast< CNode* >(new CDocumentType(*this, + pCNode = static_cast< CNode* >(new CDocumentType(*this, m_Mutex, reinterpret_cast<xmlDtdPtr>(pNode))); break; case XML_DOCUMENT_FRAG_NODE: // m_aNodeType = NodeType::DOCUMENT_FRAGMENT_NODE; - pCNode = static_cast< CNode* >(new CDocumentFragment(*this, - pNode)); + pCNode = static_cast< CNode* >( + new CDocumentFragment(*this, m_Mutex, pNode)); break; case XML_NOTATION_NODE: // m_aNodeType = NodeType::NOTATION_NODE; - pCNode = static_cast< CNode* >(new CNotation(*this, + pCNode = static_cast< CNode* >(new CNotation(*this, m_Mutex, reinterpret_cast<xmlNotationPtr>(pNode))); break; case XML_ATTRIBUTE_NODE: // m_aNodeType = NodeType::ATTRIBUTE_NODE; - pCNode = static_cast< CNode* >(new CAttr(*this, + pCNode = static_cast< CNode* >(new CAttr(*this, m_Mutex, reinterpret_cast<xmlAttrPtr>(pNode))); break; // unsupported node types @@ -266,8 +268,8 @@ namespace DOM return *this; } - void SAL_CALL CDocument::saxify( - const Reference< XDocumentHandler >& i_xHandler) { + void CDocument::saxify(const Reference< XDocumentHandler >& i_xHandler) + { i_xHandler->startDocument(); for (xmlNodePtr pChild = m_aNodePtr->children; pChild != 0; pChild = pChild->next) { @@ -278,7 +280,8 @@ namespace DOM i_xHandler->endDocument(); } - void SAL_CALL CDocument::fastSaxify( Context& rContext ) { + void CDocument::fastSaxify( Context& rContext ) + { rContext.mxDocHandler->startDocument(); for (xmlNodePtr pChild = m_aNodePtr->children; pChild != 0; pChild = pChild->next) { @@ -292,12 +295,16 @@ namespace DOM void SAL_CALL CDocument::addListener(const Reference< XStreamListener >& aListener ) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + m_streamListeners.insert(aListener); } void SAL_CALL CDocument::removeListener(const Reference< XStreamListener >& aListener ) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + m_streamListeners.erase(aListener); } @@ -333,30 +340,42 @@ namespace DOM void SAL_CALL CDocument::start() throw (RuntimeException) { - if (! m_rOutputStream.is()) return; + listenerlist_t streamListeners; + { + ::osl::MutexGuard const g(m_Mutex); + + if (! m_rOutputStream.is()) { throw RuntimeException(); } + streamListeners = m_streamListeners; + } - // notify listners about start - listenerlist_t::const_iterator iter1 = m_streamListeners.begin(); - while (iter1 != m_streamListeners.end()) { + // notify listeners about start + listenerlist_t::const_iterator iter1 = streamListeners.begin(); + while (iter1 != streamListeners.end()) { Reference< XStreamListener > aListener = *iter1; aListener->started(); iter1++; } - // setup libxml IO and write data to output stream - IOContext ioctx = {m_rOutputStream, false}; - xmlOutputBufferPtr pOut = xmlOutputBufferCreateIO( - writeCallback, closeCallback, &ioctx, NULL); - xmlSaveFileTo(pOut, m_aNodePtr->doc, NULL); + { + ::osl::MutexGuard const g(m_Mutex); + + // check again! could have been reset... + if (! m_rOutputStream.is()) { throw RuntimeException(); } + + // setup libxml IO and write data to output stream + IOContext ioctx = {m_rOutputStream, false}; + xmlOutputBufferPtr pOut = xmlOutputBufferCreateIO( + writeCallback, closeCallback, &ioctx, NULL); + xmlSaveFileTo(pOut, m_aNodePtr->doc, NULL); + } // call listeners - listenerlist_t::const_iterator iter2 = m_streamListeners.begin(); - while (iter2 != m_streamListeners.end()) { + listenerlist_t::const_iterator iter2 = streamListeners.begin(); + while (iter2 != streamListeners.end()) { Reference< XStreamListener > aListener = *iter2; aListener->closed(); iter2++; } - } void SAL_CALL CDocument::terminate() @@ -368,11 +387,15 @@ namespace DOM void SAL_CALL CDocument::setOutputStream( const Reference< XOutputStream >& aStream ) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + m_rOutputStream = aStream; } Reference< XOutputStream > SAL_CALL CDocument::getOutputStream() throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + return m_rOutputStream; } @@ -380,6 +403,8 @@ namespace DOM Reference< XAttr > SAL_CALL CDocument::createAttribute(const OUString& name) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_Mutex); + OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr, xName, NULL); @@ -395,6 +420,7 @@ namespace DOM const OUString& ns, const OUString& qname) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_Mutex); // libxml does not allow a NS definition to be attached to an // attribute node - which is a good thing, since namespaces are @@ -435,6 +461,8 @@ namespace DOM Reference< XCDATASection > SAL_CALL CDocument::createCDATASection(const OUString& data) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + xmlChar *xData = (xmlChar*)OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr(); xmlNodePtr pText = xmlNewCDataBlock(m_aDocPtr, xData, strlen((char*)xData)); Reference< XCDATASection > const xRet( @@ -447,6 +475,8 @@ namespace DOM Reference< XComment > SAL_CALL CDocument::createComment(const OUString& data) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8); xmlChar *xData = (xmlChar*)o1.getStr(); xmlNodePtr pComment = xmlNewDocComment(m_aDocPtr, xData); @@ -460,6 +490,8 @@ namespace DOM Reference< XDocumentFragment > SAL_CALL CDocument::createDocumentFragment() throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + xmlNodePtr pFrag = xmlNewDocFragment(m_aDocPtr); Reference< XDocumentFragment > const xRet( static_cast< XNode* >(GetCNode(pFrag).get()), @@ -471,6 +503,8 @@ namespace DOM Reference< XElement > SAL_CALL CDocument::createElement(const OUString& tagName) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_Mutex); + OString o1 = OUStringToOString(tagName, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL); @@ -485,6 +519,8 @@ namespace DOM const OUString& ns, const OUString& qname) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_Mutex); + sal_Int32 i = qname.indexOf(':'); if (ns.getLength() == 0) throw RuntimeException(); xmlChar *xPrefix; @@ -519,6 +555,8 @@ namespace DOM Reference< XEntityReference > SAL_CALL CDocument::createEntityReference(const OUString& name) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_Mutex); + OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); xmlNodePtr const pNode = xmlNewReference(m_aDocPtr, xName); @@ -534,6 +572,8 @@ namespace DOM const OUString& target, const OUString& data) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_Mutex); + OString o1 = OUStringToOString(target, RTL_TEXTENCODING_UTF8); xmlChar *xTarget = (xmlChar*)o1.getStr(); OString o2 = OUStringToOString(data, RTL_TEXTENCODING_UTF8); @@ -550,6 +590,8 @@ namespace DOM Reference< XText > SAL_CALL CDocument::createTextNode(const OUString& data) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8); xmlChar *xData = (xmlChar*)o1.getStr(); xmlNodePtr const pNode = xmlNewDocText(m_aDocPtr, xData); @@ -564,6 +606,8 @@ namespace DOM Reference< XDocumentType > SAL_CALL CDocument::getDoctype() throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + // find the doc type xmlNodePtr cur = m_aDocPtr->children; while (cur != NULL) @@ -582,6 +626,8 @@ namespace DOM Reference< XElement > SAL_CALL CDocument::getDocumentElement() throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr); Reference< XElement > const xRet( static_cast< XNode* >(GetCNode(pNode).get()), @@ -619,6 +665,8 @@ namespace DOM Reference< XElement > SAL_CALL CDocument::getElementById(const OUString& elementId) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + // search the tree for an element with the given ID OString o1 = OUStringToOString(elementId, RTL_TEXTENCODING_UTF8); xmlChar *xId = (xmlChar*)o1.getStr(); @@ -635,6 +683,8 @@ namespace DOM CDocument::getElementsByTagName(OUString const& rTagname) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + Reference< XNodeList > const xRet( new CElementList(this->GetDocumentElement(), rTagname)); return xRet; @@ -644,6 +694,8 @@ namespace DOM OUString const& rNamespaceURI, OUString const& rLocalName) throw (RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + Reference< XNodeList > const xRet( new CElementList( this->GetDocumentElement(), rLocalName, &rNamespaceURI)); @@ -653,6 +705,7 @@ namespace DOM Reference< XDOMImplementation > SAL_CALL CDocument::getImplementation() throw (RuntimeException) { + // does not need mutex currently return Reference< XDOMImplementation >(CDOMImplementation::get()); } @@ -870,15 +923,19 @@ namespace DOM OUString SAL_CALL CDocument::getNodeName()throw (RuntimeException) { + // does not need mutex currently return OUString::createFromAscii("#document"); } + OUString SAL_CALL CDocument::getNodeValue() throw (RuntimeException) { + // does not need mutex currently return OUString(); } Reference< XEvent > SAL_CALL CDocument::createEvent(const OUString& aType) throw (RuntimeException) { + // does not need mutex currently events::CEvent *pEvent = 0; if ( aType.compareToAscii("DOMSubtreeModified") == 0|| @@ -920,6 +977,8 @@ namespace DOM const Sequence< beans::StringPair >& i_rNamespaces) throw (RuntimeException, SAXException) { + ::osl::MutexGuard const g(m_Mutex); + // add new namespaces to root node xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr); if (0 != pRoot) { @@ -947,6 +1006,8 @@ namespace DOM const Sequence< beans::Pair< rtl::OUString, sal_Int32 > >& i_rRegisterNamespaces ) throw (SAXException, RuntimeException) { + ::osl::MutexGuard const g(m_Mutex); + // add new namespaces to root node xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr); if (0 != pRoot) { diff --git a/unoxml/source/dom/document.hxx b/unoxml/source/dom/document.hxx index f10bf5010732..0cde502a53db 100644 --- a/unoxml/source/dom/document.hxx +++ b/unoxml/source/dom/document.hxx @@ -28,14 +28,16 @@ #ifndef DOM_DOCUMENT_HXX #define DOM_DOCUMENT_HXX -#include <list> #include <set> #include <memory> +#include <libxml/tree.h> + #include <sal/types.h> + #include <cppuhelper/implbase6.hxx> + #include <com/sun/star/uno/Reference.h> -#include <com/sun/star/uno/Exception.hpp> #include <com/sun/star/beans/StringPair.hpp> #include <com/sun/star/xml/dom/XNode.hpp> #include <com/sun/star/xml/dom/XAttr.hpp> @@ -54,7 +56,6 @@ #include "node.hxx" -#include <libxml/tree.h> using namespace std; using ::rtl::OUString; @@ -84,7 +85,11 @@ namespace DOM { private: - + /// this Mutex is used for synchronization of all UNO wrapper + /// objects that belong to this document + ::osl::Mutex m_Mutex; + /// the libxml document: freed in destructor + /// => all UNO wrapper objects must keep the CDocument alive xmlDocPtr const m_aDocPtr; // datacontrol/source state @@ -119,10 +124,9 @@ namespace DOM virtual CDocument & GetOwnerDocument(); - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); - virtual void SAL_CALL fastSaxify( Context& rContext ); + virtual void fastSaxify( Context& rContext ); /** Creates an Attr of the given name. diff --git a/unoxml/source/dom/documentfragment.cxx b/unoxml/source/dom/documentfragment.cxx index a2da624b4528..ed94d639fab2 100644 --- a/unoxml/source/dom/documentfragment.cxx +++ b/unoxml/source/dom/documentfragment.cxx @@ -30,8 +30,9 @@ namespace DOM { CDocumentFragment::CDocumentFragment( - CDocument const& rDocument, xmlNodePtr const pNode) - : CDocumentFragment_Base(rDocument, + CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode) + : CDocumentFragment_Base(rDocument, rMutex, NodeType_DOCUMENT_FRAGMENT_NODE, pNode) { } diff --git a/unoxml/source/dom/documentfragment.hxx b/unoxml/source/dom/documentfragment.hxx index cc65524fa15b..afb3f04dc3bf 100644 --- a/unoxml/source/dom/documentfragment.hxx +++ b/unoxml/source/dom/documentfragment.hxx @@ -50,7 +50,8 @@ namespace DOM friend class CDocument; protected: - CDocumentFragment(CDocument const& rDocument, + CDocumentFragment( + CDocument const& rDocument, ::osl::Mutex const& rMutex, xmlNodePtr const pNode); public: diff --git a/unoxml/source/dom/documenttype.cxx b/unoxml/source/dom/documenttype.cxx index 7f970ca68369..1b0893912443 100644 --- a/unoxml/source/dom/documenttype.cxx +++ b/unoxml/source/dom/documenttype.cxx @@ -37,8 +37,9 @@ namespace DOM { CDocumentType::CDocumentType( - CDocument const& rDocument, xmlDtdPtr const pDtd) - : CDocumentType_Base(rDocument, + CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlDtdPtr const pDtd) + : CDocumentType_Base(rDocument, rMutex, NodeType_DOCUMENT_TYPE_NODE, reinterpret_cast<xmlNodePtr>(pDtd)) , m_aDtdPtr(pDtd) { @@ -50,6 +51,8 @@ namespace DOM */ Reference< XNamedNodeMap > SAL_CALL CDocumentType::getEntities() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + Reference< XNamedNodeMap > aMap; if (m_aDtdPtr != NULL) { @@ -73,6 +76,8 @@ namespace DOM */ OUString SAL_CALL CDocumentType::getName() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aDtdPtr != NULL) { @@ -86,6 +91,8 @@ namespace DOM */ Reference< XNamedNodeMap > SAL_CALL CDocumentType::getNotations() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + Reference< XNamedNodeMap > aMap; if (m_aDtdPtr != NULL) { @@ -99,6 +106,8 @@ namespace DOM */ OUString SAL_CALL CDocumentType::getPublicId() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aId; if (m_aDtdPtr != NULL) { @@ -112,6 +121,8 @@ namespace DOM */ OUString SAL_CALL CDocumentType::getSystemId() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aId; if (m_aDtdPtr != NULL) { @@ -119,10 +130,12 @@ namespace DOM } return aId; } + OUString SAL_CALL CDocumentType::getNodeName()throw (RuntimeException) { return getName(); } + OUString SAL_CALL CDocumentType::getNodeValue() throw (RuntimeException) { return OUString(); diff --git a/unoxml/source/dom/documenttype.hxx b/unoxml/source/dom/documenttype.hxx index 925c42637e91..ca276bb384e8 100644 --- a/unoxml/source/dom/documenttype.hxx +++ b/unoxml/source/dom/documenttype.hxx @@ -59,7 +59,8 @@ namespace DOM xmlDtdPtr m_aDtdPtr; protected: - CDocumentType(CDocument const& rDocument, xmlDtdPtr const pDtd); + CDocumentType(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlDtdPtr const pDtd); public: /** diff --git a/unoxml/source/dom/element.cxx b/unoxml/source/dom/element.cxx index 57fd65e7beec..83f61086bb0b 100644 --- a/unoxml/source/dom/element.cxx +++ b/unoxml/source/dom/element.cxx @@ -46,13 +46,14 @@ namespace DOM { - CElement::CElement(CDocument const& rDocument, xmlNodePtr const pNode) - : CElement_Base(rDocument, NodeType_ELEMENT_NODE, pNode) + CElement::CElement(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode) + : CElement_Base(rDocument, rMutex, NodeType_ELEMENT_NODE, pNode) { } - void SAL_CALL CElement::saxify( - const Reference< XDocumentHandler >& i_xHandler) { + void CElement::saxify(const Reference< XDocumentHandler >& i_xHandler) + { if (!i_xHandler.is()) throw RuntimeException(); comphelper::AttributeList *pAttrs = new comphelper::AttributeList(); @@ -102,7 +103,8 @@ namespace DOM i_xHandler->endElement(name); } - void SAL_CALL CElement::fastSaxify( Context& i_rContext ) { + void CElement::fastSaxify( Context& i_rContext ) + { if (!i_rContext.mxDocHandler.is()) throw RuntimeException(); pushContext(i_rContext); addNamespaces(i_rContext,m_aNodePtr); @@ -207,9 +209,11 @@ namespace DOM Retrieves an attribute value by name. return empty string if attribute is not set */ - OUString CElement::getAttribute(const OUString& name) + OUString SAL_CALL CElement::getAttribute(OUString const& name) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aValue; // search properties if (m_aNodePtr != NULL) @@ -226,9 +230,11 @@ namespace DOM /** Retrieves an attribute node by name. */ - Reference< XAttr > CElement::getAttributeNode(const OUString& name) + Reference< XAttr > SAL_CALL CElement::getAttributeNode(OUString const& name) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -249,10 +255,12 @@ namespace DOM /** Retrieves an Attr node by local name and namespace URI. */ - Reference< XAttr > CElement::getAttributeNodeNS( + Reference< XAttr > SAL_CALL CElement::getAttributeNodeNS( const OUString& namespaceURI, const OUString& localName) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -277,9 +285,13 @@ namespace DOM Retrieves an attribute value by local name and namespace URI. return empty string if attribute is not set */ - OUString CElement::getAttributeNS(const OUString& namespaceURI, const OUString& localName) + OUString SAL_CALL + CElement::getAttributeNS( + OUString const& namespaceURI, OUString const& localName) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return ::rtl::OUString(); } @@ -309,6 +321,8 @@ namespace DOM CElement::getElementsByTagName(OUString const& rLocalName) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + Reference< XNodeList > const xList(new CElementList(this, rLocalName)); return xList; } @@ -323,6 +337,8 @@ namespace DOM OUString const& rNamespaceURI, OUString const& rLocalName) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + Reference< XNodeList > const xList( new CElementList(this, rLocalName, &rNamespaceURI)); return xList; @@ -331,9 +347,11 @@ namespace DOM /** The name of the element. */ - OUString CElement::getTagName() + OUString SAL_CALL CElement::getTagName() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aNodePtr != NULL) { @@ -347,9 +365,11 @@ namespace DOM Returns true when an attribute with a given name is specified on this element or has a default value, false otherwise. */ - sal_Bool CElement::hasAttribute(const OUString& name) + sal_Bool SAL_CALL CElement::hasAttribute(OUString const& name) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); return (m_aNodePtr != NULL && xmlHasProp(m_aNodePtr, xName) != NULL); @@ -359,9 +379,12 @@ namespace DOM Returns true when an attribute with a given local name and namespace URI is specified on this element or has a default value, false otherwise. */ - sal_Bool CElement::hasAttributeNS(const OUString& namespaceURI, const OUString& localName) + sal_Bool SAL_CALL CElement::hasAttributeNS( + OUString const& namespaceURI, OUString const& localName) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8); @@ -372,9 +395,11 @@ namespace DOM /** Removes an attribute by name. */ - void CElement::removeAttribute(const OUString& name) + void SAL_CALL CElement::removeAttribute(OUString const& name) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_rMutex); + xmlChar *xName = (xmlChar*)OUStringToOString(name, RTL_TEXTENCODING_UTF8).getStr(); if (m_aNodePtr != NULL) { xmlUnsetProp(m_aNodePtr, xName); @@ -384,9 +409,12 @@ namespace DOM /** Removes an attribute by local name and namespace URI. */ - void CElement::removeAttributeNS(const OUString& namespaceURI, const OUString& localName) + void SAL_CALL CElement::removeAttributeNS( + OUString const& namespaceURI, OUString const& localName) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_rMutex); + OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8); @@ -401,9 +429,12 @@ namespace DOM /** Removes the specified attribute node. */ - Reference< XAttr > CElement::removeAttributeNode(const Reference< XAttr >& oldAttr) + Reference< XAttr > SAL_CALL + CElement::removeAttributeNode(Reference< XAttr > const& oldAttr) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_rMutex); + Reference< XAttr > aAttr; if(m_aNodePtr != NULL) { @@ -442,19 +473,23 @@ namespace DOM /** Adds a new attribute node. */ - Reference< XAttr > CElement::_setAttributeNode(const Reference< XAttr >& newAttr, sal_Bool bNS) + Reference< XAttr > + CElement::setAttributeNode_Impl_Lock( + Reference< XAttr > const& newAttr, bool const bNS) throw (RuntimeException) { + // check whether the attrib belongs to this document + Reference< XDocument > newDoc(newAttr->getOwnerDocument(), UNO_QUERY); + Reference< XDocument > oldDoc(CNode::getOwnerDocument(), UNO_QUERY); + if (newDoc != oldDoc) { + throw RuntimeException(); + } + + ::osl::ClearableMutexGuard guard(m_rMutex); + Reference< XAttr > aAttr; if (m_aNodePtr != NULL) { - // check whether the attrib belongs to this document - Reference< XDocument > newDoc(newAttr->getOwnerDocument(), UNO_QUERY); - Reference< XDocument > oldDoc(CNode::getOwnerDocument(), UNO_QUERY); - if (newDoc != oldDoc) { - throw RuntimeException(); - } - // get the implementation CNode *const pCNode = CNode::GetImplementation(newAttr); if (!pCNode) { throw RuntimeException(); } @@ -503,6 +538,9 @@ namespace DOM event->initMutationEvent(OUString::createFromAscii("DOMAttrModified"), sal_True, sal_False, Reference< XNode >(aAttr, UNO_QUERY), OUString(), aAttr->getValue(), aAttr->getName(), AttrChangeType_ADDITION); + + guard.clear(); // release mutex before calling event handlers + dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); dispatchSubtreeModified(); } @@ -512,7 +550,7 @@ namespace DOM Reference< XAttr > CElement::setAttributeNode(const Reference< XAttr >& newAttr) throw (RuntimeException, DOMException) { - return _setAttributeNode(newAttr, sal_False); + return setAttributeNode_Impl_Lock(newAttr, false); } /** @@ -521,15 +559,18 @@ namespace DOM Reference< XAttr > CElement::setAttributeNodeNS(const Reference< XAttr >& newAttr) throw (RuntimeException, DOMException) { - return _setAttributeNode(newAttr, sal_True); + return setAttributeNode_Impl_Lock(newAttr, true); } /** Adds a new attribute. */ - void CElement::setAttribute(const OUString& name, const OUString& value) + void SAL_CALL + CElement::setAttribute(OUString const& name, OUString const& value) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8); xmlChar *xName = (xmlChar*)o1.getStr(); OString o2 = OUStringToOString(value, RTL_TEXTENCODING_UTF8); @@ -558,6 +599,8 @@ namespace DOM event->initMutationEvent(OUString::createFromAscii("DOMAttrModified"), sal_True, sal_False, Reference< XNode >(getAttributeNode(name), UNO_QUERY), oldValue, value, name, aChangeType); + + guard.clear(); // release mutex before calling event handlers dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); dispatchSubtreeModified(); } @@ -566,12 +609,15 @@ namespace DOM /** Adds a new attribute. */ - void CElement::setAttributeNS( - const OUString& namespaceURI, const OUString& qualifiedName, const OUString& value) + void SAL_CALL + CElement::setAttributeNS(OUString const& namespaceURI, + OUString const& qualifiedName, OUString const& value) throw (RuntimeException, DOMException) { if (namespaceURI.getLength() == 0) throw RuntimeException(); + ::osl::ClearableMutexGuard guard(m_rMutex); + OString o1, o2, o3, o4, o5; xmlChar *xPrefix = NULL; xmlChar *xLName = NULL; @@ -628,6 +674,8 @@ namespace DOM event->initMutationEvent(OUString::createFromAscii("DOMAttrModified"), sal_True, sal_False, Reference< XNode >(getAttributeNodeNS(namespaceURI, OUString((char*)xLName, strlen((char*)xLName), RTL_TEXTENCODING_UTF8)), UNO_QUERY), oldValue, value, qualifiedName, aChangeType); + + guard.clear(); // release mutex before calling event handlers dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); dispatchSubtreeModified(); @@ -642,6 +690,8 @@ namespace DOM Reference< XNamedNodeMap > SAL_CALL CElement::getAttributes() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (!hasAttributes()) { return 0; } Reference< XNamedNodeMap > const xMap(new CAttributesMap(this)); return xMap; @@ -651,8 +701,11 @@ namespace DOM { return getLocalName(); } + OUString SAL_CALL CElement::getLocalName()throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aNodePtr != NULL) { @@ -661,26 +714,29 @@ namespace DOM } return aName; } + OUString SAL_CALL CElement::getNodeValue() throw (RuntimeException) { return OUString(); } - void SAL_CALL CElement::setElementName(const OUString& aName) throw (RuntimeException, DOMException) + void SAL_CALL CElement::setElementName(const OUString& aName) + throw (RuntimeException, DOMException) { - if (aName.getLength() > 0 && aName.indexOf(OUString::createFromAscii(":")) < 0) - { - OString oName = OUStringToOString(aName, RTL_TEXTENCODING_UTF8); - xmlChar *xName = (xmlChar*)oName.getStr(); - // xmlFree((void*)m_aNodePtr->name); - m_aNodePtr->name = xmlStrdup(xName); - } - else + if ((aName.getLength() <= 0) || + (0 <= aName.indexOf(OUString::createFromAscii(":")))) { DOMException e; e.Code = DOMExceptionType_INVALID_CHARACTER_ERR; throw e; } + + ::osl::MutexGuard const g(m_rMutex); + + OString oName = OUStringToOString(aName, RTL_TEXTENCODING_UTF8); + xmlChar *xName = (xmlChar*)oName.getStr(); + // xmlFree((void*)m_aNodePtr->name); + m_aNodePtr->name = xmlStrdup(xName); } } diff --git a/unoxml/source/dom/element.hxx b/unoxml/source/dom/element.hxx index bef1f0a5d8f6..7802678a5981 100644 --- a/unoxml/source/dom/element.hxx +++ b/unoxml/source/dom/element.hxx @@ -53,18 +53,19 @@ namespace DOM private: friend class CDocument; - Reference< XAttr > _setAttributeNode(const Reference< XAttr >& newAttr, sal_Bool bNS) + Reference< XAttr > setAttributeNode_Impl_Lock( + Reference< XAttr > const& xNewAttr, bool const bNS) throw (RuntimeException); protected: - CElement(CDocument const& rDocument, xmlNodePtr const pNode); + CElement(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode); public: - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); - virtual void SAL_CALL fastSaxify( Context& i_rContext ); + virtual void fastSaxify( Context& i_rContext ); /** Retrieves an attribute value by name. diff --git a/unoxml/source/dom/entity.cxx b/unoxml/source/dom/entity.cxx index c64f39ea11f6..dbf675f7765e 100644 --- a/unoxml/source/dom/entity.cxx +++ b/unoxml/source/dom/entity.cxx @@ -33,8 +33,9 @@ namespace DOM { - CEntity::CEntity(CDocument const& rDocument, xmlEntityPtr const pEntity) - : CEntity_Base(rDocument, + CEntity::CEntity(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlEntityPtr const pEntity) + : CEntity_Base(rDocument, rMutex, NodeType_ENTITY_NODE, reinterpret_cast<xmlNodePtr>(pEntity)) , m_aEntityPtr(pEntity) { @@ -54,6 +55,8 @@ namespace DOM */ OUString SAL_CALL CEntity::getPublicId() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aID; if(m_aEntityPtr != NULL) { @@ -67,6 +70,8 @@ namespace DOM */ OUString SAL_CALL CEntity::getSystemId() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aID; if(m_aEntityPtr != NULL) { @@ -76,6 +81,8 @@ namespace DOM } OUString SAL_CALL CEntity::getNodeName()throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aNodePtr != NULL) { diff --git a/unoxml/source/dom/entity.hxx b/unoxml/source/dom/entity.hxx index e785f9343e36..5c88f6dfe8c8 100644 --- a/unoxml/source/dom/entity.hxx +++ b/unoxml/source/dom/entity.hxx @@ -57,7 +57,8 @@ namespace DOM xmlEntityPtr m_aEntityPtr; protected: - CEntity(CDocument const& rDocument, xmlEntityPtr const pEntity); + CEntity(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlEntityPtr const pEntity); public: diff --git a/unoxml/source/dom/entityreference.cxx b/unoxml/source/dom/entityreference.cxx index 8b24bbde8ce4..942156aedf76 100644 --- a/unoxml/source/dom/entityreference.cxx +++ b/unoxml/source/dom/entityreference.cxx @@ -32,14 +32,17 @@ namespace DOM { CEntityReference::CEntityReference( - CDocument const& rDocument, xmlNodePtr const pNode) - : CEntityReference_Base(rDocument, + CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode) + : CEntityReference_Base(rDocument, rMutex, NodeType_ENTITY_REFERENCE_NODE, pNode) { } OUString SAL_CALL CEntityReference::getNodeName()throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aNodePtr != NULL) { @@ -48,6 +51,7 @@ namespace DOM } return aName; } + OUString SAL_CALL CEntityReference::getNodeValue() throw (RuntimeException) { return OUString(); diff --git a/unoxml/source/dom/entityreference.hxx b/unoxml/source/dom/entityreference.hxx index 3d1d0569b0b3..b4f20303b888 100644 --- a/unoxml/source/dom/entityreference.hxx +++ b/unoxml/source/dom/entityreference.hxx @@ -52,7 +52,9 @@ namespace DOM friend class CDocument; protected: - CEntityReference(CDocument const& rDocument, xmlNodePtr const pNode); + CEntityReference( + CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode); public: // ---- resolve uno inheritance problems... diff --git a/unoxml/source/dom/node.cxx b/unoxml/source/dom/node.cxx index f16babb3ab2f..501fd134c793 100644 --- a/unoxml/source/dom/node.cxx +++ b/unoxml/source/dom/node.cxx @@ -142,7 +142,7 @@ namespace DOM } - CNode::CNode(CDocument const& rDocument, + CNode::CNode(CDocument const& rDocument, ::osl::Mutex const& rMutex, NodeType const& reNodeType, xmlNodePtr const& rpNode) : m_bUnlinked(false) , m_aNodeType(reNodeType) @@ -151,6 +151,7 @@ namespace DOM // (but not if this is a document; that would create a leak!) , m_xDocument( (m_aNodePtr->type != XML_DOCUMENT_NODE) ? &const_cast<CDocument&>(rDocument) : 0 ) + , m_rMutex(const_cast< ::osl::Mutex & >(rMutex)) { OSL_ASSERT(m_aNodePtr); } @@ -170,7 +171,13 @@ namespace DOM CNode::~CNode() { - invalidate(); + // if this is the document itself, the mutex is already freed! + if (NodeType_DOCUMENT_NODE == m_aNodeType) { + invalidate(); + } else { + ::osl::MutexGuard const g(m_rMutex); + invalidate(); // other nodes are still alive so must lock mutex + } } CNode * @@ -266,13 +273,14 @@ namespace DOM } } - void SAL_CALL CNode::saxify( - const Reference< XDocumentHandler >& i_xHandler) { + void CNode::saxify(const Reference< XDocumentHandler >& i_xHandler) + { if (!i_xHandler.is()) throw RuntimeException(); // default: do nothing } - void SAL_CALL CNode::fastSaxify(Context& io_rContext) { + void CNode::fastSaxify(Context& io_rContext) + { if (!io_rContext.mxDocHandler.is()) throw RuntimeException(); // default: do nothing } @@ -280,9 +288,12 @@ namespace DOM /** Adds the node newChild to the end of the list of children of this node. */ - Reference< XNode > CNode::appendChild(Reference< XNode > const& xNewChild) + Reference< XNode > SAL_CALL CNode::appendChild( + Reference< XNode > const& xNewChild) throw (RuntimeException, DOMException) { + ::osl::ClearableMutexGuard guard(m_rMutex); + ::rtl::Reference<CNode> pNode; if (m_aNodePtr != NULL) { CNode *const pNewChild(CNode::GetImplementation(xNewChild)); @@ -380,8 +391,12 @@ namespace DOM , sal_True, sal_False, this, OUString(), OUString(), OUString(), (AttrChangeType)0 ); - dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); + // the following dispatch functions use only UNO interfaces + // and call event listeners, so release mutex to prevent deadlocks. + guard.clear(); + + dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); // dispatch subtree modified for this node dispatchSubtreeModified(); } @@ -392,9 +407,11 @@ namespace DOM Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes. */ - Reference< XNode > CNode::cloneNode(sal_Bool bDeep) + Reference< XNode > SAL_CALL CNode::cloneNode(sal_Bool bDeep) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -409,9 +426,10 @@ namespace DOM A NamedNodeMap containing the attributes of this node (if it is an Element) or null otherwise. */ - Reference< XNamedNodeMap > CNode::getAttributes() + Reference< XNamedNodeMap > SAL_CALL CNode::getAttributes() throw (RuntimeException) { + // return empty reference // only element node may override this impl return Reference< XNamedNodeMap>(); @@ -426,9 +444,11 @@ namespace DOM /** A NodeList that contains all children of this node. */ - Reference< XNodeList > CNode::getChildNodes() + Reference< XNodeList > SAL_CALL CNode::getChildNodes() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -439,9 +459,11 @@ namespace DOM /** The first child of this node. */ - Reference< XNode > CNode::getFirstChild() + Reference< XNode > SAL_CALL CNode::getFirstChild() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -456,6 +478,8 @@ namespace DOM Reference< XNode > SAL_CALL CNode::getLastChild() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -490,6 +514,8 @@ namespace DOM OUString SAL_CALL CNode::getNamespaceURI() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aURI; if (m_aNodePtr != NULL && (m_aNodePtr->type == XML_ELEMENT_NODE || m_aNodePtr->type == XML_ATTRIBUTE_NODE) && @@ -507,6 +533,8 @@ namespace DOM Reference< XNode > SAL_CALL CNode::getNextSibling() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -549,6 +577,8 @@ namespace DOM NodeType SAL_CALL CNode::getNodeType() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + return m_aNodeType; } @@ -568,6 +598,8 @@ namespace DOM Reference< XDocument > SAL_CALL CNode::getOwnerDocument() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -581,6 +613,8 @@ namespace DOM Reference< XNode > SAL_CALL CNode::getParentNode() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -595,6 +629,8 @@ namespace DOM OUString SAL_CALL CNode::getPrefix() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aPrefix; if (m_aNodePtr != NULL && (m_aNodePtr->type == XML_ELEMENT_NODE || m_aNodePtr->type == XML_ATTRIBUTE_NODE) && @@ -614,6 +650,8 @@ namespace DOM Reference< XNode > SAL_CALL CNode::getPreviousSibling() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + if (0 == m_aNodePtr) { return 0; } @@ -628,6 +666,8 @@ namespace DOM sal_Bool SAL_CALL CNode::hasAttributes() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + return (m_aNodePtr != NULL && m_aNodePtr->properties != NULL); } @@ -637,6 +677,8 @@ namespace DOM sal_Bool SAL_CALL CNode::hasChildNodes() throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + return (m_aNodePtr != NULL && m_aNodePtr->children != NULL); } @@ -647,7 +689,6 @@ namespace DOM const Reference< XNode >& newChild, const Reference< XNode >& refChild) throw (RuntimeException, DOMException) { - if (newChild->getOwnerDocument() != getOwnerDocument()) { DOMException e; e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR; @@ -659,6 +700,8 @@ namespace DOM throw e; } + ::osl::MutexGuard const g(m_rMutex); + CNode *const pNewNode(CNode::GetImplementation(newChild)); CNode *const pRefNode(CNode::GetImplementation(refChild)); if (!pNewNode || !pRefNode) { throw RuntimeException(); } @@ -724,6 +767,8 @@ namespace DOM throw e; } + ::osl::ClearableMutexGuard guard(m_rMutex); + Reference<XNode> xReturn( oldChild ); ::rtl::Reference<CNode> const pOld(CNode::GetImplementation(oldChild)); @@ -759,8 +804,12 @@ namespace DOM sal_False, this, OUString(), OUString(), OUString(), (AttrChangeType)0 ); - dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); + // the following dispatch functions use only UNO interfaces + // and call event listeners, so release mutex to prevent deadlocks. + guard.clear(); + + dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); // subtree modofied for this node dispatchSubtreeModified(); } @@ -787,6 +836,8 @@ namespace DOM throw e; } + ::osl::ClearableMutexGuard guard(m_rMutex); + /* Reference< XNode > aNode = removeChild(oldChild); appendChild(newChild); @@ -844,6 +895,7 @@ namespace DOM } } + guard.clear(); // release for calling event handlers dispatchSubtreeModified(); return xOldChild; @@ -851,12 +903,15 @@ namespace DOM void CNode::dispatchSubtreeModified() { + // only uses UNO interfaces => needs no mutex + // dispatch DOMSubtreeModified // target is _this_ node Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); Reference< XMutationEvent > event(docevent->createEvent( OUString::createFromAscii("DOMSubtreeModified")), UNO_QUERY); - event->initMutationEvent(OUString::createFromAscii("DOMSubtreeModified"), sal_True, + event->initMutationEvent( + OUString::createFromAscii("DOMSubtreeModified"), sal_True, sal_False, Reference< XNode >(), OUString(), OUString(), OUString(), (AttrChangeType)0 ); dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); @@ -881,6 +936,8 @@ namespace DOM void SAL_CALL CNode::setPrefix(const OUString& prefix) throw (RuntimeException, DOMException) { + ::osl::MutexGuard const g(m_rMutex); + OString o1 = OUStringToOString(prefix, RTL_TEXTENCODING_UTF8); xmlChar *pBuf = (xmlChar*)o1.getStr(); // XXX copy buf? @@ -898,6 +955,8 @@ namespace DOM sal_Bool useCapture) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + CDocument & rDocument(GetOwnerDocument()); events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher()); rDispatcher.addListener(m_aNodePtr, eventType, listener, useCapture); @@ -908,6 +967,8 @@ namespace DOM sal_Bool useCapture) throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + CDocument & rDocument(GetOwnerDocument()); events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher()); rDispatcher.removeListener(m_aNodePtr, eventType, listener, useCapture); @@ -916,9 +977,18 @@ namespace DOM sal_Bool SAL_CALL CNode::dispatchEvent(const Reference< XEvent >& evt) throw(RuntimeException, EventException) { - CDocument & rDocument(GetOwnerDocument()); - events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher()); - rDispatcher.dispatchEvent(rDocument, m_aNodePtr, this, evt); + CDocument * pDocument; + events::CEventDispatcher * pDispatcher; + xmlNodePtr pNode; + { + ::osl::MutexGuard const g(m_rMutex); + + pDocument = & GetOwnerDocument(); + pDispatcher = & pDocument->GetEventDispatcher(); + pNode = m_aNodePtr; + } + // this calls event listeners, do not call with locked mutex + pDispatcher->dispatchEvent(*pDocument, m_rMutex, pNode, this, evt); return sal_True; } diff --git a/unoxml/source/dom/node.hxx b/unoxml/source/dom/node.hxx index d959fd49a074..0e6a4834a33e 100644 --- a/unoxml/source/dom/node.hxx +++ b/unoxml/source/dom/node.hxx @@ -132,9 +132,10 @@ namespace DOM xmlNodePtr m_aNodePtr; ::rtl::Reference< CDocument > const m_xDocument; + ::osl::Mutex & m_rMutex; // for initialization by classes derived through ImplInheritanceHelper - CNode(CDocument const& rDocument, + CNode(CDocument const& rDocument, ::osl::Mutex const& rMutex, NodeType const& reNodeType, xmlNodePtr const& rpNode); void invalidate(); @@ -152,18 +153,18 @@ namespace DOM virtual CDocument & GetOwnerDocument(); // recursively create SAX events - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); // recursively create SAX events - virtual void SAL_CALL fastSaxify( Context& io_rContext ); + virtual void fastSaxify( Context& io_rContext ); // ---- DOM interfaces /** Adds the node newChild to the end of the list of children of this node. */ - virtual Reference< XNode > SAL_CALL appendChild(const Reference< XNode >& newChild) + virtual Reference< XNode > SAL_CALL + appendChild(Reference< XNode > const& xNewChild) throw (RuntimeException, DOMException); /** diff --git a/unoxml/source/dom/notation.cxx b/unoxml/source/dom/notation.cxx index ff35fae60129..2522dd236d78 100644 --- a/unoxml/source/dom/notation.cxx +++ b/unoxml/source/dom/notation.cxx @@ -31,9 +31,9 @@ namespace DOM { - CNotation::CNotation(CDocument const& rDocument, + CNotation::CNotation(CDocument const& rDocument, ::osl::Mutex const& rMutex, xmlNotationPtr const pNotation) - : CNotation_Base(rDocument, + : CNotation_Base(rDocument, rMutex, NodeType_NOTATION_NODE, reinterpret_cast<xmlNodePtr>(pNotation)) , m_aNotationPtr(pNotation) { @@ -57,6 +57,8 @@ namespace DOM OUString SAL_CALL CNotation::getNodeName()throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aNodePtr != NULL) { @@ -65,6 +67,7 @@ namespace DOM } return aName; } + OUString SAL_CALL CNotation::getNodeValue() throw (RuntimeException) { return OUString(); diff --git a/unoxml/source/dom/notation.hxx b/unoxml/source/dom/notation.hxx index b4fcca61602f..c98e81b353a3 100644 --- a/unoxml/source/dom/notation.hxx +++ b/unoxml/source/dom/notation.hxx @@ -54,7 +54,8 @@ namespace DOM xmlNotationPtr m_aNotationPtr; protected: - CNotation(CDocument const& rDocument, xmlNotationPtr const pNotation); + CNotation(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNotationPtr const pNotation); /** The public identifier of this notation. diff --git a/unoxml/source/dom/processinginstruction.cxx b/unoxml/source/dom/processinginstruction.cxx index c75f3d9d6b29..c5cbaa96866b 100644 --- a/unoxml/source/dom/processinginstruction.cxx +++ b/unoxml/source/dom/processinginstruction.cxx @@ -35,13 +35,14 @@ namespace DOM { CProcessingInstruction::CProcessingInstruction( - CDocument const& rDocument, xmlNodePtr const pNode) - : CProcessingInstruction_Base(rDocument, + CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode) + : CProcessingInstruction_Base(rDocument, rMutex, NodeType_PROCESSING_INSTRUCTION_NODE, pNode) { } - void SAL_CALL CProcessingInstruction::saxify( + void CProcessingInstruction::saxify( const Reference< XDocumentHandler >& i_xHandler) { if (!i_xHandler.is()) throw RuntimeException(); Reference< XExtendedDocumentHandler > xExtended(i_xHandler, UNO_QUERY); @@ -80,6 +81,8 @@ namespace DOM OUString SAL_CALL CProcessingInstruction::getNodeName()throw (RuntimeException) { + ::osl::MutexGuard const g(m_rMutex); + OUString aName; if (m_aNodePtr != NULL) { diff --git a/unoxml/source/dom/processinginstruction.hxx b/unoxml/source/dom/processinginstruction.hxx index 4c140123f13c..44cf07a0e7df 100644 --- a/unoxml/source/dom/processinginstruction.hxx +++ b/unoxml/source/dom/processinginstruction.hxx @@ -52,13 +52,13 @@ namespace DOM friend class CDocument; protected: - CProcessingInstruction(CDocument const& rDocument, + CProcessingInstruction( + CDocument const& rDocument, ::osl::Mutex const& rMutex, xmlNodePtr const pNode); public: - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); /** The content of this processing instruction. diff --git a/unoxml/source/dom/text.cxx b/unoxml/source/dom/text.cxx index a5fff96d30dc..f69219550fe5 100644 --- a/unoxml/source/dom/text.cxx +++ b/unoxml/source/dom/text.cxx @@ -30,35 +30,25 @@ namespace DOM { - CText::CText(CDocument const& rDocument, + CText::CText(CDocument const& rDocument, ::osl::Mutex const& rMutex, NodeType const& reNodeType, xmlNodePtr const& rpNode) - : CText_Base(rDocument, reNodeType, rpNode) + : CText_Base(rDocument, rMutex, reNodeType, rpNode) { } - CText::CText(CDocument const& rDocument, xmlNodePtr const pNode) - : CText_Base(rDocument, NodeType_TEXT_NODE, pNode) + CText::CText(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode) + : CText_Base(rDocument, rMutex, NodeType_TEXT_NODE, pNode) { } - void SAL_CALL CText::saxify( + void CText::saxify( const Reference< XDocumentHandler >& i_xHandler) { if (!i_xHandler.is()) throw RuntimeException(); i_xHandler->characters(getData()); } - Reference< XText > SAL_CALL CText::splitText(sal_Int32 /*offset*/) - throw (RuntimeException) - { - return Reference< XText >(this); - } - - OUString SAL_CALL CText::getNodeName()throw (RuntimeException) - { - return OUString::createFromAscii("#text"); - } - - void SAL_CALL CText::fastSaxify( Context& io_rContext ) + void CText::fastSaxify( Context& io_rContext ) { if (io_rContext.mxCurrentHandler.is()) { @@ -71,4 +61,14 @@ namespace DOM } } + OUString SAL_CALL CText::getNodeName() throw (RuntimeException) + { + return OUString::createFromAscii("#text"); + } + + Reference< XText > SAL_CALL CText::splitText(sal_Int32 /*offset*/) + throw (RuntimeException) + { + return Reference< XText >(this); + } } diff --git a/unoxml/source/dom/text.hxx b/unoxml/source/dom/text.hxx index 1f0e273f5426..c58a4e14255e 100644 --- a/unoxml/source/dom/text.hxx +++ b/unoxml/source/dom/text.hxx @@ -56,16 +56,16 @@ namespace DOM friend class CDocument; protected: - CText(CDocument const& rDocument, + CText(CDocument const& rDocument, ::osl::Mutex const& rMutex, NodeType const& reNodeType, xmlNodePtr const& rpNode); - CText(CDocument const& rDocument, xmlNodePtr const pNode); + CText(CDocument const& rDocument, ::osl::Mutex const& rMutex, + xmlNodePtr const pNode); public: - virtual void SAL_CALL saxify( - const Reference< XDocumentHandler >& i_xHandler); + virtual void saxify(const Reference< XDocumentHandler >& i_xHandler); - virtual void SAL_CALL fastSaxify( Context& io_rContext ); + virtual void fastSaxify( Context& io_rContext ); // Breaks this node into two nodes at the specified offset, keeping // both in the tree as siblings. diff --git a/unoxml/source/events/eventdispatcher.cxx b/unoxml/source/events/eventdispatcher.cxx index 88abd8ea057e..4b4cac807538 100644 --- a/unoxml/source/events/eventdispatcher.cxx +++ b/unoxml/source/events/eventdispatcher.cxx @@ -82,16 +82,14 @@ namespace DOM { namespace events { } } - void CEventDispatcher::callListeners(xmlNodePtr const pNode, - OUString aType, Reference< XEvent > const& xEvent, - sal_Bool const bCapture) const + void CEventDispatcher::callListeners( + TypeListenerMap const& rTMap, + xmlNodePtr const pNode, + OUString aType, Reference< XEvent > const& xEvent) { - TypeListenerMap const*const pTMap = (bCapture) - ? (& m_CaptureListeners) : (& m_TargetListeners); - // get the multimap for the specified type - TypeListenerMap::const_iterator tIter = pTMap->find(aType); - if (tIter != pTMap->end()) { + TypeListenerMap::const_iterator tIter = rTMap.find(aType); + if (tIter != rTMap.end()) { ListenerMap *pMap = tIter->second; ListenerMap::const_iterator iter = pMap->lower_bound(pNode); ListenerMap::const_iterator ibound = pMap->upper_bound(pNode); @@ -103,7 +101,8 @@ namespace DOM { namespace events { } } - bool CEventDispatcher::dispatchEvent(DOM::CDocument & rDocument, + bool CEventDispatcher::dispatchEvent( + DOM::CDocument & rDocument, ::osl::Mutex & rMutex, xmlNodePtr const pNode, Reference<XNode> const& xNode, Reference< XEvent > const& i_xEvent) const { @@ -177,12 +176,24 @@ namespace DOM { namespace events { Reference< XEvent > const xEvent(pEvent); // build the path from target node to the root - NodeVector captureVector; - xmlNodePtr cur = pNode; - while (cur != NULL) + typedef std::vector< ::std::pair<Reference<XEventTarget>, xmlNodePtr> > + NodeVector_t; + NodeVector_t captureVector; + TypeListenerMap captureListeners; + TypeListenerMap targetListeners; { - captureVector.push_back(cur); - cur = cur->parent; + ::osl::MutexGuard g(rMutex); + + xmlNodePtr cur = pNode; + while (cur != NULL) + { + Reference< XEventTarget > const xRef( + rDocument.GetCNode(cur).get()); + captureVector.push_back(::std::make_pair(xRef, cur)); + cur = cur->parent; + } + captureListeners = m_CaptureListeners; + targetListeners = m_TargetListeners; } // the caputre vector now holds the node path from target to root @@ -191,27 +202,27 @@ namespace DOM { namespace events { // then bubbeling phase listeners are called in target to root // order // start at the root - NodeVector::const_reverse_iterator rinode = - const_cast<const NodeVector&>(captureVector).rbegin(); - if (rinode != const_cast<const NodeVector&>(captureVector).rend()) + NodeVector_t::const_reverse_iterator rinode = + const_cast<NodeVector_t const&>(captureVector).rbegin(); + if (rinode != const_cast<NodeVector_t const&>(captureVector).rend()) { // capturing phase: pEvent->m_phase = PhaseType_CAPTURING_PHASE; while (rinode != - const_cast<const NodeVector&>(captureVector).rend()) + const_cast<NodeVector_t const&>(captureVector).rend()) { - pEvent->m_currentTarget = Reference< XEventTarget >( - rDocument.GetCNode(*rinode).get()); - callListeners(*rinode, aType, xEvent, sal_True); + pEvent->m_currentTarget = rinode->first; + callListeners(captureListeners, rinode->second, aType, xEvent); if (pEvent->m_canceled) return sal_True; rinode++; } - NodeVector::const_iterator inode = captureVector.begin(); + NodeVector_t::const_iterator inode = captureVector.begin(); // target phase pEvent->m_phase = PhaseType_AT_TARGET; - callListeners(*inode, aType, xEvent, sal_False); + pEvent->m_currentTarget = inode->first; + callListeners(targetListeners, inode->second, aType, xEvent); if (pEvent->m_canceled) return sal_True; // bubbeling phase inode++; @@ -219,9 +230,9 @@ namespace DOM { namespace events { pEvent->m_phase = PhaseType_BUBBLING_PHASE; while (inode != captureVector.end()) { - pEvent->m_currentTarget = Reference< XEventTarget >( - rDocument.GetCNode(*inode).get()); - callListeners(*inode, aType, xEvent, sal_False); + pEvent->m_currentTarget = inode->first; + callListeners(targetListeners, + inode->second, aType, xEvent); if (pEvent->m_canceled) return sal_True; inode++; } diff --git a/unoxml/source/events/eventdispatcher.hxx b/unoxml/source/events/eventdispatcher.hxx index bf85a80da8f7..62cb2d38b3f5 100644 --- a/unoxml/source/events/eventdispatcher.hxx +++ b/unoxml/source/events/eventdispatcher.hxx @@ -52,7 +52,6 @@ class CDocument; namespace events { -typedef std::vector< xmlNodePtr > NodeVector; typedef std::multimap< xmlNodePtr, Reference< com::sun::star::xml::dom::events::XEventListener> > ListenerMap; typedef std::map< ::rtl::OUString, ListenerMap*> TypeListenerMap; typedef std::vector<ListenerMap::value_type> ListenerPairVector; @@ -76,14 +75,15 @@ public: const Reference<com::sun::star::xml::dom::events::XEventListener>& aListener, sal_Bool bCapture); - void callListeners( + static void callListeners( + TypeListenerMap const& rTMap, xmlNodePtr const pNode, ::rtl::OUString aType, - const Reference< XEvent >& xEvent, - sal_Bool const bCapture) const; + const Reference< XEvent >& xEvent); bool dispatchEvent( DOM::CDocument & rDocument, + ::osl::Mutex & rMutex, xmlNodePtr const pNode, Reference<XNode> const& xNode, Reference< XEvent > const& xEvent) const; |