xref: /trunk/main/basic/source/uno/scriptcont.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_basic.hxx"
26 #include "scriptcont.hxx"
27 #include "sbmodule.hxx"
28 #include <com/sun/star/container/XNameContainer.hpp>
29 #include <com/sun/star/xml/sax/XParser.hpp>
30 #include <com/sun/star/xml/sax/InputSource.hpp>
31 #include <com/sun/star/io/XOutputStream.hpp>
32 #include <com/sun/star/io/XInputStream.hpp>
33 #include <com/sun/star/io/XActiveDataSource.hpp>
34 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
35 #include <com/sun/star/embed/ElementModes.hpp>
36 #include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/embed/XTransactedObject.hpp>
39 #include <com/sun/star/task/ErrorCodeIOException.hpp>
40 #include <com/sun/star/script/ModuleType.hpp>
41 #include <comphelper/processfactory.hxx>
42 #ifndef _COMPHELPER_STORAGEHELPER_HXX_
43 #include <comphelper/storagehelper.hxx>
44 #endif
45 #include <unotools/streamwrap.hxx>
46 #include <unotools/ucbstreamhelper.hxx>
47 #include <osl/mutex.hxx>
48 #include <rtl/digest.h>
49 #include <rtl/strbuf.hxx>
50 
51 // For password functionality
52 #include <tools/urlobj.hxx>
53 
54 
55 #include <unotools/pathoptions.hxx>
56 #include <svtools/sfxecode.hxx>
57 #include <svtools/ehdl.hxx>
58 #include <basic/basmgr.hxx>
59 #include <basic/sbmod.hxx>
60 #include <basic/basicmanagerrepository.hxx>
61 #include "basic/modsizeexceeded.hxx"
62 #include <xmlscript/xmlmod_imexp.hxx>
63 #include <cppuhelper/factory.hxx>
64 #include <com/sun/star/util/VetoException.hpp>
65 
66 namespace basic
67 {
68 
69 using namespace com::sun::star::document;
70 using namespace com::sun::star::container;
71 using namespace com::sun::star::io;
72 using namespace com::sun::star::uno;
73 using namespace com::sun::star::ucb;
74 using namespace com::sun::star::lang;
75 using namespace com::sun::star::script;
76 using namespace com::sun::star::xml::sax;
77 using namespace com::sun::star;
78 using namespace cppu;
79 using namespace osl;
80 
81 using ::rtl::OUString;
82 
83 //============================================================================
84 // Implementation class SfxScriptLibraryContainer
85 
getInfoFileName() const86 const sal_Char* SAL_CALL SfxScriptLibraryContainer::getInfoFileName() const { return "script"; }
getOldInfoFileName() const87 const sal_Char* SAL_CALL SfxScriptLibraryContainer::getOldInfoFileName() const { return "script"; }
getLibElementFileExtension() const88 const sal_Char* SAL_CALL SfxScriptLibraryContainer::getLibElementFileExtension() const { return "xba"; }
getLibrariesDir() const89 const sal_Char* SAL_CALL SfxScriptLibraryContainer::getLibrariesDir() const { return "Basic"; }
90 
91 // OldBasicPassword interface
setLibraryPassword(const String & rLibraryName,const String & rPassword)92 void SfxScriptLibraryContainer::setLibraryPassword
93     ( const String& rLibraryName, const String& rPassword )
94 {
95     try
96     {
97         SfxLibrary* pImplLib = getImplLib( rLibraryName );
98         if( rPassword.Len() )
99         {
100             pImplLib->mbDoc50Password = sal_True;
101             pImplLib->mbPasswordProtected = sal_True;
102             pImplLib->maPassword = rPassword;
103         }
104     }
105     catch( NoSuchElementException& ) {}
106 }
107 
getLibraryPassword(const String & rLibraryName)108 String SfxScriptLibraryContainer::getLibraryPassword( const String& rLibraryName )
109 {
110     SfxLibrary* pImplLib = getImplLib( rLibraryName );
111     String aPassword;
112     if( pImplLib->mbPasswordVerified )
113         aPassword = pImplLib->maPassword;
114     return aPassword;
115 }
116 
clearLibraryPassword(const String & rLibraryName)117 void SfxScriptLibraryContainer::clearLibraryPassword( const String& rLibraryName )
118 {
119     try
120     {
121         SfxLibrary* pImplLib = getImplLib( rLibraryName );
122         pImplLib->mbDoc50Password = sal_False;
123         pImplLib->mbPasswordProtected = sal_False;
124         pImplLib->maPassword = OUString();
125     }
126     catch( NoSuchElementException& ) {}
127 }
128 
hasLibraryPassword(const String & rLibraryName)129 sal_Bool SfxScriptLibraryContainer::hasLibraryPassword( const String& rLibraryName )
130 {
131     SfxLibrary* pImplLib = getImplLib( rLibraryName );
132     return pImplLib->mbPasswordProtected;
133 }
134 
135 
136 // Ctor for service
SfxScriptLibraryContainer(void)137 SfxScriptLibraryContainer::SfxScriptLibraryContainer( void )
138     :maScriptLanguage( RTL_CONSTASCII_USTRINGPARAM( "StarBasic" ) )
139 {
140     // all initialisation has to be done
141     // by calling XInitialization::initialize
142 }
143 
SfxScriptLibraryContainer(const uno::Reference<embed::XStorage> & xStorage)144 SfxScriptLibraryContainer::SfxScriptLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
145     :maScriptLanguage( RTL_CONSTASCII_USTRINGPARAM( "StarBasic" ) )
146 {
147     init( OUString(), xStorage );
148 }
149 
150 // Methods to get library instances of the correct type
implCreateLibrary(const OUString & aName)151 SfxLibrary* SfxScriptLibraryContainer::implCreateLibrary( const OUString& aName )
152 {
153     (void)aName;    // Only needed for SfxDialogLibrary
154     SfxLibrary* pRet = new SfxScriptLibrary( maModifiable, mxMSF, mxSFI );
155     return pRet;
156 }
157 
implCreateLibraryLink(const OUString & aName,const OUString & aLibInfoFileURL,const OUString & StorageURL,sal_Bool ReadOnly)158 SfxLibrary* SfxScriptLibraryContainer::implCreateLibraryLink
159     ( const OUString& aName, const OUString& aLibInfoFileURL,
160       const OUString& StorageURL, sal_Bool ReadOnly )
161 {
162     (void)aName;    // Only needed for SfxDialogLibrary
163     SfxLibrary* pRet =
164         new SfxScriptLibrary
165             ( maModifiable, mxMSF, mxSFI, aLibInfoFileURL, StorageURL, ReadOnly );
166     return pRet;
167 }
168 
createEmptyLibraryElement(void)169 Any SAL_CALL SfxScriptLibraryContainer::createEmptyLibraryElement( void )
170 {
171     OUString aMod;
172     Any aRetAny;
173     aRetAny <<= aMod;
174     return aRetAny;
175 }
176 
isLibraryElementValid(Any aElement) const177 bool SAL_CALL SfxScriptLibraryContainer::isLibraryElementValid( Any aElement ) const
178 {
179     return SfxScriptLibrary::containsValidModule( aElement );
180 }
181 
writeLibraryElement(const Reference<XNameContainer> & xLib,const OUString & aElementName,const Reference<XOutputStream> & xOutput)182 void SAL_CALL SfxScriptLibraryContainer::writeLibraryElement
183 (
184     const Reference < XNameContainer >& xLib,
185     const OUString& aElementName,
186     const Reference< XOutputStream >& xOutput
187 )
188 {
189     // Create sax writer
190     Reference< XExtendedDocumentHandler > xHandler(
191         mxMSF->createInstance(
192             OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
193     if( !xHandler.is() )
194     {
195         OSL_ENSURE( 0, "### couldn't create sax-writer component\n" );
196         return;
197     }
198 
199     Reference< XTruncate > xTruncate( xOutput, UNO_QUERY );
200     OSL_ENSURE( xTruncate.is(), "Currently only the streams that can be truncated are expected!" );
201     if ( xTruncate.is() )
202         xTruncate->truncate();
203 
204     Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
205     xSource->setOutputStream( xOutput );
206 
207     xmlscript::ModuleDescriptor aMod;
208     aMod.aName = aElementName;
209     aMod.aLanguage = maScriptLanguage;
210     Any aElement = xLib->getByName( aElementName );
211     aElement >>= aMod.aCode;
212 
213     Reference< script::vba::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY );
214     if( xModInfo.is() && xModInfo->hasModuleInfo( aElementName ) )
215     {
216         script::ModuleInfo aModInfo = xModInfo->getModuleInfo( aElementName );
217         switch( aModInfo.ModuleType )
218         {
219         case ModuleType::NORMAL:
220             aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("normal") );
221             break;
222         case ModuleType::CLASS:
223             aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("class") );
224             break;
225         case ModuleType::FORM:
226             aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("form") );
227             break;
228         case ModuleType::DOCUMENT:
229             aMod.aModuleType = OUString( RTL_CONSTASCII_USTRINGPARAM("document") );
230             break;
231         case ModuleType::UNKNOWN:
232             // nothing
233             break;
234         }
235     }
236 
237     xmlscript::exportScriptModule( xHandler, aMod );
238 }
239 
240 
importLibraryElement(const Reference<XNameContainer> & xLib,const OUString & aElementName,const OUString & aFile,const uno::Reference<io::XInputStream> & xInStream)241 Any SAL_CALL SfxScriptLibraryContainer::importLibraryElement
242     ( const Reference < XNameContainer >& xLib,
243       const OUString& aElementName, const OUString& aFile,
244       const uno::Reference< io::XInputStream >& xInStream )
245 {
246     Any aRetAny;
247 
248     Reference< XParser > xParser( mxMSF->createInstance(
249         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
250     if( !xParser.is() )
251     {
252         OSL_ENSURE( 0, "### couldn't create sax parser component\n" );
253         return aRetAny;
254     }
255 
256 
257     // Read from storage?
258     sal_Bool bStorage = xInStream.is();
259     Reference< XInputStream > xInput;
260 
261     if( bStorage )
262     {
263         xInput = xInStream;
264     }
265     else
266     {
267         try
268         {
269             xInput = mxSFI->openFileRead( aFile );
270         }
271         catch( Exception& )
272         //catch( Exception& e )
273         {
274             // TODO:
275             //throw WrappedTargetException( e );
276         }
277     }
278 
279     if( !xInput.is() )
280         return aRetAny;
281 
282     InputSource source;
283     source.aInputStream = xInput;
284     source.sSystemId    = aFile;
285 
286     // start parsing
287     xmlscript::ModuleDescriptor aMod;
288 
289     try
290     {
291         xParser->setDocumentHandler( ::xmlscript::importScriptModule( aMod ) );
292         xParser->parseStream( source );
293     }
294     catch( Exception& )
295     {
296         SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFile );
297         sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
298         ErrorHandler::HandleError( nErrorCode );
299     }
300 
301     aRetAny <<= aMod.aCode;
302 
303     // TODO: Check language
304     // aMod.aLanguage
305     // aMod.aName ignored
306     if( !aMod.aModuleType.isEmpty() )
307     {
308         /*  If in VBA compatibility mode, force creation of the VBA Globals
309             object. Each application will create an instance of its own
310             implementation and store it in its Basic manager. Implementations
311             will do all necessary additional initialization, such as
312             registering the global "This***Doc" UNO constant, starting the
313             document events processor etc.
314          */
315         if( getVBACompatibilityMode() ) try
316         {
317             Reference< frame::XModel > xModel( mxOwnerDocument );   // weak-ref -> ref
318             Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
319             xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
320         }
321         catch( Exception& )
322         {
323         }
324 
325         script::ModuleInfo aModInfo;
326         aModInfo.ModuleType = ModuleType::UNKNOWN;
327         if( aMod.aModuleType.equalsAsciiL(
328                     RTL_CONSTASCII_STRINGPARAM("normal") ))
329         {
330             aModInfo.ModuleType = ModuleType::NORMAL;
331         }
332         else if( aMod.aModuleType.equalsAsciiL(
333                     RTL_CONSTASCII_STRINGPARAM("class") ))
334         {
335             aModInfo.ModuleType = ModuleType::CLASS;
336         }
337         else if( aMod.aModuleType.equalsAsciiL(
338                     RTL_CONSTASCII_STRINGPARAM("form") ))
339         {
340             aModInfo.ModuleType = ModuleType::FORM;
341             aModInfo.ModuleObject = mxOwnerDocument;
342         }
343         else if( aMod.aModuleType.equalsAsciiL(
344                     RTL_CONSTASCII_STRINGPARAM("document") ))
345         {
346             aModInfo.ModuleType = ModuleType::DOCUMENT;
347 
348             // #163691# use the same codename access instance for all document modules
349             if( !mxCodeNameAccess.is() ) try
350             {
351                 Reference<frame::XModel > xModel( mxOwnerDocument );
352                 Reference< XMultiServiceFactory> xSF( xModel, UNO_QUERY_THROW );
353                 mxCodeNameAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider" ) ) ), UNO_QUERY );
354             }
355             catch( Exception& ) {}
356 
357             if( mxCodeNameAccess.is() )
358             {
359                 try
360                 {
361                     aModInfo.ModuleObject.set( mxCodeNameAccess->getByName( aElementName), uno::UNO_QUERY );
362                 }
363                 catch(uno::Exception&)
364                 {
365                     OSL_TRACE("Failed to get document object for %s", rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_UTF8 ).getStr() );
366                 }
367             }
368         }
369 
370         Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
371         if( xVBAModuleInfo.is() )
372         {
373             if( xVBAModuleInfo->hasModuleInfo( aElementName ) )
374                 xVBAModuleInfo->removeModuleInfo( aElementName );
375             xVBAModuleInfo->insertModuleInfo( aElementName, aModInfo );
376         }
377     }
378 
379     return aRetAny;
380 }
381 
createInstanceImpl(void)382 SfxLibraryContainer* SfxScriptLibraryContainer::createInstanceImpl( void )
383 {
384     return new SfxScriptLibraryContainer();
385 }
386 
importFromOldStorage(const::rtl::OUString & aFile)387 void SAL_CALL SfxScriptLibraryContainer::importFromOldStorage( const ::rtl::OUString& aFile )
388 {
389     // TODO: move loading from old storage to binary filters?
390     SotStorageRef xStorage = new SotStorage( sal_False, aFile );
391     if( xStorage.Is() && xStorage->GetError() == ERRCODE_NONE )
392     {
393         // We need a BasicManager to avoid problems
394         // StarBASIC* pBas = new StarBASIC();
395         BasicManager* pBasicManager = new BasicManager( *(SotStorage*)xStorage, aFile );
396 
397         // Set info
398         LibraryContainerInfo aInfo( this, NULL, static_cast< OldBasicPassword* >( this ) );
399         pBasicManager->SetLibraryContainerInfo( aInfo );
400 
401         // Now the libraries should be copied to this SfxScriptLibraryContainer
402         BasicManager::LegacyDeleteBasicManager( pBasicManager );
403     }
404 }
405 
406 
407 // Storing with password encryption
408 
409 // Methods XLibraryContainerPassword
isLibraryPasswordProtected(const OUString & Name)410 sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordProtected( const OUString& Name )
411 {
412     LibraryContainerMethodGuard aGuard( *this );
413     SfxLibrary* pImplLib = getImplLib( Name );
414     sal_Bool bRet = pImplLib->mbPasswordProtected;
415     return bRet;
416 }
417 
isLibraryPasswordVerified(const OUString & Name)418 sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordVerified( const OUString& Name )
419 {
420     LibraryContainerMethodGuard aGuard( *this );
421     SfxLibrary* pImplLib = getImplLib( Name );
422     if( !pImplLib->mbPasswordProtected )
423         throw IllegalArgumentException();
424     sal_Bool bRet = pImplLib->mbPasswordVerified;
425     return bRet;
426 }
427 
verifyLibraryPassword(const OUString & Name,const OUString & Password)428 sal_Bool SAL_CALL SfxScriptLibraryContainer::verifyLibraryPassword
429     ( const OUString& Name, const OUString& Password )
430 {
431     LibraryContainerMethodGuard aGuard( *this );
432     SfxLibrary* pImplLib = getImplLib( Name );
433     if( !pImplLib->mbPasswordProtected || pImplLib->mbPasswordVerified )
434         throw IllegalArgumentException();
435 
436     // Test password
437     sal_Bool bSuccess = sal_False;
438     if( pImplLib->mbDoc50Password )
439     {
440         bSuccess = ( Password == pImplLib->maPassword );
441         if( bSuccess )
442             pImplLib->mbPasswordVerified = sal_True;
443     }
444     else
445     {
446         pImplLib->maPassword = Password;
447         bSuccess = implLoadPasswordLibrary( pImplLib, Name, sal_True );
448         if( bSuccess )
449         {
450             // The library gets modified by verifying the password, because other-
451             // wise for saving the storage would be copied and that doesn't work
452             // with mtg's storages when the password is verified
453             pImplLib->implSetModified( sal_True );
454             pImplLib->mbPasswordVerified = sal_True;
455 
456             // Reload library to get source
457             if( pImplLib->mbLoaded )
458                 implLoadPasswordLibrary( pImplLib, Name );
459         }
460     }
461     return bSuccess;
462 }
463 
changeLibraryPassword(const OUString & Name,const OUString & OldPassword,const OUString & NewPassword)464 void SAL_CALL SfxScriptLibraryContainer::changeLibraryPassword( const OUString& Name,
465     const OUString& OldPassword, const OUString& NewPassword )
466 {
467     LibraryContainerMethodGuard aGuard( *this );
468     SfxLibrary* pImplLib = getImplLib( Name );
469     if( OldPassword == NewPassword )
470         return;
471 
472     sal_Bool bOldPassword = !OldPassword.isEmpty();
473     sal_Bool bNewPassword = !NewPassword.isEmpty();
474     sal_Bool bStorage = mxStorage.is() && !pImplLib->mbLink;
475 
476     if( pImplLib->mbReadOnly || (bOldPassword && !pImplLib->mbPasswordProtected) )
477         throw IllegalArgumentException();
478 
479     // Library must be loaded
480     loadLibrary( Name );
481 
482     sal_Bool bKillCryptedFiles = sal_False;
483     sal_Bool bKillUncryptedFiles = sal_False;
484 
485     // Remove or change password?
486     if( bOldPassword )
487     {
488         if( isLibraryPasswordVerified( Name ) )
489         {
490             if( pImplLib->maPassword != OldPassword )
491                 throw IllegalArgumentException();
492         }
493         else
494         {
495             if( !verifyLibraryPassword( Name, OldPassword ) )
496                 throw IllegalArgumentException();
497 
498             // Reload library to get source
499             // Should be done in verifyLibraryPassword loadLibrary( Name );
500         }
501 
502         if( !bNewPassword )
503         {
504             pImplLib->mbPasswordProtected = sal_False;
505             pImplLib->mbPasswordVerified = sal_False;
506             pImplLib->maPassword = OUString();
507 
508             maModifiable.setModified( sal_True );
509             pImplLib->implSetModified( sal_True );
510 
511             if( !bStorage && !pImplLib->mbDoc50Password )
512             {
513                 // Store application basic uncrypted
514                 uno::Reference< embed::XStorage > xStorage;
515                 storeLibraries_Impl( xStorage, sal_False );
516                 bKillCryptedFiles = sal_True;
517             }
518         }
519     }
520 
521     // Set new password?
522     if( bNewPassword )
523     {
524         pImplLib->mbPasswordProtected = sal_True;
525         pImplLib->mbPasswordVerified = sal_True;
526         pImplLib->maPassword = NewPassword;
527 
528         maModifiable.setModified( sal_True );
529         pImplLib->implSetModified( sal_True );
530 
531         if( !bStorage && !pImplLib->mbDoc50Password )
532         {
533             // Store application basic crypted
534             uno::Reference< embed::XStorage > xStorage;
535             storeLibraries_Impl( xStorage, sal_False );
536             bKillUncryptedFiles = sal_True;
537         }
538     }
539 
540     if( bKillCryptedFiles || bKillUncryptedFiles )
541     {
542         Sequence< OUString > aElementNames = pImplLib->getElementNames();
543         sal_Int32 nNameCount = aElementNames.getLength();
544         const OUString* pNames = aElementNames.getConstArray();
545         OUString aLibDirPath = createAppLibraryFolder( pImplLib, Name );
546         try
547         {
548             for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
549             {
550                 OUString aElementName = pNames[ i ];
551 
552                 INetURLObject aElementInetObj( aLibDirPath );
553                 aElementInetObj.insertName( aElementName, sal_False,
554                     INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
555                 if( bKillUncryptedFiles )
556                     aElementInetObj.setExtension( maLibElementFileExtension );
557                 else
558                     aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) );
559                 String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
560 
561                 if( mxSFI->exists( aElementPath ) )
562                     mxSFI->kill( aElementPath );
563             }
564         }
565         catch( Exception& ) {}
566     }
567 }
568 
569 
setStreamKey(uno::Reference<io::XStream> xStream,const::rtl::OUString & aPass)570 void setStreamKey( uno::Reference< io::XStream > xStream, const ::rtl::OUString& aPass )
571 {
572     uno::Reference< embed::XEncryptionProtectedSource > xEncrStream( xStream, uno::UNO_QUERY );
573     if ( xEncrStream.is() )
574         xEncrStream->setEncryptionPassword( aPass );
575 }
576 
577 
578 // Impl methods
implStorePasswordLibrary(SfxLibrary * pLib,const::rtl::OUString & aName,const uno::Reference<embed::XStorage> & xStorage,const::com::sun::star::uno::Reference<::com::sun::star::task::XInteractionHandler> & xHandler)579 sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib,
580     const ::rtl::OUString& aName, const uno::Reference< embed::XStorage >& xStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler )
581 {
582     OUString aDummyLocation;
583     Reference< XSimpleFileAccess > xDummySFA;
584     return implStorePasswordLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xHandler );
585 }
586 
implStorePasswordLibrary(SfxLibrary * pLib,const::rtl::OUString & aName,const::com::sun::star::uno::Reference<::com::sun::star::embed::XStorage> & xStorage,const::rtl::OUString & aTargetURL,const Reference<XSimpleFileAccess> xToUseSFI,const::com::sun::star::uno::Reference<::com::sun::star::task::XInteractionHandler> & xHandler)587 sal_Bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, const ::rtl::OUString& aName,
588                         const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
589                         const ::rtl::OUString& aTargetURL, const Reference< XSimpleFileAccess > xToUseSFI, const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler )
590 {
591     bool bExport = aTargetURL.getLength();
592 
593     BasicManager* pBasicMgr = getBasicManager();
594     OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implStorePasswordLibrary: cannot do this without a BasicManager!" );
595     if ( !pBasicMgr )
596         return sal_False;
597 
598     // Only need to handle the export case here,
599     // save/saveas etc are handled in sfxbasemodel::storeSelf &
600     // sfxbasemodel::impl_store
601     uno::Sequence<rtl::OUString> aNames;
602     if ( bExport && pBasicMgr->LegacyPsswdBinaryLimitExceeded(aNames) )
603     {
604         if ( xHandler.is() )
605         {
606             ModuleSizeExceeded* pReq =  new ModuleSizeExceeded( aNames );
607             uno::Reference< task::XInteractionRequest > xReq( pReq );
608             xHandler->handle( xReq );
609             if ( pReq->isAbort() )
610                 throw util::VetoException();
611         }
612     }
613 
614     StarBASIC* pBasicLib = pBasicMgr->GetLib( aName );
615     if( !pBasicLib )
616         return sal_False;
617 
618     Sequence< OUString > aElementNames = pLib->getElementNames();
619     sal_Int32 nNameCount = aElementNames.getLength();
620     const OUString* pNames = aElementNames.getConstArray();
621 
622     sal_Bool bLink = pLib->mbLink;
623     sal_Bool bStorage = xStorage.is() && !bLink;
624     if( bStorage )
625     {
626         for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
627         {
628             OUString aElementName = pNames[ i ];
629 
630             // Write binary image stream
631             SbModule* pMod = pBasicLib->FindModule( aElementName );
632             if( pMod )
633             {
634                 //OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
635                 OUString aCodeStreamName = aElementName;
636                 aCodeStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".bin") );
637 
638                 try {
639                     uno::Reference< io::XStream > xCodeStream = xStorage->openStreamElement(
640                                         aCodeStreamName,
641                                         embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
642 
643                     if ( !xCodeStream.is() )
644                         throw uno::RuntimeException();
645 
646                     SvMemoryStream aMemStream;
647                     /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream );
648 
649                     sal_Int32 nSize = (sal_Int32)aMemStream.Tell();
650                     Sequence< sal_Int8 > aBinSeq( nSize );
651                     sal_Int8* pData = aBinSeq.getArray();
652                     ::rtl_copyMemory( pData, aMemStream.GetData(), nSize );
653 
654                     Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
655                     if ( !xOut.is() )
656                         throw io::IOException(); // access denied because the stream is readonly
657 
658                     xOut->writeBytes( aBinSeq );
659                     xOut->closeOutput();
660                 }
661                 catch( uno::Exception& )
662                 {
663                     // TODO: handle error
664                 }
665             }
666 
667             if( pLib->mbPasswordVerified || pLib->mbDoc50Password )
668             {
669                 /*Any aElement = pLib->getByName( aElementName );*/
670                 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
671                 {
672                 #if OSL_DEBUG_LEVEL > 0
673                     ::rtl::OStringBuffer aMessage;
674                     aMessage.append( "invalid library element '" );
675                     aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
676                     aMessage.append( "'." );
677                     OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
678                 #endif
679                     continue;
680                 }
681 
682                 OUString aSourceStreamName = aElementName;
683                 aSourceStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
684 
685                 try {
686                     uno::Reference< io::XStream > xSourceStream = xStorage->openStreamElement(
687                                                                 aSourceStreamName,
688                                                                 embed::ElementModes::READWRITE );
689                     uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY );
690                     if ( !xProps.is() )
691                         throw uno::RuntimeException();
692 
693                     String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
694                     OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
695                     xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
696 
697                     // Set encryption key
698                     setStreamKey( xSourceStream, pLib->maPassword );
699 
700                     Reference< XOutputStream > xOutput = xSourceStream->getOutputStream();
701                     Reference< XNameContainer > xLib( pLib );
702                     writeLibraryElement( xLib, aElementName, xOutput );
703                     // writeLibraryElement should have the stream already closed
704                     // xOutput->closeOutput();
705                 }
706                 catch( uno::Exception& )
707                 {
708                     OSL_ENSURE( sal_False, "Problem on storing of password library!\n" );
709                     // TODO: error handling
710                 }
711             }
712             else    // !mbPasswordVerified
713             {
714                 // TODO
715                 // What to do if not verified?! In any case it's already loaded here
716             }
717         }
718 
719     }
720     // Application libraries have only to be saved if the password
721     // is verified because otherwise they can't be modified
722     else if( pLib->mbPasswordVerified || bExport )
723     {
724         try
725         {
726             Reference< XSimpleFileAccess > xSFI = mxSFI;
727             if( xToUseSFI.is() )
728                 xSFI = xToUseSFI;
729 
730             OUString aLibDirPath;
731             if( bExport )
732             {
733                 INetURLObject aInetObj( aTargetURL );
734                 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
735                 aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
736 
737                 if( !xSFI->isFolder( aLibDirPath ) )
738                     xSFI->createFolder( aLibDirPath );
739             }
740             else
741             {
742                 aLibDirPath = createAppLibraryFolder( pLib, aName );
743             }
744 
745             for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
746             {
747                 OUString aElementName = pNames[ i ];
748 
749                 INetURLObject aElementInetObj( aLibDirPath );
750                 aElementInetObj.insertName( aElementName, sal_False,
751                     INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
752                 aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) );
753                 String aElementPath = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
754 
755                 /*Any aElement = pLib->getByName( aElementName );*/
756                 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
757                 {
758                 #if OSL_DEBUG_LEVEL > 0
759                     ::rtl::OStringBuffer aMessage;
760                     aMessage.append( "invalid library element '" );
761                     aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
762                     aMessage.append( "'." );
763                     OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
764                 #endif
765                     continue;
766                 }
767 
768                 try
769                 {
770                     uno::Reference< embed::XStorage > xElementRootStorage =
771                                                             ::comphelper::OStorageHelper::GetStorageFromURL(
772                                                                     aElementPath,
773                                                                     embed::ElementModes::READWRITE );
774                     if ( !xElementRootStorage.is() )
775                         throw uno::RuntimeException();
776 
777                     // Write binary image stream
778                     SbModule* pMod = pBasicLib->FindModule( aElementName );
779                     if( pMod )
780                     {
781                         OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
782 
783                         uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
784                                             aCodeStreamName,
785                                             embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
786 
787                         SvMemoryStream aMemStream;
788                         /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream );
789 
790                         sal_Int32 nSize = (sal_Int32)aMemStream.Tell();
791                         Sequence< sal_Int8 > aBinSeq( nSize );
792                         sal_Int8* pData = aBinSeq.getArray();
793                         ::rtl_copyMemory( pData, aMemStream.GetData(), nSize );
794 
795                         Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
796                         if ( xOut.is() )
797                         {
798                             xOut->writeBytes( aBinSeq );
799                             xOut->closeOutput();
800                         }
801                     }
802 
803                     // Write encrypted source stream
804                     OUString aSourceStreamName( RTL_CONSTASCII_USTRINGPARAM("source.xml") );
805 
806                     uno::Reference< io::XStream > xSourceStream;
807                     try
808                     {
809                         xSourceStream = xElementRootStorage->openStreamElement(
810                             aSourceStreamName,
811                             embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
812 
813                         // #87671 Allow encryption
814                         uno::Reference< embed::XEncryptionProtectedSource > xEncr( xSourceStream, uno::UNO_QUERY );
815                         OSL_ENSURE( xEncr.is(),
816                                     "StorageStream opened for writing must implement XEncryptionProtectedSource!\n" );
817                         if ( !xEncr.is() )
818                             throw uno::RuntimeException();
819                         xEncr->setEncryptionPassword( pLib->maPassword );
820                     }
821                     catch( ::com::sun::star::packages::WrongPasswordException& )
822                     {
823                         xSourceStream = xElementRootStorage->openEncryptedStreamElement(
824                             aSourceStreamName,
825                             embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE,
826                             pLib->maPassword );
827                     }
828 
829                     uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY );
830                     if ( !xProps.is() )
831                         throw uno::RuntimeException();
832                     String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
833                     OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
834                     xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
835 
836                     Reference< XOutputStream > xOut = xSourceStream->getOutputStream();
837                     Reference< XNameContainer > xLib( pLib );
838                     writeLibraryElement( xLib, aElementName, xOut );
839                     // i50568: sax writer already closes stream
840                     // xOut->closeOutput();
841 
842                     uno::Reference< embed::XTransactedObject > xTransact( xElementRootStorage, uno::UNO_QUERY );
843                     OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
844                     if ( !xTransact.is() )
845                         throw uno::RuntimeException();
846 
847                     xTransact->commit();
848                 }
849                 catch( uno::Exception& )
850                 {
851                     // TODO: handle error
852                 }
853 
854                 // Storage Dtor commits too, that makes problems
855                 // xElementRootStorage->Commit();
856             }
857         }
858         catch( Exception& )
859         {
860             //throw e;
861         }
862     }
863     return sal_True;
864 }
865 
implLoadPasswordLibrary(SfxLibrary * pLib,const OUString & Name,sal_Bool bVerifyPasswordOnly)866 sal_Bool SfxScriptLibraryContainer::implLoadPasswordLibrary
867     ( SfxLibrary* pLib, const OUString& Name, sal_Bool bVerifyPasswordOnly )
868 {
869     sal_Bool bRet = sal_True;
870 
871     sal_Bool bLink = pLib->mbLink;
872     sal_Bool bStorage = mxStorage.is() && !bLink;
873 
874     // Already loaded? Then only verifiedPassword can change something
875     SfxScriptLibrary* pScriptLib = static_cast< SfxScriptLibrary* >( pLib );
876     if( pScriptLib->mbLoaded )
877     {
878         if( pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly &&
879             (pScriptLib->mbLoadedSource || !pLib->mbPasswordVerified) )
880                 return sal_False;
881     }
882 
883     StarBASIC* pBasicLib = NULL;
884     sal_Bool bLoadBinary = sal_False;
885     if( !pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly && !pLib->mbPasswordVerified )
886     {
887         BasicManager* pBasicMgr = getBasicManager();
888         OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implLoadPasswordLibrary: cannot do this without a BasicManager!" );
889         sal_Bool bLoaded = pScriptLib->mbLoaded;
890         pScriptLib->mbLoaded = sal_True;        // Necessary to get lib
891         pBasicLib = pBasicMgr ? pBasicMgr->GetLib( Name ) : NULL;
892         pScriptLib->mbLoaded = bLoaded;    // Restore flag
893         if( !pBasicLib )
894             return sal_False;
895 
896         bLoadBinary = sal_True;
897         pScriptLib->mbLoadedBinary = sal_True;
898     }
899 
900     sal_Bool bLoadSource = sal_False;
901     if( !pScriptLib->mbLoadedSource && pLib->mbPasswordVerified && !bVerifyPasswordOnly )
902     {
903         bLoadSource = sal_True;
904         pScriptLib->mbLoadedSource = sal_True;
905     }
906 
907     Sequence< OUString > aElementNames = pLib->getElementNames();
908     sal_Int32 nNameCount = aElementNames.getLength();
909     const OUString* pNames = aElementNames.getConstArray();
910 
911     if( bStorage )
912     {
913         uno::Reference< embed::XStorage > xLibrariesStor;
914         uno::Reference< embed::XStorage > xLibraryStor;
915         if( bStorage )
916         {
917             try {
918                 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
919                 if ( !xLibrariesStor.is() )
920                     throw uno::RuntimeException();
921 
922                 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
923                 if ( !xLibraryStor.is() )
924                     throw uno::RuntimeException();
925             }
926             catch( uno::Exception& )
927             {
928                 OSL_ENSURE( 0, "### couldn't open sub storage for library\n" );
929                 return sal_False;
930             }
931         }
932 
933         for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
934         {
935             OUString aElementName = pNames[ i ];
936 
937             // Load binary
938             if( bLoadBinary )
939             {
940                 SbModule* pMod = pBasicLib->FindModule( aElementName );
941                 if( !pMod )
942                 {
943                     pMod = pBasicLib->MakeModule( aElementName, String() );
944                     pBasicLib->SetModified( sal_False );
945                 }
946 
947                 //OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
948                 OUString aCodeStreamName= aElementName;
949                 aCodeStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".bin") );
950 
951                 try {
952                     uno::Reference< io::XStream > xCodeStream = xLibraryStor->openStreamElement(
953                                                                                         aCodeStreamName,
954                                                                                         embed::ElementModes::READ );
955                     if ( !xCodeStream.is() )
956                         throw uno::RuntimeException();
957 
958                     SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xCodeStream );
959                     if ( !pStream || pStream->GetError() )
960                     {
961                         sal_Int32 nError = pStream ? pStream->GetError() : ERRCODE_IO_GENERAL;
962                         delete pStream;
963                         throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), nError );
964                     }
965 
966                     /*sal_Bool bRet = */pMod->LoadBinaryData( *pStream );
967                     // TODO: Check return value
968 
969                     delete pStream;
970                 }
971                 catch( uno::Exception& )
972                 {
973                     // TODO: error handling
974                 }
975             }
976 
977             // Load source
978             if( bLoadSource || bVerifyPasswordOnly )
979             {
980                 // Access encrypted source stream
981                 OUString aSourceStreamName = aElementName;
982                 aSourceStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
983 
984                 try {
985                     uno::Reference< io::XStream > xSourceStream = xLibraryStor->openEncryptedStreamElement(
986                                                                     aSourceStreamName,
987                                                                     embed::ElementModes::READ,
988                                                                     pLib->maPassword );
989                     if ( !xSourceStream.is() )
990                         throw uno::RuntimeException();
991 
992                     // if this point is reached then the password is correct
993                     if ( !bVerifyPasswordOnly )
994                     {
995                         uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
996                         if ( !xInStream.is() )
997                             throw io::IOException(); // read access denied, seems to be impossible
998 
999                         Reference< XNameContainer > xLib( pLib );
1000                         Any aAny = importLibraryElement( xLib,
1001                                         aElementName, aSourceStreamName,
1002                                         xInStream );
1003                         if( pLib->hasByName( aElementName ) )
1004                         {
1005                             if( aAny.hasValue() )
1006                                 pLib->maNameContainer.replaceByName( aElementName, aAny );
1007                         }
1008                         else
1009                         {
1010                             pLib->maNameContainer.insertByName( aElementName, aAny );
1011                         }
1012                     }
1013                 }
1014                 catch( uno::Exception& )
1015                 {
1016                     bRet = sal_False;
1017                 }
1018             }
1019         }
1020     }
1021     else
1022     {
1023         try
1024         {
1025             OUString aLibDirPath = createAppLibraryFolder( pLib, Name );
1026 
1027             for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1028             {
1029                 OUString aElementName = pNames[ i ];
1030 
1031                 INetURLObject aElementInetObj( aLibDirPath );
1032                 aElementInetObj.insertName( aElementName, sal_False,
1033                     INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1034                 aElementInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("pba") ) );
1035                 String aElementPath = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
1036 
1037                 uno::Reference< embed::XStorage > xElementRootStorage;
1038                 try {
1039                     xElementRootStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
1040                                                                     aElementPath,
1041                                                                     embed::ElementModes::READ );
1042                 } catch( uno::Exception& )
1043                 {
1044                     // TODO: error handling
1045                 }
1046 
1047                 if ( xElementRootStorage.is() )
1048                 {
1049                     // Load binary
1050                     if( bLoadBinary )
1051                     {
1052                         SbModule* pMod = pBasicLib->FindModule( aElementName );
1053                         if( !pMod )
1054                         {
1055                             pMod = pBasicLib->MakeModule( aElementName, String() );
1056                             pBasicLib->SetModified( sal_False );
1057                         }
1058 
1059                         try {
1060                             OUString aCodeStreamName( RTL_CONSTASCII_USTRINGPARAM("code.bin") );
1061                             uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
1062                                                                         aCodeStreamName,
1063                                                                         embed::ElementModes::READ );
1064 
1065                             SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xCodeStream );
1066                             if ( !pStream || pStream->GetError() )
1067                             {
1068                                 sal_Int32 nError = pStream ? pStream->GetError() : ERRCODE_IO_GENERAL;
1069                                 delete pStream;
1070                                 throw task::ErrorCodeIOException( ::rtl::OUString(),
1071                                                                     uno::Reference< uno::XInterface >(),
1072                                                                     nError );
1073                             }
1074 
1075                             /*sal_Bool bRet = */pMod->LoadBinaryData( *pStream );
1076                             // TODO: Check return value
1077 
1078                             delete pStream;
1079                         }
1080                         catch( uno::Exception& )
1081                         {
1082                             // TODO: error handling
1083                         }
1084                     }
1085 
1086                     // Load source
1087                     if( bLoadSource || bVerifyPasswordOnly )
1088                     {
1089                         // Access encrypted source stream
1090                         OUString aSourceStreamName( RTL_CONSTASCII_USTRINGPARAM("source.xml") );
1091                         try {
1092                             uno::Reference< io::XStream > xSourceStream = xElementRootStorage->openEncryptedStreamElement(
1093                                                                     aSourceStreamName,
1094                                                                     embed::ElementModes::READ,
1095                                                                     pLib->maPassword );
1096                             if ( !xSourceStream.is() )
1097                                 throw uno::RuntimeException();
1098 
1099                             if ( !bVerifyPasswordOnly )
1100                             {
1101                                 uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
1102                                 if ( !xInStream.is() )
1103                                     throw io::IOException(); // read access denied, seems to be impossible
1104 
1105                                 Reference< XNameContainer > xLib( pLib );
1106                                 Any aAny = importLibraryElement( xLib,
1107                                                 aElementName,
1108                                                 aSourceStreamName,
1109                                                 xInStream );
1110                                 if( pLib->hasByName( aElementName ) )
1111                                 {
1112                                     if( aAny.hasValue() )
1113                                         pLib->maNameContainer.replaceByName( aElementName, aAny );
1114                                 }
1115                                 else
1116                                 {
1117                                     pLib->maNameContainer.insertByName( aElementName, aAny );
1118                                 }
1119                             }
1120                         }
1121                         catch ( uno::Exception& )
1122                         {
1123                             bRet = sal_False;
1124                         }
1125                     }
1126                 }
1127             }
1128 
1129         }
1130         catch( Exception& )
1131         {
1132             // TODO
1133             //throw e;
1134         }
1135     }
1136 
1137 //REMOVE        // If the password is verified the library must remain modified, because
1138 //REMOVE        // otherwise for saving the storage would be copied and that doesn't work
1139 //REMOVE        // with mtg's storages when the password is verified
1140 //REMOVE        if( !pLib->mbPasswordVerified )
1141 //REMOVE            pLib->mbModified = sal_False;
1142     return bRet;
1143 }
1144 
1145 
onNewRootStorage()1146 void SfxScriptLibraryContainer::onNewRootStorage()
1147 {
1148 }
1149 
1150 //============================================================================
1151 // Service
createRegistryInfo_SfxScriptLibraryContainer()1152 void createRegistryInfo_SfxScriptLibraryContainer()
1153 {
1154     static OAutoRegistration< SfxScriptLibraryContainer > aAutoRegistration;
1155 }
1156 
getImplementationName()1157 ::rtl::OUString SAL_CALL SfxScriptLibraryContainer::getImplementationName( )
1158 {
1159     return getImplementationName_static();
1160 }
1161 
getSupportedServiceNames()1162 Sequence< ::rtl::OUString > SAL_CALL SfxScriptLibraryContainer::getSupportedServiceNames( )
1163 {
1164     return getSupportedServiceNames_static();
1165 }
1166 
getSupportedServiceNames_static()1167 Sequence< OUString > SfxScriptLibraryContainer::getSupportedServiceNames_static()
1168 {
1169     Sequence< OUString > aServiceNames( 2 );
1170     aServiceNames[0] = OUString::createFromAscii( "com.sun.star.script.DocumentScriptLibraryContainer" );
1171     // plus, for compatibility:
1172     aServiceNames[1] = OUString::createFromAscii( "com.sun.star.script.ScriptLibraryContainer" );
1173     return aServiceNames;
1174 }
1175 
getImplementationName_static()1176 OUString SfxScriptLibraryContainer::getImplementationName_static()
1177 {
1178     static OUString aImplName;
1179     static sal_Bool bNeedsInit = sal_True;
1180 
1181     MutexGuard aGuard( Mutex::getGlobalMutex() );
1182     if( bNeedsInit )
1183     {
1184         aImplName = OUString::createFromAscii( "com.sun.star.comp.sfx2.ScriptLibraryContainer" );
1185         bNeedsInit = sal_False;
1186     }
1187     return aImplName;
1188 }
1189 
Create(const Reference<XComponentContext> &)1190 Reference< XInterface > SAL_CALL SfxScriptLibraryContainer::Create
1191     ( const Reference< XComponentContext >& )
1192 {
1193     Reference< XInterface > xRet =
1194         static_cast< XInterface* >( static_cast< OWeakObject* >(new SfxScriptLibraryContainer()) );
1195     return xRet;
1196 }
1197 
1198 //============================================================================
1199 // Implementation class SfxScriptLibrary
1200 
1201 // Ctor
SfxScriptLibrary(ModifiableHelper & _rModifiable,const Reference<XMultiServiceFactory> & xMSF,const Reference<XSimpleFileAccess> & xSFI)1202 SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
1203                                     const Reference< XMultiServiceFactory >& xMSF,
1204                                     const Reference< XSimpleFileAccess >& xSFI )
1205     : SfxLibrary( _rModifiable, getCppuType( (const OUString *)0 ), xMSF, xSFI )
1206     , mbLoadedSource( sal_False )
1207     , mbLoadedBinary( sal_False )
1208 {
1209 }
1210 
SfxScriptLibrary(ModifiableHelper & _rModifiable,const Reference<XMultiServiceFactory> & xMSF,const Reference<XSimpleFileAccess> & xSFI,const OUString & aLibInfoFileURL,const OUString & aStorageURL,sal_Bool ReadOnly)1211 SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
1212                                     const Reference< XMultiServiceFactory >& xMSF,
1213                                     const Reference< XSimpleFileAccess >& xSFI,
1214                                     const OUString& aLibInfoFileURL,
1215                                     const OUString& aStorageURL,
1216                                     sal_Bool ReadOnly )
1217     : SfxLibrary( _rModifiable, getCppuType( (const OUString *)0 ), xMSF, xSFI,
1218                         aLibInfoFileURL, aStorageURL, ReadOnly)
1219     , mbLoadedSource( sal_False )
1220     , mbLoadedBinary( sal_False )
1221 {
1222 }
1223 
1224 // Provide modify state including resources
isModified(void)1225 sal_Bool SfxScriptLibrary::isModified( void )
1226 {
1227     return implIsModified();    // No resources
1228 }
1229 
storeResources(void)1230 void SfxScriptLibrary::storeResources( void )
1231 {
1232     // No resources
1233 }
1234 
storeResourcesToURL(const::rtl::OUString & URL,const Reference<task::XInteractionHandler> & Handler)1235 void SfxScriptLibrary::storeResourcesToURL( const ::rtl::OUString& URL,
1236     const Reference< task::XInteractionHandler >& Handler )
1237 {
1238     (void)URL;
1239     (void)Handler;
1240 }
1241 
storeResourcesAsURL(const::rtl::OUString & URL,const::rtl::OUString & NewName)1242 void SfxScriptLibrary::storeResourcesAsURL
1243     ( const ::rtl::OUString& URL, const ::rtl::OUString& NewName )
1244 {
1245     (void)URL;
1246     (void)NewName;
1247 }
1248 
storeResourcesToStorage(const::com::sun::star::uno::Reference<::com::sun::star::embed::XStorage> & xStorage)1249 void SfxScriptLibrary::storeResourcesToStorage( const ::com::sun::star::uno::Reference
1250     < ::com::sun::star::embed::XStorage >& xStorage )
1251 {
1252     // No resources
1253     (void)xStorage;
1254 }
1255 
containsValidModule(const Any & aElement)1256 bool SfxScriptLibrary::containsValidModule( const Any& aElement )
1257 {
1258     OUString sModuleText;
1259     aElement >>= sModuleText;
1260     return ( !sModuleText.isEmpty() );
1261 }
1262 
isLibraryElementValid(::com::sun::star::uno::Any aElement) const1263 bool SAL_CALL SfxScriptLibrary::isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const
1264 {
1265     return SfxScriptLibrary::containsValidModule( aElement );
1266 }
1267 
1268 IMPLEMENT_FORWARD_XINTERFACE2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE );
1269 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE );
1270 
1271 script::ModuleInfo SAL_CALL
getModuleInfo(const::rtl::OUString & ModuleName)1272 SfxScriptLibrary::getModuleInfo( const ::rtl::OUString& ModuleName )
1273 {
1274     if ( !hasModuleInfo( ModuleName ) )
1275         throw NoSuchElementException();
1276     return mModuleInfos[ ModuleName ];
1277 }
1278 
1279 sal_Bool SAL_CALL
hasModuleInfo(const::rtl::OUString & ModuleName)1280 SfxScriptLibrary::hasModuleInfo( const ::rtl::OUString& ModuleName )
1281 {
1282     sal_Bool bRes = sal_False;
1283     ModuleInfoMap::iterator it = mModuleInfos.find( ModuleName );
1284 
1285     if ( it != mModuleInfos.end() )
1286         bRes = sal_True;
1287 
1288     return bRes;
1289 }
1290 
insertModuleInfo(const::rtl::OUString & ModuleName,const script::ModuleInfo & ModuleInfo)1291 void SAL_CALL SfxScriptLibrary::insertModuleInfo( const ::rtl::OUString& ModuleName, const script::ModuleInfo& ModuleInfo )
1292 {
1293     if ( hasModuleInfo( ModuleName ) )
1294         throw ElementExistException();
1295     mModuleInfos[ ModuleName ] = ModuleInfo;
1296 }
1297 
removeModuleInfo(const::rtl::OUString & ModuleName)1298 void SAL_CALL SfxScriptLibrary::removeModuleInfo( const ::rtl::OUString& ModuleName )
1299 {
1300         // #FIXME add NoSuchElementException to the spec
1301     if ( !hasModuleInfo( ModuleName ) )
1302         throw NoSuchElementException();
1303     mModuleInfos.erase( mModuleInfos.find( ModuleName ) );
1304 }
1305 
1306 
1307 //============================================================================
1308 
1309 }   // namespace basic
1310