1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/Sequence.h> 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski #include "document.hxx" 27*b1cdbd2cSJim Jagielski #include "attr.hxx" 28*b1cdbd2cSJim Jagielski #include "element.hxx" 29*b1cdbd2cSJim Jagielski #include "cdatasection.hxx" 30*b1cdbd2cSJim Jagielski #include "documentfragment.hxx" 31*b1cdbd2cSJim Jagielski #include "text.hxx" 32*b1cdbd2cSJim Jagielski #include "cdatasection.hxx" 33*b1cdbd2cSJim Jagielski #include "comment.hxx" 34*b1cdbd2cSJim Jagielski #include "processinginstruction.hxx" 35*b1cdbd2cSJim Jagielski #include "entityreference.hxx" 36*b1cdbd2cSJim Jagielski #include "documenttype.hxx" 37*b1cdbd2cSJim Jagielski #include "elementlist.hxx" 38*b1cdbd2cSJim Jagielski #include "domimplementation.hxx" 39*b1cdbd2cSJim Jagielski #include <entity.hxx> 40*b1cdbd2cSJim Jagielski #include <notation.hxx> 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski #include "../events/event.hxx" 43*b1cdbd2cSJim Jagielski #include "../events/mutationevent.hxx" 44*b1cdbd2cSJim Jagielski #include "../events/uievent.hxx" 45*b1cdbd2cSJim Jagielski #include "../events/mouseevent.hxx" 46*b1cdbd2cSJim Jagielski #include "../events/eventdispatcher.hxx" 47*b1cdbd2cSJim Jagielski 48*b1cdbd2cSJim Jagielski #include <string.h> 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/FastToken.hpp> 51*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> 52*b1cdbd2cSJim Jagielski 53*b1cdbd2cSJim Jagielski namespace DOM 54*b1cdbd2cSJim Jagielski { lcl_getDocumentType(xmlDocPtr const i_pDocument)55*b1cdbd2cSJim Jagielski static xmlNodePtr lcl_getDocumentType(xmlDocPtr const i_pDocument) 56*b1cdbd2cSJim Jagielski { 57*b1cdbd2cSJim Jagielski // find the doc type 58*b1cdbd2cSJim Jagielski xmlNodePtr cur = i_pDocument->children; 59*b1cdbd2cSJim Jagielski while (cur != NULL) 60*b1cdbd2cSJim Jagielski { 61*b1cdbd2cSJim Jagielski if ((cur->type == XML_DOCUMENT_TYPE_NODE) || 62*b1cdbd2cSJim Jagielski (cur->type == XML_DTD_NODE)) { 63*b1cdbd2cSJim Jagielski return cur; 64*b1cdbd2cSJim Jagielski } 65*b1cdbd2cSJim Jagielski } 66*b1cdbd2cSJim Jagielski return 0; 67*b1cdbd2cSJim Jagielski } 68*b1cdbd2cSJim Jagielski 69*b1cdbd2cSJim Jagielski /// get the pointer to the root element node of the document lcl_getDocumentRootPtr(xmlDocPtr const i_pDocument)70*b1cdbd2cSJim Jagielski static xmlNodePtr lcl_getDocumentRootPtr(xmlDocPtr const i_pDocument) 71*b1cdbd2cSJim Jagielski { 72*b1cdbd2cSJim Jagielski // find the document element 73*b1cdbd2cSJim Jagielski xmlNodePtr cur = i_pDocument->children; 74*b1cdbd2cSJim Jagielski while (cur != NULL) 75*b1cdbd2cSJim Jagielski { 76*b1cdbd2cSJim Jagielski if (cur->type == XML_ELEMENT_NODE) 77*b1cdbd2cSJim Jagielski break; 78*b1cdbd2cSJim Jagielski cur = cur->next; 79*b1cdbd2cSJim Jagielski } 80*b1cdbd2cSJim Jagielski return cur; 81*b1cdbd2cSJim Jagielski } 82*b1cdbd2cSJim Jagielski CDocument(xmlDocPtr const pDoc)83*b1cdbd2cSJim Jagielski CDocument::CDocument(xmlDocPtr const pDoc) 84*b1cdbd2cSJim Jagielski : CDocument_Base(*this, m_Mutex, 85*b1cdbd2cSJim Jagielski NodeType_DOCUMENT_NODE, reinterpret_cast<xmlNodePtr>(pDoc)) 86*b1cdbd2cSJim Jagielski , m_aDocPtr(pDoc) 87*b1cdbd2cSJim Jagielski , m_streamListeners() 88*b1cdbd2cSJim Jagielski , m_pEventDispatcher(new events::CEventDispatcher()) 89*b1cdbd2cSJim Jagielski { 90*b1cdbd2cSJim Jagielski } 91*b1cdbd2cSJim Jagielski CreateCDocument(xmlDocPtr const pDoc)92*b1cdbd2cSJim Jagielski ::rtl::Reference<CDocument> CDocument::CreateCDocument(xmlDocPtr const pDoc) 93*b1cdbd2cSJim Jagielski { 94*b1cdbd2cSJim Jagielski ::rtl::Reference<CDocument> const xDoc(new CDocument(pDoc)); 95*b1cdbd2cSJim Jagielski // add the doc itself to its nodemap! 96*b1cdbd2cSJim Jagielski xDoc->m_NodeMap.insert( 97*b1cdbd2cSJim Jagielski nodemap_t::value_type(reinterpret_cast<xmlNodePtr>(pDoc), 98*b1cdbd2cSJim Jagielski ::std::make_pair( 99*b1cdbd2cSJim Jagielski WeakReference<XNode>(static_cast<XDocument*>(xDoc.get())), 100*b1cdbd2cSJim Jagielski xDoc.get()))); 101*b1cdbd2cSJim Jagielski return xDoc; 102*b1cdbd2cSJim Jagielski } 103*b1cdbd2cSJim Jagielski ~CDocument()104*b1cdbd2cSJim Jagielski CDocument::~CDocument() 105*b1cdbd2cSJim Jagielski { 106*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 107*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL 108*b1cdbd2cSJim Jagielski // node map must be empty now, otherwise CDocument must not die! 109*b1cdbd2cSJim Jagielski for (nodemap_t::iterator i = m_NodeMap.begin(); 110*b1cdbd2cSJim Jagielski i != m_NodeMap.end(); ++i) 111*b1cdbd2cSJim Jagielski { 112*b1cdbd2cSJim Jagielski Reference<XNode> const xNode(i->second.first); 113*b1cdbd2cSJim Jagielski OSL_ENSURE(!xNode.is(), 114*b1cdbd2cSJim Jagielski "CDocument::~CDocument(): ERROR: live node in document node map!"); 115*b1cdbd2cSJim Jagielski } 116*b1cdbd2cSJim Jagielski #endif 117*b1cdbd2cSJim Jagielski xmlFreeDoc(m_aDocPtr); 118*b1cdbd2cSJim Jagielski } 119*b1cdbd2cSJim Jagielski 120*b1cdbd2cSJim Jagielski GetEventDispatcher()121*b1cdbd2cSJim Jagielski events::CEventDispatcher & CDocument::GetEventDispatcher() 122*b1cdbd2cSJim Jagielski { 123*b1cdbd2cSJim Jagielski return *m_pEventDispatcher; 124*b1cdbd2cSJim Jagielski } 125*b1cdbd2cSJim Jagielski GetDocumentElement()126*b1cdbd2cSJim Jagielski ::rtl::Reference< CElement > CDocument::GetDocumentElement() 127*b1cdbd2cSJim Jagielski { 128*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr); 129*b1cdbd2cSJim Jagielski ::rtl::Reference< CElement > const xRet( 130*b1cdbd2cSJim Jagielski dynamic_cast<CElement*>(GetCNode(pNode).get())); 131*b1cdbd2cSJim Jagielski return xRet; 132*b1cdbd2cSJim Jagielski } 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski void RemoveCNode(xmlNodePtr const pNode,CNode const * const pCNode)135*b1cdbd2cSJim Jagielski CDocument::RemoveCNode(xmlNodePtr const pNode, CNode const*const pCNode) 136*b1cdbd2cSJim Jagielski { 137*b1cdbd2cSJim Jagielski nodemap_t::iterator const i = m_NodeMap.find(pNode); 138*b1cdbd2cSJim Jagielski if (i != m_NodeMap.end()) { 139*b1cdbd2cSJim Jagielski // #i113681# consider this scenario: 140*b1cdbd2cSJim Jagielski // T1 calls ~CNode 141*b1cdbd2cSJim Jagielski // T2 calls getCNode: lookup will find i->second->first invalid 142*b1cdbd2cSJim Jagielski // so a new CNode is created and inserted 143*b1cdbd2cSJim Jagielski // T1 calls removeCNode: i->second->second now points to a 144*b1cdbd2cSJim Jagielski // different CNode instance! 145*b1cdbd2cSJim Jagielski // 146*b1cdbd2cSJim Jagielski // check that the CNode is the right one 147*b1cdbd2cSJim Jagielski CNode *const pCurrent = i->second.second; 148*b1cdbd2cSJim Jagielski if (pCurrent == pCNode) { 149*b1cdbd2cSJim Jagielski m_NodeMap.erase(i); 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski } 152*b1cdbd2cSJim Jagielski } 153*b1cdbd2cSJim Jagielski 154*b1cdbd2cSJim Jagielski /** NB: this is the CNode factory. 155*b1cdbd2cSJim Jagielski it is the only place where CNodes may be instantiated. 156*b1cdbd2cSJim Jagielski all CNodes must be registered at the m_NodeMap. 157*b1cdbd2cSJim Jagielski */ 158*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> GetCNode(xmlNodePtr const pNode,bool const bCreate)159*b1cdbd2cSJim Jagielski CDocument::GetCNode(xmlNodePtr const pNode, bool const bCreate) 160*b1cdbd2cSJim Jagielski { 161*b1cdbd2cSJim Jagielski if (0 == pNode) { 162*b1cdbd2cSJim Jagielski return 0; 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski //check whether there is already an instance for this node 165*b1cdbd2cSJim Jagielski nodemap_t::const_iterator const i = m_NodeMap.find(pNode); 166*b1cdbd2cSJim Jagielski if (i != m_NodeMap.end()) { 167*b1cdbd2cSJim Jagielski // #i113681# check that the CNode is still alive 168*b1cdbd2cSJim Jagielski uno::Reference<XNode> const xNode(i->second.first); 169*b1cdbd2cSJim Jagielski if (xNode.is()) 170*b1cdbd2cSJim Jagielski { 171*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> ret(i->second.second); 172*b1cdbd2cSJim Jagielski OSL_ASSERT(ret.is()); 173*b1cdbd2cSJim Jagielski return ret; 174*b1cdbd2cSJim Jagielski } 175*b1cdbd2cSJim Jagielski } 176*b1cdbd2cSJim Jagielski 177*b1cdbd2cSJim Jagielski if (!bCreate) { return 0; } 178*b1cdbd2cSJim Jagielski 179*b1cdbd2cSJim Jagielski // there is not yet an instance wrapping this node, 180*b1cdbd2cSJim Jagielski // create it and store it in the map 181*b1cdbd2cSJim Jagielski 182*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> pCNode; 183*b1cdbd2cSJim Jagielski switch (pNode->type) 184*b1cdbd2cSJim Jagielski { 185*b1cdbd2cSJim Jagielski case XML_ELEMENT_NODE: 186*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::ELEMENT_NODE; 187*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 188*b1cdbd2cSJim Jagielski new CElement(*this, m_Mutex, pNode)); 189*b1cdbd2cSJim Jagielski break; 190*b1cdbd2cSJim Jagielski case XML_TEXT_NODE: 191*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::TEXT_NODE; 192*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 193*b1cdbd2cSJim Jagielski new CText(*this, m_Mutex, pNode)); 194*b1cdbd2cSJim Jagielski break; 195*b1cdbd2cSJim Jagielski case XML_CDATA_SECTION_NODE: 196*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::CDATA_SECTION_NODE; 197*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 198*b1cdbd2cSJim Jagielski new CCDATASection(*this, m_Mutex, pNode)); 199*b1cdbd2cSJim Jagielski break; 200*b1cdbd2cSJim Jagielski case XML_ENTITY_REF_NODE: 201*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::ENTITY_REFERENCE_NODE; 202*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 203*b1cdbd2cSJim Jagielski new CEntityReference(*this, m_Mutex, pNode)); 204*b1cdbd2cSJim Jagielski break; 205*b1cdbd2cSJim Jagielski case XML_ENTITY_NODE: 206*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::ENTITY_NODE; 207*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >(new CEntity(*this, m_Mutex, 208*b1cdbd2cSJim Jagielski reinterpret_cast<xmlEntityPtr>(pNode))); 209*b1cdbd2cSJim Jagielski break; 210*b1cdbd2cSJim Jagielski case XML_PI_NODE: 211*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::PROCESSING_INSTRUCTION_NODE; 212*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 213*b1cdbd2cSJim Jagielski new CProcessingInstruction(*this, m_Mutex, pNode)); 214*b1cdbd2cSJim Jagielski break; 215*b1cdbd2cSJim Jagielski case XML_COMMENT_NODE: 216*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::COMMENT_NODE; 217*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 218*b1cdbd2cSJim Jagielski new CComment(*this, m_Mutex, pNode)); 219*b1cdbd2cSJim Jagielski break; 220*b1cdbd2cSJim Jagielski case XML_DOCUMENT_NODE: 221*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::DOCUMENT_NODE; 222*b1cdbd2cSJim Jagielski OSL_ENSURE(false, "CDocument::GetCNode is not supposed to" 223*b1cdbd2cSJim Jagielski " create a CDocument!!!"); 224*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >(new CDocument( 225*b1cdbd2cSJim Jagielski reinterpret_cast<xmlDocPtr>(pNode))); 226*b1cdbd2cSJim Jagielski break; 227*b1cdbd2cSJim Jagielski case XML_DOCUMENT_TYPE_NODE: 228*b1cdbd2cSJim Jagielski case XML_DTD_NODE: 229*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::DOCUMENT_TYPE_NODE; 230*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >(new CDocumentType(*this, m_Mutex, 231*b1cdbd2cSJim Jagielski reinterpret_cast<xmlDtdPtr>(pNode))); 232*b1cdbd2cSJim Jagielski break; 233*b1cdbd2cSJim Jagielski case XML_DOCUMENT_FRAG_NODE: 234*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::DOCUMENT_FRAGMENT_NODE; 235*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >( 236*b1cdbd2cSJim Jagielski new CDocumentFragment(*this, m_Mutex, pNode)); 237*b1cdbd2cSJim Jagielski break; 238*b1cdbd2cSJim Jagielski case XML_NOTATION_NODE: 239*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::NOTATION_NODE; 240*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >(new CNotation(*this, m_Mutex, 241*b1cdbd2cSJim Jagielski reinterpret_cast<xmlNotationPtr>(pNode))); 242*b1cdbd2cSJim Jagielski break; 243*b1cdbd2cSJim Jagielski case XML_ATTRIBUTE_NODE: 244*b1cdbd2cSJim Jagielski // m_aNodeType = NodeType::ATTRIBUTE_NODE; 245*b1cdbd2cSJim Jagielski pCNode = static_cast< CNode* >(new CAttr(*this, m_Mutex, 246*b1cdbd2cSJim Jagielski reinterpret_cast<xmlAttrPtr>(pNode))); 247*b1cdbd2cSJim Jagielski break; 248*b1cdbd2cSJim Jagielski // unsupported node types 249*b1cdbd2cSJim Jagielski case XML_HTML_DOCUMENT_NODE: 250*b1cdbd2cSJim Jagielski case XML_ELEMENT_DECL: 251*b1cdbd2cSJim Jagielski case XML_ATTRIBUTE_DECL: 252*b1cdbd2cSJim Jagielski case XML_ENTITY_DECL: 253*b1cdbd2cSJim Jagielski case XML_NAMESPACE_DECL: 254*b1cdbd2cSJim Jagielski default: 255*b1cdbd2cSJim Jagielski break; 256*b1cdbd2cSJim Jagielski } 257*b1cdbd2cSJim Jagielski 258*b1cdbd2cSJim Jagielski if (pCNode != 0) { 259*b1cdbd2cSJim Jagielski bool const bInserted = m_NodeMap.insert( 260*b1cdbd2cSJim Jagielski nodemap_t::value_type(pNode, 261*b1cdbd2cSJim Jagielski ::std::make_pair(WeakReference<XNode>(pCNode.get()), 262*b1cdbd2cSJim Jagielski pCNode.get())) 263*b1cdbd2cSJim Jagielski ).second; 264*b1cdbd2cSJim Jagielski OSL_ASSERT(bInserted); 265*b1cdbd2cSJim Jagielski if (!bInserted) { 266*b1cdbd2cSJim Jagielski // if insertion failed, delete new instance and return null 267*b1cdbd2cSJim Jagielski return 0; 268*b1cdbd2cSJim Jagielski } 269*b1cdbd2cSJim Jagielski } 270*b1cdbd2cSJim Jagielski 271*b1cdbd2cSJim Jagielski OSL_ENSURE(pCNode.is(), "no node produced during CDocument::GetCNode!"); 272*b1cdbd2cSJim Jagielski return pCNode; 273*b1cdbd2cSJim Jagielski } 274*b1cdbd2cSJim Jagielski 275*b1cdbd2cSJim Jagielski GetOwnerDocument()276*b1cdbd2cSJim Jagielski CDocument & CDocument::GetOwnerDocument() 277*b1cdbd2cSJim Jagielski { 278*b1cdbd2cSJim Jagielski return *this; 279*b1cdbd2cSJim Jagielski } 280*b1cdbd2cSJim Jagielski saxify(const Reference<XDocumentHandler> & i_xHandler)281*b1cdbd2cSJim Jagielski void CDocument::saxify(const Reference< XDocumentHandler >& i_xHandler) 282*b1cdbd2cSJim Jagielski { 283*b1cdbd2cSJim Jagielski i_xHandler->startDocument(); 284*b1cdbd2cSJim Jagielski for (xmlNodePtr pChild = m_aNodePtr->children; 285*b1cdbd2cSJim Jagielski pChild != 0; pChild = pChild->next) { 286*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pNode = GetCNode(pChild); 287*b1cdbd2cSJim Jagielski OSL_ENSURE(pNode != 0, "CNode::get returned 0"); 288*b1cdbd2cSJim Jagielski pNode->saxify(i_xHandler); 289*b1cdbd2cSJim Jagielski } 290*b1cdbd2cSJim Jagielski i_xHandler->endDocument(); 291*b1cdbd2cSJim Jagielski } 292*b1cdbd2cSJim Jagielski fastSaxify(Context & rContext)293*b1cdbd2cSJim Jagielski void CDocument::fastSaxify( Context& rContext ) 294*b1cdbd2cSJim Jagielski { 295*b1cdbd2cSJim Jagielski rContext.mxDocHandler->startDocument(); 296*b1cdbd2cSJim Jagielski for (xmlNodePtr pChild = m_aNodePtr->children; 297*b1cdbd2cSJim Jagielski pChild != 0; pChild = pChild->next) { 298*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pNode = GetCNode(pChild); 299*b1cdbd2cSJim Jagielski OSL_ENSURE(pNode != 0, "CNode::get returned 0"); 300*b1cdbd2cSJim Jagielski pNode->fastSaxify(rContext); 301*b1cdbd2cSJim Jagielski } 302*b1cdbd2cSJim Jagielski rContext.mxDocHandler->endDocument(); 303*b1cdbd2cSJim Jagielski } 304*b1cdbd2cSJim Jagielski IsChildTypeAllowed(NodeType const nodeType)305*b1cdbd2cSJim Jagielski bool CDocument::IsChildTypeAllowed(NodeType const nodeType) 306*b1cdbd2cSJim Jagielski { 307*b1cdbd2cSJim Jagielski switch (nodeType) { 308*b1cdbd2cSJim Jagielski case NodeType_PROCESSING_INSTRUCTION_NODE: 309*b1cdbd2cSJim Jagielski case NodeType_COMMENT_NODE: 310*b1cdbd2cSJim Jagielski return true; 311*b1cdbd2cSJim Jagielski case NodeType_ELEMENT_NODE: 312*b1cdbd2cSJim Jagielski // there may be only one! 313*b1cdbd2cSJim Jagielski return 0 == lcl_getDocumentRootPtr(m_aDocPtr); 314*b1cdbd2cSJim Jagielski case NodeType_DOCUMENT_TYPE_NODE: 315*b1cdbd2cSJim Jagielski // there may be only one! 316*b1cdbd2cSJim Jagielski return 0 == lcl_getDocumentType(m_aDocPtr); 317*b1cdbd2cSJim Jagielski default: 318*b1cdbd2cSJim Jagielski return false; 319*b1cdbd2cSJim Jagielski } 320*b1cdbd2cSJim Jagielski } 321*b1cdbd2cSJim Jagielski 322*b1cdbd2cSJim Jagielski addListener(const Reference<XStreamListener> & aListener)323*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::addListener(const Reference< XStreamListener >& aListener ) 324*b1cdbd2cSJim Jagielski throw (RuntimeException) 325*b1cdbd2cSJim Jagielski { 326*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 327*b1cdbd2cSJim Jagielski 328*b1cdbd2cSJim Jagielski m_streamListeners.insert(aListener); 329*b1cdbd2cSJim Jagielski } 330*b1cdbd2cSJim Jagielski removeListener(const Reference<XStreamListener> & aListener)331*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::removeListener(const Reference< XStreamListener >& aListener ) 332*b1cdbd2cSJim Jagielski throw (RuntimeException) 333*b1cdbd2cSJim Jagielski { 334*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 335*b1cdbd2cSJim Jagielski 336*b1cdbd2cSJim Jagielski m_streamListeners.erase(aListener); 337*b1cdbd2cSJim Jagielski } 338*b1cdbd2cSJim Jagielski 339*b1cdbd2cSJim Jagielski // IO context functions for libxml2 interaction 340*b1cdbd2cSJim Jagielski typedef struct { 341*b1cdbd2cSJim Jagielski Reference< XOutputStream > stream; 342*b1cdbd2cSJim Jagielski bool allowClose; 343*b1cdbd2cSJim Jagielski } IOContext; 344*b1cdbd2cSJim Jagielski 345*b1cdbd2cSJim Jagielski extern "C" { 346*b1cdbd2cSJim Jagielski // write callback 347*b1cdbd2cSJim Jagielski // int xmlOutputWriteCallback (void * context, const char * buffer, int len) writeCallback(void * context,const char * buffer,int len)348*b1cdbd2cSJim Jagielski static int writeCallback(void *context, const char* buffer, int len){ 349*b1cdbd2cSJim Jagielski // create a sequence and write it to the stream 350*b1cdbd2cSJim Jagielski IOContext *pContext = static_cast<IOContext*>(context); 351*b1cdbd2cSJim Jagielski Sequence<sal_Int8> bs(reinterpret_cast<const sal_Int8*>(buffer), len); 352*b1cdbd2cSJim Jagielski pContext->stream->writeBytes(bs); 353*b1cdbd2cSJim Jagielski return len; 354*b1cdbd2cSJim Jagielski } 355*b1cdbd2cSJim Jagielski 356*b1cdbd2cSJim Jagielski // clsoe callback 357*b1cdbd2cSJim Jagielski //int xmlOutputCloseCallback (void * context) closeCallback(void * context)358*b1cdbd2cSJim Jagielski static int closeCallback(void *context) 359*b1cdbd2cSJim Jagielski { 360*b1cdbd2cSJim Jagielski IOContext *pContext = static_cast<IOContext*>(context); 361*b1cdbd2cSJim Jagielski if (pContext->allowClose) { 362*b1cdbd2cSJim Jagielski pContext->stream->closeOutput(); 363*b1cdbd2cSJim Jagielski } 364*b1cdbd2cSJim Jagielski return 0; 365*b1cdbd2cSJim Jagielski } 366*b1cdbd2cSJim Jagielski } // extern "C" 367*b1cdbd2cSJim Jagielski start()368*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::start() 369*b1cdbd2cSJim Jagielski throw (RuntimeException) 370*b1cdbd2cSJim Jagielski { 371*b1cdbd2cSJim Jagielski listenerlist_t streamListeners; 372*b1cdbd2cSJim Jagielski { 373*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 374*b1cdbd2cSJim Jagielski 375*b1cdbd2cSJim Jagielski if (! m_rOutputStream.is()) { throw RuntimeException(); } 376*b1cdbd2cSJim Jagielski streamListeners = m_streamListeners; 377*b1cdbd2cSJim Jagielski } 378*b1cdbd2cSJim Jagielski 379*b1cdbd2cSJim Jagielski // notify listeners about start 380*b1cdbd2cSJim Jagielski listenerlist_t::const_iterator iter1 = streamListeners.begin(); 381*b1cdbd2cSJim Jagielski while (iter1 != streamListeners.end()) { 382*b1cdbd2cSJim Jagielski Reference< XStreamListener > aListener = *iter1; 383*b1cdbd2cSJim Jagielski aListener->started(); 384*b1cdbd2cSJim Jagielski iter1++; 385*b1cdbd2cSJim Jagielski } 386*b1cdbd2cSJim Jagielski 387*b1cdbd2cSJim Jagielski { 388*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 389*b1cdbd2cSJim Jagielski 390*b1cdbd2cSJim Jagielski // check again! could have been reset... 391*b1cdbd2cSJim Jagielski if (! m_rOutputStream.is()) { throw RuntimeException(); } 392*b1cdbd2cSJim Jagielski 393*b1cdbd2cSJim Jagielski // setup libxml IO and write data to output stream 394*b1cdbd2cSJim Jagielski IOContext ioctx = {m_rOutputStream, false}; 395*b1cdbd2cSJim Jagielski xmlOutputBufferPtr pOut = xmlOutputBufferCreateIO( 396*b1cdbd2cSJim Jagielski writeCallback, closeCallback, &ioctx, NULL); 397*b1cdbd2cSJim Jagielski xmlSaveFileTo(pOut, m_aNodePtr->doc, NULL); 398*b1cdbd2cSJim Jagielski } 399*b1cdbd2cSJim Jagielski 400*b1cdbd2cSJim Jagielski // call listeners 401*b1cdbd2cSJim Jagielski listenerlist_t::const_iterator iter2 = streamListeners.begin(); 402*b1cdbd2cSJim Jagielski while (iter2 != streamListeners.end()) { 403*b1cdbd2cSJim Jagielski Reference< XStreamListener > aListener = *iter2; 404*b1cdbd2cSJim Jagielski aListener->closed(); 405*b1cdbd2cSJim Jagielski iter2++; 406*b1cdbd2cSJim Jagielski } 407*b1cdbd2cSJim Jagielski } 408*b1cdbd2cSJim Jagielski terminate()409*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::terminate() 410*b1cdbd2cSJim Jagielski throw (RuntimeException) 411*b1cdbd2cSJim Jagielski { 412*b1cdbd2cSJim Jagielski // not supported 413*b1cdbd2cSJim Jagielski } 414*b1cdbd2cSJim Jagielski setOutputStream(const Reference<XOutputStream> & aStream)415*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::setOutputStream( const Reference< XOutputStream >& aStream ) 416*b1cdbd2cSJim Jagielski throw (RuntimeException) 417*b1cdbd2cSJim Jagielski { 418*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 419*b1cdbd2cSJim Jagielski 420*b1cdbd2cSJim Jagielski m_rOutputStream = aStream; 421*b1cdbd2cSJim Jagielski } 422*b1cdbd2cSJim Jagielski getOutputStream()423*b1cdbd2cSJim Jagielski Reference< XOutputStream > SAL_CALL CDocument::getOutputStream() throw (RuntimeException) 424*b1cdbd2cSJim Jagielski { 425*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 426*b1cdbd2cSJim Jagielski 427*b1cdbd2cSJim Jagielski return m_rOutputStream; 428*b1cdbd2cSJim Jagielski } 429*b1cdbd2cSJim Jagielski 430*b1cdbd2cSJim Jagielski // Creates an Attr of the given name. createAttribute(const OUString & name)431*b1cdbd2cSJim Jagielski Reference< XAttr > SAL_CALL CDocument::createAttribute(const OUString& name) 432*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 433*b1cdbd2cSJim Jagielski { 434*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 435*b1cdbd2cSJim Jagielski 436*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8); 437*b1cdbd2cSJim Jagielski xmlChar *xName = (xmlChar*)o1.getStr(); 438*b1cdbd2cSJim Jagielski xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr, xName, NULL); 439*b1cdbd2cSJim Jagielski ::rtl::Reference< CAttr > const pCAttr( 440*b1cdbd2cSJim Jagielski dynamic_cast< CAttr* >(GetCNode( 441*b1cdbd2cSJim Jagielski reinterpret_cast<xmlNodePtr>(pAttr)).get())); 442*b1cdbd2cSJim Jagielski pCAttr->m_bUnlinked = true; 443*b1cdbd2cSJim Jagielski return pCAttr.get(); 444*b1cdbd2cSJim Jagielski }; 445*b1cdbd2cSJim Jagielski 446*b1cdbd2cSJim Jagielski // Creates an attribute of the given qualified name and namespace URI. createAttributeNS(const OUString & ns,const OUString & qname)447*b1cdbd2cSJim Jagielski Reference< XAttr > SAL_CALL CDocument::createAttributeNS( 448*b1cdbd2cSJim Jagielski const OUString& ns, const OUString& qname) 449*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 450*b1cdbd2cSJim Jagielski { 451*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 452*b1cdbd2cSJim Jagielski 453*b1cdbd2cSJim Jagielski // libxml does not allow a NS definition to be attached to an 454*b1cdbd2cSJim Jagielski // attribute node - which is a good thing, since namespaces are 455*b1cdbd2cSJim Jagielski // only defined as parts of element nodes 456*b1cdbd2cSJim Jagielski // thus the namespace data is stored in CAttr::m_pNamespace 457*b1cdbd2cSJim Jagielski sal_Int32 i = qname.indexOf(':'); 458*b1cdbd2cSJim Jagielski OString oPrefix, oName, oUri; 459*b1cdbd2cSJim Jagielski if (i != -1) 460*b1cdbd2cSJim Jagielski { 461*b1cdbd2cSJim Jagielski oPrefix = OUStringToOString(qname.copy(0, i), RTL_TEXTENCODING_UTF8); 462*b1cdbd2cSJim Jagielski oName = OUStringToOString(qname.copy(i+1, qname.getLength()-i-1), RTL_TEXTENCODING_UTF8); 463*b1cdbd2cSJim Jagielski } 464*b1cdbd2cSJim Jagielski else 465*b1cdbd2cSJim Jagielski { 466*b1cdbd2cSJim Jagielski oName = OUStringToOString(qname, RTL_TEXTENCODING_UTF8); 467*b1cdbd2cSJim Jagielski } 468*b1cdbd2cSJim Jagielski oUri = OUStringToOString(ns, RTL_TEXTENCODING_UTF8); 469*b1cdbd2cSJim Jagielski xmlAttrPtr const pAttr = xmlNewDocProp(m_aDocPtr, 470*b1cdbd2cSJim Jagielski reinterpret_cast<xmlChar const*>(oName.getStr()), 0); 471*b1cdbd2cSJim Jagielski ::rtl::Reference< CAttr > const pCAttr( 472*b1cdbd2cSJim Jagielski dynamic_cast< CAttr* >(GetCNode( 473*b1cdbd2cSJim Jagielski reinterpret_cast<xmlNodePtr>(pAttr)).get())); 474*b1cdbd2cSJim Jagielski if (!pCAttr.is()) { throw RuntimeException(); } 475*b1cdbd2cSJim Jagielski // store the namespace data! 476*b1cdbd2cSJim Jagielski pCAttr->m_pNamespace.reset( new stringpair_t(oUri, oPrefix) ); 477*b1cdbd2cSJim Jagielski pCAttr->m_bUnlinked = true; 478*b1cdbd2cSJim Jagielski 479*b1cdbd2cSJim Jagielski return pCAttr.get(); 480*b1cdbd2cSJim Jagielski }; 481*b1cdbd2cSJim Jagielski 482*b1cdbd2cSJim Jagielski // Creates a CDATASection node whose value is the specified string. createCDATASection(const OUString & data)483*b1cdbd2cSJim Jagielski Reference< XCDATASection > SAL_CALL CDocument::createCDATASection(const OUString& data) 484*b1cdbd2cSJim Jagielski throw (RuntimeException) 485*b1cdbd2cSJim Jagielski { 486*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 487*b1cdbd2cSJim Jagielski 488*b1cdbd2cSJim Jagielski OString const oData( 489*b1cdbd2cSJim Jagielski ::rtl::OUStringToOString(data, RTL_TEXTENCODING_UTF8)); 490*b1cdbd2cSJim Jagielski xmlChar const*const pData = 491*b1cdbd2cSJim Jagielski reinterpret_cast<xmlChar const*>(oData.getStr()); 492*b1cdbd2cSJim Jagielski xmlNodePtr const pText = 493*b1cdbd2cSJim Jagielski xmlNewCDataBlock(m_aDocPtr, pData, strlen(oData.getStr())); 494*b1cdbd2cSJim Jagielski Reference< XCDATASection > const xRet( 495*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pText).get()), 496*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 497*b1cdbd2cSJim Jagielski return xRet; 498*b1cdbd2cSJim Jagielski } 499*b1cdbd2cSJim Jagielski 500*b1cdbd2cSJim Jagielski // Creates a Comment node given the specified string. createComment(const OUString & data)501*b1cdbd2cSJim Jagielski Reference< XComment > SAL_CALL CDocument::createComment(const OUString& data) 502*b1cdbd2cSJim Jagielski throw (RuntimeException) 503*b1cdbd2cSJim Jagielski { 504*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 505*b1cdbd2cSJim Jagielski 506*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8); 507*b1cdbd2cSJim Jagielski xmlChar *xData = (xmlChar*)o1.getStr(); 508*b1cdbd2cSJim Jagielski xmlNodePtr pComment = xmlNewDocComment(m_aDocPtr, xData); 509*b1cdbd2cSJim Jagielski Reference< XComment > const xRet( 510*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pComment).get()), 511*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 512*b1cdbd2cSJim Jagielski return xRet; 513*b1cdbd2cSJim Jagielski } 514*b1cdbd2cSJim Jagielski 515*b1cdbd2cSJim Jagielski //Creates an empty DocumentFragment object. createDocumentFragment()516*b1cdbd2cSJim Jagielski Reference< XDocumentFragment > SAL_CALL CDocument::createDocumentFragment() 517*b1cdbd2cSJim Jagielski throw (RuntimeException) 518*b1cdbd2cSJim Jagielski { 519*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 520*b1cdbd2cSJim Jagielski 521*b1cdbd2cSJim Jagielski xmlNodePtr pFrag = xmlNewDocFragment(m_aDocPtr); 522*b1cdbd2cSJim Jagielski Reference< XDocumentFragment > const xRet( 523*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pFrag).get()), 524*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 525*b1cdbd2cSJim Jagielski return xRet; 526*b1cdbd2cSJim Jagielski } 527*b1cdbd2cSJim Jagielski 528*b1cdbd2cSJim Jagielski // Creates an element of the type specified. createElement(const OUString & tagName)529*b1cdbd2cSJim Jagielski Reference< XElement > SAL_CALL CDocument::createElement(const OUString& tagName) 530*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 531*b1cdbd2cSJim Jagielski { 532*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 533*b1cdbd2cSJim Jagielski 534*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(tagName, RTL_TEXTENCODING_UTF8); 535*b1cdbd2cSJim Jagielski xmlChar *xName = (xmlChar*)o1.getStr(); 536*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL); 537*b1cdbd2cSJim Jagielski Reference< XElement > const xRet( 538*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 539*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 540*b1cdbd2cSJim Jagielski return xRet; 541*b1cdbd2cSJim Jagielski } 542*b1cdbd2cSJim Jagielski 543*b1cdbd2cSJim Jagielski // Creates an element of the given qualified name and namespace URI. createElementNS(const OUString & ns,const OUString & qname)544*b1cdbd2cSJim Jagielski Reference< XElement > SAL_CALL CDocument::createElementNS( 545*b1cdbd2cSJim Jagielski const OUString& ns, const OUString& qname) 546*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 547*b1cdbd2cSJim Jagielski { 548*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 549*b1cdbd2cSJim Jagielski 550*b1cdbd2cSJim Jagielski sal_Int32 i = qname.indexOf(':'); 551*b1cdbd2cSJim Jagielski if (ns.getLength() == 0) throw RuntimeException(); 552*b1cdbd2cSJim Jagielski xmlChar *xPrefix; 553*b1cdbd2cSJim Jagielski xmlChar *xName; 554*b1cdbd2cSJim Jagielski OString o1, o2, o3; 555*b1cdbd2cSJim Jagielski if ( i != -1) { 556*b1cdbd2cSJim Jagielski o1 = OUStringToOString(qname.copy(0, i), RTL_TEXTENCODING_UTF8); 557*b1cdbd2cSJim Jagielski xPrefix = (xmlChar*)o1.getStr(); 558*b1cdbd2cSJim Jagielski o2 = OUStringToOString(qname.copy(i+1, qname.getLength()-i-1), RTL_TEXTENCODING_UTF8); 559*b1cdbd2cSJim Jagielski xName = (xmlChar*)o2.getStr(); 560*b1cdbd2cSJim Jagielski } else { 561*b1cdbd2cSJim Jagielski // default prefix 562*b1cdbd2cSJim Jagielski xPrefix = (xmlChar*)""; 563*b1cdbd2cSJim Jagielski o2 = OUStringToOString(qname, RTL_TEXTENCODING_UTF8); 564*b1cdbd2cSJim Jagielski xName = (xmlChar*)o2.getStr(); 565*b1cdbd2cSJim Jagielski } 566*b1cdbd2cSJim Jagielski o3 = OUStringToOString(ns, RTL_TEXTENCODING_UTF8); 567*b1cdbd2cSJim Jagielski xmlChar *xUri = (xmlChar*)o3.getStr(); 568*b1cdbd2cSJim Jagielski 569*b1cdbd2cSJim Jagielski // xmlNsPtr aNsPtr = xmlNewReconciledNs? 570*b1cdbd2cSJim Jagielski // xmlNsPtr aNsPtr = xmlNewGlobalNs? 571*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = xmlNewDocNode(m_aDocPtr, NULL, xName, NULL); 572*b1cdbd2cSJim Jagielski xmlNsPtr const pNs = xmlNewNs(pNode, xUri, xPrefix); 573*b1cdbd2cSJim Jagielski xmlSetNs(pNode, pNs); 574*b1cdbd2cSJim Jagielski Reference< XElement > const xRet( 575*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 576*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 577*b1cdbd2cSJim Jagielski return xRet; 578*b1cdbd2cSJim Jagielski } 579*b1cdbd2cSJim Jagielski 580*b1cdbd2cSJim Jagielski //Creates an EntityReference object. createEntityReference(const OUString & name)581*b1cdbd2cSJim Jagielski Reference< XEntityReference > SAL_CALL CDocument::createEntityReference(const OUString& name) 582*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 583*b1cdbd2cSJim Jagielski { 584*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 585*b1cdbd2cSJim Jagielski 586*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8); 587*b1cdbd2cSJim Jagielski xmlChar *xName = (xmlChar*)o1.getStr(); 588*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = xmlNewReference(m_aDocPtr, xName); 589*b1cdbd2cSJim Jagielski Reference< XEntityReference > const xRet( 590*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 591*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 592*b1cdbd2cSJim Jagielski return xRet; 593*b1cdbd2cSJim Jagielski } 594*b1cdbd2cSJim Jagielski 595*b1cdbd2cSJim Jagielski // Creates a ProcessingInstruction node given the specified name and 596*b1cdbd2cSJim Jagielski // data strings. createProcessingInstruction(const OUString & target,const OUString & data)597*b1cdbd2cSJim Jagielski Reference< XProcessingInstruction > SAL_CALL CDocument::createProcessingInstruction( 598*b1cdbd2cSJim Jagielski const OUString& target, const OUString& data) 599*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 600*b1cdbd2cSJim Jagielski { 601*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 602*b1cdbd2cSJim Jagielski 603*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(target, RTL_TEXTENCODING_UTF8); 604*b1cdbd2cSJim Jagielski xmlChar *xTarget = (xmlChar*)o1.getStr(); 605*b1cdbd2cSJim Jagielski OString o2 = OUStringToOString(data, RTL_TEXTENCODING_UTF8); 606*b1cdbd2cSJim Jagielski xmlChar *xData = (xmlChar*)o2.getStr(); 607*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = xmlNewDocPI(m_aDocPtr, xTarget, xData); 608*b1cdbd2cSJim Jagielski pNode->doc = m_aDocPtr; 609*b1cdbd2cSJim Jagielski Reference< XProcessingInstruction > const xRet( 610*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 611*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 612*b1cdbd2cSJim Jagielski return xRet; 613*b1cdbd2cSJim Jagielski } 614*b1cdbd2cSJim Jagielski 615*b1cdbd2cSJim Jagielski // Creates a Text node given the specified string. createTextNode(const OUString & data)616*b1cdbd2cSJim Jagielski Reference< XText > SAL_CALL CDocument::createTextNode(const OUString& data) 617*b1cdbd2cSJim Jagielski throw (RuntimeException) 618*b1cdbd2cSJim Jagielski { 619*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 620*b1cdbd2cSJim Jagielski 621*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(data, RTL_TEXTENCODING_UTF8); 622*b1cdbd2cSJim Jagielski xmlChar *xData = (xmlChar*)o1.getStr(); 623*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = xmlNewDocText(m_aDocPtr, xData); 624*b1cdbd2cSJim Jagielski Reference< XText > const xRet( 625*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 626*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 627*b1cdbd2cSJim Jagielski return xRet; 628*b1cdbd2cSJim Jagielski } 629*b1cdbd2cSJim Jagielski 630*b1cdbd2cSJim Jagielski // The Document Type Declaration (see DocumentType) associated with this 631*b1cdbd2cSJim Jagielski // document. getDoctype()632*b1cdbd2cSJim Jagielski Reference< XDocumentType > SAL_CALL CDocument::getDoctype() 633*b1cdbd2cSJim Jagielski throw (RuntimeException) 634*b1cdbd2cSJim Jagielski { 635*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 636*b1cdbd2cSJim Jagielski 637*b1cdbd2cSJim Jagielski xmlNodePtr const pDocType(lcl_getDocumentType(m_aDocPtr)); 638*b1cdbd2cSJim Jagielski Reference< XDocumentType > const xRet( 639*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pDocType).get()), 640*b1cdbd2cSJim Jagielski UNO_QUERY); 641*b1cdbd2cSJim Jagielski return xRet; 642*b1cdbd2cSJim Jagielski } 643*b1cdbd2cSJim Jagielski 644*b1cdbd2cSJim Jagielski // This is a convenience attribute that allows direct access to the child 645*b1cdbd2cSJim Jagielski // node that is the root element of the document. getDocumentElement()646*b1cdbd2cSJim Jagielski Reference< XElement > SAL_CALL CDocument::getDocumentElement() 647*b1cdbd2cSJim Jagielski throw (RuntimeException) 648*b1cdbd2cSJim Jagielski { 649*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 650*b1cdbd2cSJim Jagielski 651*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = lcl_getDocumentRootPtr(m_aDocPtr); 652*b1cdbd2cSJim Jagielski if (!pNode) { return 0; } 653*b1cdbd2cSJim Jagielski Reference< XElement > const xRet( 654*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 655*b1cdbd2cSJim Jagielski UNO_QUERY); 656*b1cdbd2cSJim Jagielski return xRet; 657*b1cdbd2cSJim Jagielski } 658*b1cdbd2cSJim Jagielski 659*b1cdbd2cSJim Jagielski static xmlNodePtr lcl_search_element_by_id(const xmlNodePtr cur,const xmlChar * id)660*b1cdbd2cSJim Jagielski lcl_search_element_by_id(const xmlNodePtr cur, const xmlChar* id) 661*b1cdbd2cSJim Jagielski { 662*b1cdbd2cSJim Jagielski if (cur == NULL) 663*b1cdbd2cSJim Jagielski return NULL; 664*b1cdbd2cSJim Jagielski // look in current node 665*b1cdbd2cSJim Jagielski if (cur->type == XML_ELEMENT_NODE) 666*b1cdbd2cSJim Jagielski { 667*b1cdbd2cSJim Jagielski xmlAttrPtr a = cur->properties; 668*b1cdbd2cSJim Jagielski while (a != NULL) 669*b1cdbd2cSJim Jagielski { 670*b1cdbd2cSJim Jagielski if (a->atype == XML_ATTRIBUTE_ID) { 671*b1cdbd2cSJim Jagielski if (strcmp((char*)a->children->content, (char*)id) == 0) 672*b1cdbd2cSJim Jagielski return cur; 673*b1cdbd2cSJim Jagielski } 674*b1cdbd2cSJim Jagielski a = a->next; 675*b1cdbd2cSJim Jagielski } 676*b1cdbd2cSJim Jagielski } 677*b1cdbd2cSJim Jagielski // look in children 678*b1cdbd2cSJim Jagielski xmlNodePtr result = lcl_search_element_by_id(cur->children, id); 679*b1cdbd2cSJim Jagielski if (result != NULL) 680*b1cdbd2cSJim Jagielski return result; 681*b1cdbd2cSJim Jagielski result = lcl_search_element_by_id(cur->next, id); 682*b1cdbd2cSJim Jagielski return result; 683*b1cdbd2cSJim Jagielski } 684*b1cdbd2cSJim Jagielski 685*b1cdbd2cSJim Jagielski // Returns the Element whose ID is given by elementId. 686*b1cdbd2cSJim Jagielski Reference< XElement > SAL_CALL getElementById(const OUString & elementId)687*b1cdbd2cSJim Jagielski CDocument::getElementById(const OUString& elementId) 688*b1cdbd2cSJim Jagielski throw (RuntimeException) 689*b1cdbd2cSJim Jagielski { 690*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 691*b1cdbd2cSJim Jagielski 692*b1cdbd2cSJim Jagielski // search the tree for an element with the given ID 693*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(elementId, RTL_TEXTENCODING_UTF8); 694*b1cdbd2cSJim Jagielski xmlChar *xId = (xmlChar*)o1.getStr(); 695*b1cdbd2cSJim Jagielski xmlNodePtr const pStart = lcl_getDocumentRootPtr(m_aDocPtr); 696*b1cdbd2cSJim Jagielski if (!pStart) { return 0; } 697*b1cdbd2cSJim Jagielski xmlNodePtr const pNode = lcl_search_element_by_id(pStart, xId); 698*b1cdbd2cSJim Jagielski Reference< XElement > const xRet( 699*b1cdbd2cSJim Jagielski static_cast< XNode* >(GetCNode(pNode).get()), 700*b1cdbd2cSJim Jagielski UNO_QUERY); 701*b1cdbd2cSJim Jagielski return xRet; 702*b1cdbd2cSJim Jagielski } 703*b1cdbd2cSJim Jagielski 704*b1cdbd2cSJim Jagielski 705*b1cdbd2cSJim Jagielski Reference< XNodeList > SAL_CALL getElementsByTagName(OUString const & rTagname)706*b1cdbd2cSJim Jagielski CDocument::getElementsByTagName(OUString const& rTagname) 707*b1cdbd2cSJim Jagielski throw (RuntimeException) 708*b1cdbd2cSJim Jagielski { 709*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 710*b1cdbd2cSJim Jagielski 711*b1cdbd2cSJim Jagielski Reference< XNodeList > const xRet( 712*b1cdbd2cSJim Jagielski new CElementList(this->GetDocumentElement(), m_Mutex, rTagname)); 713*b1cdbd2cSJim Jagielski return xRet; 714*b1cdbd2cSJim Jagielski } 715*b1cdbd2cSJim Jagielski getElementsByTagNameNS(OUString const & rNamespaceURI,OUString const & rLocalName)716*b1cdbd2cSJim Jagielski Reference< XNodeList > SAL_CALL CDocument::getElementsByTagNameNS( 717*b1cdbd2cSJim Jagielski OUString const& rNamespaceURI, OUString const& rLocalName) 718*b1cdbd2cSJim Jagielski throw (RuntimeException) 719*b1cdbd2cSJim Jagielski { 720*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 721*b1cdbd2cSJim Jagielski 722*b1cdbd2cSJim Jagielski Reference< XNodeList > const xRet( 723*b1cdbd2cSJim Jagielski new CElementList(this->GetDocumentElement(), m_Mutex, 724*b1cdbd2cSJim Jagielski rLocalName, &rNamespaceURI)); 725*b1cdbd2cSJim Jagielski return xRet; 726*b1cdbd2cSJim Jagielski } 727*b1cdbd2cSJim Jagielski getImplementation()728*b1cdbd2cSJim Jagielski Reference< XDOMImplementation > SAL_CALL CDocument::getImplementation() 729*b1cdbd2cSJim Jagielski throw (RuntimeException) 730*b1cdbd2cSJim Jagielski { 731*b1cdbd2cSJim Jagielski // does not need mutex currently 732*b1cdbd2cSJim Jagielski return Reference< XDOMImplementation >(CDOMImplementation::get()); 733*b1cdbd2cSJim Jagielski } 734*b1cdbd2cSJim Jagielski 735*b1cdbd2cSJim Jagielski // helper function to recursively import siblings lcl_ImportSiblings(Reference<XDocument> const & xTargetDocument,Reference<XNode> const & xTargetParent,Reference<XNode> const & xChild)736*b1cdbd2cSJim Jagielski static void lcl_ImportSiblings( 737*b1cdbd2cSJim Jagielski Reference< XDocument > const& xTargetDocument, 738*b1cdbd2cSJim Jagielski Reference< XNode > const& xTargetParent, 739*b1cdbd2cSJim Jagielski Reference< XNode > const& xChild) 740*b1cdbd2cSJim Jagielski { 741*b1cdbd2cSJim Jagielski Reference< XNode > xSibling = xChild; 742*b1cdbd2cSJim Jagielski while (xSibling.is()) 743*b1cdbd2cSJim Jagielski { 744*b1cdbd2cSJim Jagielski Reference< XNode > const xTmp( 745*b1cdbd2cSJim Jagielski xTargetDocument->importNode(xSibling, sal_True)); 746*b1cdbd2cSJim Jagielski xTargetParent->appendChild(xTmp); 747*b1cdbd2cSJim Jagielski xSibling = xSibling->getNextSibling(); 748*b1cdbd2cSJim Jagielski } 749*b1cdbd2cSJim Jagielski } 750*b1cdbd2cSJim Jagielski 751*b1cdbd2cSJim Jagielski static Reference< XNode > lcl_ImportNode(Reference<XDocument> const & xDocument,Reference<XNode> const & xImportedNode,sal_Bool deep)752*b1cdbd2cSJim Jagielski lcl_ImportNode( Reference< XDocument > const& xDocument, 753*b1cdbd2cSJim Jagielski Reference< XNode > const& xImportedNode, sal_Bool deep) 754*b1cdbd2cSJim Jagielski { 755*b1cdbd2cSJim Jagielski Reference< XNode > xNode; 756*b1cdbd2cSJim Jagielski NodeType aNodeType = xImportedNode->getNodeType(); 757*b1cdbd2cSJim Jagielski switch (aNodeType) 758*b1cdbd2cSJim Jagielski { 759*b1cdbd2cSJim Jagielski case NodeType_ATTRIBUTE_NODE: 760*b1cdbd2cSJim Jagielski { 761*b1cdbd2cSJim Jagielski Reference< XAttr > const xAttr(xImportedNode, UNO_QUERY_THROW); 762*b1cdbd2cSJim Jagielski Reference< XAttr > const xNew = 763*b1cdbd2cSJim Jagielski xDocument->createAttribute(xAttr->getName()); 764*b1cdbd2cSJim Jagielski xNew->setValue(xAttr->getValue()); 765*b1cdbd2cSJim Jagielski xNode.set(xNew, UNO_QUERY); 766*b1cdbd2cSJim Jagielski break; 767*b1cdbd2cSJim Jagielski } 768*b1cdbd2cSJim Jagielski case NodeType_CDATA_SECTION_NODE: 769*b1cdbd2cSJim Jagielski { 770*b1cdbd2cSJim Jagielski Reference< XCDATASection > const xCData(xImportedNode, 771*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 772*b1cdbd2cSJim Jagielski Reference< XCDATASection > const xNewCData = 773*b1cdbd2cSJim Jagielski xDocument->createCDATASection(xCData->getData()); 774*b1cdbd2cSJim Jagielski xNode.set(xNewCData, UNO_QUERY); 775*b1cdbd2cSJim Jagielski break; 776*b1cdbd2cSJim Jagielski } 777*b1cdbd2cSJim Jagielski case NodeType_COMMENT_NODE: 778*b1cdbd2cSJim Jagielski { 779*b1cdbd2cSJim Jagielski Reference< XComment > const xComment(xImportedNode, 780*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 781*b1cdbd2cSJim Jagielski Reference< XComment > const xNewComment = 782*b1cdbd2cSJim Jagielski xDocument->createComment(xComment->getData()); 783*b1cdbd2cSJim Jagielski xNode.set(xNewComment, UNO_QUERY); 784*b1cdbd2cSJim Jagielski break; 785*b1cdbd2cSJim Jagielski } 786*b1cdbd2cSJim Jagielski case NodeType_DOCUMENT_FRAGMENT_NODE: 787*b1cdbd2cSJim Jagielski { 788*b1cdbd2cSJim Jagielski Reference< XDocumentFragment > const xFrag(xImportedNode, 789*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 790*b1cdbd2cSJim Jagielski Reference< XDocumentFragment > const xNewFrag = 791*b1cdbd2cSJim Jagielski xDocument->createDocumentFragment(); 792*b1cdbd2cSJim Jagielski xNode.set(xNewFrag, UNO_QUERY); 793*b1cdbd2cSJim Jagielski break; 794*b1cdbd2cSJim Jagielski } 795*b1cdbd2cSJim Jagielski case NodeType_ELEMENT_NODE: 796*b1cdbd2cSJim Jagielski { 797*b1cdbd2cSJim Jagielski Reference< XElement > const xElement(xImportedNode, 798*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 799*b1cdbd2cSJim Jagielski OUString const aNsUri = xImportedNode->getNamespaceURI(); 800*b1cdbd2cSJim Jagielski OUString const aNsPrefix = xImportedNode->getPrefix(); 801*b1cdbd2cSJim Jagielski OUString aQName = xElement->getTagName(); 802*b1cdbd2cSJim Jagielski Reference< XElement > xNewElement; 803*b1cdbd2cSJim Jagielski if (aNsUri.getLength() > 0) 804*b1cdbd2cSJim Jagielski { 805*b1cdbd2cSJim Jagielski if (aNsPrefix.getLength() > 0) { 806*b1cdbd2cSJim Jagielski aQName = aNsPrefix + OUString::createFromAscii(":") 807*b1cdbd2cSJim Jagielski + aQName; 808*b1cdbd2cSJim Jagielski } 809*b1cdbd2cSJim Jagielski xNewElement = xDocument->createElementNS(aNsUri, aQName); 810*b1cdbd2cSJim Jagielski } else { 811*b1cdbd2cSJim Jagielski xNewElement = xDocument->createElement(aQName); 812*b1cdbd2cSJim Jagielski } 813*b1cdbd2cSJim Jagielski 814*b1cdbd2cSJim Jagielski // get attributes 815*b1cdbd2cSJim Jagielski if (xElement->hasAttributes()) 816*b1cdbd2cSJim Jagielski { 817*b1cdbd2cSJim Jagielski Reference< XNamedNodeMap > attribs = xElement->getAttributes(); 818*b1cdbd2cSJim Jagielski for (sal_Int32 i = 0; i < attribs->getLength(); i++) 819*b1cdbd2cSJim Jagielski { 820*b1cdbd2cSJim Jagielski Reference< XAttr > const curAttr(attribs->item(i), 821*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 822*b1cdbd2cSJim Jagielski OUString const aAttrUri = curAttr->getNamespaceURI(); 823*b1cdbd2cSJim Jagielski OUString const aAttrPrefix = curAttr->getPrefix(); 824*b1cdbd2cSJim Jagielski OUString aAttrName = curAttr->getName(); 825*b1cdbd2cSJim Jagielski OUString const sValue = curAttr->getValue(); 826*b1cdbd2cSJim Jagielski if (aAttrUri.getLength() > 0) 827*b1cdbd2cSJim Jagielski { 828*b1cdbd2cSJim Jagielski if (aAttrPrefix.getLength() > 0) { 829*b1cdbd2cSJim Jagielski aAttrName = aAttrPrefix + 830*b1cdbd2cSJim Jagielski OUString::createFromAscii(":") + aAttrName; 831*b1cdbd2cSJim Jagielski } 832*b1cdbd2cSJim Jagielski xNewElement->setAttributeNS( 833*b1cdbd2cSJim Jagielski aAttrUri, aAttrName, sValue); 834*b1cdbd2cSJim Jagielski } else { 835*b1cdbd2cSJim Jagielski xNewElement->setAttribute(aAttrName, sValue); 836*b1cdbd2cSJim Jagielski } 837*b1cdbd2cSJim Jagielski } 838*b1cdbd2cSJim Jagielski } 839*b1cdbd2cSJim Jagielski xNode.set(xNewElement, UNO_QUERY); 840*b1cdbd2cSJim Jagielski break; 841*b1cdbd2cSJim Jagielski } 842*b1cdbd2cSJim Jagielski case NodeType_ENTITY_REFERENCE_NODE: 843*b1cdbd2cSJim Jagielski { 844*b1cdbd2cSJim Jagielski Reference< XEntityReference > const xRef(xImportedNode, 845*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 846*b1cdbd2cSJim Jagielski Reference< XEntityReference > const xNewRef( 847*b1cdbd2cSJim Jagielski xDocument->createEntityReference(xRef->getNodeName())); 848*b1cdbd2cSJim Jagielski xNode.set(xNewRef, UNO_QUERY); 849*b1cdbd2cSJim Jagielski break; 850*b1cdbd2cSJim Jagielski } 851*b1cdbd2cSJim Jagielski case NodeType_PROCESSING_INSTRUCTION_NODE: 852*b1cdbd2cSJim Jagielski { 853*b1cdbd2cSJim Jagielski Reference< XProcessingInstruction > const xPi(xImportedNode, 854*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 855*b1cdbd2cSJim Jagielski Reference< XProcessingInstruction > const xNewPi( 856*b1cdbd2cSJim Jagielski xDocument->createProcessingInstruction( 857*b1cdbd2cSJim Jagielski xPi->getTarget(), xPi->getData())); 858*b1cdbd2cSJim Jagielski xNode.set(xNewPi, UNO_QUERY); 859*b1cdbd2cSJim Jagielski break; 860*b1cdbd2cSJim Jagielski } 861*b1cdbd2cSJim Jagielski case NodeType_TEXT_NODE: 862*b1cdbd2cSJim Jagielski { 863*b1cdbd2cSJim Jagielski Reference< XText > const xText(xImportedNode, UNO_QUERY_THROW); 864*b1cdbd2cSJim Jagielski Reference< XText > const xNewText( 865*b1cdbd2cSJim Jagielski xDocument->createTextNode(xText->getData())); 866*b1cdbd2cSJim Jagielski xNode.set(xNewText, UNO_QUERY); 867*b1cdbd2cSJim Jagielski break; 868*b1cdbd2cSJim Jagielski } 869*b1cdbd2cSJim Jagielski case NodeType_ENTITY_NODE: 870*b1cdbd2cSJim Jagielski case NodeType_DOCUMENT_NODE: 871*b1cdbd2cSJim Jagielski case NodeType_DOCUMENT_TYPE_NODE: 872*b1cdbd2cSJim Jagielski case NodeType_NOTATION_NODE: 873*b1cdbd2cSJim Jagielski default: 874*b1cdbd2cSJim Jagielski // can't be imported 875*b1cdbd2cSJim Jagielski throw RuntimeException(); 876*b1cdbd2cSJim Jagielski 877*b1cdbd2cSJim Jagielski } 878*b1cdbd2cSJim Jagielski if (deep) 879*b1cdbd2cSJim Jagielski { 880*b1cdbd2cSJim Jagielski // get children and import them 881*b1cdbd2cSJim Jagielski Reference< XNode > const xChild = xImportedNode->getFirstChild(); 882*b1cdbd2cSJim Jagielski if (xChild.is()) 883*b1cdbd2cSJim Jagielski { 884*b1cdbd2cSJim Jagielski lcl_ImportSiblings(xDocument, xNode, xChild); 885*b1cdbd2cSJim Jagielski } 886*b1cdbd2cSJim Jagielski } 887*b1cdbd2cSJim Jagielski 888*b1cdbd2cSJim Jagielski /* DOMNodeInsertedIntoDocument 889*b1cdbd2cSJim Jagielski * Fired when a node is being inserted into a document, 890*b1cdbd2cSJim Jagielski * either through direct insertion of the Node or insertion of a 891*b1cdbd2cSJim Jagielski * subtree in which it is contained. This event is dispatched after 892*b1cdbd2cSJim Jagielski * the insertion has taken place. The target of this event is the node 893*b1cdbd2cSJim Jagielski * being inserted. If the Node is being directly inserted the DOMNodeInserted 894*b1cdbd2cSJim Jagielski * event will fire before the DOMNodeInsertedIntoDocument event. 895*b1cdbd2cSJim Jagielski * Bubbles: No 896*b1cdbd2cSJim Jagielski * Cancelable: No 897*b1cdbd2cSJim Jagielski * Context Info: None 898*b1cdbd2cSJim Jagielski */ 899*b1cdbd2cSJim Jagielski if (xNode.is()) 900*b1cdbd2cSJim Jagielski { 901*b1cdbd2cSJim Jagielski Reference< XDocumentEvent > const xDocevent(xDocument, UNO_QUERY); 902*b1cdbd2cSJim Jagielski Reference< XMutationEvent > const event(xDocevent->createEvent( 903*b1cdbd2cSJim Jagielski OUString::createFromAscii("DOMNodeInsertedIntoDocument")), 904*b1cdbd2cSJim Jagielski UNO_QUERY_THROW); 905*b1cdbd2cSJim Jagielski event->initMutationEvent( 906*b1cdbd2cSJim Jagielski OUString::createFromAscii("DOMNodeInsertedIntoDocument") 907*b1cdbd2cSJim Jagielski , sal_True, sal_False, Reference< XNode >(), 908*b1cdbd2cSJim Jagielski OUString(), OUString(), OUString(), (AttrChangeType)0 ); 909*b1cdbd2cSJim Jagielski Reference< XEventTarget > const xDocET(xDocument, UNO_QUERY); 910*b1cdbd2cSJim Jagielski xDocET->dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); 911*b1cdbd2cSJim Jagielski } 912*b1cdbd2cSJim Jagielski 913*b1cdbd2cSJim Jagielski return xNode; 914*b1cdbd2cSJim Jagielski } 915*b1cdbd2cSJim Jagielski importNode(Reference<XNode> const & xImportedNode,sal_Bool deep)916*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CDocument::importNode( 917*b1cdbd2cSJim Jagielski Reference< XNode > const& xImportedNode, sal_Bool deep) 918*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 919*b1cdbd2cSJim Jagielski { 920*b1cdbd2cSJim Jagielski if (!xImportedNode.is()) { throw RuntimeException(); } 921*b1cdbd2cSJim Jagielski 922*b1cdbd2cSJim Jagielski // NB: this whole operation inherently accesses 2 distinct documents. 923*b1cdbd2cSJim Jagielski // The imported node could even be from a different DOM implementation, 924*b1cdbd2cSJim Jagielski // so this implementation cannot make any assumptions about the 925*b1cdbd2cSJim Jagielski // locking strategy of the imported node. 926*b1cdbd2cSJim Jagielski // So the import takes no lock on this document; 927*b1cdbd2cSJim Jagielski // it only calls UNO methods on this document that temporarily 928*b1cdbd2cSJim Jagielski // lock the document, and UNO methods on the imported node that 929*b1cdbd2cSJim Jagielski // may temporarily lock the other document. 930*b1cdbd2cSJim Jagielski // As a consequence, the import is not atomic with regard to 931*b1cdbd2cSJim Jagielski // concurrent modifications of either document, but it should not 932*b1cdbd2cSJim Jagielski // deadlock. 933*b1cdbd2cSJim Jagielski // To ensure that no members are accessed, the implementation is in 934*b1cdbd2cSJim Jagielski // static non-member functions. 935*b1cdbd2cSJim Jagielski 936*b1cdbd2cSJim Jagielski Reference< XDocument > const xDocument(this); 937*b1cdbd2cSJim Jagielski // already in doc? 938*b1cdbd2cSJim Jagielski if (xImportedNode->getOwnerDocument() == xDocument) { 939*b1cdbd2cSJim Jagielski return xImportedNode; 940*b1cdbd2cSJim Jagielski } 941*b1cdbd2cSJim Jagielski 942*b1cdbd2cSJim Jagielski Reference< XNode > const xNode( 943*b1cdbd2cSJim Jagielski lcl_ImportNode(xDocument, xImportedNode, deep) ); 944*b1cdbd2cSJim Jagielski return xNode; 945*b1cdbd2cSJim Jagielski } 946*b1cdbd2cSJim Jagielski 947*b1cdbd2cSJim Jagielski getNodeName()948*b1cdbd2cSJim Jagielski OUString SAL_CALL CDocument::getNodeName()throw (RuntimeException) 949*b1cdbd2cSJim Jagielski { 950*b1cdbd2cSJim Jagielski // does not need mutex currently 951*b1cdbd2cSJim Jagielski return OUString::createFromAscii("#document"); 952*b1cdbd2cSJim Jagielski } 953*b1cdbd2cSJim Jagielski getNodeValue()954*b1cdbd2cSJim Jagielski OUString SAL_CALL CDocument::getNodeValue() throw (RuntimeException) 955*b1cdbd2cSJim Jagielski { 956*b1cdbd2cSJim Jagielski // does not need mutex currently 957*b1cdbd2cSJim Jagielski return OUString(); 958*b1cdbd2cSJim Jagielski } 959*b1cdbd2cSJim Jagielski cloneNode(sal_Bool bDeep)960*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CDocument::cloneNode(sal_Bool bDeep) 961*b1cdbd2cSJim Jagielski throw (RuntimeException) 962*b1cdbd2cSJim Jagielski { 963*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 964*b1cdbd2cSJim Jagielski 965*b1cdbd2cSJim Jagielski OSL_ASSERT(0 != m_aNodePtr); 966*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 967*b1cdbd2cSJim Jagielski return 0; 968*b1cdbd2cSJim Jagielski } 969*b1cdbd2cSJim Jagielski xmlDocPtr const pClone(xmlCopyDoc(m_aDocPtr, (bDeep) ? 1 : 0)); 970*b1cdbd2cSJim Jagielski if (0 == pClone) { return 0; } 971*b1cdbd2cSJim Jagielski Reference< XNode > const xRet( 972*b1cdbd2cSJim Jagielski static_cast<CNode*>(CDocument::CreateCDocument(pClone).get())); 973*b1cdbd2cSJim Jagielski return xRet; 974*b1cdbd2cSJim Jagielski } 975*b1cdbd2cSJim Jagielski createEvent(const OUString & aType)976*b1cdbd2cSJim Jagielski Reference< XEvent > SAL_CALL CDocument::createEvent(const OUString& aType) throw (RuntimeException) 977*b1cdbd2cSJim Jagielski { 978*b1cdbd2cSJim Jagielski // does not need mutex currently 979*b1cdbd2cSJim Jagielski events::CEvent *pEvent = 0; 980*b1cdbd2cSJim Jagielski if ( 981*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMSubtreeModified") == 0|| 982*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMNodeInserted") == 0|| 983*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMNodeRemoved") == 0|| 984*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMNodeRemovedFromDocument") == 0|| 985*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMNodeInsertedIntoDocument") == 0|| 986*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMAttrModified") == 0|| 987*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMCharacterDataModified") == 0) 988*b1cdbd2cSJim Jagielski { 989*b1cdbd2cSJim Jagielski pEvent = new events::CMutationEvent; 990*b1cdbd2cSJim Jagielski 991*b1cdbd2cSJim Jagielski } else if ( 992*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMFocusIn") == 0|| 993*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMFocusOut") == 0|| 994*b1cdbd2cSJim Jagielski aType.compareToAscii("DOMActivate") == 0) 995*b1cdbd2cSJim Jagielski { 996*b1cdbd2cSJim Jagielski pEvent = new events::CUIEvent; 997*b1cdbd2cSJim Jagielski } else if ( 998*b1cdbd2cSJim Jagielski aType.compareToAscii("click") == 0|| 999*b1cdbd2cSJim Jagielski aType.compareToAscii("mousedown") == 0|| 1000*b1cdbd2cSJim Jagielski aType.compareToAscii("mouseup") == 0|| 1001*b1cdbd2cSJim Jagielski aType.compareToAscii("mouseover") == 0|| 1002*b1cdbd2cSJim Jagielski aType.compareToAscii("mousemove") == 0|| 1003*b1cdbd2cSJim Jagielski aType.compareToAscii("mouseout") == 0 ) 1004*b1cdbd2cSJim Jagielski { 1005*b1cdbd2cSJim Jagielski pEvent = new events::CMouseEvent; 1006*b1cdbd2cSJim Jagielski } 1007*b1cdbd2cSJim Jagielski else // generic event 1008*b1cdbd2cSJim Jagielski { 1009*b1cdbd2cSJim Jagielski pEvent = new events::CEvent; 1010*b1cdbd2cSJim Jagielski } 1011*b1cdbd2cSJim Jagielski return Reference< XEvent >(pEvent); 1012*b1cdbd2cSJim Jagielski } 1013*b1cdbd2cSJim Jagielski 1014*b1cdbd2cSJim Jagielski // ::com::sun::star::xml::sax::XSAXSerializable serialize(const Reference<XDocumentHandler> & i_xHandler,const Sequence<beans::StringPair> & i_rNamespaces)1015*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::serialize( 1016*b1cdbd2cSJim Jagielski const Reference< XDocumentHandler >& i_xHandler, 1017*b1cdbd2cSJim Jagielski const Sequence< beans::StringPair >& i_rNamespaces) 1018*b1cdbd2cSJim Jagielski throw (RuntimeException, SAXException) 1019*b1cdbd2cSJim Jagielski { 1020*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 1021*b1cdbd2cSJim Jagielski 1022*b1cdbd2cSJim Jagielski // add new namespaces to root node 1023*b1cdbd2cSJim Jagielski xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr); 1024*b1cdbd2cSJim Jagielski if (0 != pRoot) { 1025*b1cdbd2cSJim Jagielski const beans::StringPair * pSeq = i_rNamespaces.getConstArray(); 1026*b1cdbd2cSJim Jagielski for (const beans::StringPair *pNsDef = pSeq; 1027*b1cdbd2cSJim Jagielski pNsDef < pSeq + i_rNamespaces.getLength(); ++pNsDef) { 1028*b1cdbd2cSJim Jagielski OString prefix = OUStringToOString(pNsDef->First, 1029*b1cdbd2cSJim Jagielski RTL_TEXTENCODING_UTF8); 1030*b1cdbd2cSJim Jagielski OString href = OUStringToOString(pNsDef->Second, 1031*b1cdbd2cSJim Jagielski RTL_TEXTENCODING_UTF8); 1032*b1cdbd2cSJim Jagielski // this will only add the ns if it does not exist already 1033*b1cdbd2cSJim Jagielski xmlNewNs(pRoot, reinterpret_cast<const xmlChar*>(href.getStr()), 1034*b1cdbd2cSJim Jagielski reinterpret_cast<const xmlChar*>(prefix.getStr())); 1035*b1cdbd2cSJim Jagielski } 1036*b1cdbd2cSJim Jagielski // eliminate duplicate namespace declarations 1037*b1cdbd2cSJim Jagielski nscleanup(pRoot->children, pRoot); 1038*b1cdbd2cSJim Jagielski } 1039*b1cdbd2cSJim Jagielski saxify(i_xHandler); 1040*b1cdbd2cSJim Jagielski } 1041*b1cdbd2cSJim Jagielski 1042*b1cdbd2cSJim Jagielski // ::com::sun::star::xml::sax::XFastSAXSerializable fastSerialize(const Reference<XFastDocumentHandler> & i_xHandler,const Reference<XFastTokenHandler> & i_xTokenHandler,const Sequence<beans::StringPair> & i_rNamespaces,const Sequence<beans::Pair<rtl::OUString,sal_Int32>> & i_rRegisterNamespaces)1043*b1cdbd2cSJim Jagielski void SAL_CALL CDocument::fastSerialize( const Reference< XFastDocumentHandler >& i_xHandler, 1044*b1cdbd2cSJim Jagielski const Reference< XFastTokenHandler >& i_xTokenHandler, 1045*b1cdbd2cSJim Jagielski const Sequence< beans::StringPair >& i_rNamespaces, 1046*b1cdbd2cSJim Jagielski const Sequence< beans::Pair< rtl::OUString, sal_Int32 > >& i_rRegisterNamespaces ) 1047*b1cdbd2cSJim Jagielski throw (SAXException, RuntimeException) 1048*b1cdbd2cSJim Jagielski { 1049*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_Mutex); 1050*b1cdbd2cSJim Jagielski 1051*b1cdbd2cSJim Jagielski // add new namespaces to root node 1052*b1cdbd2cSJim Jagielski xmlNodePtr const pRoot = lcl_getDocumentRootPtr(m_aDocPtr); 1053*b1cdbd2cSJim Jagielski if (0 != pRoot) { 1054*b1cdbd2cSJim Jagielski const beans::StringPair * pSeq = i_rNamespaces.getConstArray(); 1055*b1cdbd2cSJim Jagielski for (const beans::StringPair *pNsDef = pSeq; 1056*b1cdbd2cSJim Jagielski pNsDef < pSeq + i_rNamespaces.getLength(); ++pNsDef) { 1057*b1cdbd2cSJim Jagielski OString prefix = OUStringToOString(pNsDef->First, 1058*b1cdbd2cSJim Jagielski RTL_TEXTENCODING_UTF8); 1059*b1cdbd2cSJim Jagielski OString href = OUStringToOString(pNsDef->Second, 1060*b1cdbd2cSJim Jagielski RTL_TEXTENCODING_UTF8); 1061*b1cdbd2cSJim Jagielski // this will only add the ns if it does not exist already 1062*b1cdbd2cSJim Jagielski xmlNewNs(pRoot, reinterpret_cast<const xmlChar*>(href.getStr()), 1063*b1cdbd2cSJim Jagielski reinterpret_cast<const xmlChar*>(prefix.getStr())); 1064*b1cdbd2cSJim Jagielski } 1065*b1cdbd2cSJim Jagielski // eliminate duplicate namespace declarations 1066*b1cdbd2cSJim Jagielski nscleanup(pRoot->children, pRoot); 1067*b1cdbd2cSJim Jagielski } 1068*b1cdbd2cSJim Jagielski 1069*b1cdbd2cSJim Jagielski Context aContext(i_xHandler, 1070*b1cdbd2cSJim Jagielski i_xTokenHandler); 1071*b1cdbd2cSJim Jagielski 1072*b1cdbd2cSJim Jagielski // register namespace ids 1073*b1cdbd2cSJim Jagielski const beans::Pair<OUString,sal_Int32>* pSeq = i_rRegisterNamespaces.getConstArray(); 1074*b1cdbd2cSJim Jagielski for (const beans::Pair<OUString,sal_Int32>* pNs = pSeq; 1075*b1cdbd2cSJim Jagielski pNs < pSeq + i_rRegisterNamespaces.getLength(); ++pNs) 1076*b1cdbd2cSJim Jagielski { 1077*b1cdbd2cSJim Jagielski OSL_ENSURE(pNs->Second >= FastToken::NAMESPACE, 1078*b1cdbd2cSJim Jagielski "CDocument::fastSerialize(): invalid NS token id"); 1079*b1cdbd2cSJim Jagielski aContext.maNamespaceMap[ pNs->First ] = pNs->Second; 1080*b1cdbd2cSJim Jagielski } 1081*b1cdbd2cSJim Jagielski 1082*b1cdbd2cSJim Jagielski fastSaxify(aContext); 1083*b1cdbd2cSJim Jagielski } 1084*b1cdbd2cSJim Jagielski } 1085