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