LCOV - code coverage report
Current view: top level - unoxml/source/dom - element.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 384 0.0 %
Date: 2014-04-14 Functions: 0 26 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <element.hxx>
      21             : 
      22             : #include <string.h>
      23             : 
      24             : #include <boost/shared_ptr.hpp>
      25             : 
      26             : #include <rtl/ustrbuf.hxx>
      27             : 
      28             : #include <com/sun/star/xml/sax/FastToken.hpp>
      29             : 
      30             : #include <comphelper/attributelist.hxx>
      31             : 
      32             : #include <node.hxx>
      33             : #include <attr.hxx>
      34             : #include <elementlist.hxx>
      35             : #include <attributesmap.hxx>
      36             : #include <document.hxx>
      37             : 
      38             : #include "../events/mutationevent.hxx"
      39             : 
      40             : 
      41             : namespace DOM
      42             : {
      43             : 
      44           0 :     CElement::CElement(CDocument const& rDocument, ::osl::Mutex const& rMutex,
      45             :             xmlNodePtr const pNode)
      46           0 :         : CElement_Base(rDocument, rMutex, NodeType_ELEMENT_NODE, pNode)
      47             :     {
      48           0 :     }
      49             : 
      50           0 :     void CElement::saxify(const Reference< XDocumentHandler >& i_xHandler)
      51             :     {
      52           0 :         if (!i_xHandler.is()) throw RuntimeException();
      53             :         comphelper::AttributeList *pAttrs =
      54           0 :             new comphelper::AttributeList();
      55           0 :         OUString type = "";
      56             :         // add namespace definitions to attributes
      57           0 :         for (xmlNsPtr pNs = m_aNodePtr->nsDef; pNs != 0; pNs = pNs->next) {
      58           0 :             const xmlChar *pPrefix = pNs->prefix ? pNs->prefix : (const xmlChar*)"";
      59             :             OUString prefix(reinterpret_cast<const sal_Char*>(pPrefix),
      60           0 :                 strlen(reinterpret_cast<const char*>(pPrefix)),
      61           0 :                 RTL_TEXTENCODING_UTF8);
      62           0 :             OUString name = (prefix.isEmpty())
      63           0 :                 ? OUString( "xmlns" ) : OUString( "xmlns:" ) + prefix;
      64           0 :             const xmlChar *pHref = pNs->href;
      65             :             OUString val(reinterpret_cast<const sal_Char*>(pHref),
      66           0 :                 strlen(reinterpret_cast<const char*>(pHref)),
      67           0 :                 RTL_TEXTENCODING_UTF8);
      68           0 :             pAttrs->AddAttribute(name, type, val);
      69           0 :         }
      70             :         // add attributes
      71           0 :         for (xmlAttrPtr pAttr = m_aNodePtr->properties;
      72             :                         pAttr != 0; pAttr = pAttr->next) {
      73           0 :             ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
      74           0 :                     reinterpret_cast<xmlNodePtr>(pAttr));
      75             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
      76           0 :             OUString prefix = pNode->getPrefix();
      77           0 :             OUString name = (prefix.isEmpty())
      78           0 :                 ? pNode->getLocalName()
      79           0 :                 : prefix + OUString(':') + pNode->getLocalName();
      80           0 :             OUString val  = pNode->getNodeValue();
      81           0 :             pAttrs->AddAttribute(name, type, val);
      82           0 :         }
      83           0 :         OUString prefix = getPrefix();
      84           0 :         OUString name = (prefix.isEmpty())
      85           0 :             ? getLocalName()
      86           0 :             : prefix + OUString(':') + getLocalName();
      87           0 :         Reference< XAttributeList > xAttrList(pAttrs);
      88           0 :         i_xHandler->startElement(name, xAttrList);
      89             :         // recurse
      90           0 :         for (xmlNodePtr pChild = m_aNodePtr->children;
      91             :                         pChild != 0; pChild = pChild->next) {
      92             :             ::rtl::Reference<CNode> const pNode(
      93           0 :                     GetOwnerDocument().GetCNode(pChild));
      94             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
      95           0 :             pNode->saxify(i_xHandler);
      96           0 :         }
      97           0 :         i_xHandler->endElement(name);
      98           0 :     }
      99             : 
     100           0 :     void CElement::fastSaxify( Context& i_rContext )
     101             :     {
     102           0 :         if (!i_rContext.mxDocHandler.is()) throw RuntimeException();
     103           0 :         pushContext(i_rContext);
     104           0 :         addNamespaces(i_rContext,m_aNodePtr);
     105             : 
     106             :         // add attributes
     107           0 :         i_rContext.mxAttribList->clear();
     108           0 :         for (xmlAttrPtr pAttr = m_aNodePtr->properties;
     109             :                         pAttr != 0; pAttr = pAttr->next) {
     110           0 :             ::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(
     111           0 :                     reinterpret_cast<xmlNodePtr>(pAttr));
     112             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     113             : 
     114           0 :             const xmlChar* xName = pAttr->name;
     115           0 :             sal_Int32 nAttributeToken=FastToken::DONTKNOW;
     116             : 
     117           0 :             if( pAttr->ns && strlen((char*)pAttr->ns->prefix) )
     118             :                 nAttributeToken = getTokenWithPrefix( i_rContext,
     119             :                                                       (sal_Char*)pAttr->ns->prefix,
     120           0 :                                                       (sal_Char*)xName );
     121             :             else
     122           0 :                 nAttributeToken = getToken( i_rContext, (sal_Char*)xName );
     123             : 
     124           0 :             if( nAttributeToken != FastToken::DONTKNOW )
     125             :                 i_rContext.mxAttribList->add( nAttributeToken,
     126           0 :                                               OUStringToOString(pNode->getNodeValue(),
     127           0 :                                                                 RTL_TEXTENCODING_UTF8));
     128           0 :         }
     129             : 
     130           0 :         const xmlChar* xPrefix = m_aNodePtr->ns ? m_aNodePtr->ns->prefix : (const xmlChar*)"";
     131           0 :         const xmlChar* xName = m_aNodePtr->name;
     132           0 :         sal_Int32 nElementToken=FastToken::DONTKNOW;
     133           0 :         if( strlen((char*)xPrefix) )
     134           0 :             nElementToken = getTokenWithPrefix( i_rContext, (sal_Char*)xPrefix, (sal_Char*)xName );
     135             :         else
     136           0 :             nElementToken = getToken( i_rContext, (sal_Char*)xName );
     137             : 
     138           0 :         Reference<XFastContextHandler> xParentHandler(i_rContext.mxCurrentHandler);
     139             :         try
     140             :         {
     141           0 :             Reference< XFastAttributeList > xAttr( i_rContext.mxAttribList.get() );
     142           0 :             if( nElementToken == FastToken::DONTKNOW )
     143             :             {
     144           0 :                 const OUString aNamespace;
     145             :                 const OUString aElementName( (sal_Char*)xPrefix,
     146           0 :                                              strlen((char*)xPrefix),
     147           0 :                                              RTL_TEXTENCODING_UTF8 );
     148             : 
     149           0 :                 if( xParentHandler.is() )
     150           0 :                     i_rContext.mxCurrentHandler = xParentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
     151             :                 else
     152           0 :                     i_rContext.mxCurrentHandler = i_rContext.mxDocHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );
     153             : 
     154           0 :                 if( i_rContext.mxCurrentHandler.is() )
     155           0 :                     i_rContext.mxCurrentHandler->startUnknownElement( aNamespace, aElementName, xAttr );
     156             :             }
     157             :             else
     158             :             {
     159           0 :                 if( xParentHandler.is() )
     160           0 :                     i_rContext.mxCurrentHandler = xParentHandler->createFastChildContext( nElementToken, xAttr );
     161             :                 else
     162           0 :                     i_rContext.mxCurrentHandler = i_rContext.mxDocHandler->createFastChildContext( nElementToken, xAttr );
     163             : 
     164           0 :                 if( i_rContext.mxCurrentHandler.is() )
     165           0 :                     i_rContext.mxCurrentHandler->startFastElement( nElementToken, xAttr );
     166           0 :             }
     167             :         }
     168           0 :         catch( Exception& )
     169             :         {}
     170             : 
     171             :         // recurse
     172           0 :         for (xmlNodePtr pChild = m_aNodePtr->children;
     173             :                         pChild != 0; pChild = pChild->next) {
     174             :             ::rtl::Reference<CNode> const pNode(
     175           0 :                     GetOwnerDocument().GetCNode(pChild));
     176             :             OSL_ENSURE(pNode != 0, "CNode::get returned 0");
     177           0 :             pNode->fastSaxify(i_rContext);
     178           0 :         }
     179             : 
     180           0 :         if( i_rContext.mxCurrentHandler.is() ) try
     181             :         {
     182           0 :             if( nElementToken != FastToken::DONTKNOW )
     183           0 :                 i_rContext.mxCurrentHandler->endFastElement( nElementToken );
     184             :             else
     185             :             {
     186           0 :                 const OUString aNamespace;
     187             :                 const OUString aElementName( (sal_Char*)xPrefix,
     188           0 :                                              strlen((char*)xPrefix),
     189           0 :                                              RTL_TEXTENCODING_UTF8 );
     190             : 
     191           0 :                 i_rContext.mxCurrentHandler->endUnknownElement( aNamespace, aElementName );
     192             :             }
     193             :         }
     194           0 :         catch( Exception& )
     195             :         {}
     196             : 
     197             :         // restore after children have been processed
     198           0 :         i_rContext.mxCurrentHandler = xParentHandler;
     199           0 :         popContext(i_rContext);
     200           0 :     }
     201             : 
     202           0 :     bool CElement::IsChildTypeAllowed(NodeType const nodeType)
     203             :     {
     204           0 :         switch (nodeType) {
     205             :             case NodeType_ELEMENT_NODE:
     206             :             case NodeType_TEXT_NODE:
     207             :             case NodeType_COMMENT_NODE:
     208             :             case NodeType_PROCESSING_INSTRUCTION_NODE:
     209             :             case NodeType_CDATA_SECTION_NODE:
     210             :             case NodeType_ENTITY_REFERENCE_NODE:
     211           0 :                 return true;
     212             :             case NodeType_ATTRIBUTE_NODE:
     213             :                 /* this is not relly allowed by the DOM spec, but this
     214             :                    implementation has evidently supported it (by special case
     215             :                    handling, so the attribute does not actually become a child)
     216             :                    so allow it for backward compatiblity */
     217           0 :                 return true;
     218             :             default:
     219           0 :                 return false;
     220             :         }
     221             :     }
     222             : 
     223             : 
     224             :     /**
     225             :         Retrieves an attribute value by name.
     226             :         return empty string if attribute is not set
     227             :     */
     228           0 :     OUString SAL_CALL CElement::getAttribute(OUString const& name)
     229             :         throw (RuntimeException, std::exception)
     230             :     {
     231           0 :         ::osl::MutexGuard const g(m_rMutex);
     232             : 
     233           0 :         if (0 == m_aNodePtr) {
     234           0 :             return OUString();
     235             :         }
     236             :         // search properties
     237           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     238             :         ::boost::shared_ptr<xmlChar const> const pValue(
     239           0 :             xmlGetProp(m_aNodePtr, (xmlChar*)o1.getStr()), xmlFree);
     240             :         OUString const ret( (pValue)
     241           0 :             ?   OUString(reinterpret_cast<sal_Char const*>(pValue.get()),
     242           0 :                         strlen(reinterpret_cast<char const*>(pValue.get())),
     243             :                         RTL_TEXTENCODING_UTF8)
     244           0 :             :   OUString() );
     245           0 :         return ret;
     246             :     }
     247             : 
     248             :     /**
     249             :     Retrieves an attribute node by name.
     250             :     */
     251           0 :     Reference< XAttr > SAL_CALL CElement::getAttributeNode(OUString const& name)
     252             :         throw (RuntimeException, std::exception)
     253             :     {
     254           0 :         ::osl::MutexGuard const g(m_rMutex);
     255             : 
     256           0 :         if (0 == m_aNodePtr) {
     257           0 :             return 0;
     258             :         }
     259           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     260             :         xmlChar const*const pName =
     261           0 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     262           0 :         xmlAttrPtr const pAttr = xmlHasProp(m_aNodePtr, pName);
     263           0 :         if (0 == pAttr) {
     264           0 :             return 0;
     265             :         }
     266             :         Reference< XAttr > const xRet(
     267           0 :             static_cast< XNode* >(GetOwnerDocument().GetCNode(
     268           0 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()),
     269           0 :             UNO_QUERY_THROW);
     270           0 :         return xRet;
     271             :     }
     272             : 
     273             :     /**
     274             :     Retrieves an Attr node by local name and namespace URI.
     275             :     */
     276           0 :     Reference< XAttr > SAL_CALL CElement::getAttributeNodeNS(
     277             :             const OUString& namespaceURI, const OUString& localName)
     278             :         throw (RuntimeException, std::exception)
     279             :     {
     280           0 :         ::osl::MutexGuard const g(m_rMutex);
     281             : 
     282           0 :         if (0 == m_aNodePtr) {
     283           0 :             return 0;
     284             :         }
     285           0 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     286             :         xmlChar const*const pName =
     287           0 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     288           0 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     289             :         xmlChar const*const pNS =
     290           0 :             reinterpret_cast<xmlChar const*>(o2.getStr());
     291           0 :         xmlAttrPtr const pAttr = xmlHasNsProp(m_aNodePtr, pName, pNS);
     292           0 :         if (0 == pAttr) {
     293           0 :             return 0;
     294             :         }
     295             :         Reference< XAttr > const xRet(
     296           0 :             static_cast< XNode* >(GetOwnerDocument().GetCNode(
     297           0 :                     reinterpret_cast<xmlNodePtr>(pAttr)).get()),
     298           0 :             UNO_QUERY_THROW);
     299           0 :         return xRet;
     300             :     }
     301             : 
     302             :     /**
     303             :     Retrieves an attribute value by local name and namespace URI.
     304             :     return empty string if attribute is not set
     305             :     */
     306             :     OUString SAL_CALL
     307           0 :     CElement::getAttributeNS(
     308             :             OUString const& namespaceURI, OUString const& localName)
     309             :         throw (RuntimeException, std::exception)
     310             :     {
     311           0 :         ::osl::MutexGuard const g(m_rMutex);
     312             : 
     313           0 :         if (0 == m_aNodePtr) {
     314           0 :             return OUString();
     315             :         }
     316           0 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     317             :         xmlChar const*const pName =
     318           0 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     319           0 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     320             :         xmlChar const*const pNS =
     321           0 :             reinterpret_cast<xmlChar const*>(o2.getStr());
     322             :         ::boost::shared_ptr<xmlChar const> const pValue(
     323           0 :                 xmlGetNsProp(m_aNodePtr, pName, pNS), xmlFree);
     324           0 :         if (0 == pValue) {
     325           0 :             return OUString();
     326             :         }
     327           0 :         OUString const ret(reinterpret_cast<sal_Char const*>(pValue.get()),
     328           0 :                         strlen(reinterpret_cast<char const*>(pValue.get())),
     329           0 :                         RTL_TEXTENCODING_UTF8);
     330           0 :         return ret;
     331             :     }
     332             : 
     333             :     /**
     334             :     Returns a NodeList of all descendant Elements with a given tag name,
     335             :     in the order in which they are
     336             :     encountered in a preorder traversal of this Element tree.
     337             :     */
     338             :     Reference< XNodeList > SAL_CALL
     339           0 :     CElement::getElementsByTagName(OUString const& rLocalName)
     340             :         throw (RuntimeException, std::exception)
     341             :     {
     342           0 :         ::osl::MutexGuard const g(m_rMutex);
     343             : 
     344             :         Reference< XNodeList > const xList(
     345           0 :                 new CElementList(this, m_rMutex, rLocalName));
     346           0 :         return xList;
     347             :     }
     348             : 
     349             :     /**
     350             :     Returns a NodeList of all the descendant Elements with a given local
     351             :     name and namespace URI in the order in which they are encountered in
     352             :     a preorder traversal of this Element tree.
     353             :     */
     354             :     Reference< XNodeList > SAL_CALL
     355           0 :     CElement::getElementsByTagNameNS(
     356             :             OUString const& rNamespaceURI, OUString const& rLocalName)
     357             :         throw (RuntimeException, std::exception)
     358             :     {
     359           0 :         ::osl::MutexGuard const g(m_rMutex);
     360             : 
     361             :         Reference< XNodeList > const xList(
     362           0 :             new CElementList(this, m_rMutex, rLocalName, &rNamespaceURI));
     363           0 :         return xList;
     364             :     }
     365             : 
     366             :     /**
     367             :     The name of the element.
     368             :     */
     369           0 :     OUString SAL_CALL CElement::getTagName()
     370             :         throw (RuntimeException, std::exception)
     371             :     {
     372           0 :         ::osl::MutexGuard const g(m_rMutex);
     373             : 
     374           0 :         if (0 == m_aNodePtr) {
     375           0 :             return OUString();
     376             :         }
     377             :         OUString const ret((sal_Char*)m_aNodePtr->name,
     378           0 :                 strlen((char*)m_aNodePtr->name), RTL_TEXTENCODING_UTF8);
     379           0 :         return ret;
     380             :     }
     381             : 
     382             : 
     383             :     /**
     384             :     Returns true when an attribute with a given name is specified on this
     385             :     element or has a default value, false otherwise.
     386             :     */
     387           0 :     sal_Bool SAL_CALL CElement::hasAttribute(OUString const& name)
     388             :         throw (RuntimeException, std::exception)
     389             :     {
     390           0 :         ::osl::MutexGuard const g(m_rMutex);
     391             : 
     392           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     393           0 :         xmlChar *xName = (xmlChar*)o1.getStr();
     394           0 :         return (m_aNodePtr != NULL && xmlHasProp(m_aNodePtr, xName) != NULL);
     395             :     }
     396             : 
     397             :     /**
     398             :     Returns true when an attribute with a given local name and namespace
     399             :     URI is specified on this element or has a default value, false otherwise.
     400             :     */
     401           0 :     sal_Bool SAL_CALL CElement::hasAttributeNS(
     402             :             OUString const& namespaceURI, OUString const& localName)
     403             :         throw (RuntimeException, std::exception)
     404             :     {
     405           0 :         ::osl::MutexGuard const g(m_rMutex);
     406             : 
     407           0 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     408           0 :         xmlChar *xName = (xmlChar*)o1.getStr();
     409           0 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     410           0 :         xmlChar *xNs = (xmlChar*)o2.getStr();
     411           0 :         return (m_aNodePtr != NULL && xmlHasNsProp(m_aNodePtr, xName, xNs) != NULL);
     412             :     }
     413             : 
     414             :     /**
     415             :     Removes an attribute by name.
     416             :     */
     417           0 :     void SAL_CALL CElement::removeAttribute(OUString const& name)
     418             :         throw (RuntimeException, DOMException, std::exception)
     419             :     {
     420           0 :         ::osl::MutexGuard const g(m_rMutex);
     421             : 
     422           0 :         if (0 == m_aNodePtr) {
     423           0 :             return;
     424             :         }
     425           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     426             :         xmlChar const*const pName =
     427           0 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     428           0 :         xmlAttrPtr const pAttr = xmlHasProp(m_aNodePtr, pName);
     429           0 :         if (0 == xmlUnsetProp(m_aNodePtr, pName)) {
     430           0 :             ::rtl::Reference<CNode> const pCNode(GetOwnerDocument().GetCNode(
     431           0 :                     reinterpret_cast<xmlNodePtr>(pAttr), false));
     432           0 :             if (pCNode.is()) {
     433           0 :                 pCNode->invalidate(); // freed by xmlUnsetProp
     434           0 :             }
     435           0 :         }
     436             :     }
     437             : 
     438             :     /**
     439             :     Removes an attribute by local name and namespace URI.
     440             :     */
     441           0 :     void SAL_CALL CElement::removeAttributeNS(
     442             :             OUString const& namespaceURI, OUString const& localName)
     443             :         throw (RuntimeException, DOMException, std::exception)
     444             :     {
     445           0 :         ::osl::MutexGuard const g(m_rMutex);
     446             : 
     447           0 :         if (0 == m_aNodePtr) {
     448           0 :             return;
     449             :         }
     450           0 :         OString o1 = OUStringToOString(localName, RTL_TEXTENCODING_UTF8);
     451             :         xmlChar const*const pName =
     452           0 :             reinterpret_cast<xmlChar const*>(o1.getStr());
     453           0 :         OString o2 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     454             :         xmlChar const*const pURI =
     455           0 :             reinterpret_cast<xmlChar const*>(o2.getStr());
     456             :         xmlNsPtr const pNs =
     457           0 :             xmlSearchNsByHref(m_aNodePtr->doc, m_aNodePtr, pURI);
     458           0 :         xmlAttrPtr const pAttr = xmlHasNsProp(m_aNodePtr, pName, pURI);
     459           0 :         if (0 == xmlUnsetNsProp(m_aNodePtr, pNs, pName)) {
     460           0 :             ::rtl::Reference<CNode> const pCNode(GetOwnerDocument().GetCNode(
     461           0 :                     reinterpret_cast<xmlNodePtr>(pAttr), false));
     462           0 :             if (pCNode.is()) {
     463           0 :                 pCNode->invalidate(); // freed by xmlUnsetNsProp
     464           0 :             }
     465           0 :         }
     466             :     }
     467             : 
     468             :     /**
     469             :     Removes the specified attribute node.
     470             :     */
     471             :     Reference< XAttr > SAL_CALL
     472           0 :     CElement::removeAttributeNode(Reference< XAttr > const& oldAttr)
     473             :         throw (RuntimeException, DOMException, std::exception)
     474             :     {
     475           0 :         ::osl::MutexGuard const g(m_rMutex);
     476             : 
     477           0 :         if (0 == m_aNodePtr) {
     478           0 :             return 0;
     479             :         }
     480             : 
     481             :         ::rtl::Reference<CNode> const pCNode(
     482           0 :             CNode::GetImplementation(Reference<XNode>(oldAttr.get())));
     483           0 :         if (!pCNode.is()) { throw RuntimeException(); }
     484             : 
     485           0 :         xmlNodePtr const pNode = pCNode->GetNodePtr();
     486           0 :         xmlAttrPtr const pAttr = (xmlAttrPtr) pNode;
     487           0 :         if (!pAttr) { throw RuntimeException(); }
     488             : 
     489           0 :         if (pAttr->parent != m_aNodePtr)
     490             :         {
     491           0 :             DOMException e;
     492           0 :             e.Code = DOMExceptionType_HIERARCHY_REQUEST_ERR;
     493           0 :             throw e;
     494             :         }
     495           0 :         if (pAttr->doc != m_aNodePtr->doc)
     496             :         {
     497           0 :             DOMException e;
     498           0 :             e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
     499           0 :             throw e;
     500             :         }
     501             : 
     502           0 :         Reference< XAttr > aAttr;
     503           0 :         if (!oldAttr->getNamespaceURI().isEmpty()) {
     504           0 :             OUStringBuffer qname(oldAttr->getPrefix());
     505           0 :             if (!qname.isEmpty()) {
     506           0 :                 qname.append(':');
     507             :             }
     508           0 :             qname.append(oldAttr->getName());
     509           0 :             aAttr = GetOwnerDocument().createAttributeNS(
     510           0 :                 oldAttr->getNamespaceURI(), qname.makeStringAndClear());
     511             :         } else {
     512           0 :             aAttr = GetOwnerDocument().createAttribute(oldAttr->getName());
     513             :         }
     514           0 :         aAttr->setValue(oldAttr->getValue());
     515           0 :         xmlRemoveProp(pAttr);
     516           0 :         pCNode->invalidate(); // freed by xmlRemoveProp
     517             : 
     518           0 :         return aAttr;
     519             :     }
     520             : 
     521             :     /**
     522             :     Adds a new attribute node.
     523             :     */
     524             :     Reference< XAttr >
     525           0 :     CElement::setAttributeNode_Impl_Lock(
     526             :             Reference< XAttr > const& xNewAttr, bool const bNS)
     527             :     {
     528           0 :         if (xNewAttr->getOwnerDocument() != getOwnerDocument()) {
     529           0 :             DOMException e;
     530           0 :             e.Code = DOMExceptionType_WRONG_DOCUMENT_ERR;
     531           0 :             throw e;
     532             :         }
     533             : 
     534           0 :         ::osl::ClearableMutexGuard guard(m_rMutex);
     535             : 
     536           0 :         if (0 == m_aNodePtr) {
     537           0 :             throw RuntimeException();
     538             :         }
     539             : 
     540             :         // get the implementation
     541             :         CAttr *const pCAttr = dynamic_cast<CAttr*>(
     542           0 :                 CNode::GetImplementation(xNewAttr));
     543           0 :         if (!pCAttr) { throw RuntimeException(); }
     544             :         xmlAttrPtr const pAttr =
     545           0 :             reinterpret_cast<xmlAttrPtr>(pCAttr->GetNodePtr());
     546           0 :         if (!pAttr) { throw RuntimeException(); }
     547             : 
     548             :         // check whether the attribute is not in use by another element
     549           0 :         if (pAttr->parent) {
     550           0 :             DOMException e;
     551           0 :             e.Code = DOMExceptionType_INUSE_ATTRIBUTE_ERR;
     552           0 :             throw e;
     553             :         }
     554             : 
     555           0 :         xmlAttrPtr res = NULL;
     556             :         xmlChar const*const pContent(
     557           0 :                 (pAttr->children) ? pAttr->children->content : 0);
     558             : 
     559           0 :         if (bNS) {
     560           0 :             xmlNsPtr const pNs( pCAttr->GetNamespace(m_aNodePtr) );
     561           0 :             res = xmlNewNsProp(m_aNodePtr, pNs, pAttr->name, pContent);
     562             :         } else {
     563           0 :             res = xmlNewProp(m_aNodePtr, pAttr->name, pContent);
     564             :         }
     565             : 
     566             :         // get the new attr node
     567             :         Reference< XAttr > const xAttr(
     568           0 :             static_cast< XNode* >(GetOwnerDocument().GetCNode(
     569           0 :                     reinterpret_cast<xmlNodePtr>(res)).get()),
     570           0 :             UNO_QUERY_THROW);
     571             : 
     572             :         // attribute addition event
     573             :         // dispatch DOMAttrModified event
     574           0 :         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
     575           0 :         Reference< XMutationEvent > event(docevent->createEvent(
     576           0 :             "DOMAttrModified"), UNO_QUERY);
     577           0 :         event->initMutationEvent("DOMAttrModified",
     578             :             sal_True, sal_False, xAttr,
     579           0 :             OUString(), xAttr->getValue(), xAttr->getName(),
     580           0 :             AttrChangeType_ADDITION);
     581             : 
     582           0 :         guard.clear(); // release mutex before calling event handlers
     583             : 
     584           0 :         dispatchEvent(event);
     585           0 :         dispatchSubtreeModified();
     586             : 
     587           0 :         return xAttr;
     588             :     }
     589             : 
     590             :     Reference< XAttr >
     591           0 :     CElement::setAttributeNode(const Reference< XAttr >& newAttr)
     592             :         throw (RuntimeException, DOMException, std::exception)
     593             :     {
     594           0 :         return setAttributeNode_Impl_Lock(newAttr, false);
     595             :     }
     596             : 
     597             :     /**
     598             :     Adds a new attribute.
     599             :     */
     600             :     Reference< XAttr >
     601           0 :     CElement::setAttributeNodeNS(const Reference< XAttr >& newAttr)
     602             :         throw (RuntimeException, DOMException, std::exception)
     603             :     {
     604           0 :         return setAttributeNode_Impl_Lock(newAttr, true);
     605             :     }
     606             : 
     607             :     /**
     608             :     Adds a new attribute.
     609             :     */
     610             :     void SAL_CALL
     611           0 :     CElement::setAttribute(OUString const& name, OUString const& value)
     612             :         throw (RuntimeException, DOMException, std::exception)
     613             :     {
     614           0 :         ::osl::ClearableMutexGuard guard(m_rMutex);
     615             : 
     616           0 :         OString o1 = OUStringToOString(name, RTL_TEXTENCODING_UTF8);
     617           0 :         xmlChar *xName = (xmlChar*)o1.getStr();
     618           0 :         OString o2 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
     619           0 :         xmlChar *xValue = (xmlChar*)o2.getStr();
     620             : 
     621           0 :         if (0 == m_aNodePtr) {
     622           0 :             throw RuntimeException();
     623             :         }
     624           0 :         OUString oldValue;
     625           0 :         AttrChangeType aChangeType = AttrChangeType_MODIFICATION;
     626             :         ::boost::shared_ptr<xmlChar const> const pOld(
     627           0 :             xmlGetProp(m_aNodePtr, xName), xmlFree);
     628           0 :         if (pOld == 0) {
     629           0 :             aChangeType = AttrChangeType_ADDITION;
     630           0 :             xmlNewProp(m_aNodePtr, xName, xValue);
     631             :         } else {
     632           0 :             oldValue = OUString(reinterpret_cast<sal_Char const*>(pOld.get()),
     633           0 :                         strlen(reinterpret_cast<char const*>(pOld.get())),
     634           0 :                         RTL_TEXTENCODING_UTF8);
     635           0 :             xmlSetProp(m_aNodePtr, xName, xValue);
     636             :         }
     637             : 
     638             :         // dispatch DOMAttrModified event
     639           0 :         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
     640           0 :         Reference< XMutationEvent > event(docevent->createEvent(
     641           0 :             "DOMAttrModified"), UNO_QUERY);
     642           0 :         event->initMutationEvent("DOMAttrModified",
     643             :             sal_True, sal_False,
     644           0 :             Reference< XNode >(getAttributeNode(name), UNO_QUERY),
     645           0 :             oldValue, value, name, aChangeType);
     646             : 
     647           0 :         guard.clear(); // release mutex before calling event handlers
     648           0 :         dispatchEvent(event);
     649           0 :         dispatchSubtreeModified();
     650           0 :     }
     651             : 
     652             :     /**
     653             :     Adds a new attribute.
     654             :     */
     655             :     void SAL_CALL
     656           0 :     CElement::setAttributeNS(OUString const& namespaceURI,
     657             :             OUString const& qualifiedName, OUString const& value)
     658             :         throw (RuntimeException, DOMException, std::exception)
     659             :     {
     660           0 :         if (namespaceURI.isEmpty()) throw RuntimeException();
     661             : 
     662           0 :         ::osl::ClearableMutexGuard guard(m_rMutex);
     663             : 
     664           0 :         OString o1, o2, o3, o4, o5;
     665           0 :         xmlChar *xPrefix = NULL;
     666           0 :         xmlChar *xLName = NULL;
     667           0 :         o1 = OUStringToOString(qualifiedName, RTL_TEXTENCODING_UTF8);
     668           0 :         xmlChar *xQName = (xmlChar*)o1.getStr();
     669           0 :         sal_Int32 idx = qualifiedName.indexOf(':');
     670           0 :         if (idx != -1)
     671             :         {
     672           0 :             o2 = OUStringToOString(
     673             :                 qualifiedName.copy(0,idx),
     674           0 :                 RTL_TEXTENCODING_UTF8);
     675           0 :             xPrefix = (xmlChar*)o2.getStr();
     676           0 :             o3 = OUStringToOString(
     677             :                 qualifiedName.copy(idx+1),
     678           0 :                 RTL_TEXTENCODING_UTF8);
     679           0 :             xLName = (xmlChar*)o3.getStr();
     680             :         }  else {
     681           0 :             xPrefix = (xmlChar*)"";
     682           0 :             xLName = xQName;
     683             :         }
     684           0 :         o4 = OUStringToOString(namespaceURI, RTL_TEXTENCODING_UTF8);
     685           0 :         o5 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
     686           0 :         xmlChar *xURI= (xmlChar*)o4.getStr();
     687           0 :         xmlChar *xValue = (xmlChar*)o5.getStr();
     688             : 
     689           0 :         if (0 == m_aNodePtr) {
     690           0 :             throw RuntimeException();
     691             :         }
     692             : 
     693             :         //find the right namespace
     694           0 :         xmlNsPtr pNs = xmlSearchNs(m_aNodePtr->doc, m_aNodePtr, xPrefix);
     695             :         // if no namespace found, create a new one
     696           0 :         if (pNs == NULL) {
     697           0 :             pNs = xmlNewNs(m_aNodePtr, xURI, xPrefix);
     698             :         }
     699             : 
     700           0 :         if (strcmp((char*)pNs->href, (char*)xURI) != 0) {
     701             :             // ambiguous ns prefix
     702           0 :             throw RuntimeException();
     703             :         }
     704             : 
     705             :         // found namespace matches
     706             : 
     707           0 :         OUString oldValue;
     708           0 :         AttrChangeType aChangeType = AttrChangeType_MODIFICATION;
     709             :         ::boost::shared_ptr<xmlChar const> const pOld(
     710           0 :                 xmlGetNsProp(m_aNodePtr, xLName, pNs->href), xmlFree);
     711           0 :         if (pOld == 0) {
     712           0 :             aChangeType = AttrChangeType_ADDITION;
     713           0 :             xmlNewNsProp(m_aNodePtr, pNs, xLName, xValue);
     714             :         } else {
     715           0 :             oldValue = OUString(reinterpret_cast<sal_Char const*>(pOld.get()),
     716           0 :                         strlen(reinterpret_cast<char const*>(pOld.get())),
     717           0 :                         RTL_TEXTENCODING_UTF8);
     718           0 :             xmlSetNsProp(m_aNodePtr, pNs, xLName, xValue);
     719             :         }
     720             :         // dispatch DOMAttrModified event
     721           0 :         Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
     722           0 :         Reference< XMutationEvent > event(docevent->createEvent(
     723           0 :             "DOMAttrModified"), UNO_QUERY);
     724           0 :         event->initMutationEvent(
     725             :             "DOMAttrModified", sal_True, sal_False,
     726           0 :             Reference< XNode >(getAttributeNodeNS(namespaceURI, OUString((char*)xLName, strlen((char*)xLName), RTL_TEXTENCODING_UTF8)), UNO_QUERY),
     727           0 :             oldValue, value, qualifiedName, aChangeType);
     728             : 
     729           0 :         guard.clear(); // release mutex before calling event handlers
     730           0 :         dispatchEvent(event);
     731           0 :         dispatchSubtreeModified();
     732           0 :     }
     733             : 
     734             :     Reference< XNamedNodeMap > SAL_CALL
     735           0 :     CElement::getAttributes() throw (RuntimeException, std::exception)
     736             :     {
     737           0 :         ::osl::MutexGuard const g(m_rMutex);
     738             : 
     739             :         Reference< XNamedNodeMap > const xMap(
     740           0 :                 new CAttributesMap(this, m_rMutex));
     741           0 :         return xMap;
     742             :     }
     743             : 
     744           0 :     OUString SAL_CALL CElement::getNodeName()throw (RuntimeException, std::exception)
     745             :     {
     746           0 :         return getLocalName();
     747             :     }
     748             : 
     749           0 :     OUString SAL_CALL CElement::getLocalName()throw (RuntimeException, std::exception)
     750             :     {
     751           0 :         ::osl::MutexGuard const g(m_rMutex);
     752             : 
     753           0 :         OUString aName;
     754           0 :         if (m_aNodePtr != NULL)
     755             :         {
     756           0 :             const xmlChar* xName = m_aNodePtr->name;
     757           0 :             aName = OUString((const sal_Char*)xName, strlen((const char*)xName), RTL_TEXTENCODING_UTF8);
     758             :         }
     759           0 :         return aName;
     760             :     }
     761             : 
     762           0 :     OUString SAL_CALL CElement::getNodeValue() throw (RuntimeException, std::exception)
     763             :     {
     764           0 :         return OUString();
     765             :     }
     766             : 
     767           0 :     void SAL_CALL CElement::setElementName(const OUString& aName)
     768             :         throw (RuntimeException, DOMException)
     769             :     {
     770           0 :         if (aName.isEmpty() || (0 <= aName.indexOf(':')))
     771             :         {
     772           0 :             DOMException e;
     773           0 :             e.Code = DOMExceptionType_INVALID_CHARACTER_ERR;
     774           0 :             throw e;
     775             :         }
     776             : 
     777           0 :         ::osl::MutexGuard const g(m_rMutex);
     778             : 
     779           0 :         if (0 == m_aNodePtr) {
     780           0 :             throw RuntimeException();
     781             :         }
     782           0 :         OString oName = OUStringToOString(aName, RTL_TEXTENCODING_UTF8);
     783           0 :         xmlChar *xName = (xmlChar*)oName.getStr();
     784           0 :         xmlNodeSetName(m_aNodePtr, xName);
     785           0 :     }
     786             : 
     787             : }
     788             : 
     789             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10