xref: /aoo4110/main/unoxml/source/dom/elementlist.cxx (revision b1cdbd2c)
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