bump product version to 5.0.4.1
[LibreOffice.git] / xmlscript / source / xml_helper / xml_impctx.cxx
blob06f279b7c9bffeefcfcf61c0f502bdbb372afd14
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include "unoservices.hxx"
23 #include "xml_import.hxx"
25 #include <cppuhelper/factory.hxx>
26 #include <cppuhelper/implementationentry.hxx>
27 #include <cppuhelper/implbase1.hxx>
28 #include <cppuhelper/implbase4.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <com/sun/star/xml/input/XAttributes.hpp>
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/uno/XComponentContext.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <sal/log.hxx>
36 #include <memory>
37 #include <unordered_map>
38 #include <vector>
40 using namespace ::osl;
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
44 namespace xmlscript
47 const sal_Int32 UID_UNKNOWN = -1;
49 Sequence< OUString > getSupportedServiceNames_DocumentHandlerImpl()
51 OUString name( "com.sun.star.xml.input.SaxDocumentHandler" );
52 return Sequence< OUString >( &name, 1 );
55 OUString getImplementationName_DocumentHandlerImpl()
57 return OUString( "com.sun.star.comp.xml.input.SaxDocumentHandler" );
60 typedef std::unordered_map< OUString, sal_Int32, OUStringHash > t_OUString2LongMap;
62 struct PrefixEntry
64 ::std::vector< sal_Int32 > m_Uids;
66 inline PrefixEntry()
67 { m_Uids.reserve( 4 ); }
70 typedef std::unordered_map<
71 OUString, PrefixEntry *, OUStringHash > t_OUString2PrefixMap;
73 struct ElementEntry
75 Reference< xml::input::XElement > m_xElement;
76 ::std::vector< OUString > m_prefixes;
78 inline ElementEntry()
79 { m_prefixes.reserve( 2 ); }
82 typedef ::std::vector< ElementEntry * > t_ElementVector;
84 class ExtendedAttributes;
86 struct MGuard
88 Mutex * m_pMutex;
89 explicit MGuard( Mutex * pMutex )
90 : m_pMutex( pMutex )
91 { if (m_pMutex) m_pMutex->acquire(); }
92 ~MGuard() throw ()
93 { if (m_pMutex) m_pMutex->release(); }
96 class DocumentHandlerImpl :
97 public ::cppu::WeakImplHelper4< xml::sax::XDocumentHandler,
98 xml::input::XNamespaceMapping,
99 lang::XInitialization,
100 com::sun::star::lang::XServiceInfo >
102 friend class ExtendedAttributes;
104 Reference< xml::input::XRoot > m_xRoot;
106 t_OUString2LongMap m_URI2Uid;
107 sal_Int32 m_uid_count;
109 OUString m_sXMLNS_PREFIX_UNKNOWN;
110 OUString m_sXMLNS;
112 sal_Int32 m_nLastURI_lookup;
113 OUString m_aLastURI_lookup;
115 t_OUString2PrefixMap m_prefixes;
116 sal_Int32 m_nLastPrefix_lookup;
117 OUString m_aLastPrefix_lookup;
119 t_ElementVector m_elements;
120 sal_Int32 m_nSkipElements;
122 Mutex * m_pMutex;
124 inline Reference< xml::input::XElement > getCurrentElement() const;
126 inline sal_Int32 getUidByURI( OUString const & rURI );
127 inline sal_Int32 getUidByPrefix( OUString const & rPrefix );
129 inline void pushPrefix(
130 OUString const & rPrefix, OUString const & rURI );
131 inline void popPrefix( OUString const & rPrefix );
133 inline void getElementName(
134 OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName );
136 public:
137 DocumentHandlerImpl(
138 Reference< xml::input::XRoot > const & xRoot,
139 bool bSingleThreadedUse );
140 virtual ~DocumentHandlerImpl() throw ();
142 // XServiceInfo
143 virtual OUString SAL_CALL getImplementationName()
144 throw (RuntimeException, std::exception) SAL_OVERRIDE;
145 virtual sal_Bool SAL_CALL supportsService(
146 OUString const & servicename )
147 throw (RuntimeException, std::exception) SAL_OVERRIDE;
148 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
149 throw (RuntimeException, std::exception) SAL_OVERRIDE;
151 // XInitialization
152 virtual void SAL_CALL initialize(
153 Sequence< Any > const & arguments )
154 throw (Exception, std::exception) SAL_OVERRIDE;
156 // XDocumentHandler
157 virtual void SAL_CALL startDocument()
158 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
159 virtual void SAL_CALL endDocument()
160 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
161 virtual void SAL_CALL startElement(
162 OUString const & rQElementName,
163 Reference< xml::sax::XAttributeList > const & xAttribs )
164 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
165 virtual void SAL_CALL endElement(
166 OUString const & rQElementName )
167 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
168 virtual void SAL_CALL characters(
169 OUString const & rChars )
170 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
171 virtual void SAL_CALL ignorableWhitespace(
172 OUString const & rWhitespaces )
173 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
174 virtual void SAL_CALL processingInstruction(
175 OUString const & rTarget, OUString const & rData )
176 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
177 virtual void SAL_CALL setDocumentLocator(
178 Reference< xml::sax::XLocator > const & xLocator )
179 throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
181 // XNamespaceMapping
182 virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri )
183 throw (RuntimeException, std::exception) SAL_OVERRIDE;
184 virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid )
185 throw (container::NoSuchElementException, RuntimeException, std::exception) SAL_OVERRIDE;
188 DocumentHandlerImpl::DocumentHandlerImpl(
189 Reference< xml::input::XRoot > const & xRoot,
190 bool bSingleThreadedUse )
191 : m_xRoot( xRoot ),
192 m_uid_count( 0 ),
193 m_sXMLNS_PREFIX_UNKNOWN( "<<< unknown prefix >>>" ),
194 m_sXMLNS( "xmlns" ),
195 m_nLastURI_lookup( UID_UNKNOWN ),
196 m_aLastURI_lookup( "<<< unknown URI >>>" ),
197 m_nLastPrefix_lookup( UID_UNKNOWN ),
198 m_aLastPrefix_lookup( "<<< unknown URI >>>" ),
199 m_nSkipElements( 0 ),
200 m_pMutex( 0 )
202 m_elements.reserve( 10 );
204 if (! bSingleThreadedUse)
205 m_pMutex = new Mutex();
208 DocumentHandlerImpl::~DocumentHandlerImpl() throw ()
210 if (m_pMutex != 0)
212 delete m_pMutex;
213 #if OSL_DEBUG_LEVEL == 0
214 m_pMutex = 0;
215 #endif
219 inline Reference< xml::input::XElement >
220 DocumentHandlerImpl::getCurrentElement() const
222 MGuard aGuard( m_pMutex );
223 if (m_elements.empty())
224 return Reference< xml::input::XElement >();
225 else
226 return m_elements.back()->m_xElement;
229 inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI )
231 MGuard guard( m_pMutex );
232 if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI)
234 t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) );
235 if (iFind != m_URI2Uid.end()) // id found
237 m_nLastURI_lookup = iFind->second;
238 m_aLastURI_lookup = rURI;
240 else
242 m_nLastURI_lookup = m_uid_count;
243 ++m_uid_count;
244 m_URI2Uid[ rURI ] = m_nLastURI_lookup;
245 m_aLastURI_lookup = rURI;
248 return m_nLastURI_lookup;
251 inline sal_Int32 DocumentHandlerImpl::getUidByPrefix(
252 OUString const & rPrefix )
254 // commonly the last added prefix is used often for several tags...
255 // good guess
256 if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix)
258 t_OUString2PrefixMap::const_iterator iFind(
259 m_prefixes.find( rPrefix ) );
260 if (iFind != m_prefixes.end())
262 const PrefixEntry & rPrefixEntry = *iFind->second;
263 SAL_WARN_IF( rPrefixEntry.m_Uids.empty(), "xmlscript.xmlhelper", "rPrefixEntry.m_Uids is empty" );
264 m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back();
265 m_aLastPrefix_lookup = rPrefix;
267 else
269 m_nLastPrefix_lookup = UID_UNKNOWN;
270 m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
273 return m_nLastPrefix_lookup;
276 inline void DocumentHandlerImpl::pushPrefix(
277 OUString const & rPrefix, OUString const & rURI )
279 // lookup id for URI
280 sal_Int32 nUid = getUidByURI( rURI );
282 // mark prefix with id
283 t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) );
284 if (iFind == m_prefixes.end()) // unused prefix
286 PrefixEntry * pEntry = new PrefixEntry();
287 pEntry->m_Uids.push_back( nUid ); // latest id for prefix
288 m_prefixes[ rPrefix ] = pEntry;
290 else
292 PrefixEntry * pEntry = iFind->second;
293 SAL_WARN_IF( pEntry->m_Uids.empty(), "xmlscript.xmlhelper", "pEntry->m_Uids is empty" );
294 pEntry->m_Uids.push_back( nUid );
297 m_aLastPrefix_lookup = rPrefix;
298 m_nLastPrefix_lookup = nUid;
301 inline void DocumentHandlerImpl::popPrefix(
302 OUString const & rPrefix )
304 t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) );
305 if (iFind != m_prefixes.end()) // unused prefix
307 PrefixEntry * pEntry = iFind->second;
308 pEntry->m_Uids.pop_back(); // pop last id for prefix
309 if (pEntry->m_Uids.empty()) // erase prefix key
311 m_prefixes.erase( iFind );
312 delete pEntry;
316 m_nLastPrefix_lookup = UID_UNKNOWN;
317 m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
320 inline void DocumentHandlerImpl::getElementName(
321 OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName )
323 sal_Int32 nColonPos = rQName.indexOf( (sal_Unicode)':' );
324 *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName);
325 *pUid = getUidByPrefix(
326 nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() );
329 class ExtendedAttributes :
330 public ::cppu::WeakImplHelper1< xml::input::XAttributes >
332 sal_Int32 m_nAttributes;
333 sal_Int32 * m_pUids;
334 OUString * m_pPrefixes;
335 OUString * m_pLocalNames;
336 OUString * m_pQNames;
337 OUString * m_pValues;
339 DocumentHandlerImpl * m_pHandler;
341 public:
342 inline ExtendedAttributes(
343 sal_Int32 nAttributes,
344 sal_Int32 * pUids, OUString * pPrefixes,
345 OUString * pLocalNames, OUString * pQNames,
346 Reference< xml::sax::XAttributeList > const & xAttributeList,
347 DocumentHandlerImpl * pHandler );
348 virtual ~ExtendedAttributes() throw ();
350 // XAttributes
351 virtual sal_Int32 SAL_CALL getLength()
352 throw (RuntimeException, std::exception) SAL_OVERRIDE;
353 virtual sal_Int32 SAL_CALL getIndexByQName(
354 OUString const & rQName )
355 throw (RuntimeException, std::exception) SAL_OVERRIDE;
356 virtual sal_Int32 SAL_CALL getIndexByUidName(
357 sal_Int32 nUid, OUString const & rLocalName )
358 throw (RuntimeException, std::exception) SAL_OVERRIDE;
359 virtual OUString SAL_CALL getQNameByIndex(
360 sal_Int32 nIndex )
361 throw (RuntimeException, std::exception) SAL_OVERRIDE;
362 virtual sal_Int32 SAL_CALL getUidByIndex(
363 sal_Int32 nIndex )
364 throw (RuntimeException, std::exception) SAL_OVERRIDE;
365 virtual OUString SAL_CALL getLocalNameByIndex(
366 sal_Int32 nIndex )
367 throw (RuntimeException, std::exception) SAL_OVERRIDE;
368 virtual OUString SAL_CALL getValueByIndex(
369 sal_Int32 nIndex )
370 throw (RuntimeException, std::exception) SAL_OVERRIDE;
371 virtual OUString SAL_CALL getValueByUidName(
372 sal_Int32 nUid, OUString const & rLocalName )
373 throw (RuntimeException, std::exception) SAL_OVERRIDE;
374 virtual OUString SAL_CALL getTypeByIndex(
375 sal_Int32 nIndex )
376 throw (RuntimeException, std::exception) SAL_OVERRIDE;
379 inline ExtendedAttributes::ExtendedAttributes(
380 sal_Int32 nAttributes,
381 sal_Int32 * pUids, OUString * pPrefixes,
382 OUString * pLocalNames, OUString * pQNames,
383 Reference< xml::sax::XAttributeList > const & xAttributeList,
384 DocumentHandlerImpl * pHandler )
385 : m_nAttributes( nAttributes )
386 , m_pUids( pUids )
387 , m_pPrefixes( pPrefixes )
388 , m_pLocalNames( pLocalNames )
389 , m_pQNames( pQNames )
390 , m_pValues( new OUString[ nAttributes ] )
391 , m_pHandler( pHandler )
393 m_pHandler->acquire();
395 for ( sal_Int16 nPos = 0; nPos < nAttributes; ++nPos )
397 m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos );
401 ExtendedAttributes::~ExtendedAttributes() throw ()
403 m_pHandler->release();
405 delete [] m_pUids;
406 delete [] m_pPrefixes;
407 delete [] m_pLocalNames;
408 delete [] m_pQNames;
409 delete [] m_pValues;
412 // XServiceInfo
414 OUString DocumentHandlerImpl::getImplementationName()
415 throw (RuntimeException, std::exception)
417 return getImplementationName_DocumentHandlerImpl();
420 sal_Bool DocumentHandlerImpl::supportsService( OUString const & servicename )
421 throw (RuntimeException, std::exception)
423 return cppu::supportsService(this, servicename);
426 Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames()
427 throw (RuntimeException, std::exception)
429 return getSupportedServiceNames_DocumentHandlerImpl();
432 // XInitialization
434 void DocumentHandlerImpl::initialize(
435 Sequence< Any > const & arguments )
436 throw (Exception, std::exception)
438 MGuard guard( m_pMutex );
439 Reference< xml::input::XRoot > xRoot;
440 if (arguments.getLength() == 1 &&
441 (arguments[ 0 ] >>= xRoot) &&
442 xRoot.is())
444 m_xRoot = xRoot;
446 else
448 throw RuntimeException( "missing root instance!" );
452 // XNamespaceMapping
454 sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri )
455 throw (RuntimeException, std::exception)
457 sal_Int32 uid = getUidByURI( Uri );
458 SAL_WARN_IF( uid == UID_UNKNOWN, "xmlscript.xmlhelper", "uid UNKNOWN");
459 return uid;
462 OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid )
463 throw (container::NoSuchElementException, RuntimeException, std::exception)
465 MGuard guard( m_pMutex );
466 t_OUString2LongMap::const_iterator iPos( m_URI2Uid.begin() );
467 t_OUString2LongMap::const_iterator const iEnd( m_URI2Uid.end() );
468 for ( ; iPos != iEnd; ++iPos )
470 if (iPos->second == Uid)
471 return iPos->first;
473 throw container::NoSuchElementException( "no such xmlns uid!" , static_cast< OWeakObject * >(this) );
476 // XDocumentHandler
478 void DocumentHandlerImpl::startDocument()
479 throw (xml::sax::SAXException, RuntimeException, std::exception)
481 m_xRoot->startDocument( static_cast< xml::input::XNamespaceMapping * >( this ) );
484 void DocumentHandlerImpl::endDocument()
485 throw (xml::sax::SAXException, RuntimeException, std::exception)
487 m_xRoot->endDocument();
490 void DocumentHandlerImpl::startElement(
491 OUString const & rQElementName,
492 Reference< xml::sax::XAttributeList > const & xAttribs )
493 throw (xml::sax::SAXException, RuntimeException, std::exception)
495 Reference< xml::input::XElement > xCurrentElement;
496 Reference< xml::input::XAttributes > xAttributes;
497 sal_Int32 nUid;
498 OUString aLocalName;
499 ::std::unique_ptr< ElementEntry > elementEntry( new ElementEntry );
501 { // guard start:
502 MGuard aGuard( m_pMutex );
503 // currently skipping elements and waiting for end tags?
504 if (m_nSkipElements > 0)
506 ++m_nSkipElements; // wait for another end tag
507 #if OSL_DEBUG_LEVEL > 1
508 OString aQName(
509 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
510 SAL_INFO("xmlscript.xmlhelper", "### no context given on createChildElement() => ignoring element \"" << aQName.getStr() << "\" ...");
511 #endif
512 return;
515 sal_Int16 nAttribs = xAttribs->getLength();
517 // save all namespace ids
518 sal_Int32 * pUids = new sal_Int32[ nAttribs ];
519 OUString * pPrefixes = new OUString[ nAttribs ];
520 OUString * pLocalNames = new OUString[ nAttribs ];
521 OUString * pQNames = new OUString[ nAttribs ];
523 // first recognize all xmlns attributes
524 sal_Int16 nPos;
525 for ( nPos = 0; nPos < nAttribs; ++nPos )
527 // mark attribute to be collected further
528 // on with attribute's uid and current prefix
529 pUids[ nPos ] = 0; // modified
531 pQNames[ nPos ] = xAttribs->getNameByIndex( nPos );
532 OUString const & rQAttributeName = pQNames[ nPos ];
534 if (rQAttributeName.startsWith( m_sXMLNS ))
536 if (rQAttributeName.getLength() == 5) // set default namespace
538 OUString aDefNamespacePrefix;
539 pushPrefix(
540 aDefNamespacePrefix,
541 xAttribs->getValueByIndex( nPos ) );
542 elementEntry->m_prefixes.push_back( aDefNamespacePrefix );
543 pUids[ nPos ] = UID_UNKNOWN;
544 pPrefixes[ nPos ] = m_sXMLNS;
545 pLocalNames[ nPos ] = aDefNamespacePrefix;
547 else if ((sal_Unicode)':' == rQAttributeName[ 5 ]) // set prefix
549 OUString aPrefix( rQAttributeName.copy( 6 ) );
550 pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) );
551 elementEntry->m_prefixes.push_back( aPrefix );
552 pUids[ nPos ] = UID_UNKNOWN;
553 pPrefixes[ nPos ] = m_sXMLNS;
554 pLocalNames[ nPos ] = aPrefix;
556 // else just a name starting with xmlns, but no prefix
560 // now read out attribute prefixes (all namespace prefixes have been set)
561 for ( nPos = 0; nPos < nAttribs; ++nPos )
563 if (pUids[ nPos ] >= 0) // no xmlns: attribute
565 OUString const & rQAttributeName = pQNames[ nPos ];
566 SAL_WARN_IF(rQAttributeName.startsWith( "xmlns:" ), "xmlscript.xmlhelper", "### unexpected xmlns!" );
568 // collect attribute's uid and current prefix
569 sal_Int32 nColonPos = rQAttributeName.indexOf( (sal_Unicode) ':' );
570 if (nColonPos >= 0)
572 pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos );
573 pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 );
575 else
577 pPrefixes[ nPos ].clear();
578 pLocalNames[ nPos ] = rQAttributeName;
579 // leave local names unmodified
581 pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] );
584 // ownership of arrays belongs to attribute list
585 xAttributes = static_cast< xml::input::XAttributes * >(
586 new ExtendedAttributes(
587 nAttribs, pUids, pPrefixes, pLocalNames, pQNames,
588 xAttribs, this ) );
590 getElementName( rQElementName, &nUid, &aLocalName );
592 // create new child context and append to list
593 if (! m_elements.empty())
594 xCurrentElement = m_elements.back()->m_xElement;
595 } // :guard end
597 if (xCurrentElement.is())
599 elementEntry->m_xElement =
600 xCurrentElement->startChildElement( nUid, aLocalName, xAttributes );
602 else
604 elementEntry->m_xElement =
605 m_xRoot->startRootElement( nUid, aLocalName, xAttributes );
609 MGuard aGuard( m_pMutex );
610 if (elementEntry->m_xElement.is())
612 m_elements.push_back( elementEntry.release() );
614 else
616 ++m_nSkipElements;
617 #if OSL_DEBUG_LEVEL > 1
618 OString aQName(
619 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
620 SAL_INFO("xmlscript.xmlhelper", "### no context given on createChildElement() => ignoring element \"" << aQName.getStr() << "\" ...");
621 #endif
626 void DocumentHandlerImpl::endElement(
627 OUString const & rQElementName )
628 throw (xml::sax::SAXException, RuntimeException, std::exception)
630 Reference< xml::input::XElement > xCurrentElement;
632 MGuard aGuard( m_pMutex );
633 if (m_nSkipElements)
635 --m_nSkipElements;
636 #if OSL_DEBUG_LEVEL > 1
637 OString aQName(
638 OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
639 SAL_INFO("xmlscript.xmlhelper", "### received endElement() for \"" << aQName.getStr() << "\".");
640 #endif
641 static_cast<void>(rQElementName);
642 return;
645 // popping context
646 SAL_WARN_IF( m_elements.empty(), "xmlscript.xmlhelper", "m_elements is empty" );
647 ElementEntry * pEntry = m_elements.back();
648 xCurrentElement = pEntry->m_xElement;
650 #if OSL_DEBUG_LEVEL > 0
651 sal_Int32 nUid;
652 OUString aLocalName;
653 getElementName( rQElementName, &nUid, &aLocalName );
654 SAL_WARN_IF( xCurrentElement->getLocalName() != aLocalName, "xmlscript.xmlhelper", "xCurrentElement->getLocalName() != aLocalName" );
655 SAL_WARN_IF( xCurrentElement->getUid() != nUid, "xmlscript.xmlhelper", "xCurrentElement->getUid() != nUid" );
656 #endif
658 // pop prefixes
659 for ( sal_Int32 nPos = pEntry->m_prefixes.size(); nPos--; )
661 popPrefix( pEntry->m_prefixes[ nPos ] );
663 m_elements.pop_back();
664 delete pEntry;
666 xCurrentElement->endElement();
669 void DocumentHandlerImpl::characters( OUString const & rChars )
670 throw (xml::sax::SAXException, RuntimeException, std::exception)
672 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
673 if (xCurrentElement.is())
674 xCurrentElement->characters( rChars );
677 void DocumentHandlerImpl::ignorableWhitespace(
678 OUString const & rWhitespaces )
679 throw (xml::sax::SAXException, RuntimeException, std::exception)
681 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
682 if (xCurrentElement.is())
683 xCurrentElement->ignorableWhitespace( rWhitespaces );
686 void DocumentHandlerImpl::processingInstruction(
687 OUString const & rTarget, OUString const & rData )
688 throw (xml::sax::SAXException, RuntimeException, std::exception)
690 Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
691 if (xCurrentElement.is())
692 xCurrentElement->processingInstruction( rTarget, rData );
693 else
694 m_xRoot->processingInstruction( rTarget, rData );
697 void DocumentHandlerImpl::setDocumentLocator(
698 Reference< xml::sax::XLocator > const & xLocator )
699 throw (xml::sax::SAXException, RuntimeException, std::exception)
701 m_xRoot->setDocumentLocator( xLocator );
704 // XAttributes
706 sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName )
707 throw (RuntimeException, std::exception)
709 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
711 if (m_pQNames[ nPos ].equals( rQName ))
713 return nPos;
716 return -1;
719 sal_Int32 ExtendedAttributes::getLength()
720 throw (RuntimeException, std::exception)
722 return m_nAttributes;
725 OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex )
726 throw (RuntimeException, std::exception)
728 if (nIndex < m_nAttributes)
729 return m_pLocalNames[ nIndex ];
730 else
731 return OUString();
734 OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex )
735 throw (RuntimeException, std::exception)
737 if (nIndex < m_nAttributes)
738 return m_pQNames[ nIndex ];
739 else
740 return OUString();
743 OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex )
744 throw (RuntimeException, std::exception)
746 static_cast<void>(nIndex);
747 SAL_WARN_IF( nIndex >= m_nAttributes , "xmlscript.xmlhelper", "nIndex is bigger then m_nAttributes");
748 return OUString(); // unsupported
751 OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex )
752 throw (RuntimeException, std::exception)
754 if (nIndex < m_nAttributes)
755 return m_pValues[ nIndex ];
756 else
757 return OUString();
760 sal_Int32 ExtendedAttributes::getIndexByUidName(
761 sal_Int32 nUid, OUString const & rLocalName )
762 throw (RuntimeException, std::exception)
764 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
766 if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
768 return nPos;
771 return -1;
774 sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex )
775 throw (RuntimeException, std::exception)
777 if (nIndex < m_nAttributes)
778 return m_pUids[ nIndex ];
779 else
780 return -1;
783 OUString ExtendedAttributes::getValueByUidName(
784 sal_Int32 nUid, OUString const & rLocalName )
785 throw (RuntimeException, std::exception)
787 for ( sal_Int32 nPos = m_nAttributes; nPos--; )
789 if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
791 return m_pValues[ nPos ];
794 return OUString();
797 Reference< xml::sax::XDocumentHandler > SAL_CALL createDocumentHandler(
798 Reference< xml::input::XRoot > const & xRoot,
799 bool bSingleThreadedUse )
801 SAL_WARN_IF( !xRoot.is(), "xmlscript.xmlhelper", "xRoot is NULL" );
802 if (xRoot.is())
804 return static_cast< xml::sax::XDocumentHandler * >(
805 new DocumentHandlerImpl( xRoot, bSingleThreadedUse ) );
807 return Reference< xml::sax::XDocumentHandler >();
810 Reference< XInterface > SAL_CALL create_DocumentHandlerImpl(
811 SAL_UNUSED_PARAMETER Reference< XComponentContext > const & )
813 return static_cast< ::cppu::OWeakObject * >(
814 new DocumentHandlerImpl(
815 Reference< xml::input::XRoot >(), false /* mt use */ ) );
820 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */