Update ooo320-m1
[ooovba.git] / xmlscript / source / xml_helper / xml_impctx.cxx
blobafab81e40401734559ff622525ee7487fe25c2f2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xml_impctx.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlscript.hxx"
34 #include "osl/diagnose.h"
35 #include "osl/mutex.hxx"
36 #include "rtl/ustrbuf.hxx"
37 #include "cppuhelper/factory.hxx"
38 #include "cppuhelper/implementationentry.hxx"
39 #include "cppuhelper/implbase1.hxx"
40 #include "cppuhelper/implbase3.hxx"
41 #include "xmlscript/xml_import.hxx"
43 #include "com/sun/star/xml/input/XAttributes.hpp"
44 #include "com/sun/star/lang/XInitialization.hpp"
45 #include "com/sun/star/uno/XComponentContext.hpp"
47 #include <vector>
48 #include <hash_map>
50 #include <memory>
53 using namespace ::rtl;
54 using namespace ::osl;
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
58 namespace xmlscript
61 const sal_Int32 UID_UNKNOWN = -1;
63 Sequence< OUString > getSupportedServiceNames_DocumentHandlerImpl()
65 OUString name( RTL_CONSTASCII_USTRINGPARAM(
66 "com.sun.star.xml.input.SaxDocumentHandler") );
67 return Sequence< OUString >( &name, 1 );
70 OUString getImplementationName_DocumentHandlerImpl()
72 return OUString( RTL_CONSTASCII_USTRINGPARAM(
73 "com.sun.star.comp.xml.input.SaxDocumentHandler") );
76 typedef ::std::hash_map< OUString, sal_Int32, OUStringHash > t_OUString2LongMap;
77 typedef ::std::hash_map< sal_Int32, OUString > t_Long2OUStringMap;
79 struct PrefixEntry
81 ::std::vector< sal_Int32 > m_Uids;
83 inline PrefixEntry() SAL_THROW( () )
84 { m_Uids.reserve( 4 ); }
87 typedef ::std::hash_map<
88 OUString, PrefixEntry *, OUStringHash > t_OUString2PrefixMap;
90 struct ElementEntry
92 Reference< xml::input::XElement > m_xElement;
93 ::std::vector< OUString > m_prefixes;
95 inline ElementEntry()
96 { m_prefixes.reserve( 2 ); }
99 typedef ::std::vector< ElementEntry * > t_ElementVector;
101 class ExtendedAttributes;
103 //==============================================================================
104 struct MGuard
106 Mutex * m_pMutex;
107 explicit MGuard( Mutex * pMutex )
108 : m_pMutex( pMutex )
109 { if (m_pMutex) m_pMutex->acquire(); }
110 ~MGuard() throw ()
111 { if (m_pMutex) m_pMutex->release(); }
114 //==============================================================================
115 class DocumentHandlerImpl :
116 public ::cppu::WeakImplHelper3< xml::sax::XDocumentHandler,
117 xml::input::XNamespaceMapping,
118 lang::XInitialization >
120 friend class ExtendedAttributes;
122 Reference< xml::input::XRoot > m_xRoot;
124 t_OUString2LongMap m_URI2Uid;
125 sal_Int32 m_uid_count;
127 OUString m_sXMLNS_PREFIX_UNKNOWN;
128 OUString m_sXMLNS;
130 sal_Int32 m_nLastURI_lookup;
131 OUString m_aLastURI_lookup;
133 t_OUString2PrefixMap m_prefixes;
134 sal_Int32 m_nLastPrefix_lookup;
135 OUString m_aLastPrefix_lookup;
137 t_ElementVector m_elements;
138 sal_Int32 m_nSkipElements;
140 Mutex * m_pMutex;
142 inline Reference< xml::input::XElement > getCurrentElement() const;
144 inline sal_Int32 getUidByURI( OUString const & rURI );
145 inline sal_Int32 getUidByPrefix( OUString const & rPrefix );
147 inline void pushPrefix(
148 OUString const & rPrefix, OUString const & rURI );
149 inline void popPrefix( OUString const & rPrefix );
151 inline void getElementName(
152 OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName );
154 public:
155 DocumentHandlerImpl(
156 Reference< xml::input::XRoot > const & xRoot,
157 bool bSingleThreadedUse );
158 virtual ~DocumentHandlerImpl() throw ();
160 // XServiceInfo
161 virtual OUString SAL_CALL getImplementationName()
162 throw (RuntimeException);
163 virtual sal_Bool SAL_CALL supportsService(
164 OUString const & servicename )
165 throw (RuntimeException);
166 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
167 throw (RuntimeException);
169 // XInitialization
170 virtual void SAL_CALL initialize(
171 Sequence< Any > const & arguments )
172 throw (Exception);
174 // XDocumentHandler
175 virtual void SAL_CALL startDocument()
176 throw (xml::sax::SAXException, RuntimeException);
177 virtual void SAL_CALL endDocument()
178 throw (xml::sax::SAXException, RuntimeException);
179 virtual void SAL_CALL startElement(
180 OUString const & rQElementName,
181 Reference< xml::sax::XAttributeList > const & xAttribs )
182 throw (xml::sax::SAXException, RuntimeException);
183 virtual void SAL_CALL endElement(
184 OUString const & rQElementName )
185 throw (xml::sax::SAXException, RuntimeException);
186 virtual void SAL_CALL characters(
187 OUString const & rChars )
188 throw (xml::sax::SAXException, RuntimeException);
189 virtual void SAL_CALL ignorableWhitespace(
190 OUString const & rWhitespaces )
191 throw (xml::sax::SAXException, RuntimeException);
192 virtual void SAL_CALL processingInstruction(
193 OUString const & rTarget, OUString const & rData )
194 throw (xml::sax::SAXException, RuntimeException);
195 virtual void SAL_CALL setDocumentLocator(
196 Reference< xml::sax::XLocator > const & xLocator )
197 throw (xml::sax::SAXException, RuntimeException);
199 // XNamespaceMapping
200 virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri )
201 throw (RuntimeException);
202 virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid )
203 throw (container::NoSuchElementException, RuntimeException);
206 //______________________________________________________________________________
207 DocumentHandlerImpl::DocumentHandlerImpl(
208 Reference< xml::input::XRoot > const & xRoot,
209 bool bSingleThreadedUse )
210 : m_xRoot( xRoot ),
211 m_uid_count( 0 ),
212 m_sXMLNS_PREFIX_UNKNOWN(
213 RTL_CONSTASCII_USTRINGPARAM("<<< unknown prefix >>>") ),
214 m_sXMLNS( RTL_CONSTASCII_USTRINGPARAM("xmlns") ),
215 m_nLastURI_lookup( UID_UNKNOWN ),
216 m_aLastURI_lookup( RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ),
217 m_nLastPrefix_lookup( UID_UNKNOWN ),
218 m_aLastPrefix_lookup(
219 RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ),
220 m_nSkipElements( 0 ),
221 m_pMutex( 0 )
223 m_elements.reserve( 10 );
225 if (! bSingleThreadedUse)
226 m_pMutex = new Mutex();
229 //______________________________________________________________________________
230 DocumentHandlerImpl::~DocumentHandlerImpl() throw ()
232 if (m_pMutex != 0)
234 delete m_pMutex;
235 #if OSL_DEBUG_LEVEL == 0
236 m_pMutex = 0;
237 #endif
241 //______________________________________________________________________________
242 inline Reference< xml::input::XElement >
243 DocumentHandlerImpl::getCurrentElement() const
245 MGuard aGuard( m_pMutex );
246 if (m_elements.empty())
247 return Reference< xml::input::XElement >();
248 else
249 return m_elements.back()->m_xElement;
252 //______________________________________________________________________________
253 inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI )
255 MGuard guard( m_pMutex );
256 if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI)
258 t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) );
259 if (iFind != m_URI2Uid.end()) // id found
261 m_nLastURI_lookup = iFind->second;
262 m_aLastURI_lookup = rURI;
264 else
266 m_nLastURI_lookup = m_uid_count;
267 ++m_uid_count;
268 m_URI2Uid[ rURI ] = m_nLastURI_lookup;
269 m_aLastURI_lookup = rURI;
272 return m_nLastURI_lookup;
275 //______________________________________________________________________________
276 inline sal_Int32 DocumentHandlerImpl::getUidByPrefix(
277 OUString const & rPrefix )
279 // commonly the last added prefix is used often for several tags...
280 // good guess
281 if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix)
283 t_OUString2PrefixMap::const_iterator iFind(
284 m_prefixes.find( rPrefix ) );
285 if (iFind != m_prefixes.end())
287 const PrefixEntry & rPrefixEntry = *iFind->second;
288 OSL_ASSERT( ! rPrefixEntry.m_Uids.empty() );
289 m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back();
290 m_aLastPrefix_lookup = rPrefix;
292 else
294 m_nLastPrefix_lookup = UID_UNKNOWN;
295 m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
298 return m_nLastPrefix_lookup;
301 //______________________________________________________________________________
302 inline void DocumentHandlerImpl::pushPrefix(
303 OUString const & rPrefix, OUString const & rURI )
305 // lookup id for URI
306 sal_Int32 nUid = getUidByURI( rURI );
308 // mark prefix with id
309 t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) );
310 if (iFind == m_prefixes.end()) // unused prefix
312 PrefixEntry * pEntry = new PrefixEntry();
313 pEntry->m_Uids.push_back( nUid ); // latest id for prefix
314 m_prefixes[ rPrefix ] = pEntry;
316 else
318 PrefixEntry * pEntry = iFind->second;
319 OSL_ASSERT( ! pEntry->m_Uids.empty() );
320 pEntry->m_Uids.push_back( nUid );
323 m_aLastPrefix_lookup = rPrefix;
324 m_nLastPrefix_lookup = nUid;
327 //______________________________________________________________________________
328 inline void DocumentHandlerImpl::popPrefix(
329 OUString const & rPrefix )
331 t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) );
332 if (iFind != m_prefixes.end()) // unused prefix
334 PrefixEntry * pEntry = iFind->second;
335 pEntry->m_Uids.pop_back(); // pop last id for prefix
336 if (pEntry->m_Uids.empty()) // erase prefix key
338 m_prefixes.erase( iFind );
339 delete pEntry;
343 m_nLastPrefix_lookup = UID_UNKNOWN;
344 m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
347 //______________________________________________________________________________
348 inline void DocumentHandlerImpl::getElementName(
349 OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName )
351 sal_Int32 nColonPos = rQName.indexOf( (sal_Unicode)':' );
352 *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName);
353 *pUid = getUidByPrefix(
354 nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() );
358 //==============================================================================
359 class ExtendedAttributes :
360 public ::cppu::WeakImplHelper1< xml::input::XAttributes >
362 sal_Int32 m_nAttributes;
363 sal_Int32 * m_pUids;
364 OUString * m_pPrefixes;
365 OUString * m_pLocalNames;
366 OUString * m_pQNames;
367 OUString * m_pValues;
369 DocumentHandlerImpl * m_pHandler;
371 public:
372 inline ExtendedAttributes(
373 sal_Int32 nAttributes,
374 sal_Int32 * pUids, OUString * pPrefixes,
375 OUString * pLocalNames, OUString * pQNames,
376 Reference< xml::sax::XAttributeList > const & xAttributeList,
377 DocumentHandlerImpl * pHandler );
378 virtual ~ExtendedAttributes() throw ();
380 // XAttributes
381 virtual sal_Int32 SAL_CALL getLength()
382 throw (RuntimeException);
383 virtual sal_Int32 SAL_CALL getIndexByQName(
384 OUString const & rQName )
385 throw (RuntimeException);
386 virtual sal_Int32 SAL_CALL getIndexByUidName(
387 sal_Int32 nUid, OUString const & rLocalName )
388 throw (RuntimeException);
389 virtual OUString SAL_CALL getQNameByIndex(
390 sal_Int32 nIndex )
391 throw (RuntimeException);
392 virtual sal_Int32 SAL_CALL getUidByIndex(
393 sal_Int32 nIndex )
394 throw (RuntimeException);
395 virtual OUString SAL_CALL getLocalNameByIndex(
396 sal_Int32 nIndex )
397 throw (RuntimeException);
398 virtual OUString SAL_CALL getValueByIndex(
399 sal_Int32 nIndex )
400 throw (RuntimeException);
401 virtual OUString SAL_CALL getValueByUidName(
402 sal_Int32 nUid, OUString const & rLocalName )
403 throw (RuntimeException);
404 virtual OUString SAL_CALL getTypeByIndex(
405 sal_Int32 nIndex )
406 throw (RuntimeException);
409 //______________________________________________________________________________
410 inline ExtendedAttributes::ExtendedAttributes(
411 sal_Int32 nAttributes,
412 sal_Int32 * pUids, OUString * pPrefixes,
413 OUString * pLocalNames, OUString * pQNames,
414 Reference< xml::sax::XAttributeList > const & xAttributeList,
415 DocumentHandlerImpl * pHandler )
416 : m_nAttributes( nAttributes )
417 , m_pUids( pUids )
418 , m_pPrefixes( pPrefixes )
419 , m_pLocalNames( pLocalNames )
420 , m_pQNames( pQNames )
421 , m_pValues( new OUString[ nAttributes ] )
422 , m_pHandler( pHandler )
424 m_pHandler->acquire();
426 for ( sal_Int16 nPos = 0; nPos < nAttributes; ++nPos )
428 m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos );
432 //______________________________________________________________________________
433 ExtendedAttributes::~ExtendedAttributes() throw ()
435 m_pHandler->release();
437 delete [] m_pUids;
438 delete [] m_pPrefixes;
439 delete [] m_pLocalNames;
440 delete [] m_pQNames;
441 delete [] m_pValues;
445 //##############################################################################
447 // XServiceInfo
449 //______________________________________________________________________________
450 OUString DocumentHandlerImpl::getImplementationName()
451 throw (RuntimeException)
453 return getImplementationName_DocumentHandlerImpl();
456 //______________________________________________________________________________
457 sal_Bool DocumentHandlerImpl::supportsService(
458 OUString const & servicename )
459 throw (RuntimeException)
461 Sequence< OUString > names( getSupportedServiceNames_DocumentHandlerImpl() );
462 for ( sal_Int32 nPos = names.getLength(); nPos--; )
464 if (names[ nPos ].equals( servicename ))
465 return sal_True;
467 return sal_False;
470 //______________________________________________________________________________
471 Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames()
472 throw (RuntimeException)
474 return getSupportedServiceNames_DocumentHandlerImpl();
477 // XInitialization
479 //______________________________________________________________________________
480 void DocumentHandlerImpl::initialize(
481 Sequence< Any > const & arguments )
482 throw (Exception)
484 MGuard guard( m_pMutex );
485 Reference< xml::input::XRoot > xRoot;
486 if (arguments.getLength() == 1 &&
487 (arguments[ 0 ] >>= xRoot) &&
488 xRoot.is())
490 m_xRoot = xRoot;
492 else
494 throw RuntimeException(
495 OUString( RTL_CONSTASCII_USTRINGPARAM(
496 "missing root instance!") ),
497 Reference< XInterface >() );
502 // XNamespaceMapping
504 //______________________________________________________________________________
505 sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri )
506 throw (RuntimeException)
508 sal_Int32 uid = getUidByURI( Uri );
509 OSL_ASSERT( uid != UID_UNKNOWN );
510 return uid;
513 //______________________________________________________________________________
514 OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid )
515 throw (container::NoSuchElementException, RuntimeException)
517 MGuard guard( m_pMutex );
518 t_OUString2LongMap::const_iterator iPos( m_URI2Uid.begin() );
519 t_OUString2LongMap::const_iterator const iEnd( m_URI2Uid.end() );
520 for ( ; iPos != iEnd; ++iPos )
522 if (iPos->second == Uid)
523 return iPos->first;
525 throw container::NoSuchElementException(
526 OUString( RTL_CONSTASCII_USTRINGPARAM("no such xmlns uid!") ),
527 static_cast< OWeakObject * >(this) );
531 // XDocumentHandler
533 //______________________________________________________________________________
534 void DocumentHandlerImpl::startDocument()
535 throw (xml::sax::SAXException, RuntimeException)
537 m_xRoot->startDocument(
538 static_cast< xml::input::XNamespaceMapping * >( this ) );
541 //______________________________________________________________________________
542 void DocumentHandlerImpl::endDocument()
543 throw (xml::sax::SAXException, RuntimeException)
545 m_xRoot->endDocument();
548 //______________________________________________________________________________
549 void DocumentHandlerImpl::startElement(
550 OUString const & rQElementName,
551 Reference< xml::sax::XAttributeList > const & xAttribs )
552 throw (xml::sax::SAXException, RuntimeException)
554 Reference< xml::input::XElement > xCurrentElement;
555 Reference< xml::input::XAttributes > xAttributes;
556 sal_Int32 nUid;
557 OUString aLocalName;
558 ::std::auto_ptr< ElementEntry > elementEntry( new ElementEntry );
560 { // guard start:
561 MGuard aGuard( m_pMutex );
562 // currently skipping elements and waiting for end tags?
563 if (m_nSkipElements > 0)
565 ++m_nSkipElements; // wait for another end tag
566 #if OSL_DEBUG_LEVEL > 1
567 OString aQName(
568 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
569 OSL_TRACE( "### no context given on createChildElement() "
570 "=> ignoring element \"%s\" ...", aQName.getStr() );
571 #endif
572 return;
575 sal_Int16 nAttribs = xAttribs->getLength();
577 // save all namespace ids
578 sal_Int32 * pUids = new sal_Int32[ nAttribs ];
579 OUString * pPrefixes = new OUString[ nAttribs ];
580 OUString * pLocalNames = new OUString[ nAttribs ];
581 OUString * pQNames = new OUString[ nAttribs ];
583 // first recognize all xmlns attributes
584 sal_Int16 nPos;
585 for ( nPos = 0; nPos < nAttribs; ++nPos )
587 // mark attribute to be collected further
588 // on with attribute's uid and current prefix
589 pUids[ nPos ] = 0; // modified
591 pQNames[ nPos ] = xAttribs->getNameByIndex( nPos );
592 OUString const & rQAttributeName = pQNames[ nPos ];
594 if (rQAttributeName.compareTo( m_sXMLNS, 5 ) == 0)
596 if (rQAttributeName.getLength() == 5) // set default namespace
598 OUString aDefNamespacePrefix;
599 pushPrefix(
600 aDefNamespacePrefix,
601 xAttribs->getValueByIndex( nPos ) );
602 elementEntry->m_prefixes.push_back( aDefNamespacePrefix );
603 pUids[ nPos ] = UID_UNKNOWN;
604 pPrefixes[ nPos ] = m_sXMLNS;
605 pLocalNames[ nPos ] = aDefNamespacePrefix;
607 else if ((sal_Unicode)':' == rQAttributeName[ 5 ]) // set prefix
609 OUString aPrefix( rQAttributeName.copy( 6 ) );
610 pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) );
611 elementEntry->m_prefixes.push_back( aPrefix );
612 pUids[ nPos ] = UID_UNKNOWN;
613 pPrefixes[ nPos ] = m_sXMLNS;
614 pLocalNames[ nPos ] = aPrefix;
616 // else just a name starting with xmlns, but no prefix
620 // now read out attribute prefixes (all namespace prefixes have been set)
621 for ( nPos = 0; nPos < nAttribs; ++nPos )
623 if (pUids[ nPos ] >= 0) // no xmlns: attribute
625 OUString const & rQAttributeName = pQNames[ nPos ];
626 OSL_ENSURE(
627 rQAttributeName.compareToAscii(
628 RTL_CONSTASCII_STRINGPARAM("xmlns:") ) != 0,
629 "### unexpected xmlns!" );
631 // collect attribute's uid and current prefix
632 sal_Int32 nColonPos = rQAttributeName.indexOf( (sal_Unicode) ':' );
633 if (nColonPos >= 0)
635 pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos );
636 pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 );
638 else
640 pPrefixes[ nPos ] = OUString();
641 pLocalNames[ nPos ] = rQAttributeName;
642 // leave local names unmodified
644 pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] );
647 // ownership of arrays belongs to attribute list
648 xAttributes = static_cast< xml::input::XAttributes * >(
649 new ExtendedAttributes(
650 nAttribs, pUids, pPrefixes, pLocalNames, pQNames,
651 xAttribs, this ) );
653 getElementName( rQElementName, &nUid, &aLocalName );
655 // create new child context and append to list
656 if (! m_elements.empty())
657 xCurrentElement = m_elements.back()->m_xElement;
658 } // :guard end
660 if (xCurrentElement.is())
662 elementEntry->m_xElement =
663 xCurrentElement->startChildElement( nUid, aLocalName, xAttributes );
665 else
667 elementEntry->m_xElement =
668 m_xRoot->startRootElement( nUid, aLocalName, xAttributes );
672 MGuard aGuard( m_pMutex );
673 if (elementEntry->m_xElement.is())
675 m_elements.push_back( elementEntry.release() );
677 else
679 ++m_nSkipElements;
680 #if OSL_DEBUG_LEVEL > 1
681 OString aQName(
682 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
683 OSL_TRACE(
684 "### no context given on createChildElement() => "
685 "ignoring element \"%s\" ...", aQName.getStr() );
686 #endif
691 //______________________________________________________________________________
692 void DocumentHandlerImpl::endElement(
693 OUString const & rQElementName )
694 throw (xml::sax::SAXException, RuntimeException)
696 Reference< xml::input::XElement > xCurrentElement;
698 MGuard aGuard( m_pMutex );
699 if (m_nSkipElements)
701 --m_nSkipElements;
702 #if OSL_DEBUG_LEVEL > 1
703 OString aQName(
704 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
705 OSL_TRACE( "### received endElement() for \"%s\".", aQName.getStr() );
706 #endif
707 static_cast<void>(rQElementName);
708 return;
711 // popping context
712 OSL_ASSERT( ! m_elements.empty() );
713 ElementEntry * pEntry = m_elements.back();
714 xCurrentElement = pEntry->m_xElement;
716 #if OSL_DEBUG_LEVEL > 0
717 sal_Int32 nUid;
718 OUString aLocalName;
719 getElementName( rQElementName, &nUid, &aLocalName );
720 OSL_ASSERT( xCurrentElement->getLocalName() == aLocalName );
721 OSL_ASSERT( xCurrentElement->getUid() == nUid );
722 #endif
724 // pop prefixes
725 for ( sal_Int32 nPos = pEntry->m_prefixes.size(); nPos--; )
727 popPrefix( pEntry->m_prefixes[ nPos ] );
729 m_elements.pop_back();
730 delete pEntry;
732 xCurrentElement->endElement();
735 //______________________________________________________________________________
736 void DocumentHandlerImpl::characters( OUString const & rChars )
737 throw (xml::sax::SAXException, RuntimeException)
739 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
740 if (xCurrentElement.is())
741 xCurrentElement->characters( rChars );
744 //______________________________________________________________________________
745 void DocumentHandlerImpl::ignorableWhitespace(
746 OUString const & rWhitespaces )
747 throw (xml::sax::SAXException, RuntimeException)
749 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
750 if (xCurrentElement.is())
751 xCurrentElement->ignorableWhitespace( rWhitespaces );
754 //______________________________________________________________________________
755 void DocumentHandlerImpl::processingInstruction(
756 OUString const & rTarget, OUString const & rData )
757 throw (xml::sax::SAXException, RuntimeException)
759 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
760 if (xCurrentElement.is())
761 xCurrentElement->processingInstruction( rTarget, rData );
762 else
763 m_xRoot->processingInstruction( rTarget, rData );
766 //______________________________________________________________________________
767 void DocumentHandlerImpl::setDocumentLocator(
768 Reference< xml::sax::XLocator > const & xLocator )
769 throw (xml::sax::SAXException, RuntimeException)
771 m_xRoot->setDocumentLocator( xLocator );
774 //##############################################################################
776 // XAttributes
778 //______________________________________________________________________________
779 sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName )
780 throw (RuntimeException)
782 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
784 if (m_pQNames[ nPos ].equals( rQName ))
786 return nPos;
789 return -1;
792 //______________________________________________________________________________
793 sal_Int32 ExtendedAttributes::getLength()
794 throw (RuntimeException)
796 return m_nAttributes;
799 //______________________________________________________________________________
800 OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex )
801 throw (RuntimeException)
803 if (nIndex < m_nAttributes)
804 return m_pLocalNames[ nIndex ];
805 else
806 return OUString();
809 //______________________________________________________________________________
810 OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex )
811 throw (RuntimeException)
813 if (nIndex < m_nAttributes)
814 return m_pQNames[ nIndex ];
815 else
816 return OUString();
819 //______________________________________________________________________________
820 OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex )
821 throw (RuntimeException)
823 static_cast<void>(nIndex);
824 OSL_ASSERT( nIndex < m_nAttributes );
825 return OUString(); // unsupported
828 //______________________________________________________________________________
829 OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex )
830 throw (RuntimeException)
832 if (nIndex < m_nAttributes)
833 return m_pValues[ nIndex ];
834 else
835 return OUString();
838 //______________________________________________________________________________
839 sal_Int32 ExtendedAttributes::getIndexByUidName(
840 sal_Int32 nUid, OUString const & rLocalName )
841 throw (RuntimeException)
843 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
845 if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
847 return nPos;
850 return -1;
853 //______________________________________________________________________________
854 sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex )
855 throw (RuntimeException)
857 if (nIndex < m_nAttributes)
858 return m_pUids[ nIndex ];
859 else
860 return -1;
863 //______________________________________________________________________________
864 OUString ExtendedAttributes::getValueByUidName(
865 sal_Int32 nUid, OUString const & rLocalName )
866 throw (RuntimeException)
868 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
870 if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
872 return m_pValues[ nPos ];
875 return OUString();
879 //##############################################################################
882 //==============================================================================
883 Reference< xml::sax::XDocumentHandler > SAL_CALL createDocumentHandler(
884 Reference< xml::input::XRoot > const & xRoot,
885 bool bSingleThreadedUse )
886 SAL_THROW( () )
888 OSL_ASSERT( xRoot.is() );
889 if (xRoot.is())
891 return static_cast< xml::sax::XDocumentHandler * >(
892 new DocumentHandlerImpl( xRoot, bSingleThreadedUse ) );
894 return Reference< xml::sax::XDocumentHandler >();
897 //------------------------------------------------------------------------------
898 Reference< XInterface > SAL_CALL create_DocumentHandlerImpl(
899 Reference< XComponentContext > const & )
900 SAL_THROW( (Exception) )
902 return static_cast< ::cppu::OWeakObject * >(
903 new DocumentHandlerImpl(
904 Reference< xml::input::XRoot >(), false /* mt use */ ) );