xref: /trunk/main/xmlscript/source/xmlflat_imexp/xmlbas_export.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlscript.hxx"
26 #include "xmlbas_export.hxx"
27 #include "xmlscript/xmlns.h"
28 #include "xmlscript/xml_helper.hxx"
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
31 #include <com/sun/star/script/XLibraryContainer2.hpp>
32 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
33 #include <com/sun/star/document/XEmbeddedScripts.hpp>
34 #include <cppuhelper/implementationentry.hxx>
35 
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::lang;
38 using namespace ::com::sun::star::uno;
39 
40 
41 //.........................................................................
42 namespace xmlscript
43 {
44 //.........................................................................
45 
46     // =============================================================================
47     // component operations
48     // =============================================================================
49 
getImplementationName_XMLBasicExporter()50     ::rtl::OUString getImplementationName_XMLBasicExporter()
51     {
52         static ::rtl::OUString* pImplName = 0;
53         if ( !pImplName )
54         {
55             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
56             if ( !pImplName )
57             {
58                 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.xmlscript.XMLBasicExporter" ) );
59                 pImplName = &aImplName;
60             }
61         }
62         return *pImplName;
63     }
64 
65     // -----------------------------------------------------------------------------
66 
getSupportedServiceNames_XMLBasicExporter()67     Sequence< ::rtl::OUString > getSupportedServiceNames_XMLBasicExporter()
68     {
69         static Sequence< ::rtl::OUString >* pNames = 0;
70         if ( !pNames )
71         {
72             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
73             if ( !pNames )
74             {
75                 static Sequence< ::rtl::OUString > aNames(1);
76                 aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLBasicExporter" ) );
77                 pNames = &aNames;
78             }
79         }
80         return *pNames;
81     }
82 
83     // -----------------------------------------------------------------------------
84 
getImplementationName_XMLOasisBasicExporter()85     ::rtl::OUString getImplementationName_XMLOasisBasicExporter()
86     {
87         static ::rtl::OUString* pImplName = 0;
88         if ( !pImplName )
89         {
90             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
91             if ( !pImplName )
92             {
93                 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.xmlscript.XMLOasisBasicExporter" ) );
94                 pImplName = &aImplName;
95             }
96         }
97         return *pImplName;
98     }
99 
100     // -----------------------------------------------------------------------------
101 
getSupportedServiceNames_XMLOasisBasicExporter()102     Sequence< ::rtl::OUString > getSupportedServiceNames_XMLOasisBasicExporter()
103     {
104         static Sequence< ::rtl::OUString >* pNames = 0;
105         if ( !pNames )
106         {
107             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
108             if ( !pNames )
109             {
110                 static Sequence< ::rtl::OUString > aNames(1);
111                 aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.XMLOasisBasicExporter" ) );
112                 pNames = &aNames;
113             }
114         }
115         return *pNames;
116     }
117 
118 
119     // =============================================================================
120     // XMLBasicExporterBase
121     // =============================================================================
122 
XMLBasicExporterBase(const Reference<XComponentContext> & rxContext,sal_Bool bOasis)123     XMLBasicExporterBase::XMLBasicExporterBase( const Reference< XComponentContext >& rxContext, sal_Bool bOasis )
124         :m_xContext( rxContext )
125         ,m_bOasis( bOasis )
126     {
127     }
128 
129     // -----------------------------------------------------------------------------
130 
~XMLBasicExporterBase()131     XMLBasicExporterBase::~XMLBasicExporterBase()
132     {
133     }
134 
135     // -----------------------------------------------------------------------------
136     // XServiceInfo
137     // -----------------------------------------------------------------------------
138 
supportsService(const::rtl::OUString & rServiceName)139     sal_Bool XMLBasicExporterBase::supportsService( const ::rtl::OUString& rServiceName )
140     {
141         Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
142         const ::rtl::OUString* pNames = aNames.getConstArray();
143         const ::rtl::OUString* pEnd = pNames + aNames.getLength();
144         for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
145             ;
146 
147         return pNames != pEnd;
148     }
149 
150     // -----------------------------------------------------------------------------
151     // XInitialization
152     // -----------------------------------------------------------------------------
153 
initialize(const Sequence<Any> & aArguments)154     void XMLBasicExporterBase::initialize( const Sequence< Any >& aArguments )
155     {
156         ::osl::MutexGuard aGuard( m_aMutex );
157 
158         if ( aArguments.getLength() == 1 )
159         {
160             aArguments[0] >>= m_xHandler;
161 
162             if ( !m_xHandler.is() )
163             {
164                 throw RuntimeException(
165                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLBasicExporterBase::initialize: invalid argument format!" ) ),
166                     Reference< XInterface >() );
167             }
168         }
169         else
170         {
171             throw RuntimeException(
172                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLBasicExporterBase::initialize: invalid number of arguments!" ) ),
173                 Reference< XInterface >() );
174         }
175     }
176 
177     // -----------------------------------------------------------------------------
178     // XExporter
179     // -----------------------------------------------------------------------------
180 
setSourceDocument(const Reference<XComponent> & rxDoc)181     void XMLBasicExporterBase::setSourceDocument( const Reference< XComponent >& rxDoc )
182     {
183         ::osl::MutexGuard aGuard( m_aMutex );
184 
185         m_xModel.set( rxDoc, UNO_QUERY );
186 
187         if ( !m_xModel.is() )
188         {
189             throw IllegalArgumentException(
190                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLBasicExporter::setSourceDocument: no document model!" ) ),
191                 Reference< XInterface >(), 1 );
192         }
193     }
194 
195     // -----------------------------------------------------------------------------
196     // XFilter
197     // -----------------------------------------------------------------------------
198 
filter(const Sequence<beans::PropertyValue> &)199 sal_Bool XMLBasicExporterBase::filter( const Sequence< beans::PropertyValue >& /*aDescriptor*/ )
200     {
201         ::osl::MutexGuard aGuard( m_aMutex );
202 
203         sal_Bool bReturn = sal_True;
204 
205         try
206         {
207             if ( m_xHandler.is() )
208             {
209                 m_xHandler->startDocument();
210 
211                 // ooo/script prefix and URI
212                 ::rtl::OUString aPrefix;
213                 ::rtl::OUString aURI;
214                 if ( m_bOasis )
215                 {
216                     aPrefix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_OOO_PREFIX ) );
217                     aURI = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_OOO_URI ) );
218                 }
219                 else
220                 {
221                     aPrefix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_SCRIPT_PREFIX ) );
222                     aURI = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_SCRIPT_URI ) );
223                 }
224 
225                 // ooo/script:libraries element
226                 ::rtl::OUString aLibContElementName( aPrefix );
227                 aLibContElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":libraries" ) );
228                 XMLElement* pLibContElement = new XMLElement( aLibContElementName );
229                 Reference< xml::sax::XAttributeList > xLibContAttribs( pLibContElement );
230 
231                 // ooo/script namespace attribute
232                 pLibContElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" ) ) + aPrefix,
233                     aURI );
234 
235                 // xlink namespace attribute
236                 pLibContElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" XMLNS_XLINK_PREFIX ) ),
237                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_URI ) ) );
238 
239                 // <ooo/script:libraries...
240                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
241                 m_xHandler->startElement( aLibContElementName, xLibContAttribs );
242 
243                 Reference< script::XLibraryContainer2 > xLibContainer;
244 
245                 // try the XEmbeddedScripts interface
246                 Reference< document::XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
247                 if ( xDocumentScripts.is() )
248                     xLibContainer.set( xDocumentScripts->getBasicLibraries().get() );
249 
250                 if ( !xLibContainer.is() )
251                 {
252                     // try the "BasicLibraries" property (old-style, for compatibility)
253                     Reference< beans::XPropertySet > xPSet( m_xModel, UNO_QUERY );
254                     if ( xPSet.is() )
255                         xPSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ) >>= xLibContainer;
256                 }
257 
258                 OSL_ENSURE( xLibContainer.is(), "XMLBasicExporterBase::filter: nowhere to export to!" );
259 
260                 if ( xLibContainer.is() )
261                 {
262                     Sequence< ::rtl::OUString > aLibNames = xLibContainer->getElementNames();
263                     sal_Int32 nLibCount = aLibNames.getLength();
264                     const ::rtl::OUString* pLibNames = aLibNames.getConstArray();
265                     for ( sal_Int32 i = 0 ; i < nLibCount ; ++i )
266                     {
267                         ::rtl::OUString aLibName( pLibNames[i] );
268 
269                         if ( xLibContainer->hasByName( aLibName ) )
270                         {
271                             ::rtl::OUString aTrueStr( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
272 
273                             if ( xLibContainer->isLibraryLink( aLibName ) )
274                             {
275                                 // ooo/script:library-linked element
276                                 ::rtl::OUString aLibElementName( aPrefix );
277                                 aLibElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":library-linked" ) );
278                                 XMLElement* pLibElement = new XMLElement( aLibElementName );
279                                 Reference< xml::sax::XAttributeList > xLibAttribs;
280                                 xLibAttribs = static_cast< xml::sax::XAttributeList* >( pLibElement );
281 
282                                 // ooo/script:name attribute
283                                 pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":name" ) ),
284                                     aLibName );
285 
286                                 ::rtl::OUString aLinkURL( xLibContainer->getLibraryLinkURL( aLibName ) );
287                                 if ( aLinkURL.getLength() )
288                                 {
289                                     // xlink:href attribute
290                                     pLibElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ":href" ) ),
291                                         aLinkURL );
292 
293                                     // xlink:type attribute
294                                     pLibElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ":type" ) ),
295                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple" ) ) );
296                                 }
297 
298                                 if ( xLibContainer->isLibraryReadOnly( aLibName ) )
299                                 {
300                                     // ooo/script:readonly attribute
301                                     pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":readonly" ) ),
302                                         aTrueStr );
303                                 }
304 
305                                 // <ooo/script:library-linked...
306                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
307                                 m_xHandler->startElement( aLibElementName, xLibAttribs );
308 
309                                 // ...ooo/script:library-linked>
310                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
311                                 m_xHandler->endElement( aLibElementName );
312                             }
313                             else
314                             {
315                                 // ooo/script:library-embedded element
316                                 ::rtl::OUString aLibElementName( aPrefix );
317                                 aLibElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":library-embedded" ) );
318                                 XMLElement* pLibElement = new XMLElement( aLibElementName );
319                                 Reference< xml::sax::XAttributeList > xLibAttribs;
320                                 xLibAttribs = static_cast< xml::sax::XAttributeList* >( pLibElement );
321 
322                                 // ooo/script:name attribute
323                                 pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":name" ) ),
324                                     aLibName );
325 
326                                 if ( xLibContainer->isLibraryReadOnly( aLibName ) )
327                                 {
328                                     // ooo/script:readonly attribute
329                                     pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":readonly" ) ),
330                                         aTrueStr );
331                                 }
332 
333                                 // TODO: password protected libraries
334                                 Reference< script::XLibraryContainerPassword > xPasswd( xLibContainer, UNO_QUERY );
335                                 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) )
336                                     continue;
337 
338                                 // <ooo/script:library-embedded...
339                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
340                                 m_xHandler->startElement( aLibElementName, xLibAttribs );
341 
342                                 if ( !xLibContainer->isLibraryLoaded( aLibName ) )
343                                     xLibContainer->loadLibrary( aLibName );
344 
345                                 Reference< container::XNameContainer > xLib;
346                                 xLibContainer->getByName( aLibName ) >>= xLib;
347 
348                                 if ( xLib.is() )
349                                 {
350                                     Sequence< ::rtl::OUString > aModNames = xLib->getElementNames();
351                                     sal_Int32 nModCount = aModNames.getLength();
352                                     const ::rtl::OUString* pModNames = aModNames.getConstArray();
353                                     for ( sal_Int32 j = 0 ; j < nModCount ; ++j )
354                                     {
355                                         ::rtl::OUString aModName( pModNames[j] );
356                                         if ( xLib->hasByName( aModName ) )
357                                         {
358                                             // ooo/script:module element
359                                             ::rtl::OUString aModElementName( aPrefix );
360                                             aModElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":module" ) );
361                                             XMLElement* pModElement = new XMLElement( aModElementName );
362                                             Reference< xml::sax::XAttributeList > xModAttribs;
363                                             xModAttribs = static_cast< xml::sax::XAttributeList* >( pModElement );
364 
365                                             // ooo/script:name attribute
366                                             pModElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":name" ) ),
367                                                 aModName );
368 
369                                             // <ooo/script:module...
370                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
371                                             m_xHandler->startElement( aModElementName, xModAttribs );
372 
373                                             // ooo/script:source-code element
374                                             ::rtl::OUString aSourceElementName( aPrefix );
375                                             aSourceElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":source-code" ) );
376                                             XMLElement* pSourceElement = new XMLElement( aSourceElementName );
377                                             Reference< xml::sax::XAttributeList > xSourceAttribs;
378                                             xSourceAttribs = static_cast< xml::sax::XAttributeList* >( pSourceElement );
379 
380                                             // <ooo/script:source-code...
381                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
382                                             m_xHandler->startElement( aSourceElementName, xSourceAttribs );
383 
384                                             // module data
385                                             // TODO: write encrypted data for password protected libraries
386                                             ::rtl::OUString aSource;
387                                             xLib->getByName( aModName ) >>= aSource;
388                                             m_xHandler->characters( aSource );
389 
390                                             // TODO: <ooo/script:byte-code>
391 
392                                             // ...ooo/script:source-code>
393                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
394                                             m_xHandler->endElement( aSourceElementName );
395 
396                                             // ...ooo/script:module>
397                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
398                                             m_xHandler->endElement( aModElementName );
399                                         }
400                                     }
401                                 }
402 
403                                 // ...ooo/script:library-embedded>
404                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
405                                 m_xHandler->endElement( aLibElementName );
406                             }
407                         }
408                     }
409                 }
410 
411                 // ...ooo/script:libraries>
412                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
413                 m_xHandler->endElement( aLibContElementName );
414 
415                 m_xHandler->endDocument();
416             }
417         }
418         catch ( container::NoSuchElementException& e )
419         {
420             OSL_TRACE( "XMLBasicExporterBase::filter: caught NoSuchElementException reason %s",
421                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
422             bReturn = sal_False;
423         }
424         catch ( lang::IllegalArgumentException& e )
425         {
426             OSL_TRACE( "XMLBasicExporterBase::filter: caught IllegalArgumentException reason %s",
427                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
428             bReturn = sal_False;
429         }
430         catch ( lang::WrappedTargetException& e )
431         {
432             OSL_TRACE( "XMLBasicExporterBase::filter: caught WrappedTargetException reason %s",
433                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
434             bReturn = sal_False;
435         }
436         catch ( xml::sax::SAXException& e )
437         {
438             OSL_TRACE( "XMLBasicExporterBase::filter: caught SAXException reason %s",
439                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
440             bReturn = sal_False;
441         }
442 
443         return bReturn;
444     }
445 
446     // -----------------------------------------------------------------------------
447 
cancel()448     void XMLBasicExporterBase::cancel()
449     {
450         ::osl::MutexGuard aGuard( m_aMutex );
451 
452         // cancel export
453     }
454 
455 
456     // =============================================================================
457     // XMLBasicExporter
458     // =============================================================================
459 
XMLBasicExporter(const Reference<XComponentContext> & rxContext)460     XMLBasicExporter::XMLBasicExporter( const Reference< XComponentContext >& rxContext )
461         :XMLBasicExporterBase( rxContext, sal_False )
462     {
463     }
464 
465     // -----------------------------------------------------------------------------
466 
~XMLBasicExporter()467     XMLBasicExporter::~XMLBasicExporter()
468     {
469     }
470 
471     // -----------------------------------------------------------------------------
472     // XServiceInfo
473     // -----------------------------------------------------------------------------
474 
getImplementationName()475     ::rtl::OUString XMLBasicExporter::getImplementationName(  )
476     {
477         return getImplementationName_XMLBasicExporter();
478     }
479 
480     // -----------------------------------------------------------------------------
481 
getSupportedServiceNames()482     Sequence< ::rtl::OUString > XMLBasicExporter::getSupportedServiceNames(  )
483     {
484         return getSupportedServiceNames_XMLBasicExporter();
485     }
486 
487 
488     // =============================================================================
489     // XMLOasisBasicExporter
490     // =============================================================================
491 
XMLOasisBasicExporter(const Reference<XComponentContext> & rxContext)492     XMLOasisBasicExporter::XMLOasisBasicExporter( const Reference< XComponentContext >& rxContext )
493         :XMLBasicExporterBase( rxContext, sal_True )
494     {
495     }
496 
497     // -----------------------------------------------------------------------------
498 
~XMLOasisBasicExporter()499     XMLOasisBasicExporter::~XMLOasisBasicExporter()
500     {
501     }
502 
503     // -----------------------------------------------------------------------------
504     // XServiceInfo
505     // -----------------------------------------------------------------------------
506 
getImplementationName()507     ::rtl::OUString XMLOasisBasicExporter::getImplementationName(  )
508     {
509         return getImplementationName_XMLOasisBasicExporter();
510     }
511 
512     // -----------------------------------------------------------------------------
513 
getSupportedServiceNames()514     Sequence< ::rtl::OUString > XMLOasisBasicExporter::getSupportedServiceNames(  )
515     {
516         return getSupportedServiceNames_XMLOasisBasicExporter();
517     }
518 
519 
520     // =============================================================================
521     // component operations
522     // =============================================================================
523 
create_XMLBasicExporter(Reference<XComponentContext> const & xContext)524     Reference< XInterface > SAL_CALL create_XMLBasicExporter(
525         Reference< XComponentContext > const & xContext )
526         SAL_THROW( () )
527     {
528         return static_cast< lang::XTypeProvider * >( new XMLBasicExporter( xContext ) );
529     }
530 
531     // -----------------------------------------------------------------------------
532 
create_XMLOasisBasicExporter(Reference<XComponentContext> const & xContext)533     Reference< XInterface > SAL_CALL create_XMLOasisBasicExporter(
534         Reference< XComponentContext > const & xContext )
535         SAL_THROW( () )
536     {
537         return static_cast< lang::XTypeProvider * >( new XMLOasisBasicExporter( xContext ) );
538     }
539 
540     // -----------------------------------------------------------------------------
541 
542 //.........................................................................
543 }   // namespace xmlscript
544 //.........................................................................
545