xref: /AOO41X/main/xmlscript/source/xml_helper/xml_impctx.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_xmlscript.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "osl/diagnose.h"
32*cdf0e10cSrcweir #include "osl/mutex.hxx"
33*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
34*cdf0e10cSrcweir #include "cppuhelper/factory.hxx"
35*cdf0e10cSrcweir #include "cppuhelper/implementationentry.hxx"
36*cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
37*cdf0e10cSrcweir #include "cppuhelper/implbase3.hxx"
38*cdf0e10cSrcweir #include "xmlscript/xml_import.hxx"
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include "com/sun/star/xml/input/XAttributes.hpp"
41*cdf0e10cSrcweir #include "com/sun/star/lang/XInitialization.hpp"
42*cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <vector>
45*cdf0e10cSrcweir #include <hash_map>
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir #include <memory>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir using namespace ::rtl;
51*cdf0e10cSrcweir using namespace ::osl;
52*cdf0e10cSrcweir using namespace ::com::sun::star;
53*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir namespace xmlscript
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir const sal_Int32 UID_UNKNOWN = -1;
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir Sequence< OUString > getSupportedServiceNames_DocumentHandlerImpl()
61*cdf0e10cSrcweir {
62*cdf0e10cSrcweir     OUString name( RTL_CONSTASCII_USTRINGPARAM(
63*cdf0e10cSrcweir                        "com.sun.star.xml.input.SaxDocumentHandler") );
64*cdf0e10cSrcweir     return Sequence< OUString >( &name, 1 );
65*cdf0e10cSrcweir }
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir OUString getImplementationName_DocumentHandlerImpl()
68*cdf0e10cSrcweir {
69*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM(
70*cdf0e10cSrcweir                          "com.sun.star.comp.xml.input.SaxDocumentHandler") );
71*cdf0e10cSrcweir }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir typedef ::std::hash_map< OUString, sal_Int32, OUStringHash > t_OUString2LongMap;
74*cdf0e10cSrcweir typedef ::std::hash_map< sal_Int32, OUString > t_Long2OUStringMap;
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir struct PrefixEntry
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir     ::std::vector< sal_Int32 > m_Uids;
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir     inline PrefixEntry() SAL_THROW( () )
81*cdf0e10cSrcweir         { m_Uids.reserve( 4 ); }
82*cdf0e10cSrcweir };
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir typedef ::std::hash_map<
85*cdf0e10cSrcweir     OUString, PrefixEntry *, OUStringHash > t_OUString2PrefixMap;
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir struct ElementEntry
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     Reference< xml::input::XElement > m_xElement;
90*cdf0e10cSrcweir     ::std::vector< OUString > m_prefixes;
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir     inline ElementEntry()
93*cdf0e10cSrcweir         { m_prefixes.reserve( 2 ); }
94*cdf0e10cSrcweir };
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir typedef ::std::vector< ElementEntry * > t_ElementVector;
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir class ExtendedAttributes;
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir //==============================================================================
101*cdf0e10cSrcweir struct MGuard
102*cdf0e10cSrcweir {
103*cdf0e10cSrcweir     Mutex * m_pMutex;
104*cdf0e10cSrcweir     explicit MGuard( Mutex * pMutex )
105*cdf0e10cSrcweir         : m_pMutex( pMutex )
106*cdf0e10cSrcweir         { if (m_pMutex) m_pMutex->acquire(); }
107*cdf0e10cSrcweir     ~MGuard() throw ()
108*cdf0e10cSrcweir         { if (m_pMutex) m_pMutex->release(); }
109*cdf0e10cSrcweir };
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir //==============================================================================
112*cdf0e10cSrcweir class DocumentHandlerImpl :
113*cdf0e10cSrcweir     public ::cppu::WeakImplHelper3< xml::sax::XDocumentHandler,
114*cdf0e10cSrcweir                                     xml::input::XNamespaceMapping,
115*cdf0e10cSrcweir                                     lang::XInitialization >
116*cdf0e10cSrcweir {
117*cdf0e10cSrcweir     friend class ExtendedAttributes;
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir     Reference< xml::input::XRoot > m_xRoot;
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir     t_OUString2LongMap m_URI2Uid;
122*cdf0e10cSrcweir     sal_Int32 m_uid_count;
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir     OUString m_sXMLNS_PREFIX_UNKNOWN;
125*cdf0e10cSrcweir     OUString m_sXMLNS;
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir     sal_Int32 m_nLastURI_lookup;
128*cdf0e10cSrcweir     OUString m_aLastURI_lookup;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir     t_OUString2PrefixMap m_prefixes;
131*cdf0e10cSrcweir     sal_Int32 m_nLastPrefix_lookup;
132*cdf0e10cSrcweir     OUString m_aLastPrefix_lookup;
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir     t_ElementVector m_elements;
135*cdf0e10cSrcweir     sal_Int32 m_nSkipElements;
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir     Mutex * m_pMutex;
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir     inline Reference< xml::input::XElement > getCurrentElement() const;
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     inline sal_Int32 getUidByURI( OUString const & rURI );
142*cdf0e10cSrcweir     inline sal_Int32 getUidByPrefix( OUString const & rPrefix );
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir     inline void pushPrefix(
145*cdf0e10cSrcweir         OUString const & rPrefix, OUString const & rURI );
146*cdf0e10cSrcweir     inline void popPrefix( OUString const & rPrefix );
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir     inline void getElementName(
149*cdf0e10cSrcweir         OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName );
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir public:
152*cdf0e10cSrcweir     DocumentHandlerImpl(
153*cdf0e10cSrcweir         Reference< xml::input::XRoot > const & xRoot,
154*cdf0e10cSrcweir         bool bSingleThreadedUse );
155*cdf0e10cSrcweir     virtual ~DocumentHandlerImpl() throw ();
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir     // XServiceInfo
158*cdf0e10cSrcweir     virtual OUString SAL_CALL getImplementationName()
159*cdf0e10cSrcweir         throw (RuntimeException);
160*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL supportsService(
161*cdf0e10cSrcweir         OUString const & servicename )
162*cdf0e10cSrcweir         throw (RuntimeException);
163*cdf0e10cSrcweir     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
164*cdf0e10cSrcweir         throw (RuntimeException);
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     // XInitialization
167*cdf0e10cSrcweir     virtual void SAL_CALL initialize(
168*cdf0e10cSrcweir         Sequence< Any > const & arguments )
169*cdf0e10cSrcweir         throw (Exception);
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir     // XDocumentHandler
172*cdf0e10cSrcweir     virtual void SAL_CALL startDocument()
173*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
174*cdf0e10cSrcweir     virtual void SAL_CALL endDocument()
175*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
176*cdf0e10cSrcweir     virtual void SAL_CALL startElement(
177*cdf0e10cSrcweir         OUString const & rQElementName,
178*cdf0e10cSrcweir         Reference< xml::sax::XAttributeList > const & xAttribs )
179*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
180*cdf0e10cSrcweir     virtual void SAL_CALL endElement(
181*cdf0e10cSrcweir         OUString const & rQElementName )
182*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
183*cdf0e10cSrcweir     virtual void SAL_CALL characters(
184*cdf0e10cSrcweir         OUString const & rChars )
185*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
186*cdf0e10cSrcweir     virtual void SAL_CALL ignorableWhitespace(
187*cdf0e10cSrcweir         OUString const & rWhitespaces )
188*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
189*cdf0e10cSrcweir     virtual void SAL_CALL processingInstruction(
190*cdf0e10cSrcweir         OUString const & rTarget, OUString const & rData )
191*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
192*cdf0e10cSrcweir     virtual void SAL_CALL setDocumentLocator(
193*cdf0e10cSrcweir         Reference< xml::sax::XLocator > const & xLocator )
194*cdf0e10cSrcweir         throw (xml::sax::SAXException, RuntimeException);
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir     // XNamespaceMapping
197*cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri )
198*cdf0e10cSrcweir         throw (RuntimeException);
199*cdf0e10cSrcweir     virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid )
200*cdf0e10cSrcweir         throw (container::NoSuchElementException, RuntimeException);
201*cdf0e10cSrcweir };
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir //______________________________________________________________________________
204*cdf0e10cSrcweir DocumentHandlerImpl::DocumentHandlerImpl(
205*cdf0e10cSrcweir     Reference< xml::input::XRoot > const & xRoot,
206*cdf0e10cSrcweir     bool bSingleThreadedUse )
207*cdf0e10cSrcweir     : m_xRoot( xRoot ),
208*cdf0e10cSrcweir       m_uid_count( 0 ),
209*cdf0e10cSrcweir       m_sXMLNS_PREFIX_UNKNOWN(
210*cdf0e10cSrcweir           RTL_CONSTASCII_USTRINGPARAM("<<< unknown prefix >>>") ),
211*cdf0e10cSrcweir       m_sXMLNS( RTL_CONSTASCII_USTRINGPARAM("xmlns") ),
212*cdf0e10cSrcweir       m_nLastURI_lookup( UID_UNKNOWN ),
213*cdf0e10cSrcweir       m_aLastURI_lookup( RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ),
214*cdf0e10cSrcweir       m_nLastPrefix_lookup( UID_UNKNOWN ),
215*cdf0e10cSrcweir       m_aLastPrefix_lookup(
216*cdf0e10cSrcweir           RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ),
217*cdf0e10cSrcweir       m_nSkipElements( 0 ),
218*cdf0e10cSrcweir       m_pMutex( 0 )
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir     m_elements.reserve( 10 );
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir     if (! bSingleThreadedUse)
223*cdf0e10cSrcweir         m_pMutex = new Mutex();
224*cdf0e10cSrcweir }
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir //______________________________________________________________________________
227*cdf0e10cSrcweir DocumentHandlerImpl::~DocumentHandlerImpl() throw ()
228*cdf0e10cSrcweir {
229*cdf0e10cSrcweir     if (m_pMutex != 0)
230*cdf0e10cSrcweir     {
231*cdf0e10cSrcweir         delete m_pMutex;
232*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL == 0
233*cdf0e10cSrcweir         m_pMutex = 0;
234*cdf0e10cSrcweir #endif
235*cdf0e10cSrcweir     }
236*cdf0e10cSrcweir }
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir //______________________________________________________________________________
239*cdf0e10cSrcweir inline Reference< xml::input::XElement >
240*cdf0e10cSrcweir DocumentHandlerImpl::getCurrentElement() const
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir     MGuard aGuard( m_pMutex );
243*cdf0e10cSrcweir     if (m_elements.empty())
244*cdf0e10cSrcweir         return Reference< xml::input::XElement >();
245*cdf0e10cSrcweir     else
246*cdf0e10cSrcweir         return m_elements.back()->m_xElement;
247*cdf0e10cSrcweir }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir //______________________________________________________________________________
250*cdf0e10cSrcweir inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI )
251*cdf0e10cSrcweir {
252*cdf0e10cSrcweir     MGuard guard( m_pMutex );
253*cdf0e10cSrcweir     if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI)
254*cdf0e10cSrcweir     {
255*cdf0e10cSrcweir         t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) );
256*cdf0e10cSrcweir         if (iFind != m_URI2Uid.end()) // id found
257*cdf0e10cSrcweir         {
258*cdf0e10cSrcweir             m_nLastURI_lookup = iFind->second;
259*cdf0e10cSrcweir             m_aLastURI_lookup = rURI;
260*cdf0e10cSrcweir         }
261*cdf0e10cSrcweir         else
262*cdf0e10cSrcweir         {
263*cdf0e10cSrcweir             m_nLastURI_lookup = m_uid_count;
264*cdf0e10cSrcweir             ++m_uid_count;
265*cdf0e10cSrcweir             m_URI2Uid[ rURI ] = m_nLastURI_lookup;
266*cdf0e10cSrcweir             m_aLastURI_lookup = rURI;
267*cdf0e10cSrcweir         }
268*cdf0e10cSrcweir     }
269*cdf0e10cSrcweir     return m_nLastURI_lookup;
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir //______________________________________________________________________________
273*cdf0e10cSrcweir inline sal_Int32 DocumentHandlerImpl::getUidByPrefix(
274*cdf0e10cSrcweir     OUString const & rPrefix )
275*cdf0e10cSrcweir {
276*cdf0e10cSrcweir     // commonly the last added prefix is used often for several tags...
277*cdf0e10cSrcweir     // good guess
278*cdf0e10cSrcweir     if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix)
279*cdf0e10cSrcweir     {
280*cdf0e10cSrcweir         t_OUString2PrefixMap::const_iterator iFind(
281*cdf0e10cSrcweir             m_prefixes.find( rPrefix ) );
282*cdf0e10cSrcweir         if (iFind != m_prefixes.end())
283*cdf0e10cSrcweir         {
284*cdf0e10cSrcweir             const PrefixEntry & rPrefixEntry = *iFind->second;
285*cdf0e10cSrcweir             OSL_ASSERT( ! rPrefixEntry.m_Uids.empty() );
286*cdf0e10cSrcweir             m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back();
287*cdf0e10cSrcweir             m_aLastPrefix_lookup = rPrefix;
288*cdf0e10cSrcweir         }
289*cdf0e10cSrcweir         else
290*cdf0e10cSrcweir         {
291*cdf0e10cSrcweir             m_nLastPrefix_lookup = UID_UNKNOWN;
292*cdf0e10cSrcweir             m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
293*cdf0e10cSrcweir         }
294*cdf0e10cSrcweir     }
295*cdf0e10cSrcweir     return m_nLastPrefix_lookup;
296*cdf0e10cSrcweir }
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir //______________________________________________________________________________
299*cdf0e10cSrcweir inline void DocumentHandlerImpl::pushPrefix(
300*cdf0e10cSrcweir     OUString const & rPrefix, OUString const & rURI )
301*cdf0e10cSrcweir {
302*cdf0e10cSrcweir     // lookup id for URI
303*cdf0e10cSrcweir     sal_Int32 nUid = getUidByURI( rURI );
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir     // mark prefix with id
306*cdf0e10cSrcweir     t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) );
307*cdf0e10cSrcweir     if (iFind == m_prefixes.end()) // unused prefix
308*cdf0e10cSrcweir     {
309*cdf0e10cSrcweir         PrefixEntry * pEntry = new PrefixEntry();
310*cdf0e10cSrcweir         pEntry->m_Uids.push_back( nUid ); // latest id for prefix
311*cdf0e10cSrcweir         m_prefixes[ rPrefix ] = pEntry;
312*cdf0e10cSrcweir     }
313*cdf0e10cSrcweir     else
314*cdf0e10cSrcweir     {
315*cdf0e10cSrcweir         PrefixEntry * pEntry = iFind->second;
316*cdf0e10cSrcweir         OSL_ASSERT( ! pEntry->m_Uids.empty() );
317*cdf0e10cSrcweir         pEntry->m_Uids.push_back( nUid );
318*cdf0e10cSrcweir     }
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir     m_aLastPrefix_lookup = rPrefix;
321*cdf0e10cSrcweir     m_nLastPrefix_lookup = nUid;
322*cdf0e10cSrcweir }
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir //______________________________________________________________________________
325*cdf0e10cSrcweir inline void DocumentHandlerImpl::popPrefix(
326*cdf0e10cSrcweir     OUString const & rPrefix )
327*cdf0e10cSrcweir {
328*cdf0e10cSrcweir     t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) );
329*cdf0e10cSrcweir     if (iFind != m_prefixes.end()) // unused prefix
330*cdf0e10cSrcweir     {
331*cdf0e10cSrcweir         PrefixEntry * pEntry = iFind->second;
332*cdf0e10cSrcweir         pEntry->m_Uids.pop_back(); // pop last id for prefix
333*cdf0e10cSrcweir         if (pEntry->m_Uids.empty()) // erase prefix key
334*cdf0e10cSrcweir         {
335*cdf0e10cSrcweir             m_prefixes.erase( iFind );
336*cdf0e10cSrcweir             delete pEntry;
337*cdf0e10cSrcweir         }
338*cdf0e10cSrcweir     }
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir     m_nLastPrefix_lookup = UID_UNKNOWN;
341*cdf0e10cSrcweir     m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
342*cdf0e10cSrcweir }
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir //______________________________________________________________________________
345*cdf0e10cSrcweir inline void DocumentHandlerImpl::getElementName(
346*cdf0e10cSrcweir     OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName )
347*cdf0e10cSrcweir {
348*cdf0e10cSrcweir     sal_Int32 nColonPos = rQName.indexOf( (sal_Unicode)':' );
349*cdf0e10cSrcweir     *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName);
350*cdf0e10cSrcweir     *pUid = getUidByPrefix(
351*cdf0e10cSrcweir         nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() );
352*cdf0e10cSrcweir }
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir //==============================================================================
356*cdf0e10cSrcweir class ExtendedAttributes :
357*cdf0e10cSrcweir     public ::cppu::WeakImplHelper1< xml::input::XAttributes >
358*cdf0e10cSrcweir {
359*cdf0e10cSrcweir     sal_Int32 m_nAttributes;
360*cdf0e10cSrcweir     sal_Int32 * m_pUids;
361*cdf0e10cSrcweir     OUString * m_pPrefixes;
362*cdf0e10cSrcweir     OUString * m_pLocalNames;
363*cdf0e10cSrcweir     OUString * m_pQNames;
364*cdf0e10cSrcweir     OUString * m_pValues;
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir     DocumentHandlerImpl * m_pHandler;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir public:
369*cdf0e10cSrcweir     inline ExtendedAttributes(
370*cdf0e10cSrcweir         sal_Int32 nAttributes,
371*cdf0e10cSrcweir         sal_Int32 * pUids, OUString * pPrefixes,
372*cdf0e10cSrcweir         OUString * pLocalNames, OUString * pQNames,
373*cdf0e10cSrcweir         Reference< xml::sax::XAttributeList > const & xAttributeList,
374*cdf0e10cSrcweir         DocumentHandlerImpl * pHandler );
375*cdf0e10cSrcweir     virtual ~ExtendedAttributes() throw ();
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir     // XAttributes
378*cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getLength()
379*cdf0e10cSrcweir         throw (RuntimeException);
380*cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getIndexByQName(
381*cdf0e10cSrcweir         OUString const & rQName )
382*cdf0e10cSrcweir         throw (RuntimeException);
383*cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getIndexByUidName(
384*cdf0e10cSrcweir         sal_Int32 nUid, OUString const & rLocalName )
385*cdf0e10cSrcweir         throw (RuntimeException);
386*cdf0e10cSrcweir     virtual OUString SAL_CALL getQNameByIndex(
387*cdf0e10cSrcweir         sal_Int32 nIndex )
388*cdf0e10cSrcweir         throw (RuntimeException);
389*cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL getUidByIndex(
390*cdf0e10cSrcweir         sal_Int32 nIndex )
391*cdf0e10cSrcweir         throw (RuntimeException);
392*cdf0e10cSrcweir     virtual OUString SAL_CALL getLocalNameByIndex(
393*cdf0e10cSrcweir         sal_Int32 nIndex )
394*cdf0e10cSrcweir         throw (RuntimeException);
395*cdf0e10cSrcweir     virtual OUString SAL_CALL getValueByIndex(
396*cdf0e10cSrcweir         sal_Int32 nIndex )
397*cdf0e10cSrcweir         throw (RuntimeException);
398*cdf0e10cSrcweir     virtual OUString SAL_CALL getValueByUidName(
399*cdf0e10cSrcweir         sal_Int32 nUid, OUString const & rLocalName )
400*cdf0e10cSrcweir         throw (RuntimeException);
401*cdf0e10cSrcweir     virtual OUString SAL_CALL getTypeByIndex(
402*cdf0e10cSrcweir         sal_Int32 nIndex )
403*cdf0e10cSrcweir         throw (RuntimeException);
404*cdf0e10cSrcweir };
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir //______________________________________________________________________________
407*cdf0e10cSrcweir inline ExtendedAttributes::ExtendedAttributes(
408*cdf0e10cSrcweir     sal_Int32 nAttributes,
409*cdf0e10cSrcweir     sal_Int32 * pUids, OUString * pPrefixes,
410*cdf0e10cSrcweir     OUString * pLocalNames, OUString * pQNames,
411*cdf0e10cSrcweir     Reference< xml::sax::XAttributeList > const & xAttributeList,
412*cdf0e10cSrcweir     DocumentHandlerImpl * pHandler )
413*cdf0e10cSrcweir     : m_nAttributes( nAttributes )
414*cdf0e10cSrcweir     , m_pUids( pUids )
415*cdf0e10cSrcweir     , m_pPrefixes( pPrefixes )
416*cdf0e10cSrcweir     , m_pLocalNames( pLocalNames )
417*cdf0e10cSrcweir     , m_pQNames( pQNames )
418*cdf0e10cSrcweir     , m_pValues( new OUString[ nAttributes ] )
419*cdf0e10cSrcweir     , m_pHandler( pHandler )
420*cdf0e10cSrcweir {
421*cdf0e10cSrcweir     m_pHandler->acquire();
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir     for ( sal_Int16 nPos = 0; nPos < nAttributes; ++nPos )
424*cdf0e10cSrcweir     {
425*cdf0e10cSrcweir         m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos );
426*cdf0e10cSrcweir     }
427*cdf0e10cSrcweir }
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir //______________________________________________________________________________
430*cdf0e10cSrcweir ExtendedAttributes::~ExtendedAttributes() throw ()
431*cdf0e10cSrcweir {
432*cdf0e10cSrcweir     m_pHandler->release();
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir     delete [] m_pUids;
435*cdf0e10cSrcweir     delete [] m_pPrefixes;
436*cdf0e10cSrcweir     delete [] m_pLocalNames;
437*cdf0e10cSrcweir     delete [] m_pQNames;
438*cdf0e10cSrcweir     delete [] m_pValues;
439*cdf0e10cSrcweir }
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir //##############################################################################
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir // XServiceInfo
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir //______________________________________________________________________________
447*cdf0e10cSrcweir OUString DocumentHandlerImpl::getImplementationName()
448*cdf0e10cSrcweir     throw (RuntimeException)
449*cdf0e10cSrcweir {
450*cdf0e10cSrcweir     return getImplementationName_DocumentHandlerImpl();
451*cdf0e10cSrcweir }
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir //______________________________________________________________________________
454*cdf0e10cSrcweir sal_Bool DocumentHandlerImpl::supportsService(
455*cdf0e10cSrcweir     OUString const & servicename )
456*cdf0e10cSrcweir     throw (RuntimeException)
457*cdf0e10cSrcweir {
458*cdf0e10cSrcweir     Sequence< OUString > names( getSupportedServiceNames_DocumentHandlerImpl() );
459*cdf0e10cSrcweir     for ( sal_Int32 nPos = names.getLength(); nPos--; )
460*cdf0e10cSrcweir     {
461*cdf0e10cSrcweir         if (names[ nPos ].equals( servicename ))
462*cdf0e10cSrcweir             return sal_True;
463*cdf0e10cSrcweir     }
464*cdf0e10cSrcweir     return sal_False;
465*cdf0e10cSrcweir }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir //______________________________________________________________________________
468*cdf0e10cSrcweir Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames()
469*cdf0e10cSrcweir     throw (RuntimeException)
470*cdf0e10cSrcweir {
471*cdf0e10cSrcweir     return getSupportedServiceNames_DocumentHandlerImpl();
472*cdf0e10cSrcweir }
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir // XInitialization
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir //______________________________________________________________________________
477*cdf0e10cSrcweir void DocumentHandlerImpl::initialize(
478*cdf0e10cSrcweir     Sequence< Any > const & arguments )
479*cdf0e10cSrcweir     throw (Exception)
480*cdf0e10cSrcweir {
481*cdf0e10cSrcweir     MGuard guard( m_pMutex );
482*cdf0e10cSrcweir     Reference< xml::input::XRoot > xRoot;
483*cdf0e10cSrcweir     if (arguments.getLength() == 1 &&
484*cdf0e10cSrcweir         (arguments[ 0 ] >>= xRoot) &&
485*cdf0e10cSrcweir         xRoot.is())
486*cdf0e10cSrcweir     {
487*cdf0e10cSrcweir         m_xRoot = xRoot;
488*cdf0e10cSrcweir     }
489*cdf0e10cSrcweir     else
490*cdf0e10cSrcweir     {
491*cdf0e10cSrcweir         throw RuntimeException(
492*cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM(
493*cdf0e10cSrcweir                           "missing root instance!") ),
494*cdf0e10cSrcweir             Reference< XInterface >() );
495*cdf0e10cSrcweir     }
496*cdf0e10cSrcweir }
497*cdf0e10cSrcweir 
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir // XNamespaceMapping
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir //______________________________________________________________________________
502*cdf0e10cSrcweir sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri )
503*cdf0e10cSrcweir     throw (RuntimeException)
504*cdf0e10cSrcweir {
505*cdf0e10cSrcweir     sal_Int32 uid = getUidByURI( Uri );
506*cdf0e10cSrcweir     OSL_ASSERT( uid != UID_UNKNOWN );
507*cdf0e10cSrcweir     return uid;
508*cdf0e10cSrcweir }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir //______________________________________________________________________________
511*cdf0e10cSrcweir OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid )
512*cdf0e10cSrcweir     throw (container::NoSuchElementException, RuntimeException)
513*cdf0e10cSrcweir {
514*cdf0e10cSrcweir     MGuard guard( m_pMutex );
515*cdf0e10cSrcweir     t_OUString2LongMap::const_iterator iPos( m_URI2Uid.begin() );
516*cdf0e10cSrcweir     t_OUString2LongMap::const_iterator const iEnd( m_URI2Uid.end() );
517*cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
518*cdf0e10cSrcweir     {
519*cdf0e10cSrcweir         if (iPos->second == Uid)
520*cdf0e10cSrcweir             return iPos->first;
521*cdf0e10cSrcweir     }
522*cdf0e10cSrcweir     throw container::NoSuchElementException(
523*cdf0e10cSrcweir         OUString( RTL_CONSTASCII_USTRINGPARAM("no such xmlns uid!") ),
524*cdf0e10cSrcweir         static_cast< OWeakObject * >(this) );
525*cdf0e10cSrcweir }
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir // XDocumentHandler
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir //______________________________________________________________________________
531*cdf0e10cSrcweir void DocumentHandlerImpl::startDocument()
532*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
533*cdf0e10cSrcweir {
534*cdf0e10cSrcweir     m_xRoot->startDocument(
535*cdf0e10cSrcweir         static_cast< xml::input::XNamespaceMapping * >( this ) );
536*cdf0e10cSrcweir }
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir //______________________________________________________________________________
539*cdf0e10cSrcweir void DocumentHandlerImpl::endDocument()
540*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir     m_xRoot->endDocument();
543*cdf0e10cSrcweir }
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir //______________________________________________________________________________
546*cdf0e10cSrcweir void DocumentHandlerImpl::startElement(
547*cdf0e10cSrcweir     OUString const & rQElementName,
548*cdf0e10cSrcweir     Reference< xml::sax::XAttributeList > const & xAttribs )
549*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
550*cdf0e10cSrcweir {
551*cdf0e10cSrcweir     Reference< xml::input::XElement > xCurrentElement;
552*cdf0e10cSrcweir     Reference< xml::input::XAttributes > xAttributes;
553*cdf0e10cSrcweir     sal_Int32 nUid;
554*cdf0e10cSrcweir     OUString aLocalName;
555*cdf0e10cSrcweir     ::std::auto_ptr< ElementEntry > elementEntry( new ElementEntry );
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir     { // guard start:
558*cdf0e10cSrcweir     MGuard aGuard( m_pMutex );
559*cdf0e10cSrcweir     // currently skipping elements and waiting for end tags?
560*cdf0e10cSrcweir     if (m_nSkipElements > 0)
561*cdf0e10cSrcweir     {
562*cdf0e10cSrcweir         ++m_nSkipElements; // wait for another end tag
563*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
564*cdf0e10cSrcweir         OString aQName(
565*cdf0e10cSrcweir             OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
566*cdf0e10cSrcweir         OSL_TRACE( "### no context given on createChildElement() "
567*cdf0e10cSrcweir                    "=> ignoring element \"%s\" ...", aQName.getStr() );
568*cdf0e10cSrcweir #endif
569*cdf0e10cSrcweir         return;
570*cdf0e10cSrcweir     }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir     sal_Int16 nAttribs = xAttribs->getLength();
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir     // save all namespace ids
575*cdf0e10cSrcweir     sal_Int32 * pUids = new sal_Int32[ nAttribs ];
576*cdf0e10cSrcweir     OUString * pPrefixes = new OUString[ nAttribs ];
577*cdf0e10cSrcweir     OUString * pLocalNames = new OUString[ nAttribs ];
578*cdf0e10cSrcweir     OUString * pQNames = new OUString[ nAttribs ];
579*cdf0e10cSrcweir 
580*cdf0e10cSrcweir     // first recognize all xmlns attributes
581*cdf0e10cSrcweir     sal_Int16 nPos;
582*cdf0e10cSrcweir     for ( nPos = 0; nPos < nAttribs; ++nPos )
583*cdf0e10cSrcweir     {
584*cdf0e10cSrcweir         // mark attribute to be collected further
585*cdf0e10cSrcweir         // on with attribute's uid and current prefix
586*cdf0e10cSrcweir         pUids[ nPos ] = 0; // modified
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir         pQNames[ nPos ] = xAttribs->getNameByIndex( nPos );
589*cdf0e10cSrcweir         OUString const & rQAttributeName = pQNames[ nPos ];
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir         if (rQAttributeName.compareTo( m_sXMLNS, 5 ) == 0)
592*cdf0e10cSrcweir         {
593*cdf0e10cSrcweir             if (rQAttributeName.getLength() == 5) // set default namespace
594*cdf0e10cSrcweir             {
595*cdf0e10cSrcweir                 OUString aDefNamespacePrefix;
596*cdf0e10cSrcweir                 pushPrefix(
597*cdf0e10cSrcweir                     aDefNamespacePrefix,
598*cdf0e10cSrcweir                     xAttribs->getValueByIndex( nPos ) );
599*cdf0e10cSrcweir                 elementEntry->m_prefixes.push_back( aDefNamespacePrefix );
600*cdf0e10cSrcweir                 pUids[ nPos ]          = UID_UNKNOWN;
601*cdf0e10cSrcweir                 pPrefixes[ nPos ]      = m_sXMLNS;
602*cdf0e10cSrcweir                 pLocalNames[ nPos ]    = aDefNamespacePrefix;
603*cdf0e10cSrcweir             }
604*cdf0e10cSrcweir             else if ((sal_Unicode)':' == rQAttributeName[ 5 ]) // set prefix
605*cdf0e10cSrcweir             {
606*cdf0e10cSrcweir                 OUString aPrefix( rQAttributeName.copy( 6 ) );
607*cdf0e10cSrcweir                 pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) );
608*cdf0e10cSrcweir                 elementEntry->m_prefixes.push_back( aPrefix );
609*cdf0e10cSrcweir                 pUids[ nPos ]          = UID_UNKNOWN;
610*cdf0e10cSrcweir                 pPrefixes[ nPos ]      = m_sXMLNS;
611*cdf0e10cSrcweir                 pLocalNames[ nPos ]    = aPrefix;
612*cdf0e10cSrcweir             }
613*cdf0e10cSrcweir             // else just a name starting with xmlns, but no prefix
614*cdf0e10cSrcweir         }
615*cdf0e10cSrcweir     }
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir     // now read out attribute prefixes (all namespace prefixes have been set)
618*cdf0e10cSrcweir     for ( nPos = 0; nPos < nAttribs; ++nPos )
619*cdf0e10cSrcweir     {
620*cdf0e10cSrcweir         if (pUids[ nPos ] >= 0) // no xmlns: attribute
621*cdf0e10cSrcweir         {
622*cdf0e10cSrcweir             OUString const & rQAttributeName = pQNames[ nPos ];
623*cdf0e10cSrcweir             OSL_ENSURE(
624*cdf0e10cSrcweir                 rQAttributeName.compareToAscii(
625*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("xmlns:") ) != 0,
626*cdf0e10cSrcweir                 "### unexpected xmlns!" );
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir             // collect attribute's uid and current prefix
629*cdf0e10cSrcweir             sal_Int32 nColonPos = rQAttributeName.indexOf( (sal_Unicode) ':' );
630*cdf0e10cSrcweir             if (nColonPos >= 0)
631*cdf0e10cSrcweir             {
632*cdf0e10cSrcweir                 pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos );
633*cdf0e10cSrcweir                 pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 );
634*cdf0e10cSrcweir             }
635*cdf0e10cSrcweir             else
636*cdf0e10cSrcweir             {
637*cdf0e10cSrcweir                 pPrefixes[ nPos ] = OUString();
638*cdf0e10cSrcweir                 pLocalNames[ nPos ] = rQAttributeName;
639*cdf0e10cSrcweir                 // leave local names unmodified
640*cdf0e10cSrcweir             }
641*cdf0e10cSrcweir             pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] );
642*cdf0e10cSrcweir         }
643*cdf0e10cSrcweir     }
644*cdf0e10cSrcweir     // ownership of arrays belongs to attribute list
645*cdf0e10cSrcweir     xAttributes = static_cast< xml::input::XAttributes * >(
646*cdf0e10cSrcweir         new ExtendedAttributes(
647*cdf0e10cSrcweir             nAttribs, pUids, pPrefixes, pLocalNames, pQNames,
648*cdf0e10cSrcweir             xAttribs, this ) );
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir     getElementName( rQElementName, &nUid, &aLocalName );
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir     // create new child context and append to list
653*cdf0e10cSrcweir     if (! m_elements.empty())
654*cdf0e10cSrcweir         xCurrentElement = m_elements.back()->m_xElement;
655*cdf0e10cSrcweir     } // :guard end
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir     if (xCurrentElement.is())
658*cdf0e10cSrcweir     {
659*cdf0e10cSrcweir         elementEntry->m_xElement =
660*cdf0e10cSrcweir             xCurrentElement->startChildElement( nUid, aLocalName, xAttributes );
661*cdf0e10cSrcweir     }
662*cdf0e10cSrcweir     else
663*cdf0e10cSrcweir     {
664*cdf0e10cSrcweir         elementEntry->m_xElement =
665*cdf0e10cSrcweir             m_xRoot->startRootElement( nUid, aLocalName, xAttributes );
666*cdf0e10cSrcweir     }
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir     {
669*cdf0e10cSrcweir     MGuard aGuard( m_pMutex );
670*cdf0e10cSrcweir     if (elementEntry->m_xElement.is())
671*cdf0e10cSrcweir     {
672*cdf0e10cSrcweir         m_elements.push_back( elementEntry.release() );
673*cdf0e10cSrcweir     }
674*cdf0e10cSrcweir     else
675*cdf0e10cSrcweir     {
676*cdf0e10cSrcweir         ++m_nSkipElements;
677*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
678*cdf0e10cSrcweir         OString aQName(
679*cdf0e10cSrcweir             OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
680*cdf0e10cSrcweir         OSL_TRACE(
681*cdf0e10cSrcweir             "### no context given on createChildElement() => "
682*cdf0e10cSrcweir             "ignoring element \"%s\" ...", aQName.getStr() );
683*cdf0e10cSrcweir #endif
684*cdf0e10cSrcweir     }
685*cdf0e10cSrcweir     }
686*cdf0e10cSrcweir }
687*cdf0e10cSrcweir 
688*cdf0e10cSrcweir //______________________________________________________________________________
689*cdf0e10cSrcweir void DocumentHandlerImpl::endElement(
690*cdf0e10cSrcweir     OUString const & rQElementName )
691*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
692*cdf0e10cSrcweir {
693*cdf0e10cSrcweir     Reference< xml::input::XElement > xCurrentElement;
694*cdf0e10cSrcweir     {
695*cdf0e10cSrcweir     MGuard aGuard( m_pMutex );
696*cdf0e10cSrcweir     if (m_nSkipElements)
697*cdf0e10cSrcweir     {
698*cdf0e10cSrcweir         --m_nSkipElements;
699*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
700*cdf0e10cSrcweir         OString aQName(
701*cdf0e10cSrcweir             OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
702*cdf0e10cSrcweir         OSL_TRACE( "### received endElement() for \"%s\".", aQName.getStr() );
703*cdf0e10cSrcweir #endif
704*cdf0e10cSrcweir         static_cast<void>(rQElementName);
705*cdf0e10cSrcweir         return;
706*cdf0e10cSrcweir     }
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir     // popping context
709*cdf0e10cSrcweir     OSL_ASSERT( ! m_elements.empty() );
710*cdf0e10cSrcweir     ElementEntry * pEntry = m_elements.back();
711*cdf0e10cSrcweir     xCurrentElement = pEntry->m_xElement;
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
714*cdf0e10cSrcweir     sal_Int32 nUid;
715*cdf0e10cSrcweir     OUString aLocalName;
716*cdf0e10cSrcweir     getElementName( rQElementName, &nUid, &aLocalName );
717*cdf0e10cSrcweir     OSL_ASSERT( xCurrentElement->getLocalName() == aLocalName );
718*cdf0e10cSrcweir     OSL_ASSERT( xCurrentElement->getUid() == nUid );
719*cdf0e10cSrcweir #endif
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir     // pop prefixes
722*cdf0e10cSrcweir     for ( sal_Int32 nPos = pEntry->m_prefixes.size(); nPos--; )
723*cdf0e10cSrcweir     {
724*cdf0e10cSrcweir         popPrefix( pEntry->m_prefixes[ nPos ] );
725*cdf0e10cSrcweir     }
726*cdf0e10cSrcweir     m_elements.pop_back();
727*cdf0e10cSrcweir     delete pEntry;
728*cdf0e10cSrcweir     }
729*cdf0e10cSrcweir     xCurrentElement->endElement();
730*cdf0e10cSrcweir }
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir //______________________________________________________________________________
733*cdf0e10cSrcweir void DocumentHandlerImpl::characters( OUString const & rChars )
734*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
735*cdf0e10cSrcweir {
736*cdf0e10cSrcweir     Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
737*cdf0e10cSrcweir     if (xCurrentElement.is())
738*cdf0e10cSrcweir         xCurrentElement->characters( rChars );
739*cdf0e10cSrcweir }
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir //______________________________________________________________________________
742*cdf0e10cSrcweir void DocumentHandlerImpl::ignorableWhitespace(
743*cdf0e10cSrcweir     OUString const & rWhitespaces )
744*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
745*cdf0e10cSrcweir {
746*cdf0e10cSrcweir     Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
747*cdf0e10cSrcweir     if (xCurrentElement.is())
748*cdf0e10cSrcweir         xCurrentElement->ignorableWhitespace( rWhitespaces );
749*cdf0e10cSrcweir }
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir //______________________________________________________________________________
752*cdf0e10cSrcweir void DocumentHandlerImpl::processingInstruction(
753*cdf0e10cSrcweir     OUString const & rTarget, OUString const & rData )
754*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
755*cdf0e10cSrcweir {
756*cdf0e10cSrcweir     Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
757*cdf0e10cSrcweir     if (xCurrentElement.is())
758*cdf0e10cSrcweir         xCurrentElement->processingInstruction( rTarget, rData );
759*cdf0e10cSrcweir     else
760*cdf0e10cSrcweir         m_xRoot->processingInstruction( rTarget, rData );
761*cdf0e10cSrcweir }
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir //______________________________________________________________________________
764*cdf0e10cSrcweir void DocumentHandlerImpl::setDocumentLocator(
765*cdf0e10cSrcweir     Reference< xml::sax::XLocator > const & xLocator )
766*cdf0e10cSrcweir     throw (xml::sax::SAXException, RuntimeException)
767*cdf0e10cSrcweir {
768*cdf0e10cSrcweir     m_xRoot->setDocumentLocator( xLocator );
769*cdf0e10cSrcweir }
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir //##############################################################################
772*cdf0e10cSrcweir 
773*cdf0e10cSrcweir // XAttributes
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir //______________________________________________________________________________
776*cdf0e10cSrcweir sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName )
777*cdf0e10cSrcweir     throw (RuntimeException)
778*cdf0e10cSrcweir {
779*cdf0e10cSrcweir     for ( sal_Int32 nPos = m_nAttributes; nPos--; )
780*cdf0e10cSrcweir     {
781*cdf0e10cSrcweir         if (m_pQNames[ nPos ].equals( rQName ))
782*cdf0e10cSrcweir         {
783*cdf0e10cSrcweir             return nPos;
784*cdf0e10cSrcweir         }
785*cdf0e10cSrcweir     }
786*cdf0e10cSrcweir     return -1;
787*cdf0e10cSrcweir }
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir //______________________________________________________________________________
790*cdf0e10cSrcweir sal_Int32 ExtendedAttributes::getLength()
791*cdf0e10cSrcweir     throw (RuntimeException)
792*cdf0e10cSrcweir {
793*cdf0e10cSrcweir     return m_nAttributes;
794*cdf0e10cSrcweir }
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir //______________________________________________________________________________
797*cdf0e10cSrcweir OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex )
798*cdf0e10cSrcweir     throw (RuntimeException)
799*cdf0e10cSrcweir {
800*cdf0e10cSrcweir     if (nIndex < m_nAttributes)
801*cdf0e10cSrcweir         return m_pLocalNames[ nIndex ];
802*cdf0e10cSrcweir     else
803*cdf0e10cSrcweir         return OUString();
804*cdf0e10cSrcweir }
805*cdf0e10cSrcweir 
806*cdf0e10cSrcweir //______________________________________________________________________________
807*cdf0e10cSrcweir OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex )
808*cdf0e10cSrcweir     throw (RuntimeException)
809*cdf0e10cSrcweir {
810*cdf0e10cSrcweir     if (nIndex < m_nAttributes)
811*cdf0e10cSrcweir         return m_pQNames[ nIndex ];
812*cdf0e10cSrcweir     else
813*cdf0e10cSrcweir         return OUString();
814*cdf0e10cSrcweir }
815*cdf0e10cSrcweir 
816*cdf0e10cSrcweir //______________________________________________________________________________
817*cdf0e10cSrcweir OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex )
818*cdf0e10cSrcweir     throw (RuntimeException)
819*cdf0e10cSrcweir {
820*cdf0e10cSrcweir     static_cast<void>(nIndex);
821*cdf0e10cSrcweir     OSL_ASSERT( nIndex < m_nAttributes );
822*cdf0e10cSrcweir     return OUString(); // unsupported
823*cdf0e10cSrcweir }
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir //______________________________________________________________________________
826*cdf0e10cSrcweir OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex )
827*cdf0e10cSrcweir     throw (RuntimeException)
828*cdf0e10cSrcweir {
829*cdf0e10cSrcweir     if (nIndex < m_nAttributes)
830*cdf0e10cSrcweir         return m_pValues[ nIndex ];
831*cdf0e10cSrcweir     else
832*cdf0e10cSrcweir         return OUString();
833*cdf0e10cSrcweir }
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir //______________________________________________________________________________
836*cdf0e10cSrcweir sal_Int32 ExtendedAttributes::getIndexByUidName(
837*cdf0e10cSrcweir     sal_Int32 nUid, OUString const & rLocalName )
838*cdf0e10cSrcweir     throw (RuntimeException)
839*cdf0e10cSrcweir {
840*cdf0e10cSrcweir     for ( sal_Int32 nPos = m_nAttributes; nPos--; )
841*cdf0e10cSrcweir     {
842*cdf0e10cSrcweir         if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
843*cdf0e10cSrcweir         {
844*cdf0e10cSrcweir             return nPos;
845*cdf0e10cSrcweir         }
846*cdf0e10cSrcweir     }
847*cdf0e10cSrcweir     return -1;
848*cdf0e10cSrcweir }
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir //______________________________________________________________________________
851*cdf0e10cSrcweir sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex )
852*cdf0e10cSrcweir     throw (RuntimeException)
853*cdf0e10cSrcweir {
854*cdf0e10cSrcweir     if (nIndex < m_nAttributes)
855*cdf0e10cSrcweir         return m_pUids[ nIndex ];
856*cdf0e10cSrcweir     else
857*cdf0e10cSrcweir         return -1;
858*cdf0e10cSrcweir }
859*cdf0e10cSrcweir 
860*cdf0e10cSrcweir //______________________________________________________________________________
861*cdf0e10cSrcweir OUString ExtendedAttributes::getValueByUidName(
862*cdf0e10cSrcweir     sal_Int32 nUid, OUString const & rLocalName )
863*cdf0e10cSrcweir     throw (RuntimeException)
864*cdf0e10cSrcweir {
865*cdf0e10cSrcweir     for ( sal_Int32 nPos = m_nAttributes; nPos--; )
866*cdf0e10cSrcweir     {
867*cdf0e10cSrcweir         if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
868*cdf0e10cSrcweir         {
869*cdf0e10cSrcweir             return m_pValues[ nPos ];
870*cdf0e10cSrcweir         }
871*cdf0e10cSrcweir     }
872*cdf0e10cSrcweir     return OUString();
873*cdf0e10cSrcweir }
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir //##############################################################################
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir //==============================================================================
880*cdf0e10cSrcweir Reference< xml::sax::XDocumentHandler > SAL_CALL createDocumentHandler(
881*cdf0e10cSrcweir     Reference< xml::input::XRoot > const & xRoot,
882*cdf0e10cSrcweir     bool bSingleThreadedUse )
883*cdf0e10cSrcweir     SAL_THROW( () )
884*cdf0e10cSrcweir {
885*cdf0e10cSrcweir     OSL_ASSERT( xRoot.is() );
886*cdf0e10cSrcweir     if (xRoot.is())
887*cdf0e10cSrcweir     {
888*cdf0e10cSrcweir         return static_cast< xml::sax::XDocumentHandler * >(
889*cdf0e10cSrcweir             new DocumentHandlerImpl( xRoot, bSingleThreadedUse ) );
890*cdf0e10cSrcweir     }
891*cdf0e10cSrcweir     return Reference< xml::sax::XDocumentHandler >();
892*cdf0e10cSrcweir }
893*cdf0e10cSrcweir 
894*cdf0e10cSrcweir //------------------------------------------------------------------------------
895*cdf0e10cSrcweir Reference< XInterface > SAL_CALL create_DocumentHandlerImpl(
896*cdf0e10cSrcweir     Reference< XComponentContext > const & )
897*cdf0e10cSrcweir     SAL_THROW( (Exception) )
898*cdf0e10cSrcweir {
899*cdf0e10cSrcweir     return static_cast< ::cppu::OWeakObject * >(
900*cdf0e10cSrcweir         new DocumentHandlerImpl(
901*cdf0e10cSrcweir             Reference< xml::input::XRoot >(), false /* mt use */ ) );
902*cdf0e10cSrcweir }
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir }
905