1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "xmlbas_import.hxx"
23 #include <sal/log.hxx>
24 #include <xmlscript/xmlns.h>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
27 #include <com/sun/star/document/XEmbeddedScripts.hpp>
28 #include <com/sun/star/xml/sax/SAXException.hpp>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <tools/diagnose_ex.h>
32 using namespace ::com::sun::star
;
33 using namespace ::com::sun::star::lang
;
34 using namespace ::com::sun::star::uno
;
41 BasicElementBase::BasicElementBase( const OUString
& rLocalName
,
42 const Reference
< xml::input::XAttributes
>& xAttributes
,
43 BasicElementBase
* pParent
, BasicImport
* pImport
)
46 ,m_aLocalName( rLocalName
)
47 ,m_xAttributes( xAttributes
)
51 BasicElementBase::~BasicElementBase()
55 bool BasicElementBase::getBoolAttr( bool* pRet
, const OUString
& rAttrName
,
56 const css::uno::Reference
< css::xml::input::XAttributes
>& xAttributes
,
59 if ( xAttributes
.is() )
61 OUString
aValue( xAttributes
->getValueByUidName( nUid
, rAttrName
) );
62 if ( !aValue
.isEmpty() )
64 if ( aValue
== "true" )
69 else if ( aValue
== "false" )
76 throw xml::sax::SAXException(rAttrName
+ ": no boolean value (true|false)!", Reference
< XInterface
>(), Any() );
85 Reference
< xml::input::XElement
> BasicElementBase::getParent()
87 return m_xParent
.get();
90 OUString
BasicElementBase::getLocalName()
95 sal_Int32
BasicElementBase::getUid()
99 nId
= m_xImport
->XMLNS_UID
;
103 Reference
< xml::input::XAttributes
> BasicElementBase::getAttributes()
105 return m_xAttributes
;
108 Reference
< xml::input::XElement
> BasicElementBase::startChildElement(
109 sal_Int32
/*nUid*/, const OUString
& /*rLocalName*/,
110 const Reference
< xml::input::XAttributes
>& /*xAttributes*/ )
112 throw xml::sax::SAXException("unexpected element!", Reference
< XInterface
>(), Any() );
115 void BasicElementBase::characters( const OUString
& /*rChars*/ )
117 // not used, all characters ignored
120 void BasicElementBase::ignorableWhitespace( const OUString
& /*rWhitespaces*/ )
124 void BasicElementBase::processingInstruction( const OUString
& /*rTarget*/, const OUString
& /*rData*/ )
128 void BasicElementBase::endElement()
132 // BasicLibrariesElement
134 BasicLibrariesElement::BasicLibrariesElement( const OUString
& rLocalName
,
135 const Reference
< xml::input::XAttributes
>& xAttributes
,
136 BasicImport
* pImport
,
137 const Reference
< script::XLibraryContainer2
>& rxLibContainer
)
138 :BasicElementBase( rLocalName
, xAttributes
, nullptr, pImport
)
139 ,m_xLibContainer( rxLibContainer
)
145 Reference
< xml::input::XElement
> BasicLibrariesElement::startChildElement(
146 sal_Int32 nUid
, const OUString
& rLocalName
,
147 const Reference
< xml::input::XAttributes
>& xAttributes
)
149 Reference
< xml::input::XElement
> xElement
;
151 if ( nUid
!= m_xImport
->XMLNS_UID
)
153 throw xml::sax::SAXException( "illegal namespace!", Reference
< XInterface
>(), Any() );
155 else if ( rLocalName
== "library-linked" )
157 if ( xAttributes
.is() )
159 OUString aName
= xAttributes
->getValueByUidName( m_xImport
->XMLNS_UID
, "name" );
161 OUString aStorageURL
= xAttributes
->getValueByUidName(m_xImport
->XMLNS_XLINK_UID
, "href" );
163 bool bReadOnly
= false;
164 getBoolAttr( &bReadOnly
,"readonly", xAttributes
, m_xImport
->XMLNS_UID
);
166 if ( m_xLibContainer
.is() )
170 Reference
< container::XNameAccess
> xLib(
171 m_xLibContainer
->createLibraryLink( aName
, aStorageURL
, bReadOnly
) );
173 xElement
.set( new BasicElementBase( rLocalName
, xAttributes
, this, m_xImport
.get() ) );
175 catch ( const container::ElementExistException
& )
177 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicLibrariesElement::startChildElement" );
179 catch ( const lang::IllegalArgumentException
& )
181 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicLibrariesElement::startChildElement" );
186 else if ( rLocalName
== "library-embedded" )
188 // TODO: create password protected libraries
190 if ( xAttributes
.is() )
192 OUString aName
= xAttributes
->getValueByUidName( m_xImport
->XMLNS_UID
, "name" );
194 bool bReadOnly
= false;
195 getBoolAttr( &bReadOnly
, "readonly", xAttributes
, m_xImport
->XMLNS_UID
);
197 if ( m_xLibContainer
.is() )
201 Reference
< container::XNameContainer
> xLib
;
202 if ( m_xLibContainer
->hasByName( aName
) )
205 m_xLibContainer
->getByName( aName
) >>= xLib
;
209 xLib
.set( m_xLibContainer
->createLibrary( aName
) );
213 xElement
.set( new BasicEmbeddedLibraryElement( rLocalName
, xAttributes
, this, m_xImport
.get(), m_xLibContainer
, aName
, bReadOnly
) );
215 catch ( const lang::IllegalArgumentException
& )
217 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicLibrariesElement::startChildElement" );
224 throw xml::sax::SAXException( "expected library-linked or library-embedded element!", Reference
< XInterface
>(), Any() );
230 void BasicLibrariesElement::endElement()
234 // BasicEmbeddedLibraryElement
236 BasicEmbeddedLibraryElement::BasicEmbeddedLibraryElement( const OUString
& rLocalName
,
237 const Reference
< xml::input::XAttributes
>& xAttributes
,
238 BasicElementBase
* pParent
, BasicImport
* pImport
,
239 const Reference
< script::XLibraryContainer2
>& rxLibContainer
,
240 const OUString
& rLibName
, bool bReadOnly
)
241 :BasicElementBase( rLocalName
, xAttributes
, pParent
, pImport
)
242 ,m_xLibContainer( rxLibContainer
)
243 ,m_aLibName( rLibName
)
244 ,m_bReadOnly( bReadOnly
)
248 if ( m_xLibContainer
.is() && m_xLibContainer
->hasByName( m_aLibName
) )
249 m_xLibContainer
->getByName( m_aLibName
) >>= m_xLib
;
251 catch ( const lang::WrappedTargetException
& )
253 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicEmbeddedLibraryElement::CTOR:" );
259 Reference
< xml::input::XElement
> BasicEmbeddedLibraryElement::startChildElement(
260 sal_Int32 nUid
, const OUString
& rLocalName
,
261 const Reference
< xml::input::XAttributes
>& xAttributes
)
263 Reference
< xml::input::XElement
> xElement
;
265 if ( nUid
!= m_xImport
->XMLNS_UID
)
267 throw xml::sax::SAXException( "illegal namespace!", Reference
< XInterface
>(), Any() );
269 else if ( rLocalName
== "module" )
271 if ( xAttributes
.is() )
273 OUString aName
= xAttributes
->getValueByUidName(m_xImport
->XMLNS_UID
, "name" );
275 if ( m_xLib
.is() && !aName
.isEmpty() )
276 xElement
.set( new BasicModuleElement( rLocalName
, xAttributes
, this, m_xImport
.get(), m_xLib
, aName
) );
281 throw xml::sax::SAXException( "expected module element!", Reference
< XInterface
>(), Any() );
287 void BasicEmbeddedLibraryElement::endElement()
289 if ( m_xLibContainer
.is() && m_xLibContainer
->hasByName( m_aLibName
) && m_bReadOnly
)
290 m_xLibContainer
->setLibraryReadOnly( m_aLibName
, m_bReadOnly
);
293 // BasicModuleElement
295 BasicModuleElement::BasicModuleElement( const OUString
& rLocalName
,
296 const Reference
< xml::input::XAttributes
>& xAttributes
,
297 BasicElementBase
* pParent
, BasicImport
* pImport
,
298 const Reference
< container::XNameContainer
>& rxLib
, const OUString
& rName
)
299 :BasicElementBase( rLocalName
, xAttributes
, pParent
, pImport
)
307 Reference
< xml::input::XElement
> BasicModuleElement::startChildElement(
308 sal_Int32 nUid
, const OUString
& rLocalName
,
309 const Reference
< xml::input::XAttributes
>& xAttributes
)
313 Reference
< xml::input::XElement
> xElement
;
315 if ( nUid
!= m_xImport
->XMLNS_UID
)
317 throw xml::sax::SAXException( "illegal namespace!", Reference
< XInterface
>(), Any() );
319 else if ( rLocalName
== "source-code" )
321 // TODO: password protected libraries
323 if ( xAttributes
.is() )
325 if ( m_xLib
.is() && !m_aName
.isEmpty() )
326 xElement
.set( new BasicSourceCodeElement( rLocalName
, xAttributes
, this, m_xImport
.get(), m_xLib
, m_aName
) );
331 throw xml::sax::SAXException( "expected source-code element!", Reference
< XInterface
>(), Any() );
337 void BasicModuleElement::endElement()
341 // BasicSourceCodeElement
343 BasicSourceCodeElement::BasicSourceCodeElement( const OUString
& rLocalName
,
344 const Reference
< xml::input::XAttributes
>& xAttributes
,
345 BasicElementBase
* pParent
, BasicImport
* pImport
,
346 const Reference
< container::XNameContainer
>& rxLib
, const OUString
& rName
)
347 :BasicElementBase( rLocalName
, xAttributes
, pParent
, pImport
)
355 void BasicSourceCodeElement::characters( const OUString
& rChars
)
357 m_aBuffer
.append( rChars
);
360 void BasicSourceCodeElement::endElement()
364 if ( m_xLib
.is() && !m_aName
.isEmpty() )
367 aElement
<<= m_aBuffer
.makeStringAndClear();
368 m_xLib
->insertByName( m_aName
, aElement
);
371 catch ( const container::ElementExistException
& )
373 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicSourceCodeElement::endElement" );
375 catch ( const lang::IllegalArgumentException
& )
377 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicSourceCodeElement::endElement" );
379 catch ( const lang::WrappedTargetException
& )
381 TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "BasicSourceCodeElement::endElement" );
387 BasicImport::BasicImport( const Reference
< frame::XModel
>& rxModel
, bool bOasis
)
395 BasicImport::~BasicImport()
401 void BasicImport::startDocument( const Reference
< xml::input::XNamespaceMapping
>& xNamespaceMapping
)
403 if ( xNamespaceMapping
.is() )
407 aURI
= XMLNS_OOO_URI
;
409 aURI
= XMLNS_SCRIPT_URI
;
410 XMLNS_UID
= xNamespaceMapping
->getUidByUri( aURI
);
411 XMLNS_XLINK_UID
= xNamespaceMapping
->getUidByUri( XMLNS_XLINK_URI
);
415 void BasicImport::endDocument()
419 void BasicImport::processingInstruction( const OUString
& /*rTarget*/, const OUString
& /*rData*/ )
423 void BasicImport::setDocumentLocator( const Reference
< xml::sax::XLocator
>& /*xLocator*/ )
427 Reference
< xml::input::XElement
> BasicImport::startRootElement( sal_Int32 nUid
, const OUString
& rLocalName
,
428 Reference
< xml::input::XAttributes
> const & xAttributes
)
430 Reference
< xml::input::XElement
> xElement
;
432 if ( nUid
!= XMLNS_UID
)
434 throw xml::sax::SAXException( "illegal namespace!", Reference
< XInterface
>(), Any() );
436 else if ( rLocalName
== "libraries" )
438 Reference
< script::XLibraryContainer2
> xLibContainer
;
440 // try the XEmbeddedScripts interface
441 Reference
< document::XEmbeddedScripts
> xDocumentScripts( m_xModel
, UNO_QUERY
);
442 if ( xDocumentScripts
.is() )
443 xLibContainer
.set( xDocumentScripts
->getBasicLibraries().get() );
445 if ( !xLibContainer
.is() )
447 // try the "BasicLibraries" property (old-style, for compatibility)
448 Reference
< beans::XPropertySet
> xPSet( m_xModel
, UNO_QUERY
);
450 xPSet
->getPropertyValue("BasicLibraries" ) >>= xLibContainer
;
453 SAL_WARN_IF( !xLibContainer
.is(), "xmlscript.xmlflat", "BasicImport::startRootElement: nowhere to import to!" );
455 if ( xLibContainer
.is() )
457 xElement
.set( new BasicLibrariesElement( rLocalName
, xAttributes
, this, xLibContainer
) );
462 throw xml::sax::SAXException("illegal root element (expected libraries) given: " + rLocalName
, Reference
< XInterface
>(), Any() );
468 // XMLBasicImporterBase
470 XMLBasicImporterBase::XMLBasicImporterBase( const Reference
< XComponentContext
>& rxContext
, bool bOasis
)
471 :m_xContext( rxContext
)
476 XMLBasicImporterBase::~XMLBasicImporterBase()
481 sal_Bool
XMLBasicImporterBase::supportsService( const OUString
& rServiceName
)
483 return cppu::supportsService(this, rServiceName
);
487 void XMLBasicImporterBase::setTargetDocument( const Reference
< XComponent
>& rxDoc
)
489 ::osl::MutexGuard
aGuard( m_aMutex
);
491 m_xModel
.set( rxDoc
, UNO_QUERY
);
493 if ( !m_xModel
.is() )
495 throw IllegalArgumentException( "XMLBasicExporter::setTargetDocument: no document model!", Reference
< XInterface
>(), 1 );
498 if ( m_xContext
.is() )
500 Reference
< XMultiComponentFactory
> xSMgr( m_xContext
->getServiceManager() );
503 Reference
< xml::input::XRoot
> xRoot( new BasicImport( m_xModel
, m_bOasis
) );
504 Sequence
< Any
> aArgs( 1 );
506 m_xHandler
.set( xSMgr
->createInstanceWithArgumentsAndContext("com.sun.star.xml.input.SaxDocumentHandler", aArgs
, m_xContext
), UNO_QUERY
);
513 void XMLBasicImporterBase::startDocument()
515 ::osl::MutexGuard
aGuard( m_aMutex
);
517 if ( m_xHandler
.is() )
518 m_xHandler
->startDocument();
521 void XMLBasicImporterBase::endDocument()
523 ::osl::MutexGuard
aGuard( m_aMutex
);
525 if ( m_xHandler
.is() )
526 m_xHandler
->endDocument();
529 void XMLBasicImporterBase::startElement( const OUString
& aName
,
530 const Reference
< xml::sax::XAttributeList
>& xAttribs
)
532 ::osl::MutexGuard
aGuard( m_aMutex
);
534 if ( m_xHandler
.is() )
535 m_xHandler
->startElement( aName
, xAttribs
);
538 void XMLBasicImporterBase::endElement( const OUString
& aName
)
540 ::osl::MutexGuard
aGuard( m_aMutex
);
542 if ( m_xHandler
.is() )
543 m_xHandler
->endElement( aName
);
546 void XMLBasicImporterBase::characters( const OUString
& aChars
)
548 ::osl::MutexGuard
aGuard( m_aMutex
);
550 if ( m_xHandler
.is() )
551 m_xHandler
->characters( aChars
);
554 void XMLBasicImporterBase::ignorableWhitespace( const OUString
& aWhitespaces
)
556 ::osl::MutexGuard
aGuard( m_aMutex
);
558 if ( m_xHandler
.is() )
559 m_xHandler
->ignorableWhitespace( aWhitespaces
);
562 void XMLBasicImporterBase::processingInstruction( const OUString
& aTarget
,
563 const OUString
& aData
)
565 ::osl::MutexGuard
aGuard( m_aMutex
);
567 if ( m_xHandler
.is() )
568 m_xHandler
->processingInstruction( aTarget
, aData
);
571 void XMLBasicImporterBase::setDocumentLocator( const Reference
< xml::sax::XLocator
>& xLocator
)
573 ::osl::MutexGuard
aGuard( m_aMutex
);
575 if ( m_xHandler
.is() )
576 m_xHandler
->setDocumentLocator( xLocator
);
581 XMLBasicImporter::XMLBasicImporter( const Reference
< XComponentContext
>& rxContext
)
582 :XMLBasicImporterBase( rxContext
, false )
586 XMLBasicImporter::~XMLBasicImporter()
592 OUString
XMLBasicImporter::getImplementationName( )
594 return "com.sun.star.comp.xmlscript.XMLBasicImporter";
597 Sequence
< OUString
> XMLBasicImporter::getSupportedServiceNames( )
599 Sequence
< OUString
> aNames
{ "com.sun.star.document.XMLBasicImporter" };
603 // XMLOasisBasicImporter
605 XMLOasisBasicImporter::XMLOasisBasicImporter( const Reference
< XComponentContext
>& rxContext
)
606 :XMLBasicImporterBase( rxContext
, true )
610 XMLOasisBasicImporter::~XMLOasisBasicImporter()
616 OUString
XMLOasisBasicImporter::getImplementationName( )
618 return "com.sun.star.comp.xmlscript.XMLOasisBasicImporter";
621 Sequence
< OUString
> XMLOasisBasicImporter::getSupportedServiceNames( )
623 Sequence
< OUString
> aNames
{ "com.sun.star.document.XMLOasisBasicImporter" };
627 } // namespace xmlscript
629 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
630 com_sun_star_comp_xmlscript_XMLBasicImporter(
631 css::uno::XComponentContext
*context
,
632 css::uno::Sequence
<css::uno::Any
> const &)
634 return cppu::acquire(new xmlscript::XMLBasicImporter(context
));
637 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
638 com_sun_star_comp_xmlscript_XMLOasisBasicImporter(
639 css::uno::XComponentContext
*context
,
640 css::uno::Sequence
<css::uno::Any
> const &)
642 return cppu::acquire(new xmlscript::XMLOasisBasicImporter(context
));
645 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */