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 ) throw (RuntimeException)
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 ) throw (Exception, RuntimeException)
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 	    throw (IllegalArgumentException, RuntimeException)
183     {
184         ::osl::MutexGuard aGuard( m_aMutex );
185 
186         m_xModel.set( rxDoc, UNO_QUERY );
187 
188         if ( !m_xModel.is() )
189         {
190             throw IllegalArgumentException(
191                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLBasicExporter::setSourceDocument: no document model!" ) ),
192                 Reference< XInterface >(), 1 );
193         }
194     }
195 
196     // -----------------------------------------------------------------------------
197     // XFilter
198     // -----------------------------------------------------------------------------
199 
filter(const Sequence<beans::PropertyValue> &)200 sal_Bool XMLBasicExporterBase::filter( const Sequence< beans::PropertyValue >& /*aDescriptor*/ )
201         throw (RuntimeException)
202     {
203         ::osl::MutexGuard aGuard( m_aMutex );
204 
205         sal_Bool bReturn = sal_True;
206 
207         try
208         {
209             if ( m_xHandler.is() )
210             {
211                 m_xHandler->startDocument();
212 
213                 // ooo/script prefix and URI
214                 ::rtl::OUString aPrefix;
215                 ::rtl::OUString aURI;
216                 if ( m_bOasis )
217                 {
218                     aPrefix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_OOO_PREFIX ) );
219                     aURI = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_OOO_URI ) );
220                 }
221                 else
222                 {
223                     aPrefix = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_SCRIPT_PREFIX ) );
224                     aURI = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_SCRIPT_URI ) );
225                 }
226 
227                 // ooo/script:libraries element
228                 ::rtl::OUString aLibContElementName( aPrefix );
229                 aLibContElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":libraries" ) );
230                 XMLElement* pLibContElement = new XMLElement( aLibContElementName );
231                 Reference< xml::sax::XAttributeList > xLibContAttribs( pLibContElement );
232 
233                 // ooo/script namespace attribute
234                 pLibContElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" ) ) + aPrefix,
235                     aURI );
236 
237                 // xlink namespace attribute
238                 pLibContElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" XMLNS_XLINK_PREFIX ) ),
239                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_URI ) ) );
240 
241                 // <ooo/script:libraries...
242                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
243                 m_xHandler->startElement( aLibContElementName, xLibContAttribs );
244 
245                 Reference< script::XLibraryContainer2 > xLibContainer;
246 
247                 // try the XEmbeddedScripts interface
248                 Reference< document::XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
249                 if ( xDocumentScripts.is() )
250                     xLibContainer.set( xDocumentScripts->getBasicLibraries().get() );
251 
252                 if ( !xLibContainer.is() )
253                 {
254                     // try the "BasicLibraries" property (old-style, for compatibility)
255                     Reference< beans::XPropertySet > xPSet( m_xModel, UNO_QUERY );
256                     if ( xPSet.is() )
257                         xPSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ) >>= xLibContainer;
258                 }
259 
260                 OSL_ENSURE( xLibContainer.is(), "XMLBasicExporterBase::filter: nowhere to export to!" );
261 
262                 if ( xLibContainer.is() )
263                 {
264                     Sequence< ::rtl::OUString > aLibNames = xLibContainer->getElementNames();
265                     sal_Int32 nLibCount = aLibNames.getLength();
266                     const ::rtl::OUString* pLibNames = aLibNames.getConstArray();
267                     for ( sal_Int32 i = 0 ; i < nLibCount ; ++i )
268                     {
269                         ::rtl::OUString aLibName( pLibNames[i] );
270 
271                         if ( xLibContainer->hasByName( aLibName ) )
272                         {
273                             ::rtl::OUString aTrueStr( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
274 
275                             if ( xLibContainer->isLibraryLink( aLibName ) )
276                             {
277                                 // ooo/script:library-linked element
278                                 ::rtl::OUString aLibElementName( aPrefix );
279                                 aLibElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":library-linked" ) );
280                                 XMLElement* pLibElement = new XMLElement( aLibElementName );
281                                 Reference< xml::sax::XAttributeList > xLibAttribs;
282                                 xLibAttribs = static_cast< xml::sax::XAttributeList* >( pLibElement );
283 
284                                 // ooo/script:name attribute
285                                 pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":name" ) ),
286                                     aLibName );
287 
288                                 ::rtl::OUString aLinkURL( xLibContainer->getLibraryLinkURL( aLibName ) );
289                                 if ( aLinkURL.getLength() )
290                                 {
291                                     // xlink:href attribute
292                                     pLibElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ":href" ) ),
293                                         aLinkURL );
294 
295                                     // xlink:type attribute
296                                     pLibElement->addAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ":type" ) ),
297                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple" ) ) );
298                                 }
299 
300                                 if ( xLibContainer->isLibraryReadOnly( aLibName ) )
301                                 {
302                                     // ooo/script:readonly attribute
303                                     pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":readonly" ) ),
304                                         aTrueStr );
305                                 }
306 
307                                 // <ooo/script:library-linked...
308                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
309                                 m_xHandler->startElement( aLibElementName, xLibAttribs );
310 
311                                 // ...ooo/script:library-linked>
312                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
313                                 m_xHandler->endElement( aLibElementName );
314                             }
315                             else
316                             {
317                                 // ooo/script:library-embedded element
318                                 ::rtl::OUString aLibElementName( aPrefix );
319                                 aLibElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":library-embedded" ) );
320                                 XMLElement* pLibElement = new XMLElement( aLibElementName );
321                                 Reference< xml::sax::XAttributeList > xLibAttribs;
322                                 xLibAttribs = static_cast< xml::sax::XAttributeList* >( pLibElement );
323 
324                                 // ooo/script:name attribute
325                                 pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":name" ) ),
326                                     aLibName );
327 
328                                 if ( xLibContainer->isLibraryReadOnly( aLibName ) )
329                                 {
330                                     // ooo/script:readonly attribute
331                                     pLibElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":readonly" ) ),
332                                         aTrueStr );
333                                 }
334 
335                                 // TODO: password protected libraries
336                                 Reference< script::XLibraryContainerPassword > xPasswd( xLibContainer, UNO_QUERY );
337                                 if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) )
338                                     continue;
339 
340                                 // <ooo/script:library-embedded...
341                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
342                                 m_xHandler->startElement( aLibElementName, xLibAttribs );
343 
344                                 if ( !xLibContainer->isLibraryLoaded( aLibName ) )
345                                     xLibContainer->loadLibrary( aLibName );
346 
347                                 Reference< container::XNameContainer > xLib;
348 	                            xLibContainer->getByName( aLibName ) >>= xLib;
349 
350                                 if ( xLib.is() )
351                                 {
352                                     Sequence< ::rtl::OUString > aModNames = xLib->getElementNames();
353                                     sal_Int32 nModCount = aModNames.getLength();
354                                     const ::rtl::OUString* pModNames = aModNames.getConstArray();
355                                     for ( sal_Int32 j = 0 ; j < nModCount ; ++j )
356                                     {
357                                         ::rtl::OUString aModName( pModNames[j] );
358                                         if ( xLib->hasByName( aModName ) )
359                                         {
360                                             // ooo/script:module element
361                                             ::rtl::OUString aModElementName( aPrefix );
362                                             aModElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":module" ) );
363                                             XMLElement* pModElement = new XMLElement( aModElementName );
364                                             Reference< xml::sax::XAttributeList > xModAttribs;
365                                             xModAttribs = static_cast< xml::sax::XAttributeList* >( pModElement );
366 
367                                             // ooo/script:name attribute
368                                             pModElement->addAttribute( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":name" ) ),
369                                                 aModName );
370 
371                                             // <ooo/script:module...
372                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
373                                             m_xHandler->startElement( aModElementName, xModAttribs );
374 
375                                             // ooo/script:source-code element
376                                             ::rtl::OUString aSourceElementName( aPrefix );
377                                             aSourceElementName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":source-code" ) );
378                                             XMLElement* pSourceElement = new XMLElement( aSourceElementName );
379                                             Reference< xml::sax::XAttributeList > xSourceAttribs;
380                                             xSourceAttribs = static_cast< xml::sax::XAttributeList* >( pSourceElement );
381 
382                                             // <ooo/script:source-code...
383                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
384                                             m_xHandler->startElement( aSourceElementName, xSourceAttribs );
385 
386                                             // module data
387                                             // TODO: write encrypted data for password protected libraries
388                                             ::rtl::OUString aSource;
389 	                                        xLib->getByName( aModName ) >>= aSource;
390                                             m_xHandler->characters( aSource );
391 
392                                             // TODO: <ooo/script:byte-code>
393 
394                                             // ...ooo/script:source-code>
395                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
396                                             m_xHandler->endElement( aSourceElementName );
397 
398                                             // ...ooo/script:module>
399                                             m_xHandler->ignorableWhitespace( ::rtl::OUString() );
400                                             m_xHandler->endElement( aModElementName );
401                                         }
402                                     }
403                                 }
404 
405                                 // ...ooo/script:library-embedded>
406                                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
407                                 m_xHandler->endElement( aLibElementName );
408                             }
409                         }
410                     }
411                 }
412 
413                 // ...ooo/script:libraries>
414                 m_xHandler->ignorableWhitespace( ::rtl::OUString() );
415                 m_xHandler->endElement( aLibContElementName );
416 
417                 m_xHandler->endDocument();
418             }
419         }
420         catch ( container::NoSuchElementException& e )
421         {
422             OSL_TRACE( "XMLBasicExporterBase::filter: caught NoSuchElementException reason %s",
423                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
424             bReturn = sal_False;
425         }
426         catch ( lang::IllegalArgumentException& e )
427         {
428             OSL_TRACE( "XMLBasicExporterBase::filter: caught IllegalArgumentException reason %s",
429                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
430             bReturn = sal_False;
431         }
432         catch ( lang::WrappedTargetException& e )
433         {
434             OSL_TRACE( "XMLBasicExporterBase::filter: caught WrappedTargetException reason %s",
435                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
436             bReturn = sal_False;
437         }
438         catch ( xml::sax::SAXException& e )
439         {
440             OSL_TRACE( "XMLBasicExporterBase::filter: caught SAXException reason %s",
441                 ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
442             bReturn = sal_False;
443         }
444 
445         return bReturn;
446     }
447 
448     // -----------------------------------------------------------------------------
449 
cancel()450     void XMLBasicExporterBase::cancel()
451         throw (RuntimeException)
452     {
453         ::osl::MutexGuard aGuard( m_aMutex );
454 
455         // cancel export
456     }
457 
458 
459     // =============================================================================
460     // XMLBasicExporter
461     // =============================================================================
462 
XMLBasicExporter(const Reference<XComponentContext> & rxContext)463     XMLBasicExporter::XMLBasicExporter( const Reference< XComponentContext >& rxContext )
464         :XMLBasicExporterBase( rxContext, sal_False )
465     {
466     }
467 
468     // -----------------------------------------------------------------------------
469 
~XMLBasicExporter()470     XMLBasicExporter::~XMLBasicExporter()
471     {
472     }
473 
474     // -----------------------------------------------------------------------------
475     // XServiceInfo
476     // -----------------------------------------------------------------------------
477 
getImplementationName()478     ::rtl::OUString XMLBasicExporter::getImplementationName(  ) throw (RuntimeException)
479     {
480         return getImplementationName_XMLBasicExporter();
481     }
482 
483     // -----------------------------------------------------------------------------
484 
getSupportedServiceNames()485     Sequence< ::rtl::OUString > XMLBasicExporter::getSupportedServiceNames(  ) throw (RuntimeException)
486     {
487         return getSupportedServiceNames_XMLBasicExporter();
488     }
489 
490 
491     // =============================================================================
492     // XMLOasisBasicExporter
493     // =============================================================================
494 
XMLOasisBasicExporter(const Reference<XComponentContext> & rxContext)495     XMLOasisBasicExporter::XMLOasisBasicExporter( const Reference< XComponentContext >& rxContext )
496         :XMLBasicExporterBase( rxContext, sal_True )
497     {
498     }
499 
500     // -----------------------------------------------------------------------------
501 
~XMLOasisBasicExporter()502     XMLOasisBasicExporter::~XMLOasisBasicExporter()
503     {
504     }
505 
506     // -----------------------------------------------------------------------------
507     // XServiceInfo
508     // -----------------------------------------------------------------------------
509 
getImplementationName()510     ::rtl::OUString XMLOasisBasicExporter::getImplementationName(  ) throw (RuntimeException)
511     {
512         return getImplementationName_XMLOasisBasicExporter();
513     }
514 
515     // -----------------------------------------------------------------------------
516 
getSupportedServiceNames()517     Sequence< ::rtl::OUString > XMLOasisBasicExporter::getSupportedServiceNames(  ) throw (RuntimeException)
518     {
519         return getSupportedServiceNames_XMLOasisBasicExporter();
520     }
521 
522 
523     // =============================================================================
524     // component operations
525     // =============================================================================
526 
create_XMLBasicExporter(Reference<XComponentContext> const & xContext)527     Reference< XInterface > SAL_CALL create_XMLBasicExporter(
528         Reference< XComponentContext > const & xContext )
529         SAL_THROW( () )
530     {
531         return static_cast< lang::XTypeProvider * >( new XMLBasicExporter( xContext ) );
532     }
533 
534     // -----------------------------------------------------------------------------
535 
create_XMLOasisBasicExporter(Reference<XComponentContext> const & xContext)536     Reference< XInterface > SAL_CALL create_XMLOasisBasicExporter(
537         Reference< XComponentContext > const & xContext )
538         SAL_THROW( () )
539     {
540         return static_cast< lang::XTypeProvider * >( new XMLOasisBasicExporter( xContext ) );
541     }
542 
543     // -----------------------------------------------------------------------------
544 
545 //.........................................................................
546 }	// namespace xmlscript
547 //.........................................................................
548