Bump for 3.6-28
[LibreOffice.git] / xmlscript / source / xml_helper / xml_impctx.cxx
blob2aa2c0eac5db01733ff819c0389a4260a64b969f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "osl/diagnose.h"
31 #include "osl/mutex.hxx"
32 #include "rtl/ustrbuf.hxx"
33 #include "cppuhelper/factory.hxx"
34 #include "cppuhelper/implementationentry.hxx"
35 #include "cppuhelper/implbase1.hxx"
36 #include "cppuhelper/implbase3.hxx"
37 #include "xml_import.hxx"
39 #include "com/sun/star/xml/input/XAttributes.hpp"
40 #include "com/sun/star/lang/XInitialization.hpp"
41 #include "com/sun/star/uno/XComponentContext.hpp"
43 #include <vector>
44 #include <boost/unordered_map.hpp>
46 #include <memory>
49 using namespace ::rtl;
50 using namespace ::osl;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
54 namespace xmlscript
57 const sal_Int32 UID_UNKNOWN = -1;
59 Sequence< OUString > getSupportedServiceNames_DocumentHandlerImpl()
61 OUString name( RTL_CONSTASCII_USTRINGPARAM(
62 "com.sun.star.xml.input.SaxDocumentHandler") );
63 return Sequence< OUString >( &name, 1 );
66 OUString getImplementationName_DocumentHandlerImpl()
68 return OUString( RTL_CONSTASCII_USTRINGPARAM(
69 "com.sun.star.comp.xml.input.SaxDocumentHandler") );
72 typedef ::boost::unordered_map< OUString, sal_Int32, OUStringHash > t_OUString2LongMap;
74 struct PrefixEntry
76 ::std::vector< sal_Int32 > m_Uids;
78 inline PrefixEntry() SAL_THROW(())
79 { m_Uids.reserve( 4 ); }
82 typedef ::boost::unordered_map<
83 OUString, PrefixEntry *, OUStringHash > t_OUString2PrefixMap;
85 struct ElementEntry
87 Reference< xml::input::XElement > m_xElement;
88 ::std::vector< OUString > m_prefixes;
90 inline ElementEntry()
91 { m_prefixes.reserve( 2 ); }
94 typedef ::std::vector< ElementEntry * > t_ElementVector;
96 class ExtendedAttributes;
98 //==============================================================================
99 struct MGuard
101 Mutex * m_pMutex;
102 explicit MGuard( Mutex * pMutex )
103 : m_pMutex( pMutex )
104 { if (m_pMutex) m_pMutex->acquire(); }
105 ~MGuard() throw ()
106 { if (m_pMutex) m_pMutex->release(); }
109 //==============================================================================
110 class DocumentHandlerImpl :
111 public ::cppu::WeakImplHelper3< xml::sax::XDocumentHandler,
112 xml::input::XNamespaceMapping,
113 lang::XInitialization >
115 friend class ExtendedAttributes;
117 Reference< xml::input::XRoot > m_xRoot;
119 t_OUString2LongMap m_URI2Uid;
120 sal_Int32 m_uid_count;
122 OUString m_sXMLNS_PREFIX_UNKNOWN;
123 OUString m_sXMLNS;
125 sal_Int32 m_nLastURI_lookup;
126 OUString m_aLastURI_lookup;
128 t_OUString2PrefixMap m_prefixes;
129 sal_Int32 m_nLastPrefix_lookup;
130 OUString m_aLastPrefix_lookup;
132 t_ElementVector m_elements;
133 sal_Int32 m_nSkipElements;
135 Mutex * m_pMutex;
137 inline Reference< xml::input::XElement > getCurrentElement() const;
139 inline sal_Int32 getUidByURI( OUString const & rURI );
140 inline sal_Int32 getUidByPrefix( OUString const & rPrefix );
142 inline void pushPrefix(
143 OUString const & rPrefix, OUString const & rURI );
144 inline void popPrefix( OUString const & rPrefix );
146 inline void getElementName(
147 OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName );
149 public:
150 DocumentHandlerImpl(
151 Reference< xml::input::XRoot > const & xRoot,
152 bool bSingleThreadedUse );
153 virtual ~DocumentHandlerImpl() throw ();
155 // XServiceInfo
156 virtual OUString SAL_CALL getImplementationName()
157 throw (RuntimeException);
158 virtual sal_Bool SAL_CALL supportsService(
159 OUString const & servicename )
160 throw (RuntimeException);
161 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
162 throw (RuntimeException);
164 // XInitialization
165 virtual void SAL_CALL initialize(
166 Sequence< Any > const & arguments )
167 throw (Exception);
169 // XDocumentHandler
170 virtual void SAL_CALL startDocument()
171 throw (xml::sax::SAXException, RuntimeException);
172 virtual void SAL_CALL endDocument()
173 throw (xml::sax::SAXException, RuntimeException);
174 virtual void SAL_CALL startElement(
175 OUString const & rQElementName,
176 Reference< xml::sax::XAttributeList > const & xAttribs )
177 throw (xml::sax::SAXException, RuntimeException);
178 virtual void SAL_CALL endElement(
179 OUString const & rQElementName )
180 throw (xml::sax::SAXException, RuntimeException);
181 virtual void SAL_CALL characters(
182 OUString const & rChars )
183 throw (xml::sax::SAXException, RuntimeException);
184 virtual void SAL_CALL ignorableWhitespace(
185 OUString const & rWhitespaces )
186 throw (xml::sax::SAXException, RuntimeException);
187 virtual void SAL_CALL processingInstruction(
188 OUString const & rTarget, OUString const & rData )
189 throw (xml::sax::SAXException, RuntimeException);
190 virtual void SAL_CALL setDocumentLocator(
191 Reference< xml::sax::XLocator > const & xLocator )
192 throw (xml::sax::SAXException, RuntimeException);
194 // XNamespaceMapping
195 virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri )
196 throw (RuntimeException);
197 virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid )
198 throw (container::NoSuchElementException, RuntimeException);
201 //______________________________________________________________________________
202 DocumentHandlerImpl::DocumentHandlerImpl(
203 Reference< xml::input::XRoot > const & xRoot,
204 bool bSingleThreadedUse )
205 : m_xRoot( xRoot ),
206 m_uid_count( 0 ),
207 m_sXMLNS_PREFIX_UNKNOWN(
208 RTL_CONSTASCII_USTRINGPARAM("<<< unknown prefix >>>") ),
209 m_sXMLNS( RTL_CONSTASCII_USTRINGPARAM("xmlns") ),
210 m_nLastURI_lookup( UID_UNKNOWN ),
211 m_aLastURI_lookup( RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ),
212 m_nLastPrefix_lookup( UID_UNKNOWN ),
213 m_aLastPrefix_lookup(
214 RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ),
215 m_nSkipElements( 0 ),
216 m_pMutex( 0 )
218 m_elements.reserve( 10 );
220 if (! bSingleThreadedUse)
221 m_pMutex = new Mutex();
224 //______________________________________________________________________________
225 DocumentHandlerImpl::~DocumentHandlerImpl() throw ()
227 if (m_pMutex != 0)
229 delete m_pMutex;
230 #if OSL_DEBUG_LEVEL == 0
231 m_pMutex = 0;
232 #endif
236 //______________________________________________________________________________
237 inline Reference< xml::input::XElement >
238 DocumentHandlerImpl::getCurrentElement() const
240 MGuard aGuard( m_pMutex );
241 if (m_elements.empty())
242 return Reference< xml::input::XElement >();
243 else
244 return m_elements.back()->m_xElement;
247 //______________________________________________________________________________
248 inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI )
250 MGuard guard( m_pMutex );
251 if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI)
253 t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) );
254 if (iFind != m_URI2Uid.end()) // id found
256 m_nLastURI_lookup = iFind->second;
257 m_aLastURI_lookup = rURI;
259 else
261 m_nLastURI_lookup = m_uid_count;
262 ++m_uid_count;
263 m_URI2Uid[ rURI ] = m_nLastURI_lookup;
264 m_aLastURI_lookup = rURI;
267 return m_nLastURI_lookup;
270 //______________________________________________________________________________
271 inline sal_Int32 DocumentHandlerImpl::getUidByPrefix(
272 OUString const & rPrefix )
274 // commonly the last added prefix is used often for several tags...
275 // good guess
276 if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix)
278 t_OUString2PrefixMap::const_iterator iFind(
279 m_prefixes.find( rPrefix ) );
280 if (iFind != m_prefixes.end())
282 const PrefixEntry & rPrefixEntry = *iFind->second;
283 OSL_ASSERT( ! rPrefixEntry.m_Uids.empty() );
284 m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back();
285 m_aLastPrefix_lookup = rPrefix;
287 else
289 m_nLastPrefix_lookup = UID_UNKNOWN;
290 m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
293 return m_nLastPrefix_lookup;
296 //______________________________________________________________________________
297 inline void DocumentHandlerImpl::pushPrefix(
298 OUString const & rPrefix, OUString const & rURI )
300 // lookup id for URI
301 sal_Int32 nUid = getUidByURI( rURI );
303 // mark prefix with id
304 t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) );
305 if (iFind == m_prefixes.end()) // unused prefix
307 PrefixEntry * pEntry = new PrefixEntry();
308 pEntry->m_Uids.push_back( nUid ); // latest id for prefix
309 m_prefixes[ rPrefix ] = pEntry;
311 else
313 PrefixEntry * pEntry = iFind->second;
314 OSL_ASSERT( ! pEntry->m_Uids.empty() );
315 pEntry->m_Uids.push_back( nUid );
318 m_aLastPrefix_lookup = rPrefix;
319 m_nLastPrefix_lookup = nUid;
322 //______________________________________________________________________________
323 inline void DocumentHandlerImpl::popPrefix(
324 OUString const & rPrefix )
326 t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) );
327 if (iFind != m_prefixes.end()) // unused prefix
329 PrefixEntry * pEntry = iFind->second;
330 pEntry->m_Uids.pop_back(); // pop last id for prefix
331 if (pEntry->m_Uids.empty()) // erase prefix key
333 m_prefixes.erase( iFind );
334 delete pEntry;
338 m_nLastPrefix_lookup = UID_UNKNOWN;
339 m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
342 //______________________________________________________________________________
343 inline void DocumentHandlerImpl::getElementName(
344 OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName )
346 sal_Int32 nColonPos = rQName.indexOf( (sal_Unicode)':' );
347 *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName);
348 *pUid = getUidByPrefix(
349 nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() );
353 //==============================================================================
354 class ExtendedAttributes :
355 public ::cppu::WeakImplHelper1< xml::input::XAttributes >
357 sal_Int32 m_nAttributes;
358 sal_Int32 * m_pUids;
359 OUString * m_pPrefixes;
360 OUString * m_pLocalNames;
361 OUString * m_pQNames;
362 OUString * m_pValues;
364 DocumentHandlerImpl * m_pHandler;
366 public:
367 inline ExtendedAttributes(
368 sal_Int32 nAttributes,
369 sal_Int32 * pUids, OUString * pPrefixes,
370 OUString * pLocalNames, OUString * pQNames,
371 Reference< xml::sax::XAttributeList > const & xAttributeList,
372 DocumentHandlerImpl * pHandler );
373 virtual ~ExtendedAttributes() throw ();
375 // XAttributes
376 virtual sal_Int32 SAL_CALL getLength()
377 throw (RuntimeException);
378 virtual sal_Int32 SAL_CALL getIndexByQName(
379 OUString const & rQName )
380 throw (RuntimeException);
381 virtual sal_Int32 SAL_CALL getIndexByUidName(
382 sal_Int32 nUid, OUString const & rLocalName )
383 throw (RuntimeException);
384 virtual OUString SAL_CALL getQNameByIndex(
385 sal_Int32 nIndex )
386 throw (RuntimeException);
387 virtual sal_Int32 SAL_CALL getUidByIndex(
388 sal_Int32 nIndex )
389 throw (RuntimeException);
390 virtual OUString SAL_CALL getLocalNameByIndex(
391 sal_Int32 nIndex )
392 throw (RuntimeException);
393 virtual OUString SAL_CALL getValueByIndex(
394 sal_Int32 nIndex )
395 throw (RuntimeException);
396 virtual OUString SAL_CALL getValueByUidName(
397 sal_Int32 nUid, OUString const & rLocalName )
398 throw (RuntimeException);
399 virtual OUString SAL_CALL getTypeByIndex(
400 sal_Int32 nIndex )
401 throw (RuntimeException);
404 //______________________________________________________________________________
405 inline ExtendedAttributes::ExtendedAttributes(
406 sal_Int32 nAttributes,
407 sal_Int32 * pUids, OUString * pPrefixes,
408 OUString * pLocalNames, OUString * pQNames,
409 Reference< xml::sax::XAttributeList > const & xAttributeList,
410 DocumentHandlerImpl * pHandler )
411 : m_nAttributes( nAttributes )
412 , m_pUids( pUids )
413 , m_pPrefixes( pPrefixes )
414 , m_pLocalNames( pLocalNames )
415 , m_pQNames( pQNames )
416 , m_pValues( new OUString[ nAttributes ] )
417 , m_pHandler( pHandler )
419 m_pHandler->acquire();
421 for ( sal_Int16 nPos = 0; nPos < nAttributes; ++nPos )
423 m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos );
427 //______________________________________________________________________________
428 ExtendedAttributes::~ExtendedAttributes() throw ()
430 m_pHandler->release();
432 delete [] m_pUids;
433 delete [] m_pPrefixes;
434 delete [] m_pLocalNames;
435 delete [] m_pQNames;
436 delete [] m_pValues;
440 //##############################################################################
442 // XServiceInfo
444 //______________________________________________________________________________
445 OUString DocumentHandlerImpl::getImplementationName()
446 throw (RuntimeException)
448 return getImplementationName_DocumentHandlerImpl();
451 //______________________________________________________________________________
452 sal_Bool DocumentHandlerImpl::supportsService(
453 OUString const & servicename )
454 throw (RuntimeException)
456 Sequence< OUString > names( getSupportedServiceNames_DocumentHandlerImpl() );
457 for ( sal_Int32 nPos = names.getLength(); nPos--; )
459 if (names[ nPos ].equals( servicename ))
460 return sal_True;
462 return sal_False;
465 //______________________________________________________________________________
466 Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames()
467 throw (RuntimeException)
469 return getSupportedServiceNames_DocumentHandlerImpl();
472 // XInitialization
474 //______________________________________________________________________________
475 void DocumentHandlerImpl::initialize(
476 Sequence< Any > const & arguments )
477 throw (Exception)
479 MGuard guard( m_pMutex );
480 Reference< xml::input::XRoot > xRoot;
481 if (arguments.getLength() == 1 &&
482 (arguments[ 0 ] >>= xRoot) &&
483 xRoot.is())
485 m_xRoot = xRoot;
487 else
489 throw RuntimeException(
490 OUString( RTL_CONSTASCII_USTRINGPARAM(
491 "missing root instance!") ),
492 Reference< XInterface >() );
497 // XNamespaceMapping
499 //______________________________________________________________________________
500 sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri )
501 throw (RuntimeException)
503 sal_Int32 uid = getUidByURI( Uri );
504 OSL_ASSERT( uid != UID_UNKNOWN );
505 return uid;
508 //______________________________________________________________________________
509 OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid )
510 throw (container::NoSuchElementException, RuntimeException)
512 MGuard guard( m_pMutex );
513 t_OUString2LongMap::const_iterator iPos( m_URI2Uid.begin() );
514 t_OUString2LongMap::const_iterator const iEnd( m_URI2Uid.end() );
515 for ( ; iPos != iEnd; ++iPos )
517 if (iPos->second == Uid)
518 return iPos->first;
520 throw container::NoSuchElementException(
521 OUString( RTL_CONSTASCII_USTRINGPARAM("no such xmlns uid!") ),
522 static_cast< OWeakObject * >(this) );
526 // XDocumentHandler
528 //______________________________________________________________________________
529 void DocumentHandlerImpl::startDocument()
530 throw (xml::sax::SAXException, RuntimeException)
532 m_xRoot->startDocument(
533 static_cast< xml::input::XNamespaceMapping * >( this ) );
536 //______________________________________________________________________________
537 void DocumentHandlerImpl::endDocument()
538 throw (xml::sax::SAXException, RuntimeException)
540 m_xRoot->endDocument();
543 //______________________________________________________________________________
544 void DocumentHandlerImpl::startElement(
545 OUString const & rQElementName,
546 Reference< xml::sax::XAttributeList > const & xAttribs )
547 throw (xml::sax::SAXException, RuntimeException)
549 Reference< xml::input::XElement > xCurrentElement;
550 Reference< xml::input::XAttributes > xAttributes;
551 sal_Int32 nUid;
552 OUString aLocalName;
553 ::std::auto_ptr< ElementEntry > elementEntry( new ElementEntry );
555 { // guard start:
556 MGuard aGuard( m_pMutex );
557 // currently skipping elements and waiting for end tags?
558 if (m_nSkipElements > 0)
560 ++m_nSkipElements; // wait for another end tag
561 #if OSL_DEBUG_LEVEL > 1
562 OString aQName(
563 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
564 OSL_TRACE( "### no context given on createChildElement() "
565 "=> ignoring element \"%s\" ...", aQName.getStr() );
566 #endif
567 return;
570 sal_Int16 nAttribs = xAttribs->getLength();
572 // save all namespace ids
573 sal_Int32 * pUids = new sal_Int32[ nAttribs ];
574 OUString * pPrefixes = new OUString[ nAttribs ];
575 OUString * pLocalNames = new OUString[ nAttribs ];
576 OUString * pQNames = new OUString[ nAttribs ];
578 // first recognize all xmlns attributes
579 sal_Int16 nPos;
580 for ( nPos = 0; nPos < nAttribs; ++nPos )
582 // mark attribute to be collected further
583 // on with attribute's uid and current prefix
584 pUids[ nPos ] = 0; // modified
586 pQNames[ nPos ] = xAttribs->getNameByIndex( nPos );
587 OUString const & rQAttributeName = pQNames[ nPos ];
589 if (rQAttributeName.compareTo( m_sXMLNS, 5 ) == 0)
591 if (rQAttributeName.getLength() == 5) // set default namespace
593 OUString aDefNamespacePrefix;
594 pushPrefix(
595 aDefNamespacePrefix,
596 xAttribs->getValueByIndex( nPos ) );
597 elementEntry->m_prefixes.push_back( aDefNamespacePrefix );
598 pUids[ nPos ] = UID_UNKNOWN;
599 pPrefixes[ nPos ] = m_sXMLNS;
600 pLocalNames[ nPos ] = aDefNamespacePrefix;
602 else if ((sal_Unicode)':' == rQAttributeName[ 5 ]) // set prefix
604 OUString aPrefix( rQAttributeName.copy( 6 ) );
605 pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) );
606 elementEntry->m_prefixes.push_back( aPrefix );
607 pUids[ nPos ] = UID_UNKNOWN;
608 pPrefixes[ nPos ] = m_sXMLNS;
609 pLocalNames[ nPos ] = aPrefix;
611 // else just a name starting with xmlns, but no prefix
615 // now read out attribute prefixes (all namespace prefixes have been set)
616 for ( nPos = 0; nPos < nAttribs; ++nPos )
618 if (pUids[ nPos ] >= 0) // no xmlns: attribute
620 OUString const & rQAttributeName = pQNames[ nPos ];
621 OSL_ENSURE(
622 rQAttributeName.compareToAscii(
623 RTL_CONSTASCII_STRINGPARAM("xmlns:") ) != 0,
624 "### unexpected xmlns!" );
626 // collect attribute's uid and current prefix
627 sal_Int32 nColonPos = rQAttributeName.indexOf( (sal_Unicode) ':' );
628 if (nColonPos >= 0)
630 pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos );
631 pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 );
633 else
635 pPrefixes[ nPos ] = OUString();
636 pLocalNames[ nPos ] = rQAttributeName;
637 // leave local names unmodified
639 pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] );
642 // ownership of arrays belongs to attribute list
643 xAttributes = static_cast< xml::input::XAttributes * >(
644 new ExtendedAttributes(
645 nAttribs, pUids, pPrefixes, pLocalNames, pQNames,
646 xAttribs, this ) );
648 getElementName( rQElementName, &nUid, &aLocalName );
650 // create new child context and append to list
651 if (! m_elements.empty())
652 xCurrentElement = m_elements.back()->m_xElement;
653 } // :guard end
655 if (xCurrentElement.is())
657 elementEntry->m_xElement =
658 xCurrentElement->startChildElement( nUid, aLocalName, xAttributes );
660 else
662 elementEntry->m_xElement =
663 m_xRoot->startRootElement( nUid, aLocalName, xAttributes );
667 MGuard aGuard( m_pMutex );
668 if (elementEntry->m_xElement.is())
670 m_elements.push_back( elementEntry.release() );
672 else
674 ++m_nSkipElements;
675 #if OSL_DEBUG_LEVEL > 1
676 OString aQName(
677 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
678 OSL_TRACE(
679 "### no context given on createChildElement() => "
680 "ignoring element \"%s\" ...", aQName.getStr() );
681 #endif
686 //______________________________________________________________________________
687 void DocumentHandlerImpl::endElement(
688 OUString const & rQElementName )
689 throw (xml::sax::SAXException, RuntimeException)
691 Reference< xml::input::XElement > xCurrentElement;
693 MGuard aGuard( m_pMutex );
694 if (m_nSkipElements)
696 --m_nSkipElements;
697 #if OSL_DEBUG_LEVEL > 1
698 OString aQName(
699 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
700 OSL_TRACE( "### received endElement() for \"%s\".", aQName.getStr() );
701 #endif
702 static_cast<void>(rQElementName);
703 return;
706 // popping context
707 OSL_ASSERT( ! m_elements.empty() );
708 ElementEntry * pEntry = m_elements.back();
709 xCurrentElement = pEntry->m_xElement;
711 #if OSL_DEBUG_LEVEL > 0
712 sal_Int32 nUid;
713 OUString aLocalName;
714 getElementName( rQElementName, &nUid, &aLocalName );
715 OSL_ASSERT( xCurrentElement->getLocalName() == aLocalName );
716 OSL_ASSERT( xCurrentElement->getUid() == nUid );
717 #endif
719 // pop prefixes
720 for ( sal_Int32 nPos = pEntry->m_prefixes.size(); nPos--; )
722 popPrefix( pEntry->m_prefixes[ nPos ] );
724 m_elements.pop_back();
725 delete pEntry;
727 xCurrentElement->endElement();
730 //______________________________________________________________________________
731 void DocumentHandlerImpl::characters( OUString const & rChars )
732 throw (xml::sax::SAXException, RuntimeException)
734 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
735 if (xCurrentElement.is())
736 xCurrentElement->characters( rChars );
739 //______________________________________________________________________________
740 void DocumentHandlerImpl::ignorableWhitespace(
741 OUString const & rWhitespaces )
742 throw (xml::sax::SAXException, RuntimeException)
744 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
745 if (xCurrentElement.is())
746 xCurrentElement->ignorableWhitespace( rWhitespaces );
749 //______________________________________________________________________________
750 void DocumentHandlerImpl::processingInstruction(
751 OUString const & rTarget, OUString const & rData )
752 throw (xml::sax::SAXException, RuntimeException)
754 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
755 if (xCurrentElement.is())
756 xCurrentElement->processingInstruction( rTarget, rData );
757 else
758 m_xRoot->processingInstruction( rTarget, rData );
761 //______________________________________________________________________________
762 void DocumentHandlerImpl::setDocumentLocator(
763 Reference< xml::sax::XLocator > const & xLocator )
764 throw (xml::sax::SAXException, RuntimeException)
766 m_xRoot->setDocumentLocator( xLocator );
769 //##############################################################################
771 // XAttributes
773 //______________________________________________________________________________
774 sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName )
775 throw (RuntimeException)
777 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
779 if (m_pQNames[ nPos ].equals( rQName ))
781 return nPos;
784 return -1;
787 //______________________________________________________________________________
788 sal_Int32 ExtendedAttributes::getLength()
789 throw (RuntimeException)
791 return m_nAttributes;
794 //______________________________________________________________________________
795 OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex )
796 throw (RuntimeException)
798 if (nIndex < m_nAttributes)
799 return m_pLocalNames[ nIndex ];
800 else
801 return OUString();
804 //______________________________________________________________________________
805 OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex )
806 throw (RuntimeException)
808 if (nIndex < m_nAttributes)
809 return m_pQNames[ nIndex ];
810 else
811 return OUString();
814 //______________________________________________________________________________
815 OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex )
816 throw (RuntimeException)
818 static_cast<void>(nIndex);
819 OSL_ASSERT( nIndex < m_nAttributes );
820 return OUString(); // unsupported
823 //______________________________________________________________________________
824 OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex )
825 throw (RuntimeException)
827 if (nIndex < m_nAttributes)
828 return m_pValues[ nIndex ];
829 else
830 return OUString();
833 //______________________________________________________________________________
834 sal_Int32 ExtendedAttributes::getIndexByUidName(
835 sal_Int32 nUid, OUString const & rLocalName )
836 throw (RuntimeException)
838 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
840 if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
842 return nPos;
845 return -1;
848 //______________________________________________________________________________
849 sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex )
850 throw (RuntimeException)
852 if (nIndex < m_nAttributes)
853 return m_pUids[ nIndex ];
854 else
855 return -1;
858 //______________________________________________________________________________
859 OUString ExtendedAttributes::getValueByUidName(
860 sal_Int32 nUid, OUString const & rLocalName )
861 throw (RuntimeException)
863 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
865 if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
867 return m_pValues[ nPos ];
870 return OUString();
874 //##############################################################################
877 //==============================================================================
878 Reference< xml::sax::XDocumentHandler > SAL_CALL createDocumentHandler(
879 Reference< xml::input::XRoot > const & xRoot,
880 bool bSingleThreadedUse )
881 SAL_THROW(())
883 OSL_ASSERT( xRoot.is() );
884 if (xRoot.is())
886 return static_cast< xml::sax::XDocumentHandler * >(
887 new DocumentHandlerImpl( xRoot, bSingleThreadedUse ) );
889 return Reference< xml::sax::XDocumentHandler >();
892 //------------------------------------------------------------------------------
893 Reference< XInterface > SAL_CALL create_DocumentHandlerImpl(
894 SAL_UNUSED_PARAMETER Reference< XComponentContext > const & )
895 SAL_THROW( (Exception) )
897 return static_cast< ::cppu::OWeakObject * >(
898 new DocumentHandlerImpl(
899 Reference< xml::input::XRoot >(), false /* mt use */ ) );
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */