xref: /aoo42x/main/unoxml/source/dom/elementlist.cxx (revision e9cbe144)
1*e9cbe144SAndrew Rist /**************************************************************
2*e9cbe144SAndrew Rist  *
3*e9cbe144SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*e9cbe144SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*e9cbe144SAndrew Rist  * distributed with this work for additional information
6*e9cbe144SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*e9cbe144SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*e9cbe144SAndrew Rist  * "License"); you may not use this file except in compliance
9*e9cbe144SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*e9cbe144SAndrew Rist  *
11*e9cbe144SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*e9cbe144SAndrew Rist  *
13*e9cbe144SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*e9cbe144SAndrew Rist  * software distributed under the License is distributed on an
15*e9cbe144SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*e9cbe144SAndrew Rist  * KIND, either express or implied.  See the License for the
17*e9cbe144SAndrew Rist  * specific language governing permissions and limitations
18*e9cbe144SAndrew Rist  * under the License.
19*e9cbe144SAndrew Rist  *
20*e9cbe144SAndrew Rist  *************************************************************/
21*e9cbe144SAndrew Rist 
22*e9cbe144SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "elementlist.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <string.h>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <element.hxx>
29cdf0e10cSrcweir #include <document.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir 
32cdf0e10cSrcweir namespace DOM
33cdf0e10cSrcweir {
34cdf0e10cSrcweir 
lcl_initXmlString(::rtl::OUString const & rString)35cdf0e10cSrcweir     static xmlChar* lcl_initXmlString(::rtl::OUString const& rString)
36cdf0e10cSrcweir     {
37cdf0e10cSrcweir         ::rtl::OString const os =
38cdf0e10cSrcweir             ::rtl::OUStringToOString(rString, RTL_TEXTENCODING_UTF8);
39cdf0e10cSrcweir         xmlChar *const pRet = new xmlChar[os.getLength() + 1];
40cdf0e10cSrcweir         strcpy(reinterpret_cast<char*>(pRet), os.getStr());
41cdf0e10cSrcweir         return pRet;
42cdf0e10cSrcweir     }
43cdf0e10cSrcweir 
CElementList(::rtl::Reference<CElement> const & pElement,::osl::Mutex & rMutex,OUString const & rName,OUString const * const pURI)44cdf0e10cSrcweir     CElementList::CElementList(::rtl::Reference<CElement> const& pElement,
45cdf0e10cSrcweir             ::osl::Mutex & rMutex,
46cdf0e10cSrcweir             OUString const& rName, OUString const*const pURI)
47cdf0e10cSrcweir         : m_pElement(pElement)
48cdf0e10cSrcweir         , m_rMutex(rMutex)
49cdf0e10cSrcweir         , m_pName(lcl_initXmlString(rName))
50cdf0e10cSrcweir         , m_pURI((pURI) ? lcl_initXmlString(*pURI) : 0)
51cdf0e10cSrcweir         , m_bRebuild(true)
52cdf0e10cSrcweir     {
53cdf0e10cSrcweir         if (m_pElement.is()) {
54cdf0e10cSrcweir             registerListener(*m_pElement);
55cdf0e10cSrcweir         }
56cdf0e10cSrcweir     }
57cdf0e10cSrcweir 
registerListener(CElement & rElement)58cdf0e10cSrcweir     void CElementList::registerListener(CElement & rElement)
59cdf0e10cSrcweir     {
60cdf0e10cSrcweir         try {
61cdf0e10cSrcweir             Reference< XEventTarget > const xTarget(
62cdf0e10cSrcweir                     static_cast<XElement*>(& rElement), UNO_QUERY_THROW);
63cdf0e10cSrcweir             OUString aType = OUString::createFromAscii("DOMSubtreeModified");
64cdf0e10cSrcweir             sal_Bool capture = sal_False;
65cdf0e10cSrcweir             xTarget->addEventListener(aType,
66cdf0e10cSrcweir                     Reference< XEventListener >(this), capture);
67cdf0e10cSrcweir         } catch (Exception &e){
68cdf0e10cSrcweir             OString aMsg("Exception caught while registering NodeList as listener:\n");
69cdf0e10cSrcweir             aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
70cdf0e10cSrcweir             OSL_ENSURE(sal_False, aMsg.getStr());
71cdf0e10cSrcweir         }
72cdf0e10cSrcweir     }
73cdf0e10cSrcweir 
buildlist(xmlNodePtr pNode,sal_Bool start)74cdf0e10cSrcweir     void CElementList::buildlist(xmlNodePtr pNode, sal_Bool start)
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir         // bail out if no rebuild is needed
77cdf0e10cSrcweir         if (start) {
78cdf0e10cSrcweir             if (!m_bRebuild)
79cdf0e10cSrcweir             {
80cdf0e10cSrcweir                 return;
81cdf0e10cSrcweir             } else {
82cdf0e10cSrcweir                 m_nodevector.erase(m_nodevector.begin(), m_nodevector.end());
83cdf0e10cSrcweir                 m_bRebuild = false; // don't rebuild until tree is mutated
84cdf0e10cSrcweir             }
85cdf0e10cSrcweir         }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         while (pNode != NULL )
88cdf0e10cSrcweir         {
89cdf0e10cSrcweir             if (pNode->type == XML_ELEMENT_NODE &&
90cdf0e10cSrcweir                 (strcmp((char*)pNode->name, (char*)m_pName.get()) == 0))
91cdf0e10cSrcweir             {
92cdf0e10cSrcweir                 if (!m_pURI) {
93cdf0e10cSrcweir                     m_nodevector.push_back(pNode);
94cdf0e10cSrcweir                 } else {
95cdf0e10cSrcweir                     if (pNode->ns != NULL && (0 ==
96cdf0e10cSrcweir                          strcmp((char*)pNode->ns->href, (char*)m_pURI.get())))
97cdf0e10cSrcweir                     {
98cdf0e10cSrcweir                         m_nodevector.push_back(pNode);
99cdf0e10cSrcweir                     }
100cdf0e10cSrcweir                 }
101cdf0e10cSrcweir             }
102cdf0e10cSrcweir             if (pNode->children != NULL) buildlist(pNode->children, sal_False);
103cdf0e10cSrcweir 
104cdf0e10cSrcweir             if (!start) pNode = pNode->next;
105cdf0e10cSrcweir             else break; // fold back
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir     }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     /**
110cdf0e10cSrcweir     The number of nodes in the list.
111cdf0e10cSrcweir     */
getLength()112cdf0e10cSrcweir     sal_Int32 SAL_CALL CElementList::getLength() throw (RuntimeException)
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
115cdf0e10cSrcweir 
116cdf0e10cSrcweir         if (!m_pElement.is()) { return 0; }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir         // this has to be 'live'
119cdf0e10cSrcweir         buildlist(m_pElement->GetNodePtr());
120cdf0e10cSrcweir         return m_nodevector.size();
121cdf0e10cSrcweir     }
122cdf0e10cSrcweir     /**
123cdf0e10cSrcweir     Returns the indexth item in the collection.
124cdf0e10cSrcweir     */
item(sal_Int32 index)125cdf0e10cSrcweir     Reference< XNode > SAL_CALL CElementList::item(sal_Int32 index)
126cdf0e10cSrcweir         throw (RuntimeException)
127cdf0e10cSrcweir     {
128cdf0e10cSrcweir         if (index < 0) throw RuntimeException();
129cdf0e10cSrcweir 
130cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
131cdf0e10cSrcweir 
132cdf0e10cSrcweir         if (!m_pElement.is()) { return 0; }
133cdf0e10cSrcweir 
134cdf0e10cSrcweir         buildlist(m_pElement->GetNodePtr());
135cdf0e10cSrcweir         if (m_nodevector.size() <= static_cast<size_t>(index)) {
136cdf0e10cSrcweir             throw RuntimeException();
137cdf0e10cSrcweir         }
138cdf0e10cSrcweir         Reference< XNode > const xRet(
139cdf0e10cSrcweir             m_pElement->GetOwnerDocument().GetCNode(m_nodevector[index]).get());
140cdf0e10cSrcweir         return xRet;
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir 
143cdf0e10cSrcweir     // tree mutations can change the list
handleEvent(Reference<XEvent> const &)144cdf0e10cSrcweir     void SAL_CALL CElementList::handleEvent(Reference< XEvent > const&)
145cdf0e10cSrcweir         throw (RuntimeException)
146cdf0e10cSrcweir     {
147cdf0e10cSrcweir         ::osl::MutexGuard const g(m_rMutex);
148cdf0e10cSrcweir 
149cdf0e10cSrcweir         m_bRebuild = true;
150cdf0e10cSrcweir     }
151cdf0e10cSrcweir }
152