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 "elementlist.hxx" 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski #include <string.h> 27*b1cdbd2cSJim Jagielski 28*b1cdbd2cSJim Jagielski #include <element.hxx> 29*b1cdbd2cSJim Jagielski #include <document.hxx> 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski 32*b1cdbd2cSJim Jagielski namespace DOM 33*b1cdbd2cSJim Jagielski { 34*b1cdbd2cSJim Jagielski lcl_initXmlString(::rtl::OUString const & rString)35*b1cdbd2cSJim Jagielski static xmlChar* lcl_initXmlString(::rtl::OUString const& rString) 36*b1cdbd2cSJim Jagielski { 37*b1cdbd2cSJim Jagielski ::rtl::OString const os = 38*b1cdbd2cSJim Jagielski ::rtl::OUStringToOString(rString, RTL_TEXTENCODING_UTF8); 39*b1cdbd2cSJim Jagielski xmlChar *const pRet = new xmlChar[os.getLength() + 1]; 40*b1cdbd2cSJim Jagielski strcpy(reinterpret_cast<char*>(pRet), os.getStr()); 41*b1cdbd2cSJim Jagielski return pRet; 42*b1cdbd2cSJim Jagielski } 43*b1cdbd2cSJim Jagielski CElementList(::rtl::Reference<CElement> const & pElement,::osl::Mutex & rMutex,OUString const & rName,OUString const * const pURI)44*b1cdbd2cSJim Jagielski CElementList::CElementList(::rtl::Reference<CElement> const& pElement, 45*b1cdbd2cSJim Jagielski ::osl::Mutex & rMutex, 46*b1cdbd2cSJim Jagielski OUString const& rName, OUString const*const pURI) 47*b1cdbd2cSJim Jagielski : m_pElement(pElement) 48*b1cdbd2cSJim Jagielski , m_rMutex(rMutex) 49*b1cdbd2cSJim Jagielski , m_pName(lcl_initXmlString(rName)) 50*b1cdbd2cSJim Jagielski , m_pURI((pURI) ? lcl_initXmlString(*pURI) : 0) 51*b1cdbd2cSJim Jagielski , m_bRebuild(true) 52*b1cdbd2cSJim Jagielski { 53*b1cdbd2cSJim Jagielski if (m_pElement.is()) { 54*b1cdbd2cSJim Jagielski registerListener(*m_pElement); 55*b1cdbd2cSJim Jagielski } 56*b1cdbd2cSJim Jagielski } 57*b1cdbd2cSJim Jagielski registerListener(CElement & rElement)58*b1cdbd2cSJim Jagielski void CElementList::registerListener(CElement & rElement) 59*b1cdbd2cSJim Jagielski { 60*b1cdbd2cSJim Jagielski try { 61*b1cdbd2cSJim Jagielski Reference< XEventTarget > const xTarget( 62*b1cdbd2cSJim Jagielski static_cast<XElement*>(& rElement), UNO_QUERY_THROW); 63*b1cdbd2cSJim Jagielski OUString aType = OUString::createFromAscii("DOMSubtreeModified"); 64*b1cdbd2cSJim Jagielski sal_Bool capture = sal_False; 65*b1cdbd2cSJim Jagielski xTarget->addEventListener(aType, 66*b1cdbd2cSJim Jagielski Reference< XEventListener >(this), capture); 67*b1cdbd2cSJim Jagielski } catch (Exception &e){ 68*b1cdbd2cSJim Jagielski OString aMsg("Exception caught while registering NodeList as listener:\n"); 69*b1cdbd2cSJim Jagielski aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 70*b1cdbd2cSJim Jagielski OSL_ENSURE(sal_False, aMsg.getStr()); 71*b1cdbd2cSJim Jagielski } 72*b1cdbd2cSJim Jagielski } 73*b1cdbd2cSJim Jagielski buildlist(xmlNodePtr pNode,sal_Bool start)74*b1cdbd2cSJim Jagielski void CElementList::buildlist(xmlNodePtr pNode, sal_Bool start) 75*b1cdbd2cSJim Jagielski { 76*b1cdbd2cSJim Jagielski // bail out if no rebuild is needed 77*b1cdbd2cSJim Jagielski if (start) { 78*b1cdbd2cSJim Jagielski if (!m_bRebuild) 79*b1cdbd2cSJim Jagielski { 80*b1cdbd2cSJim Jagielski return; 81*b1cdbd2cSJim Jagielski } else { 82*b1cdbd2cSJim Jagielski m_nodevector.erase(m_nodevector.begin(), m_nodevector.end()); 83*b1cdbd2cSJim Jagielski m_bRebuild = false; // don't rebuild until tree is mutated 84*b1cdbd2cSJim Jagielski } 85*b1cdbd2cSJim Jagielski } 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski while (pNode != NULL ) 88*b1cdbd2cSJim Jagielski { 89*b1cdbd2cSJim Jagielski if (pNode->type == XML_ELEMENT_NODE && 90*b1cdbd2cSJim Jagielski (strcmp((char*)pNode->name, (char*)m_pName.get()) == 0)) 91*b1cdbd2cSJim Jagielski { 92*b1cdbd2cSJim Jagielski if (!m_pURI) { 93*b1cdbd2cSJim Jagielski m_nodevector.push_back(pNode); 94*b1cdbd2cSJim Jagielski } else { 95*b1cdbd2cSJim Jagielski if (pNode->ns != NULL && (0 == 96*b1cdbd2cSJim Jagielski strcmp((char*)pNode->ns->href, (char*)m_pURI.get()))) 97*b1cdbd2cSJim Jagielski { 98*b1cdbd2cSJim Jagielski m_nodevector.push_back(pNode); 99*b1cdbd2cSJim Jagielski } 100*b1cdbd2cSJim Jagielski } 101*b1cdbd2cSJim Jagielski } 102*b1cdbd2cSJim Jagielski if (pNode->children != NULL) buildlist(pNode->children, sal_False); 103*b1cdbd2cSJim Jagielski 104*b1cdbd2cSJim Jagielski if (!start) pNode = pNode->next; 105*b1cdbd2cSJim Jagielski else break; // fold back 106*b1cdbd2cSJim Jagielski } 107*b1cdbd2cSJim Jagielski } 108*b1cdbd2cSJim Jagielski 109*b1cdbd2cSJim Jagielski /** 110*b1cdbd2cSJim Jagielski The number of nodes in the list. 111*b1cdbd2cSJim Jagielski */ getLength()112*b1cdbd2cSJim Jagielski sal_Int32 SAL_CALL CElementList::getLength() throw (RuntimeException) 113*b1cdbd2cSJim Jagielski { 114*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 115*b1cdbd2cSJim Jagielski 116*b1cdbd2cSJim Jagielski if (!m_pElement.is()) { return 0; } 117*b1cdbd2cSJim Jagielski 118*b1cdbd2cSJim Jagielski // this has to be 'live' 119*b1cdbd2cSJim Jagielski buildlist(m_pElement->GetNodePtr()); 120*b1cdbd2cSJim Jagielski return m_nodevector.size(); 121*b1cdbd2cSJim Jagielski } 122*b1cdbd2cSJim Jagielski /** 123*b1cdbd2cSJim Jagielski Returns the indexth item in the collection. 124*b1cdbd2cSJim Jagielski */ item(sal_Int32 index)125*b1cdbd2cSJim Jagielski Reference< XNode > SAL_CALL CElementList::item(sal_Int32 index) 126*b1cdbd2cSJim Jagielski throw (RuntimeException) 127*b1cdbd2cSJim Jagielski { 128*b1cdbd2cSJim Jagielski if (index < 0) throw RuntimeException(); 129*b1cdbd2cSJim Jagielski 130*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 131*b1cdbd2cSJim Jagielski 132*b1cdbd2cSJim Jagielski if (!m_pElement.is()) { return 0; } 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski buildlist(m_pElement->GetNodePtr()); 135*b1cdbd2cSJim Jagielski if (m_nodevector.size() <= static_cast<size_t>(index)) { 136*b1cdbd2cSJim Jagielski throw RuntimeException(); 137*b1cdbd2cSJim Jagielski } 138*b1cdbd2cSJim Jagielski Reference< XNode > const xRet( 139*b1cdbd2cSJim Jagielski m_pElement->GetOwnerDocument().GetCNode(m_nodevector[index]).get()); 140*b1cdbd2cSJim Jagielski return xRet; 141*b1cdbd2cSJim Jagielski } 142*b1cdbd2cSJim Jagielski 143*b1cdbd2cSJim Jagielski // tree mutations can change the list handleEvent(Reference<XEvent> const &)144*b1cdbd2cSJim Jagielski void SAL_CALL CElementList::handleEvent(Reference< XEvent > const&) 145*b1cdbd2cSJim Jagielski throw (RuntimeException) 146*b1cdbd2cSJim Jagielski { 147*b1cdbd2cSJim Jagielski ::osl::MutexGuard const g(m_rMutex); 148*b1cdbd2cSJim Jagielski 149*b1cdbd2cSJim Jagielski m_bRebuild = true; 150*b1cdbd2cSJim Jagielski } 151*b1cdbd2cSJim Jagielski } 152