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