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 <node.hxx> 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski #include <stdio.h> 27*b1cdbd2cSJim Jagielski #include <string.h> 28*b1cdbd2cSJim Jagielski 29*b1cdbd2cSJim Jagielski #include <libxml/xmlstring.h> 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski #include <algorithm> 32*b1cdbd2cSJim Jagielski 33*b1cdbd2cSJim Jagielski #include <boost/bind.hpp> 34*b1cdbd2cSJim Jagielski 35*b1cdbd2cSJim Jagielski #include <rtl/uuid.h> 36*b1cdbd2cSJim Jagielski #include <rtl/instance.hxx> 37*b1cdbd2cSJim Jagielski #include <osl/mutex.hxx> 38*b1cdbd2cSJim Jagielski 39*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/FastToken.hpp> 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski #include <document.hxx> 42*b1cdbd2cSJim Jagielski #include <attr.hxx> 43*b1cdbd2cSJim Jagielski #include <childlist.hxx> 44*b1cdbd2cSJim Jagielski 45*b1cdbd2cSJim Jagielski #include "../events/eventdispatcher.hxx" 46*b1cdbd2cSJim Jagielski #include "../events/mutationevent.hxx" 47*b1cdbd2cSJim Jagielski 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielski using namespace ::com::sun::star; 51*b1cdbd2cSJim Jagielski 52*b1cdbd2cSJim Jagielski 53*b1cdbd2cSJim Jagielski namespace { 54*b1cdbd2cSJim Jagielski struct UnoTunnelId 55*b1cdbd2cSJim Jagielski : public ::rtl::StaticWithInit< Sequence<sal_Int8>, UnoTunnelId > 56*b1cdbd2cSJim Jagielski { operator ()__anonbe23c9670111::UnoTunnelId57*b1cdbd2cSJim Jagielski Sequence<sal_Int8> operator() () 58*b1cdbd2cSJim Jagielski { 59*b1cdbd2cSJim Jagielski Sequence<sal_Int8> ret(16); 60*b1cdbd2cSJim Jagielski rtl_createUuid( 61*b1cdbd2cSJim Jagielski reinterpret_cast<sal_uInt8*>(ret.getArray()), 0, sal_True); 62*b1cdbd2cSJim Jagielski return ret; 63*b1cdbd2cSJim Jagielski } 64*b1cdbd2cSJim Jagielski }; 65*b1cdbd2cSJim Jagielski } 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski namespace DOM 68*b1cdbd2cSJim Jagielski { pushContext(Context & io_rContext)69*b1cdbd2cSJim Jagielski void pushContext(Context& io_rContext) 70*b1cdbd2cSJim Jagielski { 71*b1cdbd2cSJim Jagielski io_rContext.maNamespaces.push_back( 72*b1cdbd2cSJim Jagielski io_rContext.maNamespaces.back()); 73*b1cdbd2cSJim Jagielski } 74*b1cdbd2cSJim Jagielski popContext(Context & io_rContext)75*b1cdbd2cSJim Jagielski void popContext(Context& io_rContext) 76*b1cdbd2cSJim Jagielski { 77*b1cdbd2cSJim Jagielski io_rContext.maNamespaces.pop_back(); 78*b1cdbd2cSJim Jagielski } 79*b1cdbd2cSJim Jagielski addNamespaces(Context & io_rContext,xmlNodePtr pNode)80*b1cdbd2cSJim Jagielski void addNamespaces(Context& io_rContext, xmlNodePtr pNode) 81*b1cdbd2cSJim Jagielski { 82*b1cdbd2cSJim Jagielski // add node's namespaces to current context 83*b1cdbd2cSJim Jagielski for (xmlNsPtr pNs = pNode->nsDef; pNs != 0; pNs = pNs->next) { 84*b1cdbd2cSJim Jagielski const xmlChar *pPrefix = pNs->prefix; 85*b1cdbd2cSJim Jagielski OString prefix(reinterpret_cast<const sal_Char*>(pPrefix), 86*b1cdbd2cSJim Jagielski strlen(reinterpret_cast<const char*>(pPrefix))); 87*b1cdbd2cSJim Jagielski const xmlChar *pHref = pNs->href; 88*b1cdbd2cSJim Jagielski OUString val(reinterpret_cast<const sal_Char*>(pHref), 89*b1cdbd2cSJim Jagielski strlen(reinterpret_cast<const char*>(pHref)), 90*b1cdbd2cSJim Jagielski RTL_TEXTENCODING_UTF8); 91*b1cdbd2cSJim Jagielski 92*b1cdbd2cSJim Jagielski OSL_TRACE("Trying to add namespace %s (prefix %s)", 93*b1cdbd2cSJim Jagielski (const char*)pHref, (const char*)pPrefix); 94*b1cdbd2cSJim Jagielski 95*b1cdbd2cSJim Jagielski Context::NamespaceMapType::iterator aIter= 96*b1cdbd2cSJim Jagielski io_rContext.maNamespaceMap.find(val); 97*b1cdbd2cSJim Jagielski if( aIter != io_rContext.maNamespaceMap.end() ) 98*b1cdbd2cSJim Jagielski { 99*b1cdbd2cSJim Jagielski Context::Namespace aNS; 100*b1cdbd2cSJim Jagielski aNS.maPrefix = prefix; 101*b1cdbd2cSJim Jagielski aNS.mnToken = aIter->second; 102*b1cdbd2cSJim Jagielski aNS.maNamespaceURL = val; 103*b1cdbd2cSJim Jagielski 104*b1cdbd2cSJim Jagielski io_rContext.maNamespaces.back().push_back(aNS); 105*b1cdbd2cSJim Jagielski 106*b1cdbd2cSJim Jagielski OSL_TRACE("Added with token 0x%x", aIter->second); 107*b1cdbd2cSJim Jagielski } 108*b1cdbd2cSJim Jagielski } 109*b1cdbd2cSJim Jagielski } 110*b1cdbd2cSJim Jagielski getToken(const Context & rContext,const sal_Char * pToken)111*b1cdbd2cSJim Jagielski sal_Int32 getToken( const Context& rContext, const sal_Char* pToken ) 112*b1cdbd2cSJim Jagielski { 113*b1cdbd2cSJim Jagielski const Sequence<sal_Int8> aSeq( (sal_Int8*)pToken, strlen( pToken ) ); 114*b1cdbd2cSJim Jagielski return rContext.mxTokenHandler->getTokenFromUTF8( aSeq ); 115*b1cdbd2cSJim Jagielski } 116*b1cdbd2cSJim Jagielski getTokenWithPrefix(const Context & rContext,const sal_Char * pPrefix,const sal_Char * pName)117*b1cdbd2cSJim Jagielski sal_Int32 getTokenWithPrefix( const Context& rContext, const sal_Char* pPrefix, const sal_Char* pName ) 118*b1cdbd2cSJim Jagielski { 119*b1cdbd2cSJim Jagielski sal_Int32 nNamespaceToken = FastToken::DONTKNOW; 120*b1cdbd2cSJim Jagielski OString prefix(pPrefix, 121*b1cdbd2cSJim Jagielski strlen(reinterpret_cast<const char*>(pPrefix))); 122*b1cdbd2cSJim Jagielski 123*b1cdbd2cSJim Jagielski OSL_TRACE("getTokenWithPrefix(): prefix %s, name %s", 124*b1cdbd2cSJim Jagielski (const char*)pPrefix, (const char*)pName); 125*b1cdbd2cSJim Jagielski 126*b1cdbd2cSJim Jagielski Context::NamespaceVectorType::value_type::const_iterator aIter; 127*b1cdbd2cSJim Jagielski if( (aIter=std::find_if(rContext.maNamespaces.back().begin(), 128*b1cdbd2cSJim Jagielski rContext.maNamespaces.back().end(), 129*b1cdbd2cSJim Jagielski boost::bind(std::equal_to<OString>(), 130*b1cdbd2cSJim Jagielski boost::bind(&Context::Namespace::getPrefix, 131*b1cdbd2cSJim Jagielski _1), 132*b1cdbd2cSJim Jagielski boost::cref(prefix)))) != rContext.maNamespaces.back().end() ) 133*b1cdbd2cSJim Jagielski { 134*b1cdbd2cSJim Jagielski nNamespaceToken = aIter->mnToken; 135*b1cdbd2cSJim Jagielski sal_Int32 nNameToken = getToken( rContext, pName ); 136*b1cdbd2cSJim Jagielski if( nNameToken != FastToken::DONTKNOW ) 137*b1cdbd2cSJim Jagielski nNamespaceToken |= nNameToken; 138*b1cdbd2cSJim Jagielski } 139*b1cdbd2cSJim Jagielski 140*b1cdbd2cSJim Jagielski return nNamespaceToken; 141*b1cdbd2cSJim Jagielski } 142*b1cdbd2cSJim Jagielski 143*b1cdbd2cSJim Jagielski CNode(CDocument const & rDocument,::osl::Mutex const & rMutex,NodeType const & reNodeType,xmlNodePtr const & rpNode)144*b1cdbd2cSJim Jagielski CNode::CNode(CDocument const& rDocument, ::osl::Mutex const& rMutex, 145*b1cdbd2cSJim Jagielski NodeType const& reNodeType, xmlNodePtr const& rpNode) 146*b1cdbd2cSJim Jagielski : m_bUnlinked(false) 147*b1cdbd2cSJim Jagielski , m_aNodeType(reNodeType) 148*b1cdbd2cSJim Jagielski , m_aNodePtr(rpNode) 149*b1cdbd2cSJim Jagielski // keep containing document alive 150*b1cdbd2cSJim Jagielski // (but not if this is a document; that would create a leak!) 151*b1cdbd2cSJim Jagielski , m_xDocument( (m_aNodePtr->type != XML_DOCUMENT_NODE) 152*b1cdbd2cSJim Jagielski ? &const_cast<CDocument&>(rDocument) : 0 ) 153*b1cdbd2cSJim Jagielski , m_rMutex(const_cast< ::osl::Mutex & >(rMutex)) 154*b1cdbd2cSJim Jagielski { 155*b1cdbd2cSJim Jagielski OSL_ASSERT(m_aNodePtr); 156*b1cdbd2cSJim Jagielski } 157*b1cdbd2cSJim Jagielski invalidate()158*b1cdbd2cSJim Jagielski void CNode::invalidate() 159*b1cdbd2cSJim Jagielski { 160*b1cdbd2cSJim Jagielski //remove from list if this wrapper goes away 161*b1cdbd2cSJim Jagielski if (m_aNodePtr != 0 && m_xDocument.is()) { 162*b1cdbd2cSJim Jagielski m_xDocument->RemoveCNode(m_aNodePtr, this); 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski // #i113663#: unlinked nodes will not be freed by xmlFreeDoc 165*b1cdbd2cSJim Jagielski if (m_bUnlinked) { 166*b1cdbd2cSJim Jagielski xmlFreeNode(m_aNodePtr); 167*b1cdbd2cSJim Jagielski } 168*b1cdbd2cSJim Jagielski m_aNodePtr = 0; 169*b1cdbd2cSJim Jagielski } 170*b1cdbd2cSJim Jagielski ~CNode()171*b1cdbd2cSJim Jagielski CNode::~CNode() 172*b1cdbd2cSJim Jagielski { 173*b1cdbd2cSJim Jagielski // if this is the document itself, the mutex is already freed! 174*b1cdbd2cSJim Jagielski if (NodeType_DOCUMENT_NODE == m_aNodeType) { 175*b1cdbd2cSJim Jagielski invalidate(); 176*b1cdbd2cSJim Jagielski } else { 177*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 178*b1cdbd2cSJim Jagielski invalidate(); // other nodes are still alive so must lock mutex 179*b1cdbd2cSJim Jagielski } 180*b1cdbd2cSJim Jagielski } 181*b1cdbd2cSJim Jagielski 182*b1cdbd2cSJim Jagielski CNode * GetImplementation(uno::Reference<uno::XInterface> const & xNode)183*b1cdbd2cSJim Jagielski CNode::GetImplementation(uno::Reference<uno::XInterface> const& xNode) 184*b1cdbd2cSJim Jagielski { 185*b1cdbd2cSJim Jagielski uno::Reference<lang::XUnoTunnel> const xUnoTunnel(xNode, UNO_QUERY); 186*b1cdbd2cSJim Jagielski if (!xUnoTunnel.is()) { return 0; } 187*b1cdbd2cSJim Jagielski CNode *const pCNode( reinterpret_cast< CNode* >( 188*b1cdbd2cSJim Jagielski ::sal::static_int_cast< sal_IntPtr >( 189*b1cdbd2cSJim Jagielski xUnoTunnel->getSomething(UnoTunnelId::get())))); 190*b1cdbd2cSJim Jagielski return pCNode; 191*b1cdbd2cSJim Jagielski } 192*b1cdbd2cSJim Jagielski GetOwnerDocument()193*b1cdbd2cSJim Jagielski CDocument & CNode::GetOwnerDocument() 194*b1cdbd2cSJim Jagielski { 195*b1cdbd2cSJim Jagielski OSL_ASSERT(m_xDocument.is()); 196*b1cdbd2cSJim Jagielski return *m_xDocument; // needs overriding in CDocument! 197*b1cdbd2cSJim Jagielski } 198*b1cdbd2cSJim Jagielski 199*b1cdbd2cSJim Jagielski lcl_nsexchange(xmlNodePtr const aNode,xmlNsPtr const oldNs,xmlNsPtr const newNs)200*b1cdbd2cSJim Jagielski static void lcl_nsexchange( 201*b1cdbd2cSJim Jagielski xmlNodePtr const aNode, xmlNsPtr const oldNs, xmlNsPtr const newNs) 202*b1cdbd2cSJim Jagielski { 203*b1cdbd2cSJim Jagielski // recursively exchange any references to oldNs with references to newNs 204*b1cdbd2cSJim Jagielski xmlNodePtr cur = aNode; 205*b1cdbd2cSJim Jagielski while (cur != 0) 206*b1cdbd2cSJim Jagielski { 207*b1cdbd2cSJim Jagielski if (cur->ns == oldNs) 208*b1cdbd2cSJim Jagielski cur->ns = newNs; 209*b1cdbd2cSJim Jagielski if (cur->type == XML_ELEMENT_NODE) 210*b1cdbd2cSJim Jagielski { 211*b1cdbd2cSJim Jagielski xmlAttrPtr curAttr = cur->properties; 212*b1cdbd2cSJim Jagielski while(curAttr != 0) 213*b1cdbd2cSJim Jagielski { 214*b1cdbd2cSJim Jagielski if (curAttr->ns == oldNs) 215*b1cdbd2cSJim Jagielski curAttr->ns = newNs; 216*b1cdbd2cSJim Jagielski curAttr = curAttr->next; 217*b1cdbd2cSJim Jagielski } 218*b1cdbd2cSJim Jagielski lcl_nsexchange(cur->children, oldNs, newNs); 219*b1cdbd2cSJim Jagielski } 220*b1cdbd2cSJim Jagielski cur = cur->next; 221*b1cdbd2cSJim Jagielski } 222*b1cdbd2cSJim Jagielski } 223*b1cdbd2cSJim Jagielski nscleanup(const xmlNodePtr aNode,const xmlNodePtr aParent)224*b1cdbd2cSJim Jagielski /*static*/ void nscleanup(const xmlNodePtr aNode, const xmlNodePtr aParent) 225*b1cdbd2cSJim Jagielski { 226*b1cdbd2cSJim Jagielski xmlNodePtr cur = aNode; 227*b1cdbd2cSJim Jagielski 228*b1cdbd2cSJim Jagielski //handle attributes 229*b1cdbd2cSJim Jagielski if (cur != NULL && cur->type == XML_ELEMENT_NODE) 230*b1cdbd2cSJim Jagielski { 231*b1cdbd2cSJim Jagielski xmlAttrPtr curAttr = cur->properties; 232*b1cdbd2cSJim Jagielski while(curAttr != 0) 233*b1cdbd2cSJim Jagielski { 234*b1cdbd2cSJim Jagielski if (curAttr->ns != NULL) 235*b1cdbd2cSJim Jagielski { 236*b1cdbd2cSJim Jagielski xmlNsPtr ns = xmlSearchNs(cur->doc, aParent, curAttr->ns->prefix); 237*b1cdbd2cSJim Jagielski if (ns != NULL) 238*b1cdbd2cSJim Jagielski curAttr->ns = ns; 239*b1cdbd2cSJim Jagielski } 240*b1cdbd2cSJim Jagielski curAttr = curAttr->next; 241*b1cdbd2cSJim Jagielski } 242*b1cdbd2cSJim Jagielski } 243*b1cdbd2cSJim Jagielski 244*b1cdbd2cSJim Jagielski while (cur != NULL) 245*b1cdbd2cSJim Jagielski { 246*b1cdbd2cSJim Jagielski nscleanup(cur->children, cur); 247*b1cdbd2cSJim Jagielski if (cur->ns != NULL) 248*b1cdbd2cSJim Jagielski { 249*b1cdbd2cSJim Jagielski xmlNsPtr ns = xmlSearchNs(cur->doc, aParent, cur->ns->prefix); 250*b1cdbd2cSJim Jagielski if (ns != NULL && ns != cur->ns && strcmp((char*)ns->href, (char*)cur->ns->href)==0) 251*b1cdbd2cSJim Jagielski { 252*b1cdbd2cSJim Jagielski xmlNsPtr curDef = cur->nsDef; 253*b1cdbd2cSJim Jagielski xmlNsPtr *refp = &(cur->nsDef); // insert point 254*b1cdbd2cSJim Jagielski while (curDef != NULL) 255*b1cdbd2cSJim Jagielski { 256*b1cdbd2cSJim Jagielski ns = xmlSearchNs(cur->doc, aParent, curDef->prefix); 257*b1cdbd2cSJim Jagielski if (ns != NULL && ns != curDef && strcmp((char*)ns->href, (char*)curDef->href)==0) 258*b1cdbd2cSJim Jagielski { 259*b1cdbd2cSJim Jagielski // reconnect ns pointers in sub-tree to newly found ns before 260*b1cdbd2cSJim Jagielski // removing redundant nsdecl to prevent dangling pointers. 261*b1cdbd2cSJim Jagielski lcl_nsexchange(cur, curDef, ns); 262*b1cdbd2cSJim Jagielski *refp = curDef->next; 263*b1cdbd2cSJim Jagielski xmlFreeNs(curDef); 264*b1cdbd2cSJim Jagielski curDef = *refp; 265*b1cdbd2cSJim Jagielski } else { 266*b1cdbd2cSJim Jagielski refp = &(curDef->next); 267*b1cdbd2cSJim Jagielski curDef = curDef->next; 268*b1cdbd2cSJim Jagielski } 269*b1cdbd2cSJim Jagielski } 270*b1cdbd2cSJim Jagielski } 271*b1cdbd2cSJim Jagielski } 272*b1cdbd2cSJim Jagielski cur = cur->next; 273*b1cdbd2cSJim Jagielski } 274*b1cdbd2cSJim Jagielski } 275*b1cdbd2cSJim Jagielski saxify(const Reference<XDocumentHandler> & i_xHandler)276*b1cdbd2cSJim Jagielski void CNode::saxify(const Reference< XDocumentHandler >& i_xHandler) 277*b1cdbd2cSJim Jagielski { 278*b1cdbd2cSJim Jagielski if (!i_xHandler.is()) throw RuntimeException(); 279*b1cdbd2cSJim Jagielski // default: do nothing 280*b1cdbd2cSJim Jagielski } 281*b1cdbd2cSJim Jagielski fastSaxify(Context & io_rContext)282*b1cdbd2cSJim Jagielski void CNode::fastSaxify(Context& io_rContext) 283*b1cdbd2cSJim Jagielski { 284*b1cdbd2cSJim Jagielski if (!io_rContext.mxDocHandler.is()) throw RuntimeException(); 285*b1cdbd2cSJim Jagielski // default: do nothing 286*b1cdbd2cSJim Jagielski } 287*b1cdbd2cSJim Jagielski IsChildTypeAllowed(NodeType const)288*b1cdbd2cSJim Jagielski bool CNode::IsChildTypeAllowed(NodeType const /*nodeType*/) 289*b1cdbd2cSJim Jagielski { 290*b1cdbd2cSJim Jagielski // default: no children allowed 291*b1cdbd2cSJim Jagielski return false; 292*b1cdbd2cSJim Jagielski } 293*b1cdbd2cSJim Jagielski 294*b1cdbd2cSJim Jagielski /** 295*b1cdbd2cSJim Jagielski Adds the node newChild to the end of the list of children of this node. 296*b1cdbd2cSJim Jagielski */ appendChild(Reference<XNode> const & xNewChild)297*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::appendChild( 298*b1cdbd2cSJim Jagielski Reference< XNode > const& xNewChild) 299*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 300*b1cdbd2cSJim Jagielski { 301*b1cdbd2cSJim Jagielski ::osl::ClearableMutexGuard guard(m_rMutex); 302*b1cdbd2cSJim Jagielski 303*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { return 0; } 304*b1cdbd2cSJim Jagielski 305*b1cdbd2cSJim Jagielski CNode *const pNewChild(CNode::GetImplementation(xNewChild)); 306*b1cdbd2cSJim Jagielski if (!pNewChild) { throw RuntimeException(); } 307*b1cdbd2cSJim Jagielski xmlNodePtr const cur = pNewChild->GetNodePtr(); 308*b1cdbd2cSJim Jagielski if (!cur) { throw RuntimeException(); } 309*b1cdbd2cSJim Jagielski 310*b1cdbd2cSJim Jagielski // error checks: 311*b1cdbd2cSJim Jagielski // from other document 312*b1cdbd2cSJim Jagielski if (cur->doc != m_aNodePtr->doc) { 313*b1cdbd2cSJim Jagielski DOMException e; 314*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR; 315*b1cdbd2cSJim Jagielski throw e; 316*b1cdbd2cSJim Jagielski } 317*b1cdbd2cSJim Jagielski // same node 318*b1cdbd2cSJim Jagielski if (cur == m_aNodePtr) { 319*b1cdbd2cSJim Jagielski DOMException e; 320*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 321*b1cdbd2cSJim Jagielski throw e; 322*b1cdbd2cSJim Jagielski } 323*b1cdbd2cSJim Jagielski if (cur->parent != NULL) { 324*b1cdbd2cSJim Jagielski DOMException e; 325*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 326*b1cdbd2cSJim Jagielski throw e; 327*b1cdbd2cSJim Jagielski } 328*b1cdbd2cSJim Jagielski if (!IsChildTypeAllowed(pNewChild->m_aNodeType)) { 329*b1cdbd2cSJim Jagielski DOMException e; 330*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 331*b1cdbd2cSJim Jagielski throw e; 332*b1cdbd2cSJim Jagielski } 333*b1cdbd2cSJim Jagielski 334*b1cdbd2cSJim Jagielski // check whether this is an attribute node; it needs special handling 335*b1cdbd2cSJim Jagielski xmlNodePtr res = NULL; 336*b1cdbd2cSJim Jagielski if (cur->type == XML_ATTRIBUTE_NODE) 337*b1cdbd2cSJim Jagielski { 338*b1cdbd2cSJim Jagielski xmlChar const*const pChildren((cur->children) 339*b1cdbd2cSJim Jagielski ? cur->children->content 340*b1cdbd2cSJim Jagielski : reinterpret_cast<xmlChar const*>("")); 341*b1cdbd2cSJim Jagielski CAttr *const pCAttr(dynamic_cast<CAttr *>(pNewChild)); 342*b1cdbd2cSJim Jagielski if (!pCAttr) { throw RuntimeException(); } 343*b1cdbd2cSJim Jagielski xmlNsPtr const pNs( pCAttr->GetNamespace(m_aNodePtr) ); 344*b1cdbd2cSJim Jagielski if (pNs) { 345*b1cdbd2cSJim Jagielski res = reinterpret_cast<xmlNodePtr>( 346*b1cdbd2cSJim Jagielski xmlNewNsProp(m_aNodePtr, pNs, cur->name, pChildren)); 347*b1cdbd2cSJim Jagielski } else { 348*b1cdbd2cSJim Jagielski res = reinterpret_cast<xmlNodePtr>( 349*b1cdbd2cSJim Jagielski xmlNewProp(m_aNodePtr, cur->name, pChildren)); 350*b1cdbd2cSJim Jagielski } 351*b1cdbd2cSJim Jagielski } 352*b1cdbd2cSJim Jagielski else 353*b1cdbd2cSJim Jagielski { 354*b1cdbd2cSJim Jagielski res = xmlAddChild(m_aNodePtr, cur); 355*b1cdbd2cSJim Jagielski 356*b1cdbd2cSJim Jagielski // libxml can do optimization when appending nodes. 357*b1cdbd2cSJim Jagielski // if res != cur, something was optimized and the newchild-wrapper 358*b1cdbd2cSJim Jagielski // should be updated 359*b1cdbd2cSJim Jagielski if (res && (cur != res)) { 360*b1cdbd2cSJim Jagielski pNewChild->invalidate(); // cur has been freed 361*b1cdbd2cSJim Jagielski } 362*b1cdbd2cSJim Jagielski } 363*b1cdbd2cSJim Jagielski 364*b1cdbd2cSJim Jagielski if (!res) { return 0; } 365*b1cdbd2cSJim Jagielski 366*b1cdbd2cSJim Jagielski // use custom ns cleanup instead of 367*b1cdbd2cSJim Jagielski // xmlReconciliateNs(m_aNodePtr->doc, m_aNodePtr); 368*b1cdbd2cSJim Jagielski // because that will not remove unneeded ns decls 369*b1cdbd2cSJim Jagielski nscleanup(res, m_aNodePtr); 370*b1cdbd2cSJim Jagielski 371*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(res); 372*b1cdbd2cSJim Jagielski 373*b1cdbd2cSJim Jagielski if (!pNode.is()) { return 0; } 374*b1cdbd2cSJim Jagielski 375*b1cdbd2cSJim Jagielski // dispatch DOMNodeInserted event, target is the new node 376*b1cdbd2cSJim Jagielski // this node is the related node 377*b1cdbd2cSJim Jagielski // does bubble 378*b1cdbd2cSJim Jagielski pNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc 379*b1cdbd2cSJim Jagielski Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); 380*b1cdbd2cSJim Jagielski Reference< XMutationEvent > event(docevent->createEvent( 381*b1cdbd2cSJim Jagielski OUString::createFromAscii("DOMNodeInserted")), UNO_QUERY); 382*b1cdbd2cSJim Jagielski event->initMutationEvent(OUString::createFromAscii("DOMNodeInserted") 383*b1cdbd2cSJim Jagielski , sal_True, sal_False, 384*b1cdbd2cSJim Jagielski this, 385*b1cdbd2cSJim Jagielski OUString(), OUString(), OUString(), (AttrChangeType)0 ); 386*b1cdbd2cSJim Jagielski 387*b1cdbd2cSJim Jagielski // the following dispatch functions use only UNO interfaces 388*b1cdbd2cSJim Jagielski // and call event listeners, so release mutex to prevent deadlocks. 389*b1cdbd2cSJim Jagielski guard.clear(); 390*b1cdbd2cSJim Jagielski 391*b1cdbd2cSJim Jagielski dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); 392*b1cdbd2cSJim Jagielski // dispatch subtree modified for this node 393*b1cdbd2cSJim Jagielski dispatchSubtreeModified(); 394*b1cdbd2cSJim Jagielski 395*b1cdbd2cSJim Jagielski return pNode.get(); 396*b1cdbd2cSJim Jagielski } 397*b1cdbd2cSJim Jagielski 398*b1cdbd2cSJim Jagielski /** 399*b1cdbd2cSJim Jagielski Returns a duplicate of this node, i.e., serves as a generic copy 400*b1cdbd2cSJim Jagielski constructor for nodes. 401*b1cdbd2cSJim Jagielski */ cloneNode(sal_Bool bDeep)402*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::cloneNode(sal_Bool bDeep) 403*b1cdbd2cSJim Jagielski throw (RuntimeException) 404*b1cdbd2cSJim Jagielski { 405*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 406*b1cdbd2cSJim Jagielski 407*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 408*b1cdbd2cSJim Jagielski return 0; 409*b1cdbd2cSJim Jagielski } 410*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode( 411*b1cdbd2cSJim Jagielski xmlCopyNode(m_aNodePtr, (bDeep) ? 1 : 0)); 412*b1cdbd2cSJim Jagielski if (!pNode.is()) { return 0; } 413*b1cdbd2cSJim Jagielski pNode->m_bUnlinked = true; // not linked yet 414*b1cdbd2cSJim Jagielski return pNode.get(); 415*b1cdbd2cSJim Jagielski } 416*b1cdbd2cSJim Jagielski 417*b1cdbd2cSJim Jagielski /** 418*b1cdbd2cSJim Jagielski A NamedNodeMap containing the attributes of this node (if it is an Element) 419*b1cdbd2cSJim Jagielski or null otherwise. 420*b1cdbd2cSJim Jagielski */ getAttributes()421*b1cdbd2cSJim Jagielski Reference< XNamedNodeMap > SAL_CALL CNode::getAttributes() 422*b1cdbd2cSJim Jagielski throw (RuntimeException) 423*b1cdbd2cSJim Jagielski { 424*b1cdbd2cSJim Jagielski // return empty reference; only element node may override this impl 425*b1cdbd2cSJim Jagielski return Reference< XNamedNodeMap>(); 426*b1cdbd2cSJim Jagielski } 427*b1cdbd2cSJim Jagielski 428*b1cdbd2cSJim Jagielski /** 429*b1cdbd2cSJim Jagielski A NodeList that contains all children of this node. 430*b1cdbd2cSJim Jagielski */ getChildNodes()431*b1cdbd2cSJim Jagielski Reference< XNodeList > SAL_CALL CNode::getChildNodes() 432*b1cdbd2cSJim Jagielski throw (RuntimeException) 433*b1cdbd2cSJim Jagielski { 434*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 435*b1cdbd2cSJim Jagielski 436*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 437*b1cdbd2cSJim Jagielski return 0; 438*b1cdbd2cSJim Jagielski } 439*b1cdbd2cSJim Jagielski Reference< XNodeList > const xNodeList(new CChildList(this, m_rMutex)); 440*b1cdbd2cSJim Jagielski return xNodeList; 441*b1cdbd2cSJim Jagielski } 442*b1cdbd2cSJim Jagielski 443*b1cdbd2cSJim Jagielski /** 444*b1cdbd2cSJim Jagielski The first child of this node. 445*b1cdbd2cSJim Jagielski */ getFirstChild()446*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::getFirstChild() 447*b1cdbd2cSJim Jagielski throw (RuntimeException) 448*b1cdbd2cSJim Jagielski { 449*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 450*b1cdbd2cSJim Jagielski 451*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 452*b1cdbd2cSJim Jagielski return 0; 453*b1cdbd2cSJim Jagielski } 454*b1cdbd2cSJim Jagielski Reference< XNode > const xNode( 455*b1cdbd2cSJim Jagielski GetOwnerDocument().GetCNode(m_aNodePtr->children).get()); 456*b1cdbd2cSJim Jagielski return xNode; 457*b1cdbd2cSJim Jagielski } 458*b1cdbd2cSJim Jagielski 459*b1cdbd2cSJim Jagielski /** 460*b1cdbd2cSJim Jagielski The last child of this node. 461*b1cdbd2cSJim Jagielski */ getLastChild()462*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::getLastChild() 463*b1cdbd2cSJim Jagielski throw (RuntimeException) 464*b1cdbd2cSJim Jagielski { 465*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 466*b1cdbd2cSJim Jagielski 467*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 468*b1cdbd2cSJim Jagielski return 0; 469*b1cdbd2cSJim Jagielski } 470*b1cdbd2cSJim Jagielski Reference< XNode > const xNode( 471*b1cdbd2cSJim Jagielski GetOwnerDocument().GetCNode(xmlGetLastChild(m_aNodePtr)).get()); 472*b1cdbd2cSJim Jagielski return xNode; 473*b1cdbd2cSJim Jagielski } 474*b1cdbd2cSJim Jagielski 475*b1cdbd2cSJim Jagielski /** 476*b1cdbd2cSJim Jagielski Returns the local part of the qualified name of this node. 477*b1cdbd2cSJim Jagielski */ getLocalName()478*b1cdbd2cSJim Jagielski OUString SAL_CALL CNode::getLocalName() 479*b1cdbd2cSJim Jagielski throw (RuntimeException) 480*b1cdbd2cSJim Jagielski { 481*b1cdbd2cSJim Jagielski // see CElement/CAttr 482*b1cdbd2cSJim Jagielski return ::rtl::OUString(); 483*b1cdbd2cSJim Jagielski } 484*b1cdbd2cSJim Jagielski 485*b1cdbd2cSJim Jagielski 486*b1cdbd2cSJim Jagielski /** 487*b1cdbd2cSJim Jagielski The namespace URI of this node, or null if it is unspecified. 488*b1cdbd2cSJim Jagielski */ getNamespaceURI()489*b1cdbd2cSJim Jagielski OUString SAL_CALL CNode::getNamespaceURI() 490*b1cdbd2cSJim Jagielski throw (RuntimeException) 491*b1cdbd2cSJim Jagielski { 492*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 493*b1cdbd2cSJim Jagielski 494*b1cdbd2cSJim Jagielski OUString aURI; 495*b1cdbd2cSJim Jagielski if (m_aNodePtr != NULL && 496*b1cdbd2cSJim Jagielski (m_aNodePtr->type == XML_ELEMENT_NODE || m_aNodePtr->type == XML_ATTRIBUTE_NODE) && 497*b1cdbd2cSJim Jagielski m_aNodePtr->ns != NULL) 498*b1cdbd2cSJim Jagielski { 499*b1cdbd2cSJim Jagielski const xmlChar* xHref = m_aNodePtr->ns->href; 500*b1cdbd2cSJim Jagielski aURI = OUString((sal_Char*)xHref, strlen((char*)xHref), RTL_TEXTENCODING_UTF8); 501*b1cdbd2cSJim Jagielski } 502*b1cdbd2cSJim Jagielski return aURI; 503*b1cdbd2cSJim Jagielski } 504*b1cdbd2cSJim Jagielski 505*b1cdbd2cSJim Jagielski /** 506*b1cdbd2cSJim Jagielski The node immediately following this node. 507*b1cdbd2cSJim Jagielski */ getNextSibling()508*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::getNextSibling() 509*b1cdbd2cSJim Jagielski throw (RuntimeException) 510*b1cdbd2cSJim Jagielski { 511*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 512*b1cdbd2cSJim Jagielski 513*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 514*b1cdbd2cSJim Jagielski return 0; 515*b1cdbd2cSJim Jagielski } 516*b1cdbd2cSJim Jagielski Reference< XNode > const xNode( 517*b1cdbd2cSJim Jagielski GetOwnerDocument().GetCNode(m_aNodePtr->next).get()); 518*b1cdbd2cSJim Jagielski return xNode; 519*b1cdbd2cSJim Jagielski } 520*b1cdbd2cSJim Jagielski 521*b1cdbd2cSJim Jagielski /** 522*b1cdbd2cSJim Jagielski The name of this node, depending on its type; see the table above. 523*b1cdbd2cSJim Jagielski */ getNodeName()524*b1cdbd2cSJim Jagielski OUString SAL_CALL CNode::getNodeName() 525*b1cdbd2cSJim Jagielski throw (RuntimeException) 526*b1cdbd2cSJim Jagielski { 527*b1cdbd2cSJim Jagielski /* 528*b1cdbd2cSJim Jagielski Interface nodeName nodeValue attributes 529*b1cdbd2cSJim Jagielski -------------------------------------------------------------------------------------- 530*b1cdbd2cSJim Jagielski Attr name of attribute value of attribute null 531*b1cdbd2cSJim Jagielski CDATASection "#cdata-section" content of the CDATA Section null 532*b1cdbd2cSJim Jagielski Comment "#comment" content of the comment null 533*b1cdbd2cSJim Jagielski Document "#document" null null 534*b1cdbd2cSJim Jagielski DocumentFragment "#document-fragment" null null 535*b1cdbd2cSJim Jagielski DocumentType document type name null null 536*b1cdbd2cSJim Jagielski Element tag name null NamedNodeMap 537*b1cdbd2cSJim Jagielski Entity entity name null null 538*b1cdbd2cSJim Jagielski EntityReference name of entity null null 539*b1cdbd2cSJim Jagielski referenced 540*b1cdbd2cSJim Jagielski Notation notation name null null 541*b1cdbd2cSJim Jagielski Processing\ target entire content excluding null 542*b1cdbd2cSJim Jagielski Instruction the target 543*b1cdbd2cSJim Jagielski Text "#text" content of the text node null 544*b1cdbd2cSJim Jagielski */ 545*b1cdbd2cSJim Jagielski OUString aName; 546*b1cdbd2cSJim Jagielski return aName; 547*b1cdbd2cSJim Jagielski } 548*b1cdbd2cSJim Jagielski 549*b1cdbd2cSJim Jagielski /** 550*b1cdbd2cSJim Jagielski A code representing the type of the underlying object, as defined above. 551*b1cdbd2cSJim Jagielski */ getNodeType()552*b1cdbd2cSJim Jagielski NodeType SAL_CALL CNode::getNodeType() 553*b1cdbd2cSJim Jagielski throw (RuntimeException) 554*b1cdbd2cSJim Jagielski { 555*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 556*b1cdbd2cSJim Jagielski 557*b1cdbd2cSJim Jagielski return m_aNodeType; 558*b1cdbd2cSJim Jagielski } 559*b1cdbd2cSJim Jagielski 560*b1cdbd2cSJim Jagielski /** 561*b1cdbd2cSJim Jagielski The value of this node, depending on its type; see the table above. 562*b1cdbd2cSJim Jagielski */ getNodeValue()563*b1cdbd2cSJim Jagielski OUString SAL_CALL CNode::getNodeValue() 564*b1cdbd2cSJim Jagielski throw (RuntimeException) 565*b1cdbd2cSJim Jagielski { 566*b1cdbd2cSJim Jagielski OUString aValue; 567*b1cdbd2cSJim Jagielski return aValue; 568*b1cdbd2cSJim Jagielski } 569*b1cdbd2cSJim Jagielski 570*b1cdbd2cSJim Jagielski /** 571*b1cdbd2cSJim Jagielski The Document object associated with this node. 572*b1cdbd2cSJim Jagielski */ getOwnerDocument()573*b1cdbd2cSJim Jagielski Reference< XDocument > SAL_CALL CNode::getOwnerDocument() 574*b1cdbd2cSJim Jagielski throw (RuntimeException) 575*b1cdbd2cSJim Jagielski { 576*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 577*b1cdbd2cSJim Jagielski 578*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 579*b1cdbd2cSJim Jagielski return 0; 580*b1cdbd2cSJim Jagielski } 581*b1cdbd2cSJim Jagielski Reference< XDocument > const xDoc(& GetOwnerDocument()); 582*b1cdbd2cSJim Jagielski return xDoc; 583*b1cdbd2cSJim Jagielski } 584*b1cdbd2cSJim Jagielski 585*b1cdbd2cSJim Jagielski /** 586*b1cdbd2cSJim Jagielski The parent of this node. 587*b1cdbd2cSJim Jagielski */ getParentNode()588*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::getParentNode() 589*b1cdbd2cSJim Jagielski throw (RuntimeException) 590*b1cdbd2cSJim Jagielski { 591*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 592*b1cdbd2cSJim Jagielski 593*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 594*b1cdbd2cSJim Jagielski return 0; 595*b1cdbd2cSJim Jagielski } 596*b1cdbd2cSJim Jagielski Reference< XNode > const xNode( 597*b1cdbd2cSJim Jagielski GetOwnerDocument().GetCNode(m_aNodePtr->parent).get()); 598*b1cdbd2cSJim Jagielski return xNode; 599*b1cdbd2cSJim Jagielski } 600*b1cdbd2cSJim Jagielski 601*b1cdbd2cSJim Jagielski /** 602*b1cdbd2cSJim Jagielski The namespace prefix of this node, or null if it is unspecified. 603*b1cdbd2cSJim Jagielski */ getPrefix()604*b1cdbd2cSJim Jagielski OUString SAL_CALL CNode::getPrefix() 605*b1cdbd2cSJim Jagielski throw (RuntimeException) 606*b1cdbd2cSJim Jagielski { 607*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 608*b1cdbd2cSJim Jagielski 609*b1cdbd2cSJim Jagielski OUString aPrefix; 610*b1cdbd2cSJim Jagielski if (m_aNodePtr != NULL && 611*b1cdbd2cSJim Jagielski (m_aNodePtr->type == XML_ELEMENT_NODE || m_aNodePtr->type == XML_ATTRIBUTE_NODE) && 612*b1cdbd2cSJim Jagielski m_aNodePtr->ns != NULL) 613*b1cdbd2cSJim Jagielski { 614*b1cdbd2cSJim Jagielski const xmlChar* xPrefix = m_aNodePtr->ns->prefix; 615*b1cdbd2cSJim Jagielski if( xPrefix != NULL ) 616*b1cdbd2cSJim Jagielski aPrefix = OUString((sal_Char*)xPrefix, strlen((char*)xPrefix), RTL_TEXTENCODING_UTF8); 617*b1cdbd2cSJim Jagielski } 618*b1cdbd2cSJim Jagielski return aPrefix; 619*b1cdbd2cSJim Jagielski 620*b1cdbd2cSJim Jagielski } 621*b1cdbd2cSJim Jagielski 622*b1cdbd2cSJim Jagielski /** 623*b1cdbd2cSJim Jagielski The node immediately preceding this node. 624*b1cdbd2cSJim Jagielski */ getPreviousSibling()625*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::getPreviousSibling() 626*b1cdbd2cSJim Jagielski throw (RuntimeException) 627*b1cdbd2cSJim Jagielski { 628*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 629*b1cdbd2cSJim Jagielski 630*b1cdbd2cSJim Jagielski if (0 == m_aNodePtr) { 631*b1cdbd2cSJim Jagielski return 0; 632*b1cdbd2cSJim Jagielski } 633*b1cdbd2cSJim Jagielski Reference< XNode > const xNode( 634*b1cdbd2cSJim Jagielski GetOwnerDocument().GetCNode(m_aNodePtr->prev).get()); 635*b1cdbd2cSJim Jagielski return xNode; 636*b1cdbd2cSJim Jagielski } 637*b1cdbd2cSJim Jagielski 638*b1cdbd2cSJim Jagielski /** 639*b1cdbd2cSJim Jagielski Returns whether this node (if it is an element) has any attributes. 640*b1cdbd2cSJim Jagielski */ hasAttributes()641*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL CNode::hasAttributes() 642*b1cdbd2cSJim Jagielski throw (RuntimeException) 643*b1cdbd2cSJim Jagielski { 644*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 645*b1cdbd2cSJim Jagielski 646*b1cdbd2cSJim Jagielski return (m_aNodePtr != NULL && m_aNodePtr->properties != NULL); 647*b1cdbd2cSJim Jagielski } 648*b1cdbd2cSJim Jagielski 649*b1cdbd2cSJim Jagielski /** 650*b1cdbd2cSJim Jagielski Returns whether this node has any children. 651*b1cdbd2cSJim Jagielski */ hasChildNodes()652*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL CNode::hasChildNodes() 653*b1cdbd2cSJim Jagielski throw (RuntimeException) 654*b1cdbd2cSJim Jagielski { 655*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 656*b1cdbd2cSJim Jagielski 657*b1cdbd2cSJim Jagielski return (m_aNodePtr != NULL && m_aNodePtr->children != NULL); 658*b1cdbd2cSJim Jagielski } 659*b1cdbd2cSJim Jagielski 660*b1cdbd2cSJim Jagielski /** 661*b1cdbd2cSJim Jagielski Inserts the node newChild before the existing child node refChild. 662*b1cdbd2cSJim Jagielski */ insertBefore(const Reference<XNode> & newChild,const Reference<XNode> & refChild)663*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::insertBefore( 664*b1cdbd2cSJim Jagielski const Reference< XNode >& newChild, const Reference< XNode >& refChild) 665*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 666*b1cdbd2cSJim Jagielski { 667*b1cdbd2cSJim Jagielski if (!newChild.is() || !refChild.is()) { throw RuntimeException(); } 668*b1cdbd2cSJim Jagielski 669*b1cdbd2cSJim Jagielski if (newChild->getOwnerDocument() != getOwnerDocument()) { 670*b1cdbd2cSJim Jagielski DOMException e; 671*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR; 672*b1cdbd2cSJim Jagielski throw e; 673*b1cdbd2cSJim Jagielski } 674*b1cdbd2cSJim Jagielski if (refChild->getParentNode() != Reference< XNode >(this)) { 675*b1cdbd2cSJim Jagielski DOMException e; 676*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 677*b1cdbd2cSJim Jagielski throw e; 678*b1cdbd2cSJim Jagielski } 679*b1cdbd2cSJim Jagielski 680*b1cdbd2cSJim Jagielski ::osl::ClearableMutexGuard guard(m_rMutex); 681*b1cdbd2cSJim Jagielski 682*b1cdbd2cSJim Jagielski CNode *const pNewNode(CNode::GetImplementation(newChild)); 683*b1cdbd2cSJim Jagielski CNode *const pRefNode(CNode::GetImplementation(refChild)); 684*b1cdbd2cSJim Jagielski if (!pNewNode || !pRefNode) { throw RuntimeException(); } 685*b1cdbd2cSJim Jagielski xmlNodePtr const pNewChild(pNewNode->GetNodePtr()); 686*b1cdbd2cSJim Jagielski xmlNodePtr const pRefChild(pRefNode->GetNodePtr()); 687*b1cdbd2cSJim Jagielski if (!pNewChild || !pRefChild) { throw RuntimeException(); } 688*b1cdbd2cSJim Jagielski 689*b1cdbd2cSJim Jagielski if (pNewChild == m_aNodePtr) { 690*b1cdbd2cSJim Jagielski DOMException e; 691*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 692*b1cdbd2cSJim Jagielski throw e; 693*b1cdbd2cSJim Jagielski } 694*b1cdbd2cSJim Jagielski // already has parent 695*b1cdbd2cSJim Jagielski if (pNewChild->parent != NULL) 696*b1cdbd2cSJim Jagielski { 697*b1cdbd2cSJim Jagielski DOMException e; 698*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 699*b1cdbd2cSJim Jagielski throw e; 700*b1cdbd2cSJim Jagielski } 701*b1cdbd2cSJim Jagielski if (!IsChildTypeAllowed(pNewNode->m_aNodeType)) { 702*b1cdbd2cSJim Jagielski DOMException e; 703*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 704*b1cdbd2cSJim Jagielski throw e; 705*b1cdbd2cSJim Jagielski } 706*b1cdbd2cSJim Jagielski 707*b1cdbd2cSJim Jagielski // attributes are unordered anyway, so just do appendChild 708*b1cdbd2cSJim Jagielski if (XML_ATTRIBUTE_NODE == pNewChild->type) { 709*b1cdbd2cSJim Jagielski guard.clear(); 710*b1cdbd2cSJim Jagielski return appendChild(newChild); 711*b1cdbd2cSJim Jagielski } 712*b1cdbd2cSJim Jagielski 713*b1cdbd2cSJim Jagielski xmlNodePtr cur = m_aNodePtr->children; 714*b1cdbd2cSJim Jagielski 715*b1cdbd2cSJim Jagielski //search child before which to insert 716*b1cdbd2cSJim Jagielski while (cur != NULL) 717*b1cdbd2cSJim Jagielski { 718*b1cdbd2cSJim Jagielski if (cur == pRefChild) { 719*b1cdbd2cSJim Jagielski // insert before 720*b1cdbd2cSJim Jagielski pNewChild->next = cur; 721*b1cdbd2cSJim Jagielski pNewChild->prev = cur->prev; 722*b1cdbd2cSJim Jagielski cur->prev = pNewChild; 723*b1cdbd2cSJim Jagielski if (pNewChild->prev != NULL) { 724*b1cdbd2cSJim Jagielski pNewChild->prev->next = pNewChild; 725*b1cdbd2cSJim Jagielski } 726*b1cdbd2cSJim Jagielski pNewChild->parent = cur->parent; 727*b1cdbd2cSJim Jagielski if (pNewChild->parent->children == cur) { 728*b1cdbd2cSJim Jagielski pNewChild->parent->children = pNewChild; 729*b1cdbd2cSJim Jagielski } 730*b1cdbd2cSJim Jagielski // do not update parent->last here! 731*b1cdbd2cSJim Jagielski pNewNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc 732*b1cdbd2cSJim Jagielski break; 733*b1cdbd2cSJim Jagielski } 734*b1cdbd2cSJim Jagielski cur = cur->next; 735*b1cdbd2cSJim Jagielski } 736*b1cdbd2cSJim Jagielski return refChild; 737*b1cdbd2cSJim Jagielski } 738*b1cdbd2cSJim Jagielski 739*b1cdbd2cSJim Jagielski /** 740*b1cdbd2cSJim Jagielski Tests whether the DOM implementation implements a specific feature and 741*b1cdbd2cSJim Jagielski that feature is supported by this node. 742*b1cdbd2cSJim Jagielski */ isSupported(const OUString &,const OUString &)743*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL CNode::isSupported(const OUString& /*feature*/, const OUString& /*ver*/) 744*b1cdbd2cSJim Jagielski throw (RuntimeException) 745*b1cdbd2cSJim Jagielski { 746*b1cdbd2cSJim Jagielski OSL_ENSURE(false, "CNode::isSupported: not implemented (#i113683#)"); 747*b1cdbd2cSJim Jagielski return sal_False; 748*b1cdbd2cSJim Jagielski } 749*b1cdbd2cSJim Jagielski 750*b1cdbd2cSJim Jagielski /** 751*b1cdbd2cSJim Jagielski Puts all Text nodes in the full depth of the sub-tree underneath this 752*b1cdbd2cSJim Jagielski Node, including attribute nodes, into a "normal" form where only structure 753*b1cdbd2cSJim Jagielski (e.g., elements, comments, processing instructions, CDATA sections, and 754*b1cdbd2cSJim Jagielski entity references) separates Text nodes, i.e., there are neither adjacent 755*b1cdbd2cSJim Jagielski Text nodes nor empty Text nodes. 756*b1cdbd2cSJim Jagielski */ normalize()757*b1cdbd2cSJim Jagielski void SAL_CALL CNode::normalize() 758*b1cdbd2cSJim Jagielski throw (RuntimeException) 759*b1cdbd2cSJim Jagielski { 760*b1cdbd2cSJim Jagielski //XXX combine adjacent text nodes and remove empty ones 761*b1cdbd2cSJim Jagielski OSL_ENSURE(false, "CNode::normalize: not implemented (#i113683#)"); 762*b1cdbd2cSJim Jagielski } 763*b1cdbd2cSJim Jagielski 764*b1cdbd2cSJim Jagielski /** 765*b1cdbd2cSJim Jagielski Removes the child node indicated by oldChild from the list of children, 766*b1cdbd2cSJim Jagielski and returns it. 767*b1cdbd2cSJim Jagielski */ 768*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL removeChild(const Reference<XNode> & xOldChild)769*b1cdbd2cSJim Jagielski CNode::removeChild(const Reference< XNode >& xOldChild) 770*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 771*b1cdbd2cSJim Jagielski { 772*b1cdbd2cSJim Jagielski if (!xOldChild.is()) { 773*b1cdbd2cSJim Jagielski throw RuntimeException(); 774*b1cdbd2cSJim Jagielski } 775*b1cdbd2cSJim Jagielski 776*b1cdbd2cSJim Jagielski if (xOldChild->getOwnerDocument() != getOwnerDocument()) { 777*b1cdbd2cSJim Jagielski DOMException e; 778*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR; 779*b1cdbd2cSJim Jagielski throw e; 780*b1cdbd2cSJim Jagielski } 781*b1cdbd2cSJim Jagielski if (xOldChild->getParentNode() != Reference< XNode >(this)) { 782*b1cdbd2cSJim Jagielski DOMException e; 783*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 784*b1cdbd2cSJim Jagielski throw e; 785*b1cdbd2cSJim Jagielski } 786*b1cdbd2cSJim Jagielski 787*b1cdbd2cSJim Jagielski ::osl::ClearableMutexGuard guard(m_rMutex); 788*b1cdbd2cSJim Jagielski 789*b1cdbd2cSJim Jagielski if (!m_aNodePtr) { throw RuntimeException(); } 790*b1cdbd2cSJim Jagielski 791*b1cdbd2cSJim Jagielski Reference<XNode> xReturn( xOldChild ); 792*b1cdbd2cSJim Jagielski 793*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pOld(CNode::GetImplementation(xOldChild)); 794*b1cdbd2cSJim Jagielski if (!pOld.is()) { throw RuntimeException(); } 795*b1cdbd2cSJim Jagielski xmlNodePtr const old = pOld->GetNodePtr(); 796*b1cdbd2cSJim Jagielski if (!old) { throw RuntimeException(); } 797*b1cdbd2cSJim Jagielski 798*b1cdbd2cSJim Jagielski if( old->type == XML_ATTRIBUTE_NODE ) 799*b1cdbd2cSJim Jagielski { 800*b1cdbd2cSJim Jagielski xmlAttrPtr pAttr = reinterpret_cast<xmlAttrPtr>(old); 801*b1cdbd2cSJim Jagielski xmlRemoveProp( pAttr ); 802*b1cdbd2cSJim Jagielski pOld->invalidate(); // freed by xmlRemoveProp 803*b1cdbd2cSJim Jagielski xReturn.clear(); 804*b1cdbd2cSJim Jagielski } 805*b1cdbd2cSJim Jagielski else 806*b1cdbd2cSJim Jagielski { 807*b1cdbd2cSJim Jagielski xmlUnlinkNode(old); 808*b1cdbd2cSJim Jagielski pOld->m_bUnlinked = true; 809*b1cdbd2cSJim Jagielski } 810*b1cdbd2cSJim Jagielski 811*b1cdbd2cSJim Jagielski /*DOMNodeRemoved 812*b1cdbd2cSJim Jagielski * Fired when a node is being removed from its parent node. 813*b1cdbd2cSJim Jagielski * This event is dispatched before the node is removed from the tree. 814*b1cdbd2cSJim Jagielski * The target of this event is the node being removed. 815*b1cdbd2cSJim Jagielski * Bubbles: Yes 816*b1cdbd2cSJim Jagielski * Cancelable: No 817*b1cdbd2cSJim Jagielski * Context Info: relatedNode holds the parent node 818*b1cdbd2cSJim Jagielski */ 819*b1cdbd2cSJim Jagielski Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); 820*b1cdbd2cSJim Jagielski Reference< XMutationEvent > event(docevent->createEvent( 821*b1cdbd2cSJim Jagielski OUString::createFromAscii("DOMNodeRemoved")), UNO_QUERY); 822*b1cdbd2cSJim Jagielski event->initMutationEvent(OUString::createFromAscii("DOMNodeRemoved"), 823*b1cdbd2cSJim Jagielski sal_True, 824*b1cdbd2cSJim Jagielski sal_False, 825*b1cdbd2cSJim Jagielski this, 826*b1cdbd2cSJim Jagielski OUString(), OUString(), OUString(), (AttrChangeType)0 ); 827*b1cdbd2cSJim Jagielski 828*b1cdbd2cSJim Jagielski // the following dispatch functions use only UNO interfaces 829*b1cdbd2cSJim Jagielski // and call event listeners, so release mutex to prevent deadlocks. 830*b1cdbd2cSJim Jagielski guard.clear(); 831*b1cdbd2cSJim Jagielski 832*b1cdbd2cSJim Jagielski dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); 833*b1cdbd2cSJim Jagielski // subtree modified for this node 834*b1cdbd2cSJim Jagielski dispatchSubtreeModified(); 835*b1cdbd2cSJim Jagielski 836*b1cdbd2cSJim Jagielski return xReturn; 837*b1cdbd2cSJim Jagielski } 838*b1cdbd2cSJim Jagielski 839*b1cdbd2cSJim Jagielski /** 840*b1cdbd2cSJim Jagielski Replaces the child node oldChild with newChild in the list of children, 841*b1cdbd2cSJim Jagielski and returns the oldChild node. 842*b1cdbd2cSJim Jagielski */ replaceChild(Reference<XNode> const & xNewChild,Reference<XNode> const & xOldChild)843*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CNode::replaceChild( 844*b1cdbd2cSJim Jagielski Reference< XNode > const& xNewChild, 845*b1cdbd2cSJim Jagielski Reference< XNode > const& xOldChild) 846*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 847*b1cdbd2cSJim Jagielski { 848*b1cdbd2cSJim Jagielski if (!xOldChild.is() || !xNewChild.is()) { 849*b1cdbd2cSJim Jagielski throw RuntimeException(); 850*b1cdbd2cSJim Jagielski } 851*b1cdbd2cSJim Jagielski 852*b1cdbd2cSJim Jagielski if (xNewChild->getOwnerDocument() != getOwnerDocument()) { 853*b1cdbd2cSJim Jagielski DOMException e; 854*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR; 855*b1cdbd2cSJim Jagielski throw e; 856*b1cdbd2cSJim Jagielski } 857*b1cdbd2cSJim Jagielski if (xOldChild->getParentNode() != Reference< XNode >(this)) { 858*b1cdbd2cSJim Jagielski DOMException e; 859*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 860*b1cdbd2cSJim Jagielski throw e; 861*b1cdbd2cSJim Jagielski } 862*b1cdbd2cSJim Jagielski 863*b1cdbd2cSJim Jagielski ::osl::ClearableMutexGuard guard(m_rMutex); 864*b1cdbd2cSJim Jagielski 865*b1cdbd2cSJim Jagielski /* 866*b1cdbd2cSJim Jagielski Reference< XNode > aNode = removeChild(oldChild); 867*b1cdbd2cSJim Jagielski appendChild(newChild); 868*b1cdbd2cSJim Jagielski */ 869*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pOldNode( 870*b1cdbd2cSJim Jagielski CNode::GetImplementation(xOldChild)); 871*b1cdbd2cSJim Jagielski ::rtl::Reference<CNode> const pNewNode( 872*b1cdbd2cSJim Jagielski CNode::GetImplementation(xNewChild)); 873*b1cdbd2cSJim Jagielski if (!pOldNode.is() || !pNewNode.is()) { throw RuntimeException(); } 874*b1cdbd2cSJim Jagielski xmlNodePtr const pOld = pOldNode->GetNodePtr(); 875*b1cdbd2cSJim Jagielski xmlNodePtr const pNew = pNewNode->GetNodePtr(); 876*b1cdbd2cSJim Jagielski if (!pOld || !pNew) { throw RuntimeException(); } 877*b1cdbd2cSJim Jagielski 878*b1cdbd2cSJim Jagielski if (pNew == m_aNodePtr) { 879*b1cdbd2cSJim Jagielski DOMException e; 880*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 881*b1cdbd2cSJim Jagielski throw e; 882*b1cdbd2cSJim Jagielski } 883*b1cdbd2cSJim Jagielski // already has parent 884*b1cdbd2cSJim Jagielski if (pNew->parent != NULL) { 885*b1cdbd2cSJim Jagielski DOMException e; 886*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 887*b1cdbd2cSJim Jagielski throw e; 888*b1cdbd2cSJim Jagielski } 889*b1cdbd2cSJim Jagielski if (!IsChildTypeAllowed(pNewNode->m_aNodeType)) { 890*b1cdbd2cSJim Jagielski DOMException e; 891*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 892*b1cdbd2cSJim Jagielski throw e; 893*b1cdbd2cSJim Jagielski } 894*b1cdbd2cSJim Jagielski 895*b1cdbd2cSJim Jagielski if( pOld->type == XML_ATTRIBUTE_NODE ) 896*b1cdbd2cSJim Jagielski { 897*b1cdbd2cSJim Jagielski // can only replace attribute with attribute 898*b1cdbd2cSJim Jagielski if ( pOld->type != pNew->type ) 899*b1cdbd2cSJim Jagielski { 900*b1cdbd2cSJim Jagielski DOMException e; 901*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR; 902*b1cdbd2cSJim Jagielski throw e; 903*b1cdbd2cSJim Jagielski } 904*b1cdbd2cSJim Jagielski 905*b1cdbd2cSJim Jagielski xmlAttrPtr pAttr = (xmlAttrPtr)pOld; 906*b1cdbd2cSJim Jagielski xmlRemoveProp( pAttr ); 907*b1cdbd2cSJim Jagielski pOldNode->invalidate(); // freed by xmlRemoveProp 908*b1cdbd2cSJim Jagielski appendChild(xNewChild); 909*b1cdbd2cSJim Jagielski } 910*b1cdbd2cSJim Jagielski else 911*b1cdbd2cSJim Jagielski { 912*b1cdbd2cSJim Jagielski 913*b1cdbd2cSJim Jagielski xmlNodePtr cur = m_aNodePtr->children; 914*b1cdbd2cSJim Jagielski //find old node in child list 915*b1cdbd2cSJim Jagielski while (cur != NULL) 916*b1cdbd2cSJim Jagielski { 917*b1cdbd2cSJim Jagielski if(cur == pOld) 918*b1cdbd2cSJim Jagielski { 919*b1cdbd2cSJim Jagielski // exchange nodes 920*b1cdbd2cSJim Jagielski pNew->prev = pOld->prev; 921*b1cdbd2cSJim Jagielski if (pNew->prev != NULL) 922*b1cdbd2cSJim Jagielski pNew->prev->next = pNew; 923*b1cdbd2cSJim Jagielski pNew->next = pOld->next; 924*b1cdbd2cSJim Jagielski if (pNew->next != NULL) 925*b1cdbd2cSJim Jagielski pNew->next->prev = pNew; 926*b1cdbd2cSJim Jagielski pNew->parent = pOld->parent; 927*b1cdbd2cSJim Jagielski if(pNew->parent->children == pOld) 928*b1cdbd2cSJim Jagielski pNew->parent->children = pNew; 929*b1cdbd2cSJim Jagielski if(pNew->parent->last == pOld) 930*b1cdbd2cSJim Jagielski pNew->parent->last = pNew; 931*b1cdbd2cSJim Jagielski pOld->next = NULL; 932*b1cdbd2cSJim Jagielski pOld->prev = NULL; 933*b1cdbd2cSJim Jagielski pOld->parent = NULL; 934*b1cdbd2cSJim Jagielski pOldNode->m_bUnlinked = true; 935*b1cdbd2cSJim Jagielski pNewNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc 936*b1cdbd2cSJim Jagielski } 937*b1cdbd2cSJim Jagielski cur = cur->next; 938*b1cdbd2cSJim Jagielski } 939*b1cdbd2cSJim Jagielski } 940*b1cdbd2cSJim Jagielski 941*b1cdbd2cSJim Jagielski guard.clear(); // release for calling event handlers 942*b1cdbd2cSJim Jagielski dispatchSubtreeModified(); 943*b1cdbd2cSJim Jagielski 944*b1cdbd2cSJim Jagielski return xOldChild; 945*b1cdbd2cSJim Jagielski } 946*b1cdbd2cSJim Jagielski dispatchSubtreeModified()947*b1cdbd2cSJim Jagielski void CNode::dispatchSubtreeModified() 948*b1cdbd2cSJim Jagielski { 949*b1cdbd2cSJim Jagielski // only uses UNO interfaces => needs no mutex 950*b1cdbd2cSJim Jagielski 951*b1cdbd2cSJim Jagielski // dispatch DOMSubtreeModified 952*b1cdbd2cSJim Jagielski // target is _this_ node 953*b1cdbd2cSJim Jagielski Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); 954*b1cdbd2cSJim Jagielski Reference< XMutationEvent > event(docevent->createEvent( 955*b1cdbd2cSJim Jagielski OUString::createFromAscii("DOMSubtreeModified")), UNO_QUERY); 956*b1cdbd2cSJim Jagielski event->initMutationEvent( 957*b1cdbd2cSJim Jagielski OUString::createFromAscii("DOMSubtreeModified"), sal_True, 958*b1cdbd2cSJim Jagielski sal_False, Reference< XNode >(), 959*b1cdbd2cSJim Jagielski OUString(), OUString(), OUString(), (AttrChangeType)0 ); 960*b1cdbd2cSJim Jagielski dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); 961*b1cdbd2cSJim Jagielski } 962*b1cdbd2cSJim Jagielski 963*b1cdbd2cSJim Jagielski /** 964*b1cdbd2cSJim Jagielski The value of this node, depending on its type; see the table above. 965*b1cdbd2cSJim Jagielski */ setNodeValue(const OUString &)966*b1cdbd2cSJim Jagielski void SAL_CALL CNode::setNodeValue(const OUString& /*nodeValue*/) 967*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 968*b1cdbd2cSJim Jagielski { 969*b1cdbd2cSJim Jagielski // use specific node implememntation 970*b1cdbd2cSJim Jagielski // if we end up down here, something went wrong 971*b1cdbd2cSJim Jagielski DOMException e; 972*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_NO_MODIFICATION_ALLOWED_ERR; 973*b1cdbd2cSJim Jagielski throw e; 974*b1cdbd2cSJim Jagielski } 975*b1cdbd2cSJim Jagielski 976*b1cdbd2cSJim Jagielski /** 977*b1cdbd2cSJim Jagielski The namespace prefix of this node, or null if it is unspecified. 978*b1cdbd2cSJim Jagielski */ setPrefix(const OUString & prefix)979*b1cdbd2cSJim Jagielski void SAL_CALL CNode::setPrefix(const OUString& prefix) 980*b1cdbd2cSJim Jagielski throw (RuntimeException, DOMException) 981*b1cdbd2cSJim Jagielski { 982*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 983*b1cdbd2cSJim Jagielski 984*b1cdbd2cSJim Jagielski if ((0 == m_aNodePtr) || 985*b1cdbd2cSJim Jagielski ((m_aNodePtr->type != XML_ELEMENT_NODE) && 986*b1cdbd2cSJim Jagielski (m_aNodePtr->type != XML_ATTRIBUTE_NODE))) 987*b1cdbd2cSJim Jagielski { 988*b1cdbd2cSJim Jagielski DOMException e; 989*b1cdbd2cSJim Jagielski e.Code = DOMExceptionType_NO_MODIFICATION_ALLOWED_ERR; 990*b1cdbd2cSJim Jagielski throw e; 991*b1cdbd2cSJim Jagielski } 992*b1cdbd2cSJim Jagielski OString o1 = OUStringToOString(prefix, RTL_TEXTENCODING_UTF8); 993*b1cdbd2cSJim Jagielski xmlChar *pBuf = (xmlChar*)o1.getStr(); 994*b1cdbd2cSJim Jagielski if (m_aNodePtr != NULL && m_aNodePtr->ns != NULL) 995*b1cdbd2cSJim Jagielski { 996*b1cdbd2cSJim Jagielski xmlFree(const_cast<xmlChar *>(m_aNodePtr->ns->prefix)); 997*b1cdbd2cSJim Jagielski m_aNodePtr->ns->prefix = xmlStrdup(pBuf); 998*b1cdbd2cSJim Jagielski } 999*b1cdbd2cSJim Jagielski 1000*b1cdbd2cSJim Jagielski } 1001*b1cdbd2cSJim Jagielski 1002*b1cdbd2cSJim Jagielski // --- XEventTarget addEventListener(const OUString & eventType,const Reference<com::sun::star::xml::dom::events::XEventListener> & listener,sal_Bool useCapture)1003*b1cdbd2cSJim Jagielski void SAL_CALL CNode::addEventListener(const OUString& eventType, 1004*b1cdbd2cSJim Jagielski const Reference< com::sun::star::xml::dom::events::XEventListener >& listener, 1005*b1cdbd2cSJim Jagielski sal_Bool useCapture) 1006*b1cdbd2cSJim Jagielski throw (RuntimeException) 1007*b1cdbd2cSJim Jagielski { 1008*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 1009*b1cdbd2cSJim Jagielski 1010*b1cdbd2cSJim Jagielski CDocument & rDocument(GetOwnerDocument()); 1011*b1cdbd2cSJim Jagielski events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher()); 1012*b1cdbd2cSJim Jagielski rDispatcher.addListener(m_aNodePtr, eventType, listener, useCapture); 1013*b1cdbd2cSJim Jagielski } 1014*b1cdbd2cSJim Jagielski removeEventListener(const OUString & eventType,const Reference<com::sun::star::xml::dom::events::XEventListener> & listener,sal_Bool useCapture)1015*b1cdbd2cSJim Jagielski void SAL_CALL CNode::removeEventListener(const OUString& eventType, 1016*b1cdbd2cSJim Jagielski const Reference< com::sun::star::xml::dom::events::XEventListener >& listener, 1017*b1cdbd2cSJim Jagielski sal_Bool useCapture) 1018*b1cdbd2cSJim Jagielski throw (RuntimeException) 1019*b1cdbd2cSJim Jagielski { 1020*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 1021*b1cdbd2cSJim Jagielski 1022*b1cdbd2cSJim Jagielski CDocument & rDocument(GetOwnerDocument()); 1023*b1cdbd2cSJim Jagielski events::CEventDispatcher & rDispatcher(rDocument.GetEventDispatcher()); 1024*b1cdbd2cSJim Jagielski rDispatcher.removeListener(m_aNodePtr, eventType, listener, useCapture); 1025*b1cdbd2cSJim Jagielski } 1026*b1cdbd2cSJim Jagielski dispatchEvent(const Reference<XEvent> & evt)1027*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL CNode::dispatchEvent(const Reference< XEvent >& evt) 1028*b1cdbd2cSJim Jagielski throw(RuntimeException, EventException) 1029*b1cdbd2cSJim Jagielski { 1030*b1cdbd2cSJim Jagielski CDocument * pDocument; 1031*b1cdbd2cSJim Jagielski events::CEventDispatcher * pDispatcher; 1032*b1cdbd2cSJim Jagielski xmlNodePtr pNode; 1033*b1cdbd2cSJim Jagielski { 1034*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 1035*b1cdbd2cSJim Jagielski 1036*b1cdbd2cSJim Jagielski pDocument = & GetOwnerDocument(); 1037*b1cdbd2cSJim Jagielski pDispatcher = & pDocument->GetEventDispatcher(); 1038*b1cdbd2cSJim Jagielski pNode = m_aNodePtr; 1039*b1cdbd2cSJim Jagielski } 1040*b1cdbd2cSJim Jagielski // this calls event listeners, do not call with locked mutex 1041*b1cdbd2cSJim Jagielski pDispatcher->dispatchEvent(*pDocument, m_rMutex, pNode, this, evt); 1042*b1cdbd2cSJim Jagielski return sal_True; 1043*b1cdbd2cSJim Jagielski } 1044*b1cdbd2cSJim Jagielski 1045*b1cdbd2cSJim Jagielski ::sal_Int64 SAL_CALL getSomething(Sequence<::sal_Int8> const & rId)1046*b1cdbd2cSJim Jagielski CNode::getSomething(Sequence< ::sal_Int8 > const& rId) 1047*b1cdbd2cSJim Jagielski throw (RuntimeException) 1048*b1cdbd2cSJim Jagielski { 1049*b1cdbd2cSJim Jagielski if ((rId.getLength() == 16) && 1050*b1cdbd2cSJim Jagielski (0 == rtl_compareMemory(UnoTunnelId::get().getConstArray(), 1051*b1cdbd2cSJim Jagielski rId.getConstArray(), 16))) 1052*b1cdbd2cSJim Jagielski { 1053*b1cdbd2cSJim Jagielski return ::sal::static_int_cast< sal_Int64 >( 1054*b1cdbd2cSJim Jagielski reinterpret_cast< sal_IntPtr >(this) ); 1055*b1cdbd2cSJim Jagielski } 1056*b1cdbd2cSJim Jagielski return 0; 1057*b1cdbd2cSJim Jagielski } 1058*b1cdbd2cSJim Jagielski } 1059*b1cdbd2cSJim Jagielski 1060