xref: /trunk/main/basic/source/uno/namecont.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/container/XContainer.hpp>
32 #include <com/sun/star/embed/ElementModes.hpp>
33 #include <com/sun/star/embed/XTransactedObject.hpp>
34 #include <com/sun/star/lang/XServiceInfo.hpp>
35 #include <vcl/svapp.hxx>
36 #include <vos/mutex.hxx>
37 #include <tools/errinf.hxx>
38 #include <osl/mutex.hxx>
39 #include <vos/diagnose.hxx>
40 #include <rtl/uri.hxx>
41 #include <rtl/strbuf.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/anytostring.hxx>
44 
45 #include "namecont.hxx"
46 #include <basic/basicmanagerrepository.hxx>
47 #include <tools/diagnose_ex.h>
48 #include <tools/urlobj.hxx>
49 #include <unotools/streamwrap.hxx>
50 #include <unotools/pathoptions.hxx>
51 #include <svtools/sfxecode.hxx>
52 #include <svtools/ehdl.hxx>
53 #include <basic/basmgr.hxx>
54 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
55 #include <com/sun/star/xml/sax/XParser.hpp>
56 #include <com/sun/star/xml/sax/InputSource.hpp>
57 #include <com/sun/star/io/XOutputStream.hpp>
58 #include <com/sun/star/io/XInputStream.hpp>
59 #include <com/sun/star/io/XActiveDataSource.hpp>
60 #include <com/sun/star/beans/XPropertySet.hpp>
61 #include <com/sun/star/uno/DeploymentException.hpp>
62 #include <com/sun/star/lang/DisposedException.hpp>
63 #include <com/sun/star/script/LibraryNotLoadedException.hpp>
64 #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
65 #include <com/sun/star/deployment/ExtensionManager.hpp>
66 #include <comphelper/storagehelper.hxx>
67 #include <cppuhelper/exc_hlp.hxx>
68 #include <basic/sbmod.hxx>
69 
70 namespace basic
71 {
72 
73 using namespace com::sun::star::document;
74 using namespace com::sun::star::container;
75 using namespace com::sun::star::uno;
76 using namespace com::sun::star::lang;
77 using namespace com::sun::star::io;
78 using namespace com::sun::star::ucb;
79 using namespace com::sun::star::script;
80 using namespace com::sun::star::beans;
81 using namespace com::sun::star::xml::sax;
82 using namespace com::sun::star::util;
83 using namespace com::sun::star::task;
84 using namespace com::sun::star::embed;
85 using namespace com::sun::star::frame;
86 using namespace com::sun::star::deployment;
87 using namespace com::sun::star;
88 using namespace cppu;
89 using namespace rtl;
90 using namespace osl;
91 
92 using com::sun::star::uno::Reference;
93 
94 // #i34411: Flag for error handling during migration
95 static bool GbMigrationSuppressErrors = false;
96 
97 //============================================================================
98 // Implementation class NameContainer
99 
100 // Methods XElementAccess
101 Type NameContainer::getElementType()
102     throw(RuntimeException)
103 {
104     return mType;
105 }
106 
107 sal_Bool NameContainer::hasElements()
108     throw(RuntimeException)
109 {
110     sal_Bool bRet = (mnElementCount > 0);
111     return bRet;
112 }
113 
114 // Methods XNameAccess
115 Any NameContainer::getByName( const OUString& aName )
116     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
117 {
118     NameContainerNameMap::iterator aIt = mHashMap.find( aName );
119     if( aIt == mHashMap.end() )
120     {
121         throw NoSuchElementException();
122     }
123     sal_Int32 iHashResult = (*aIt).second;
124     Any aRetAny = mValues.getConstArray()[ iHashResult ];
125     return aRetAny;
126 }
127 
128 Sequence< OUString > NameContainer::getElementNames()
129     throw(RuntimeException)
130 {
131     return mNames;
132 }
133 
134 sal_Bool NameContainer::hasByName( const OUString& aName )
135     throw(RuntimeException)
136 {
137     NameContainerNameMap::iterator aIt = mHashMap.find( aName );
138     sal_Bool bRet = ( aIt != mHashMap.end() );
139     return bRet;
140 }
141 
142 
143 // Methods XNameReplace
144 void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
145     throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
146 {
147     Type aAnyType = aElement.getValueType();
148     if( mType != aAnyType )
149         throw IllegalArgumentException();
150 
151     NameContainerNameMap::iterator aIt = mHashMap.find( aName );
152     if( aIt == mHashMap.end() )
153     {
154         throw NoSuchElementException();
155     }
156     sal_Int32 iHashResult = (*aIt).second;
157     Any aOldElement = mValues.getConstArray()[ iHashResult ];
158     mValues.getArray()[ iHashResult ] = aElement;
159 
160 
161     // Fire event
162     if( maContainerListeners.getLength() > 0 )
163     {
164         ContainerEvent aEvent;
165         aEvent.Source = mpxEventSource;
166         aEvent.Accessor <<= aName;
167         aEvent.Element = aElement;
168         aEvent.ReplacedElement = aOldElement;
169         maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent );
170     }
171 
172     /*  After the container event has been fired (one listener will update the
173         core Basic manager), fire change event. Listeners can rely that the
174         Basic source code of the core Basic manager is up-to-date. */
175     if( maChangesListeners.getLength() > 0 )
176     {
177         ChangesEvent aEvent;
178         aEvent.Source = mpxEventSource;
179         aEvent.Base <<= aEvent.Source;
180         aEvent.Changes.realloc( 1 );
181         aEvent.Changes[ 0 ].Accessor <<= aName;
182         aEvent.Changes[ 0 ].Element <<= aElement;
183         aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
184         maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
185     }
186 }
187 
188 
189 // Methods XNameContainer
190 void NameContainer::insertByName( const OUString& aName, const Any& aElement )
191     throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
192 {
193     Type aAnyType = aElement.getValueType();
194     if( mType != aAnyType )
195         throw IllegalArgumentException();
196 
197     NameContainerNameMap::iterator aIt = mHashMap.find( aName );
198     if( aIt != mHashMap.end() )
199     {
200         throw ElementExistException();
201     }
202 
203     sal_Int32 nCount = mNames.getLength();
204     mNames.realloc( nCount + 1 );
205     mValues.realloc( nCount + 1 );
206     mNames.getArray()[ nCount ] = aName;
207     mValues.getArray()[ nCount ] = aElement;
208 
209     mHashMap[ aName ] = nCount;
210     mnElementCount++;
211 
212     // Fire event
213     if( maContainerListeners.getLength() > 0 )
214     {
215         ContainerEvent aEvent;
216         aEvent.Source = mpxEventSource;
217         aEvent.Accessor <<= aName;
218         aEvent.Element = aElement;
219         maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
220     }
221 
222     /*  After the container event has been fired (one listener will update the
223         core Basic manager), fire change event. Listeners can rely that the
224         Basic source code of the core Basic manager is up-to-date. */
225     if( maChangesListeners.getLength() > 0 )
226     {
227         ChangesEvent aEvent;
228         aEvent.Source = mpxEventSource;
229         aEvent.Base <<= aEvent.Source;
230         aEvent.Changes.realloc( 1 );
231         aEvent.Changes[ 0 ].Accessor <<= aName;
232         aEvent.Changes[ 0 ].Element <<= aElement;
233         maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
234     }
235 }
236 
237 void NameContainer::removeByName( const OUString& aName )
238     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
239 {
240     NameContainerNameMap::iterator aIt = mHashMap.find( aName );
241     if( aIt == mHashMap.end() )
242     {
243         throw NoSuchElementException();
244     }
245 
246     sal_Int32 iHashResult = (*aIt).second;
247     Any aOldElement = mValues.getConstArray()[ iHashResult ];
248     mHashMap.erase( aIt );
249     sal_Int32 iLast = mNames.getLength() - 1;
250     if( iLast != iHashResult )
251     {
252         OUString* pNames = mNames.getArray();
253         Any* pValues = mValues.getArray();
254         pNames[ iHashResult ] = pNames[ iLast ];
255         pValues[ iHashResult ] = pValues[ iLast ];
256         mHashMap[ pNames[ iHashResult ] ] = iHashResult;
257     }
258     mNames.realloc( iLast );
259     mValues.realloc( iLast );
260     mnElementCount--;
261 
262     // Fire event
263     if( maContainerListeners.getLength() > 0 )
264     {
265         ContainerEvent aEvent;
266         aEvent.Source = mpxEventSource;
267         aEvent.Accessor <<= aName;
268         aEvent.Element = aOldElement;
269         maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
270     }
271 
272     /*  After the container event has been fired (one listener will update the
273         core Basic manager), fire change event. Listeners can rely that the
274         Basic source code of the core Basic manager is up-to-date. */
275     if( maChangesListeners.getLength() > 0 )
276     {
277         ChangesEvent aEvent;
278         aEvent.Source = mpxEventSource;
279         aEvent.Base <<= aEvent.Source;
280         aEvent.Changes.realloc( 1 );
281         aEvent.Changes[ 0 ].Accessor <<= aName;
282         // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
283         aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
284         maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
285     }
286 }
287 
288 
289 // Methods XContainer
290 void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
291     throw (RuntimeException)
292 {
293     if( !xListener.is() )
294         throw RuntimeException();
295     Reference< XInterface > xIface( xListener, UNO_QUERY );
296     maContainerListeners.addInterface( xIface );
297 }
298 
299 void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
300     throw (RuntimeException)
301 {
302     if( !xListener.is() )
303         throw RuntimeException();
304     Reference< XInterface > xIface( xListener, UNO_QUERY );
305     maContainerListeners.removeInterface( xIface );
306 }
307 
308 // Methods XChangesNotifier
309 void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener )
310     throw (RuntimeException)
311 {
312     if( !xListener.is() )
313         throw RuntimeException();
314     Reference< XInterface > xIface( xListener, UNO_QUERY );
315     maChangesListeners.addInterface( xIface );
316 }
317 
318 void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener )
319     throw (RuntimeException)
320 {
321     if( !xListener.is() )
322         throw RuntimeException();
323     Reference< XInterface > xIface( xListener, UNO_QUERY );
324     maChangesListeners.removeInterface( xIface );
325 }
326 
327 //============================================================================
328 // ModifiableHelper
329 
330 void ModifiableHelper::setModified( sal_Bool _bModified )
331 {
332     if ( _bModified == mbModified )
333         return;
334     mbModified = _bModified;
335 
336     if ( m_aModifyListeners.getLength() == 0 )
337         return;
338 
339     EventObject aModifyEvent( m_rEventSource );
340     m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
341 }
342 
343 //============================================================================
344 
345 VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex& rMutex ) :
346     VBAScriptListenerContainer_BASE( rMutex )
347 {
348 }
349 
350 bool VBAScriptListenerContainer::implTypedNotify( const Reference< vba::XVBAScriptListener >& rxListener, const vba::VBAScriptEvent& rEvent ) throw (Exception)
351 {
352     rxListener->notifyVBAScriptEvent( rEvent );
353     return true;    // notify all other listeners too
354 }
355 
356 //============================================================================
357 
358 // Implementation class SfxLibraryContainer
359 DBG_NAME( SfxLibraryContainer )
360 
361 // Ctor
362 SfxLibraryContainer::SfxLibraryContainer( void )
363     : SfxLibraryContainer_BASE( maMutex )
364 
365     , maVBAScriptListeners( maMutex )
366     , mnRunningVBAScripts( 0 )
367     , mbVBACompat( sal_False )
368     , maModifiable( *this, maMutex )
369     , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
370     , mbOldInfoFormat( sal_False )
371     , mbOasis2OOoFormat( sal_False )
372     , mpBasMgr( NULL )
373     , mbOwnBasMgr( sal_False )
374 {
375     DBG_CTOR( SfxLibraryContainer, NULL );
376 
377     mxMSF = comphelper::getProcessServiceFactory();
378     if( !mxMSF.is() )
379     {
380         OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
381     }
382 
383     mxSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
384         ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
385     if( !mxSFI.is() )
386     {
387         OSL_ENSURE( 0, "### couln't create SimpleFileAccess component\n" );
388     }
389 
390     mxStringSubstitution = Reference< XStringSubstitution >( mxMSF->createInstance
391         ( OUString::createFromAscii( "com.sun.star.util.PathSubstitution" ) ), UNO_QUERY );
392     if( !mxStringSubstitution.is() )
393     {
394         OSL_ENSURE( 0, "### couln't create PathSubstitution component\n" );
395     }
396 }
397 
398 SfxLibraryContainer::~SfxLibraryContainer()
399 {
400     if( mbOwnBasMgr )
401         BasicManager::LegacyDeleteBasicManager( mpBasMgr );
402     DBG_DTOR( SfxLibraryContainer, NULL );
403 }
404 
405 void SfxLibraryContainer::checkDisposed() const
406 {
407     if ( isDisposed() )
408         throw DisposedException( ::rtl::OUString(), *const_cast< SfxLibraryContainer* >( this ) );
409 }
410 
411 void SfxLibraryContainer::enterMethod()
412 {
413     maMutex.acquire();
414     checkDisposed();
415 }
416 
417 void SfxLibraryContainer::leaveMethod()
418 {
419     maMutex.release();
420 }
421 
422 BasicManager* SfxLibraryContainer::getBasicManager( void )
423 {
424     if ( mpBasMgr )
425         return mpBasMgr;
426 
427     Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
428     OSL_ENSURE( xDocument.is(), "SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager without document!" );
429     if ( xDocument.is() )
430         mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );
431 
432     return mpBasMgr;
433 }
434 
435 // Methods XStorageBasedLibraryContainer
436 Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage() throw (RuntimeException)
437 {
438     LibraryContainerMethodGuard aGuard( *this );
439     return mxStorage;
440 }
441 
442 void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage ) throw (IllegalArgumentException, RuntimeException)
443 {
444     LibraryContainerMethodGuard aGuard( *this );
445     if ( !_rxRootStorage.is() )
446         throw IllegalArgumentException();
447 
448     mxStorage = _rxRootStorage;
449     onNewRootStorage();
450 }
451 
452 void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
453 {
454     LibraryContainerMethodGuard aGuard( *this );
455     if ( !_rxRootStorage.is() )
456         throw IllegalArgumentException();
457 
458     try
459     {
460         storeLibraries_Impl( _rxRootStorage, sal_True );
461     }
462     catch( const Exception& )
463     {
464         throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
465     }
466 }
467 
468 
469 // Methods XModifiable
470 sal_Bool SfxLibraryContainer::isModified() throw (RuntimeException)
471 {
472     LibraryContainerMethodGuard aGuard( *this );
473     if ( maModifiable.isModified() )
474         return sal_True;
475 
476     // the library container is not modified, go through the libraries and check whether they are modified
477     Sequence< OUString > aNames = maNameContainer.getElementNames();
478     const OUString* pNames = aNames.getConstArray();
479     sal_Int32 nNameCount = aNames.getLength();
480 
481     for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
482     {
483         OUString aName = pNames[ i ];
484         SfxLibrary* pImplLib = getImplLib( aName );
485         if( pImplLib->isModified() )
486         {
487             if ( aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ) ) )
488             {
489                 // this is a workaround that has to be implemented because
490                 // empty standard library should stay marked as modified
491                 // but should not be treated as modified while it is empty
492                 if ( pImplLib->hasElements() )
493                     return sal_True;
494             }
495             else
496                 return sal_True;
497         }
498     }
499 
500     return sal_False;
501 }
502 
503 void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException)
504 {
505     LibraryContainerMethodGuard aGuard( *this );
506     maModifiable.setModified( _bModified );
507 }
508 
509 void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
510 {
511     LibraryContainerMethodGuard aGuard( *this );
512     maModifiable.addModifyListener( _rxListener );
513 }
514 
515 void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
516 {
517     LibraryContainerMethodGuard aGuard( *this );
518     maModifiable.removeModifyListener( _rxListener );
519 }
520 
521 // Methods XPersistentLibraryContainer
522 Any SAL_CALL SfxLibraryContainer::getRootLocation() throw (RuntimeException)
523 {
524     LibraryContainerMethodGuard aGuard( *this );
525     return makeAny( getRootStorage() );
526 }
527 
528 ::rtl::OUString SAL_CALL SfxLibraryContainer::getContainerLocationName() throw (RuntimeException)
529 {
530     LibraryContainerMethodGuard aGuard( *this );
531     return maLibrariesDir;
532 }
533 
534 void SAL_CALL SfxLibraryContainer::storeLibraries(  ) throw (WrappedTargetException, RuntimeException)
535 {
536     LibraryContainerMethodGuard aGuard( *this );
537     try
538     {
539         storeLibraries_Impl( mxStorage, mxStorage.is()  );
540         // we need to store *all* libraries if and only if we are based on a storage:
541         // in this case, storeLibraries_Impl will remove the source storage, after loading
542         // all libraries, so we need to force them to be stored, again
543     }
544     catch( const Exception& )
545     {
546         throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
547     }
548 }
549 
550 static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
551                                   const INetURLObject& rTargetFolderInetObj,
552                                   const OUString& rCheckFileName,
553                                   const OUString& rCheckExtension,
554                                   Reference< XSimpleFileAccess > xSFI )
555 {
556     INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
557     aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
558                                      sal_True, INetURLObject::ENCODE_ALL );
559     aTargetFolderInetObj.setExtension( rCheckExtension );
560     OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
561     if( !xSFI->exists( aTargetFile ) )
562     {
563         INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
564         aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
565                                          sal_True, INetURLObject::ENCODE_ALL );
566         aSourceFolderInetObj.setExtension( rCheckExtension );
567         OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
568         xSFI->copy( aSourceFile, aTargetFile );
569     }
570 }
571 
572 static void createVariableURL( OUString& rStr, const OUString& rLibName,
573                                const OUString& rInfoFileName, bool bUser )
574 {
575     if( bUser )
576         rStr = OUString::createFromAscii( "$(USER)/basic/" );
577     else
578         rStr = OUString::createFromAscii( "$(INST)/share/basic/" );
579 
580     rStr += rLibName;
581     rStr += OUString::createFromAscii( "/" );
582     rStr += rInfoFileName;
583     rStr += OUString::createFromAscii( ".xlb/" );
584 }
585 
586 sal_Bool SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
587 {
588     // this might be called from within the ctor, and the impl_init might (indirectly) create
589     // an UNO reference to ourself.
590     // Ensure that we're not destroyed while we're in here
591     osl_incrementInterlockedCount( &m_refCount );
592     sal_Bool bSuccess = init_Impl( rInitialDocumentURL, rxInitialStorage );
593     osl_decrementInterlockedCount( &m_refCount );
594 
595     return bSuccess;
596 }
597 
598 sal_Bool SfxLibraryContainer::init_Impl(
599     const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
600 {
601     uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
602 
603     maInitialDocumentURL = rInitialDocumentURL;
604     maInfoFileName = OUString::createFromAscii( getInfoFileName() );
605     maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
606     maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
607     maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );
608 
609     meInitMode = DEFAULT;
610     INetURLObject aInitUrlInetObj( maInitialDocumentURL );
611     OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
612     if( aInitFileName.getLength() )
613     {
614         // We need a BasicManager to avoid problems
615         StarBASIC* pBas = new StarBASIC();
616         mpBasMgr = new BasicManager( pBas );
617         mbOwnBasMgr = sal_True;
618 
619         OUString aExtension = aInitUrlInetObj.getExtension();
620         if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
621         {
622             meInitMode = CONTAINER_INIT_FILE;
623             INetURLObject aLibPathInetObj( aInitUrlInetObj );
624             aLibPathInetObj.removeSegment();
625             maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
626         }
627         else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
628         {
629             meInitMode = LIBRARY_INIT_FILE;
630             uno::Reference< embed::XStorage > xDummyStor;
631             ::xmlscript::LibDescriptor aLibDesc;
632             sal_Bool bReadIndexFile = implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
633             return bReadIndexFile;
634         }
635         else
636         {
637             // Decide between old and new document
638             sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
639             if ( bOldStorage )
640             {
641                 meInitMode = OLD_BASIC_STORAGE;
642                 importFromOldStorage( aInitFileName );
643                 return sal_True;
644             }
645             else
646             {
647                 meInitMode = OFFICE_DOCUMENT;
648                 try
649                 {
650                     xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
651                 }
652                 catch ( uno::Exception& )
653                 {
654                     // TODO: error handling
655                 }
656             }
657         }
658     }
659     else
660     {
661         // Default pathes
662         maLibraryPath = SvtPathOptions().GetBasicPath();
663     }
664 
665     Reference< XParser > xParser( mxMSF->createInstance(
666         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
667     if( !xParser.is() )
668     {
669         OSL_ENSURE( 0, "### couln't create sax parser component\n" );
670         return sal_False;
671     }
672 
673     uno::Reference< io::XInputStream > xInput;
674 
675     mxStorage = xStorage;
676     sal_Bool bStorage = mxStorage.is();
677 
678 
679     // #110009: Scope to force the StorageRefs to be destructed and
680     // so the streams to be closed before the preload operation
681     {
682     // #110009
683 
684     uno::Reference< embed::XStorage > xLibrariesStor;
685     String aFileName;
686 
687     int nPassCount = 1;
688     if( !bStorage && meInitMode == DEFAULT )
689         nPassCount = 2;
690     for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
691     {
692         if( bStorage )
693         {
694             OSL_ENSURE( meInitMode == DEFAULT || meInitMode == OFFICE_DOCUMENT,
695                 "### Wrong InitMode for document\n" );
696             try
697             {
698                 uno::Reference< io::XStream > xStream;
699                 xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
700                 //if ( !xLibrariesStor.is() )
701                     // TODO: the method must either return a storage or throw an exception
702                     //throw uno::RuntimeException();
703 
704                 if ( xLibrariesStor.is() )
705                 {
706                     aFileName = maInfoFileName;
707                     aFileName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
708 
709                     try
710                     {
711                         xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
712                     }
713                     catch( uno::Exception& )
714                     {}
715 
716                     if( !xStream.is() )
717                     {
718                         mbOldInfoFormat = true;
719 
720                         // Check old version
721                         aFileName = maOldInfoFileName;
722                         aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
723 
724                         try
725                         {
726                             xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
727                         }
728                         catch( uno::Exception& )
729                         {}
730 
731                         if( !xStream.is() )
732                         {
733                             // Check for EA2 document version with wrong extensions
734                             aFileName = maOldInfoFileName;
735                             aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xli") );
736                             xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
737                         }
738                     }
739                 }
740 
741                 if ( xStream.is() )
742                     xInput = xStream->getInputStream();
743             }
744             catch( uno::Exception& )
745             {
746                 // TODO: error handling?
747             }
748         }
749         else
750         {
751             INetURLObject* pLibInfoInetObj = NULL;
752             if( meInitMode == CONTAINER_INIT_FILE )
753             {
754                 aFileName = aInitFileName;
755             }
756             else
757             {
758                 if( nPass == 1 )
759                     pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(0) );
760                 else
761                     pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(1) );
762                 pLibInfoInetObj->insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
763                 pLibInfoInetObj->setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
764                 aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
765             }
766 
767             try
768             {
769                 xInput = mxSFI->openFileRead( aFileName );
770             }
771             catch( Exception& )
772             {
773                 xInput.clear();
774                 if( nPass == 0 )
775                 {
776                     SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
777                     sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
778                     ErrorHandler::HandleError( nErrorCode );
779                 }
780             }
781 
782             // Old variant?
783             if( !xInput.is() && nPass == 0 )
784             {
785                 INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
786                 aLibInfoInetObj.insertName( maOldInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
787                 aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xli") ) );
788                 aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
789 
790                 try
791                 {
792                     xInput = mxSFI->openFileRead( aFileName );
793                     mbOldInfoFormat = true;
794                 }
795                 catch( Exception& )
796                 {
797                     xInput.clear();
798                     SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
799                     sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
800                     ErrorHandler::HandleError( nErrorCode );
801                 }
802             }
803 
804             delete pLibInfoInetObj;
805         }
806 
807         if( xInput.is() )
808         {
809             InputSource source;
810             source.aInputStream = xInput;
811             source.sSystemId    = aFileName;
812 
813             // start parsing
814             ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();
815 
816             try
817             {
818                 xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
819                 xParser->parseStream( source );
820             }
821             catch ( xml::sax::SAXException& e )
822             {
823                 (void) e; // avoid warning
824                 OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
825                 return sal_False;
826             }
827             catch ( io::IOException& e )
828             {
829                 (void) e; // avoid warning
830                 OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
831                 return sal_False;
832             }
833 
834             sal_Int32 nLibCount = pLibArray->mnLibCount;
835             for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
836             {
837                 ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
838 
839                 // Check storage URL
840                 OUString aStorageURL = rLib.aStorageURL;
841                 if( !bStorage && !aStorageURL.getLength() && nPass == 0 )
842                 {
843                     String aLibraryPath;
844                     if( meInitMode == CONTAINER_INIT_FILE )
845                         aLibraryPath = maLibraryPath;
846                     else
847                         aLibraryPath = String(maLibraryPath).GetToken(1);
848                     INetURLObject aInetObj( aLibraryPath );
849 
850                     aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
851                         sal_True, INetURLObject::ENCODE_ALL );
852                     OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
853                     if( mxSFI->isFolder( aLibDirPath ) )
854                     {
855                         createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
856                         maModifiable.setModified( sal_True );
857                     }
858                     else if( rLib.bLink )
859                     {
860                         // Check "share" path
861                         INetURLObject aShareInetObj( String(maLibraryPath).GetToken(0) );
862                         aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
863                             sal_True, INetURLObject::ENCODE_ALL );
864                         OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
865                         if( mxSFI->isFolder( aShareLibDirPath ) )
866                         {
867                             createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
868                             maModifiable.setModified( sal_True );
869                         }
870                         else
871                         {
872                             // #i25537: Ignore lib if library folder does not really exist
873                             continue;
874                         }
875                     }
876                 }
877 
878                 OUString aLibName = rLib.aName;
879 
880                 // If the same library name is used by the shared and the
881                 // user lib container index files the user file wins
882                 if( nPass == 1 && hasByName( aLibName ) )
883                     continue;
884 
885                 SfxLibrary* pImplLib;
886                 if( rLib.bLink )
887                 {
888                     Reference< XNameAccess > xLib =
889                         createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
890                     pImplLib = static_cast< SfxLibrary* >( xLib.get() );
891                 }
892                 else
893                 {
894                     Reference< XNameContainer > xLib = createLibrary( aLibName );
895                     pImplLib = static_cast< SfxLibrary* >( xLib.get() );
896                     pImplLib->mbLoaded = sal_False;
897                     pImplLib->mbReadOnly = rLib.bReadOnly;
898                     if( !bStorage )
899                         checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
900                             pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
901                 }
902                 maModifiable.setModified( sal_False );
903 
904                 // Read library info files
905                 if( !mbOldInfoFormat )
906                 {
907                     uno::Reference< embed::XStorage > xLibraryStor;
908                     if( !pImplLib->mbInitialised && bStorage )
909                     {
910                         try {
911                             xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
912                                                                                 embed::ElementModes::READ );
913                         }
914                         catch( uno::Exception& )
915                         {
916                         #if OSL_DEBUG_LEVEL > 0
917                             Any aError( ::cppu::getCaughtException() );
918                             ::rtl::OStringBuffer aMessage;
919                             aMessage.append( "couln't open sub storage for library '" );
920                             aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
921                             aMessage.append( "'.\n\nException:" );
922                             aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
923                             OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
924                         #endif
925                         }
926                     }
927 
928                     // Link is already initialised in createLibraryLink()
929                     if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
930                     {
931                         OUString aIndexFileName;
932                         sal_Bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
933                         if( bLoaded && aLibName != rLib.aName )
934                         {
935                             OSL_ENSURE( 0, "Different library names in library"
936                                 " container and library info files!\n" );
937                         }
938                         if( GbMigrationSuppressErrors && !bLoaded )
939                             removeLibrary( aLibName );
940                     }
941                 }
942                 else if( !bStorage )
943                 {
944                     // Write new index file immediately because otherwise
945                     // the library elements will be lost when storing into
946                     // the new info format
947                     uno::Reference< embed::XStorage > xTmpStorage;
948                     implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
949                 }
950 
951                 implImportLibDescriptor( pImplLib, rLib );
952 
953                 if( nPass == 1 )
954                 {
955                     pImplLib->mbSharedIndexFile = sal_True;
956                     pImplLib->mbReadOnly = sal_True;
957                 }
958             }
959 
960             // Keep flag for documents to force writing the new index files
961             if( !bStorage )
962                 mbOldInfoFormat = sal_False;
963 
964             delete pLibArray;
965         }
966         // Only in the first pass it's an error when no index file is found
967         else if( nPass == 0 )
968         {
969             return sal_False;
970         }
971     }
972 
973     // #110009: END Scope to force the StorageRefs to be destructed
974     }
975     // #110009
976 
977     if( !bStorage && meInitMode == DEFAULT )
978     {
979         try
980         {
981             implScanExtensions();
982         }
983         catch( uno::Exception& )
984         {
985             // TODO: error handling?
986             OSL_ASSERT( "Cannot access extensions!" );
987         }
988     }
989 
990     // #110009 Preload?
991     {
992         Sequence< OUString > aNames = maNameContainer.getElementNames();
993         const OUString* pNames = aNames.getConstArray();
994         sal_Int32 nNameCount = aNames.getLength();
995         for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
996         {
997             OUString aName = pNames[ i ];
998             SfxLibrary* pImplLib = getImplLib( aName );
999             if( pImplLib->mbPreload )
1000                 loadLibrary( aName );
1001         }
1002     }
1003 
1004     // #118803# upgrade installation 7.0 -> 8.0
1005     if( meInitMode == DEFAULT )
1006     {
1007         INetURLObject aUserBasicInetObj( String(maLibraryPath).GetToken(1) );
1008         OUString aStandardStr( RTL_CONSTASCII_USTRINGPARAM("Standard") );
1009 
1010         static char strPrevFolderName_1[] = "__basic_80";
1011         static char strPrevFolderName_2[] = "__basic_80_2";
1012         INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
1013         aPrevUserBasicInetObj_1.removeSegment();
1014         INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
1015         aPrevUserBasicInetObj_1.Append( strPrevFolderName_1 );
1016         aPrevUserBasicInetObj_2.Append( strPrevFolderName_2 );
1017 
1018         // #i93163
1019         bool bCleanUp = false;
1020         try
1021         {
1022             INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
1023             String aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1024             bool bSecondTime = false;
1025             if( mxSFI->isFolder( aPrevFolder ) )
1026             {
1027                 // #110101 Check if Standard folder exists and is complete
1028                 INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
1029                 aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1030                                                       sal_True, INetURLObject::ENCODE_ALL );
1031                 INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
1032                 aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1033                                                         sal_True, INetURLObject::ENCODE_ALL );
1034                 OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1035                 if( mxSFI->isFolder( aPrevStandardFolder ) )
1036                 {
1037                     OUString aXlbExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1038                     OUString aCheckFileName;
1039 
1040                     // Check if script.xlb exists
1041                     aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("script") );
1042                     checkAndCopyFileImpl( aUserBasicStandardInetObj,
1043                                           aPrevUserBasicStandardInetObj,
1044                                           aCheckFileName, aXlbExtension, mxSFI );
1045 
1046                     // Check if dialog.xlb exists
1047                     aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("dialog") );
1048                     checkAndCopyFileImpl( aUserBasicStandardInetObj,
1049                                           aPrevUserBasicStandardInetObj,
1050                                           aCheckFileName, aXlbExtension, mxSFI );
1051 
1052                     // Check if module1.xba exists
1053                     OUString aXbaExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xba") ) );
1054                     aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("Module1") );
1055                     checkAndCopyFileImpl( aUserBasicStandardInetObj,
1056                                           aPrevUserBasicStandardInetObj,
1057                                           aCheckFileName, aXbaExtension, mxSFI );
1058                 }
1059                 else
1060                 {
1061                     String aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1062                     mxSFI->copy( aStandardFolder, aPrevStandardFolder );
1063                 }
1064 
1065                 String aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1066                 mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
1067             }
1068             else
1069             {
1070                 bSecondTime = true;
1071                 aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
1072                 aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1073             }
1074             if( mxSFI->isFolder( aPrevFolder ) )
1075             {
1076                 SfxLibraryContainer* pPrevCont = createInstanceImpl();
1077                 Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
1078 
1079                 // Rename previous basic folder to make storage URLs correct during initialisation
1080                 String aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1081                 INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
1082                 aUserBasicTmpInetObj.removeSegment();
1083                 aUserBasicTmpInetObj.Append( "__basic_tmp" );
1084                 String aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
1085 
1086                 mxSFI->move( aFolderUserBasic, aFolderTmp );
1087                 try
1088                 {
1089                     mxSFI->move( aPrevFolder, aFolderUserBasic );
1090                 }
1091                 catch( Exception& )
1092                 {
1093                     // Move back user/basic folder
1094                     try
1095                     {
1096                         mxSFI->kill( aFolderUserBasic );
1097                     }
1098                     catch( Exception& )
1099                     {}
1100                     mxSFI->move( aFolderTmp, aFolderUserBasic );
1101                     throw;
1102                 }
1103 
1104                 INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
1105                 aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT,
1106                                                     sal_True, INetURLObject::ENCODE_ALL );
1107                 aPrevUserBasicLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
1108                 OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
1109                 Sequence<Any> aInitSeq( 1 );
1110                 aInitSeq.getArray()[0] <<= aLibInfoFileName;
1111                 GbMigrationSuppressErrors = true;
1112                 pPrevCont->initialize( aInitSeq );
1113                 GbMigrationSuppressErrors = false;
1114 
1115                 // Rename folders back
1116                 mxSFI->move( aFolderUserBasic, aPrevFolder );
1117                 mxSFI->move( aFolderTmp, aFolderUserBasic );
1118 
1119                 OUString aUserSearchStr   = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
1120                 OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
1121                 OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
1122                 OUString aInstSearchStr   = OUString::createFromAscii( "$(INST)" );
1123 
1124                 Sequence< OUString > aNames = pPrevCont->getElementNames();
1125                 const OUString* pNames = aNames.getConstArray();
1126                 sal_Int32 nNameCount = aNames.getLength();
1127 
1128                 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1129                 {
1130                     OUString aLibName = pNames[ i ];
1131                     if( hasByName( aLibName ) )
1132                     {
1133                         if( aLibName == aStandardStr )
1134                         {
1135                             SfxLibrary* pImplLib = getImplLib( aStandardStr );
1136                             INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
1137                             String aStandardFolder = pImplLib->maStorageURL;
1138                             mxSFI->kill( aStandardFolder );
1139                         }
1140                         else
1141                         {
1142                             continue;
1143                         }
1144                     }
1145 
1146                     SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
1147                     if( pImplLib->mbLink )
1148                     {
1149                         OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
1150                         bool bCreateLink = true;
1151                         if( aStorageURL.indexOf( aUserSearchStr   ) != -1 ||
1152                             aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
1153                             aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
1154                             aStorageURL.indexOf( aInstSearchStr   ) != -1 )
1155                         {
1156                             bCreateLink = false;
1157                         }
1158                         if( bCreateLink )
1159                             createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
1160                     }
1161                     else
1162                     {
1163                         // Move folder if not already done
1164                         INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
1165                         aUserBasicLibFolderInetObj.Append( aLibName );
1166                         String aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1167 
1168                         INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
1169                         aPrevUserBasicLibFolderInetObj.Append( aLibName );
1170                         String aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1171 
1172                         if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
1173                             mxSFI->move( aPrevLibFolder, aLibFolder );
1174 
1175                         if( aLibName == aStandardStr )
1176                             maNameContainer.removeByName( aLibName );
1177 
1178                         // Create library
1179                         Reference< XNameContainer > xLib = createLibrary( aLibName );
1180                         SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
1181                         pNewLib->mbLoaded = false;
1182                         pNewLib->implSetModified( sal_False );
1183                         checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
1184                             pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
1185 
1186                         uno::Reference< embed::XStorage > xDummyStor;
1187                         ::xmlscript::LibDescriptor aLibDesc;
1188                         /*sal_Bool bReadIndexFile =*/ implLoadLibraryIndexFile
1189                             ( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
1190                         implImportLibDescriptor( pNewLib, aLibDesc );
1191                     }
1192                 }
1193                 mxSFI->kill( aPrevFolder );
1194             }
1195         }
1196         catch( Exception& )
1197         {
1198             bCleanUp = true;
1199         }
1200 
1201         // #i93163
1202         if( bCleanUp )
1203         {
1204             DBG_ERROR( "Upgrade of Basic installation failed somehow" );
1205 
1206             static char strErrorSavFolderName[] = "__basic_80_err";
1207             INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
1208             aPrevUserBasicInetObj_Err.removeSegment();
1209             aPrevUserBasicInetObj_Err.Append( strErrorSavFolderName );
1210             String aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );
1211 
1212             bool bSaved = false;
1213             try
1214             {
1215                 String aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
1216                 if( mxSFI->isFolder( aPrevFolder_1 ) )
1217                 {
1218                     mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
1219                     bSaved = true;
1220                 }
1221             }
1222             catch( Exception& )
1223             {}
1224             try
1225             {
1226                 String aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1227                 if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
1228                     mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
1229                 else
1230                     mxSFI->kill( aPrevFolder_2 );
1231             }
1232             catch( Exception& )
1233             {}
1234         }
1235     }
1236 
1237     return sal_True;
1238 }
1239 
1240 void SfxLibraryContainer::implScanExtensions( void )
1241 {
1242     ScriptExtensionIterator aScriptIt;
1243     rtl::OUString aLibURL;
1244 
1245     bool bPureDialogLib = false;
1246     while( (aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).getLength() > 0 )
1247     {
1248         if( bPureDialogLib && maInfoFileName.equalsAscii( "script" ) )
1249             continue;
1250 
1251         // Extract lib name
1252         sal_Int32 nLen = aLibURL.getLength();
1253         sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
1254         sal_Int32 nReduceCopy = 0;
1255         if( indexLastSlash == nLen - 1 )
1256         {
1257             nReduceCopy = 1;
1258             indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
1259         }
1260 
1261         OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
1262 
1263         // If a library of the same exists the existing library wins
1264         if( hasByName( aLibName ) )
1265             continue;
1266 
1267         // Add index file to URL
1268         OUString aIndexFileURL = aLibURL;
1269         if( nReduceCopy == 0 )
1270             aIndexFileURL += OUString::createFromAscii( "/" );
1271         aIndexFileURL += maInfoFileName;
1272         aIndexFileURL += OUString::createFromAscii( ".xlb" );
1273 
1274         // Create link
1275         const bool bReadOnly = false;
1276         Reference< XNameAccess > xLib =
1277             createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
1278     }
1279 }
1280 
1281 // Handle maLibInfoFileURL and maStorageURL correctly
1282 void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
1283     OUString& aLibInfoFileURL, OUString& aStorageURL, OUString& aUnexpandedStorageURL )
1284 {
1285     OUString aExpandedSourceURL = expand_url( aSourceURL );
1286     if( aExpandedSourceURL != aSourceURL )
1287         aUnexpandedStorageURL = aSourceURL;
1288 
1289     INetURLObject aInetObj( aExpandedSourceURL );
1290     OUString aExtension = aInetObj.getExtension();
1291     if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
1292     {
1293         // URL to xlb file
1294         aLibInfoFileURL = aExpandedSourceURL;
1295         aInetObj.removeSegment();
1296         aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1297     }
1298     else
1299     {
1300         // URL to library folder
1301         aStorageURL = aExpandedSourceURL;
1302         aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1303         aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1304         aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1305     }
1306 }
1307 
1308 SfxLibrary* SfxLibraryContainer::getImplLib( const String& rLibraryName )
1309 {
1310     Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
1311     Reference< XNameAccess > xNameAccess;
1312     aLibAny >>= xNameAccess;
1313     SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
1314     return pImplLib;
1315 }
1316 
1317 
1318 // Storing with password encryption
1319 
1320 // Empty implementation, avoids unneccesary implementation in dlgcont.cxx
1321 sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
1322     SfxLibrary*,
1323     const OUString&,
1324     const uno::Reference< embed::XStorage >&, const uno::Reference< task::XInteractionHandler >&  )
1325 {
1326     return sal_False;
1327 }
1328 
1329 sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
1330     SfxLibrary* /*pLib*/,
1331     const ::rtl::OUString& /*aName*/,
1332     const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
1333     const ::rtl::OUString& /*aTargetURL*/,
1334     const Reference< XSimpleFileAccess > /*xToUseSFI*/,
1335     const uno::Reference< task::XInteractionHandler >&  )
1336 {
1337     return sal_False;
1338 }
1339 
1340 sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
1341     SfxLibrary* /*pLib*/,
1342     const OUString& /*Name*/,
1343     sal_Bool /*bVerifyPasswordOnly*/ )
1344 throw(WrappedTargetException, RuntimeException)
1345 {
1346     return sal_True;
1347 }
1348 
1349 
1350 
1351 #define EXPAND_PROTOCOL "vnd.sun.star.expand"
1352 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
1353 
1354 OUString SfxLibraryContainer::createAppLibraryFolder
1355     ( SfxLibrary* pLib, const OUString& aName )
1356 {
1357     OUString aLibDirPath = pLib->maStorageURL;
1358     if( !aLibDirPath.getLength() )
1359     {
1360         INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
1361         aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1362         checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
1363             pLib->maStorageURL, pLib->maUnexpandedStorageURL );
1364         aLibDirPath = pLib->maStorageURL;
1365     }
1366 
1367     if( !mxSFI->isFolder( aLibDirPath ) )
1368     {
1369         try
1370         {
1371             mxSFI->createFolder( aLibDirPath );
1372         }
1373         catch( Exception& )
1374         {}
1375     }
1376 
1377     return aLibDirPath;
1378 }
1379 
1380 // Storing
1381 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1382     const OUString& aName, const uno::Reference< embed::XStorage >& xStorage )
1383 {
1384     OUString aDummyLocation;
1385     Reference< XSimpleFileAccess > xDummySFA;
1386     Reference< XInteractionHandler > xDummyHandler;
1387     implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
1388 }
1389 
1390 // New variant for library export
1391 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1392     const OUString& aName, const uno::Reference< embed::XStorage >& xStorage,
1393     const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI,
1394     const Reference< XInteractionHandler >& xHandler )
1395 {
1396     sal_Bool bLink = pLib->mbLink;
1397     sal_Bool bStorage = xStorage.is() && !bLink;
1398 
1399     Sequence< OUString > aElementNames = pLib->getElementNames();
1400     sal_Int32 nNameCount = aElementNames.getLength();
1401     const OUString* pNames = aElementNames.getConstArray();
1402 
1403     if( bStorage )
1404     {
1405         for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1406         {
1407             OUString aElementName = pNames[ i ];
1408 
1409             OUString aStreamName = aElementName;
1410             aStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
1411 
1412             /*Any aElement = pLib->getByName( aElementName );*/
1413             if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1414             {
1415             #if OSL_DEBUG_LEVEL > 0
1416                 ::rtl::OStringBuffer aMessage;
1417                 aMessage.append( "invalid library element '" );
1418                 aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
1419                 aMessage.append( "'." );
1420                 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
1421             #endif
1422                 continue;
1423             }
1424             try {
1425                 uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
1426                                                                     aStreamName,
1427                                                                     embed::ElementModes::READWRITE );
1428                 //if ( !xElementStream.is() )
1429                 //    throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1430 
1431                 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
1432                 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
1433 
1434                 uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1435                 OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
1436                 //if ( !xProps.is() ) //TODO
1437                 //    throw uno::RuntimeException();
1438 
1439                 if ( xProps.is() )
1440                 {
1441                     xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
1442 
1443                     // #87671 Allow encryption
1444 //REMOVE                            aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
1445                     aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
1446                     xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
1447 
1448                     Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
1449                     Reference< XNameContainer > xLib( pLib );
1450                     writeLibraryElement( xLib, aElementName, xOutput );
1451                     // writeLibraryElement closes the stream
1452                     // xOutput->closeOutput();
1453                 }
1454             }
1455             catch( uno::Exception& )
1456             {
1457                 OSL_ENSURE( sal_False, "Problem during storing of library!\n" );
1458                 // TODO: error handling?
1459             }
1460         }
1461 
1462         pLib->storeResourcesToStorage( xStorage );
1463     }
1464     else
1465     {
1466         // Export?
1467         bool bExport = aTargetURL.getLength();
1468         try
1469         {
1470             Reference< XSimpleFileAccess > xSFI = mxSFI;
1471             if( xToUseSFI.is() )
1472                 xSFI = xToUseSFI;
1473 
1474             OUString aLibDirPath;
1475             if( bExport )
1476             {
1477                 INetURLObject aInetObj( aTargetURL );
1478                 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1479                 aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1480 
1481                 if( !xSFI->isFolder( aLibDirPath ) )
1482                     xSFI->createFolder( aLibDirPath );
1483 
1484                 pLib->storeResourcesToURL( aLibDirPath, xHandler );
1485             }
1486             else
1487             {
1488                 aLibDirPath = createAppLibraryFolder( pLib, aName );
1489                 pLib->storeResources();
1490             }
1491 
1492             for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1493             {
1494                 OUString aElementName = pNames[ i ];
1495 
1496                 INetURLObject aElementInetObj( aLibDirPath );
1497                 aElementInetObj.insertName( aElementName, sal_False,
1498                     INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1499                 aElementInetObj.setExtension( maLibElementFileExtension );
1500                 String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
1501 
1502                 /*Any aElement = pLib->getByName( aElementName );*/
1503                 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1504                 {
1505                 #if OSL_DEBUG_LEVEL > 0
1506                     ::rtl::OStringBuffer aMessage;
1507                     aMessage.append( "invalid library element '" );
1508                     aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
1509                     aMessage.append( "'." );
1510                     OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
1511                 #endif
1512                     continue;
1513                 }
1514 
1515                 // TODO: Check modified
1516                 try
1517                 {
1518                     if( xSFI->exists( aElementPath ) )
1519                         xSFI->kill( aElementPath );
1520                     Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
1521                     Reference< XNameContainer > xLib( pLib );
1522                     writeLibraryElement( xLib, aElementName, xOutput );
1523                     xOutput->closeOutput();
1524                 }
1525                 catch( Exception& )
1526                 {
1527                     if( bExport )
1528                         throw;
1529 
1530                     SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
1531                     sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1532                     ErrorHandler::HandleError( nErrorCode );
1533                 }
1534             }
1535         }
1536         catch( Exception& )
1537         {
1538             if( bExport )
1539                 throw;
1540         }
1541     }
1542 }
1543 
1544 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1545     const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage )
1546 {
1547     OUString aDummyLocation;
1548     Reference< XSimpleFileAccess > xDummySFA;
1549     implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
1550 }
1551 
1552 // New variant for library export
1553 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1554     const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage,
1555     const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI )
1556 {
1557     // Create sax writer
1558     Reference< XExtendedDocumentHandler > xHandler(
1559         mxMSF->createInstance(
1560             OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
1561     if( !xHandler.is() )
1562     {
1563         OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
1564         return;
1565     }
1566 
1567     sal_Bool bLink = pLib->mbLink;
1568     sal_Bool bStorage = xStorage.is() && !bLink;
1569 
1570     // Write info file
1571     uno::Reference< io::XOutputStream > xOut;
1572     uno::Reference< io::XStream > xInfoStream;
1573     if( bStorage )
1574     {
1575         OUString aStreamName( maInfoFileName );
1576         aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
1577 
1578         try {
1579             xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
1580             OSL_ENSURE( xInfoStream.is(), "No stream!\n" );
1581             uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
1582             //if ( !xProps.is() )
1583             //    throw uno::RuntimeException(); // TODO
1584 
1585             if ( xProps.is() )
1586             {
1587                 String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
1588                 OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
1589                 xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
1590 
1591                 // #87671 Allow encryption
1592 //REMOVE                    aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
1593                 aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
1594                 xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
1595 
1596                 xOut = xInfoStream->getOutputStream();
1597             }
1598         }
1599         catch( uno::Exception& )
1600         {
1601             OSL_ENSURE( sal_False, "Problem during storing of library index file!\n" );
1602             // TODO: error handling?
1603         }
1604     }
1605     else
1606     {
1607         // Export?
1608         bool bExport = aTargetURL.getLength();
1609         Reference< XSimpleFileAccess > xSFI = mxSFI;
1610         if( xToUseSFI.is() )
1611             xSFI = xToUseSFI;
1612 
1613         OUString aLibInfoPath;
1614         if( bExport )
1615         {
1616             INetURLObject aInetObj( aTargetURL );
1617             aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1618             OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1619             if( !xSFI->isFolder( aLibDirPath ) )
1620                 xSFI->createFolder( aLibDirPath );
1621 
1622             aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1623             aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1624             aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1625         }
1626         else
1627         {
1628             createAppLibraryFolder( pLib, rLib.aName );
1629             aLibInfoPath = pLib->maLibInfoFileURL;
1630         }
1631 
1632         try
1633         {
1634             if( xSFI->exists( aLibInfoPath ) )
1635                 xSFI->kill( aLibInfoPath );
1636             xOut = xSFI->openFileWrite( aLibInfoPath );
1637         }
1638         catch( Exception& )
1639         {
1640             if( bExport )
1641                 throw;
1642 
1643             SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
1644             sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1645             ErrorHandler::HandleError( nErrorCode );
1646         }
1647     }
1648     if( !xOut.is() )
1649     {
1650         OSL_ENSURE( 0, "### couln't open output stream\n" );
1651         return;
1652     }
1653 
1654     Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
1655     xSource->setOutputStream( xOut );
1656 
1657     xmlscript::exportLibrary( xHandler, rLib );
1658 }
1659 
1660 
1661 sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile(  SfxLibrary* pLib,
1662     ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, const OUString& aIndexFileName )
1663 {
1664     Reference< XParser > xParser( mxMSF->createInstance(
1665         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
1666     if( !xParser.is() )
1667     {
1668         OSL_ENSURE( 0, "### couln't create sax parser component\n" );
1669         return sal_False;
1670     }
1671 
1672     sal_Bool bLink = sal_False;
1673     sal_Bool bStorage = sal_False;
1674     if( pLib )
1675     {
1676         bLink = pLib->mbLink;
1677         bStorage = xStorage.is() && !bLink;
1678     }
1679 
1680     // Read info file
1681     uno::Reference< io::XInputStream > xInput;
1682     String aLibInfoPath;
1683     if( bStorage )
1684     {
1685         aLibInfoPath = maInfoFileName;
1686         aLibInfoPath += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
1687 
1688         try {
1689             uno::Reference< io::XStream > xInfoStream =
1690                         xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
1691             xInput = xInfoStream->getInputStream();
1692         }
1693         catch( uno::Exception& )
1694         {}
1695     }
1696     else
1697     {
1698         // Create Input stream
1699         //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1700 
1701         if( pLib )
1702         {
1703             createAppLibraryFolder( pLib, rLib.aName );
1704             aLibInfoPath = pLib->maLibInfoFileURL;
1705         }
1706         else
1707             aLibInfoPath = aIndexFileName;
1708 
1709         try
1710         {
1711             xInput = mxSFI->openFileRead( aLibInfoPath );
1712         }
1713         catch( Exception& )
1714         {
1715             xInput.clear();
1716             if( !GbMigrationSuppressErrors )
1717             {
1718                 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1719                 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1720                 ErrorHandler::HandleError( nErrorCode );
1721             }
1722         }
1723     }
1724     if( !xInput.is() )
1725     {
1726         // OSL_ENSURE( 0, "### couln't open input stream\n" );
1727         return sal_False;
1728     }
1729 
1730     InputSource source;
1731     source.aInputStream = xInput;
1732     source.sSystemId    = aLibInfoPath;
1733 
1734     // start parsing
1735     try {
1736         xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
1737         xParser->parseStream( source );
1738     }
1739     catch( Exception& )
1740     {
1741         // throw WrappedTargetException( OUString::createFromAscii( "parsing error!\n" ),
1742         //                              Reference< XInterface >(),
1743         //                              makeAny( e ) );
1744         OSL_ENSURE( 0, "Parsing error\n" );
1745         SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1746         sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1747         ErrorHandler::HandleError( nErrorCode );
1748         return sal_False;
1749     }
1750 
1751     if( !pLib )
1752     {
1753         Reference< XNameContainer > xLib = createLibrary( rLib.aName );
1754         pLib = static_cast< SfxLibrary* >( xLib.get() );
1755         pLib->mbLoaded = sal_False;
1756         rLib.aStorageURL = aIndexFileName;
1757         checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
1758             pLib->maUnexpandedStorageURL );
1759 
1760         implImportLibDescriptor( pLib, rLib );
1761     }
1762 
1763     return sal_True;
1764 }
1765 
1766 void SfxLibraryContainer::implImportLibDescriptor
1767     ( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib )
1768 {
1769     if( !pLib->mbInitialised )
1770     {
1771         sal_Int32 nElementCount = rLib.aElementNames.getLength();
1772         const OUString* pElementNames = rLib.aElementNames.getConstArray();
1773         Any aDummyElement = createEmptyLibraryElement();
1774         for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
1775         {
1776             pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
1777         }
1778         pLib->mbPasswordProtected = rLib.bPasswordProtected;
1779         pLib->mbReadOnly = rLib.bReadOnly;
1780         pLib->mbPreload  = rLib.bPreload;
1781         pLib->implSetModified( sal_False );
1782 
1783         pLib->mbInitialised = sal_True;
1784     }
1785 }
1786 
1787 
1788 // Methods of new XLibraryStorage interface?
1789 void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage, sal_Bool bComplete )
1790 {
1791     const Sequence< OUString > aNames = maNameContainer.getElementNames();
1792     sal_Int32 nNameCount = aNames.getLength();
1793     const OUString* pName = aNames.getConstArray();
1794     const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
1795 
1796     // Don't count libs from shared index file
1797     sal_Int32 nLibsToSave = nNameCount;
1798     for( ; pName != pNamesEnd; ++pName )
1799     {
1800         SfxLibrary* pImplLib = getImplLib( *pName );
1801         if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
1802             nLibsToSave--;
1803     }
1804     if( !nLibsToSave )
1805         return;
1806 
1807     ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray( nLibsToSave );
1808 
1809     // Write to storage?
1810     sal_Bool bStorage = i_rStorage.is();
1811     uno::Reference< embed::XStorage > xSourceLibrariesStor;
1812     uno::Reference< embed::XStorage > xTargetLibrariesStor;
1813     ::rtl::OUString sTempTargetStorName;
1814     const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
1815     if ( bStorage )
1816     {
1817         // Don't write if only empty standard lib exists
1818         if ( ( nNameCount == 1 ) && ( aNames[0].equalsAscii( "Standard" ) ) )
1819         {
1820             Any aLibAny = maNameContainer.getByName( aNames[0] );
1821             Reference< XNameAccess > xNameAccess;
1822             aLibAny >>= xNameAccess;
1823             if ( !xNameAccess->hasElements() )
1824                 return;
1825         }
1826 
1827         // create the empty target storage
1828         try
1829         {
1830             ::rtl::OUString sTargetLibrariesStoreName;
1831             if ( bInplaceStorage )
1832             {
1833                 // create a temporary target storage
1834                 const ::rtl::OUStringBuffer aTempTargetNameBase = maLibrariesDir + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_temp_" ) );
1835                 sal_Int32 index = 0;
1836                 do
1837                 {
1838                     ::rtl::OUStringBuffer aTempTargetName( aTempTargetNameBase );
1839                     aTempTargetName.append( index++ );
1840 
1841                     sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
1842                     if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1843                         break;
1844                 }
1845                 while ( true );
1846                 sTempTargetStorName = sTargetLibrariesStoreName;
1847             }
1848             else
1849             {
1850                 sTargetLibrariesStoreName = maLibrariesDir;
1851                 if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1852                     i_rStorage->removeElement( sTargetLibrariesStoreName );
1853             }
1854 
1855             xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
1856         }
1857         catch( const uno::Exception& )
1858         {
1859             DBG_UNHANDLED_EXCEPTION();
1860             return;
1861         }
1862 
1863         // open the source storage which might be used to copy yet-unmodified libraries
1864         try
1865         {
1866             if ( mxStorage->hasByName( maLibrariesDir ) )
1867                 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
1868             else if ( bInplaceStorage )
1869                 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
1870         }
1871         catch( const uno::Exception& )
1872         {
1873             DBG_UNHANDLED_EXCEPTION();
1874             return;
1875         }
1876     }
1877 
1878     int iArray = 0;
1879     pName = aNames.getConstArray();
1880     ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
1881     for( ; pName != pNamesEnd; ++pName )
1882     {
1883         SfxLibrary* pImplLib = getImplLib( *pName );
1884         if( pImplLib->mbSharedIndexFile )
1885             continue;
1886         const bool bExtensionLib = pImplLib->mbExtension;
1887         ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
1888             aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
1889         if( !bExtensionLib )
1890             iArray++;
1891         rLib.aName = *pName;
1892 
1893         rLib.bLink = pImplLib->mbLink;
1894         if( !bStorage || pImplLib->mbLink )
1895         {
1896             rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
1897                 pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
1898         }
1899         rLib.bReadOnly = pImplLib->mbReadOnly;
1900         rLib.bPreload = pImplLib->mbPreload;
1901         rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
1902         rLib.aElementNames = pImplLib->getElementNames();
1903 
1904         if( pImplLib->implIsModified() || bComplete )
1905         {
1906             // Can we simply copy the storage?
1907             if( !mbOldInfoFormat && !pImplLib->implIsModified() && !mbOasis2OOoFormat && xSourceLibrariesStor.is() )
1908             {
1909                 try
1910                 {
1911                     xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
1912                 }
1913                 catch( const uno::Exception& )
1914                 {
1915                     DBG_UNHANDLED_EXCEPTION();
1916                     // TODO: error handling?
1917                 }
1918             }
1919             else
1920             {
1921                 uno::Reference< embed::XStorage > xLibraryStor;
1922                 if( bStorage )
1923                 {
1924                     try
1925                     {
1926                         xLibraryStor = xTargetLibrariesStor->openStorageElement(
1927                                                                         rLib.aName,
1928                                                                         embed::ElementModes::READWRITE );
1929                     }
1930                     catch( uno::Exception& )
1931                     {
1932                     #if OSL_DEBUG_LEVEL > 0
1933                         Any aError( ::cppu::getCaughtException() );
1934                         ::rtl::OStringBuffer aMessage;
1935                         aMessage.append( "couln't create sub storage for library '" );
1936                         aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
1937                         aMessage.append( "'.\n\nException:" );
1938                         aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
1939                         OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
1940                     #endif
1941                         return;
1942                     }
1943                 }
1944 
1945                 // Maybe lib is not loaded?!
1946                 if( bComplete )
1947                     loadLibrary( rLib.aName );
1948 
1949                 if( pImplLib->mbPasswordProtected )
1950                     implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
1951                     // TODO: Check return value
1952                 else
1953                     implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
1954 
1955                 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
1956                 if( bStorage )
1957                 {
1958                     try
1959                     {
1960                         uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
1961                         xTransact->commit();
1962                     }
1963                     catch( uno::Exception& )
1964                     {
1965                         DBG_UNHANDLED_EXCEPTION();
1966                         // TODO: error handling
1967                     }
1968                 }
1969             }
1970 
1971             maModifiable.setModified( sal_True );
1972             pImplLib->implSetModified( sal_False );
1973         }
1974 
1975         // For container info ReadOnly refers to mbReadOnlyLink
1976         rLib.bReadOnly = pImplLib->mbReadOnlyLink;
1977     }
1978 
1979     // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
1980     // then we need to clean up the temporary storage we used for this
1981     if ( bInplaceStorage && sTempTargetStorName.getLength() )
1982     {
1983         OSL_ENSURE( xSourceLibrariesStor.is(), "SfxLibrariesContainer::storeLibraries_impl: unexpected: we should have a source storage here!" );
1984         try
1985         {
1986             // for this, we first remove everything from the source storage, then copy the complete content
1987             // from the temporary target storage. From then on, what used to be the "source storage" becomes
1988             // the "targt storage" for all subsequent operations.
1989 
1990             // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
1991             // open references to it.)
1992 
1993             if ( xSourceLibrariesStor.is() )
1994             {
1995                 // remove
1996                 const Sequence< ::rtl::OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
1997                 for (   const ::rtl::OUString* pRemoveName = aRemoveNames.getConstArray();
1998                         pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
1999                             ++pRemoveName
2000                     )
2001                 {
2002                     xSourceLibrariesStor->removeElement( *pRemoveName );
2003                 }
2004 
2005                 // copy
2006                 const Sequence< ::rtl::OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
2007                 for (   const ::rtl::OUString* pCopyName = aCopyNames.getConstArray();
2008                         pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
2009                         ++pCopyName
2010                     )
2011                 {
2012                     xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
2013                 }
2014             }
2015 
2016             // close and remove temp target
2017             xTargetLibrariesStor->dispose();
2018             i_rStorage->removeElement( sTempTargetStorName );
2019             xTargetLibrariesStor.clear();
2020             sTempTargetStorName = ::rtl::OUString();
2021 
2022             // adjust target
2023             xTargetLibrariesStor = xSourceLibrariesStor;
2024             xSourceLibrariesStor.clear();
2025         }
2026         catch( const Exception& )
2027         {
2028             DBG_UNHANDLED_EXCEPTION();
2029         }
2030     }
2031 
2032     if( !mbOldInfoFormat && !maModifiable.isModified() )
2033         return;
2034     maModifiable.setModified( sal_False );
2035     mbOldInfoFormat = sal_False;
2036 
2037     // Write library container info
2038     // Create sax writer
2039     Reference< XExtendedDocumentHandler > xHandler(
2040         mxMSF->createInstance(
2041             OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
2042     if( !xHandler.is() )
2043     {
2044         OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
2045         return;
2046     }
2047 
2048     // Write info file
2049     uno::Reference< io::XOutputStream > xOut;
2050     uno::Reference< io::XStream > xInfoStream;
2051     if( bStorage )
2052     {
2053         OUString aStreamName( maInfoFileName );
2054         aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
2055 
2056         try {
2057             xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2058             uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
2059             OSL_ENSURE ( xProps.is(), "The stream must implement XPropertySet!\n" );
2060             if ( !xProps.is() )
2061                 throw uno::RuntimeException();
2062 
2063             String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
2064             OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
2065             xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
2066 
2067             // #87671 Allow encryption
2068             aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("UseCommonStoragePasswordEncryption") );
2069             xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
2070 
2071             xOut = xInfoStream->getOutputStream();
2072         }
2073         catch( uno::Exception& )
2074         {
2075             sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2076             ErrorHandler::HandleError( nErrorCode );
2077         }
2078     }
2079     else
2080     {
2081         // Create Output stream
2082         INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
2083         aLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2084         aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
2085         String aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2086 
2087         try
2088         {
2089             if( mxSFI->exists( aLibInfoPath ) )
2090                 mxSFI->kill( aLibInfoPath );
2091             xOut = mxSFI->openFileWrite( aLibInfoPath );
2092         }
2093         catch( Exception& )
2094         {
2095             xOut.clear();
2096             SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2097             sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2098             ErrorHandler::HandleError( nErrorCode );
2099         }
2100 
2101     }
2102     if( !xOut.is() )
2103     {
2104         OSL_ENSURE( 0, "### couln't open output stream\n" );
2105         return;
2106     }
2107 
2108     Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
2109     xSource->setOutputStream( xOut );
2110 
2111     try
2112     {
2113         xmlscript::exportLibraryContainer( xHandler, pLibArray );
2114         if ( bStorage )
2115         {
2116             uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
2117             OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
2118             if ( !xTransact.is() )
2119                 throw uno::RuntimeException();
2120 
2121             xTransact->commit();
2122         }
2123     }
2124     catch( uno::Exception& )
2125     {
2126         OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
2127         sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2128         ErrorHandler::HandleError( nErrorCode );
2129     }
2130 
2131     delete pLibArray;
2132 }
2133 
2134 
2135 // Methods XElementAccess
2136 Type SAL_CALL SfxLibraryContainer::getElementType()
2137     throw(RuntimeException)
2138 {
2139     LibraryContainerMethodGuard aGuard( *this );
2140     return maNameContainer.getElementType();
2141 }
2142 
2143 sal_Bool SfxLibraryContainer::hasElements()
2144     throw(RuntimeException)
2145 {
2146     LibraryContainerMethodGuard aGuard( *this );
2147     sal_Bool bRet = maNameContainer.hasElements();
2148     return bRet;
2149 }
2150 
2151 // Methods XNameAccess
2152 Any SfxLibraryContainer::getByName( const OUString& aName )
2153     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2154 {
2155     LibraryContainerMethodGuard aGuard( *this );
2156     Any aRetAny = maNameContainer.getByName( aName ) ;
2157     return aRetAny;
2158 }
2159 
2160 Sequence< OUString > SfxLibraryContainer::getElementNames()
2161     throw(RuntimeException)
2162 {
2163     LibraryContainerMethodGuard aGuard( *this );
2164     return maNameContainer.getElementNames();
2165 }
2166 
2167 sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
2168     throw(RuntimeException)
2169 {
2170     LibraryContainerMethodGuard aGuard( *this );
2171     return maNameContainer.hasByName( aName ) ;
2172 }
2173 
2174 // Methods XLibraryContainer
2175 Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
2176         throw(IllegalArgumentException, ElementExistException, RuntimeException)
2177 {
2178     LibraryContainerMethodGuard aGuard( *this );
2179     SfxLibrary* pNewLib = implCreateLibrary( Name );
2180     pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2181 
2182     createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2183 
2184     Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
2185     Any aElement;
2186     aElement <<= xNameAccess;
2187     maNameContainer.insertByName( Name, aElement );
2188     maModifiable.setModified( sal_True );
2189     Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2190     return xRet;
2191 }
2192 
2193 Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
2194     ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2195         throw(IllegalArgumentException, ElementExistException, RuntimeException)
2196 {
2197     LibraryContainerMethodGuard aGuard( *this );
2198     // TODO: Check other reasons to force ReadOnly status
2199     //if( !ReadOnly )
2200     //{
2201     //}
2202 
2203     OUString aLibInfoFileURL;
2204     OUString aLibDirURL;
2205     OUString aUnexpandedStorageURL;
2206     checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2207 
2208 
2209     SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2210     pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2211     pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2212     pNewLib->maOrignialStorageURL = StorageURL;
2213 
2214     OUString aInitFileName;
2215     uno::Reference< embed::XStorage > xDummyStor;
2216     ::xmlscript::LibDescriptor aLibDesc;
2217     /*sal_Bool bReadIndexFile = */implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
2218     implImportLibDescriptor( pNewLib, aLibDesc );
2219 
2220     Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
2221     Any aElement;
2222     aElement <<= xRet;
2223     maNameContainer.insertByName( Name, aElement );
2224     maModifiable.setModified( sal_True );
2225 
2226     OUString aUserSearchStr   = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
2227     OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
2228     OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
2229     if( StorageURL.indexOf( aUserSearchStr ) != -1 )
2230     {
2231         pNewLib->mbExtension = sal_True;
2232     }
2233     else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
2234     {
2235         pNewLib->mbExtension = sal_True;
2236         pNewLib->mbReadOnly = sal_True;
2237     }
2238 
2239     return xRet;
2240 }
2241 
2242 void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2243     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2244 {
2245     LibraryContainerMethodGuard aGuard( *this );
2246     // Get and hold library before removing
2247     Any aLibAny = maNameContainer.getByName( Name ) ;
2248     Reference< XNameAccess > xNameAccess;
2249     aLibAny >>= xNameAccess;
2250     SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2251     if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2252         throw IllegalArgumentException();
2253 
2254     // Remove from container
2255     maNameContainer.removeByName( Name );
2256     maModifiable.setModified( sal_True );
2257 
2258     // Delete library files, but not for linked libraries
2259     if( !pImplLib->mbLink )
2260     {
2261         if( mxStorage.is() )
2262             return;
2263         if( xNameAccess->hasElements() )
2264         {
2265             Sequence< OUString > aNames = pImplLib->getElementNames();
2266             sal_Int32 nNameCount = aNames.getLength();
2267             const OUString* pNames = aNames.getConstArray();
2268             for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2269             {
2270                 pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
2271             }
2272         }
2273 
2274         // Delete index file
2275         createAppLibraryFolder( pImplLib, Name );
2276         String aLibInfoPath = pImplLib->maLibInfoFileURL;
2277         try
2278         {
2279             if( mxSFI->exists( aLibInfoPath ) )
2280                 mxSFI->kill( aLibInfoPath );
2281         }
2282         catch( Exception& ) {}
2283 
2284         // Delete folder if empty
2285         INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
2286         aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
2287             sal_True, INetURLObject::ENCODE_ALL );
2288         OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
2289 
2290         try
2291         {
2292             if( mxSFI->isFolder( aLibDirPath ) )
2293             {
2294                 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2295                 sal_Int32 nCount = aContentSeq.getLength();
2296                 if( !nCount )
2297                     mxSFI->kill( aLibDirPath );
2298             }
2299         }
2300         catch( Exception& )
2301         {
2302         }
2303     }
2304 }
2305 
2306 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2307     throw(NoSuchElementException, RuntimeException)
2308 {
2309     LibraryContainerMethodGuard aGuard( *this );
2310     SfxLibrary* pImplLib = getImplLib( Name );
2311     sal_Bool bRet = pImplLib->mbLoaded;
2312     return bRet;
2313 }
2314 
2315 
2316 void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2317     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2318 {
2319     LibraryContainerMethodGuard aGuard( *this );
2320     Any aLibAny = maNameContainer.getByName( Name ) ;
2321     Reference< XNameAccess > xNameAccess;
2322     aLibAny >>= xNameAccess;
2323     SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2324 
2325     sal_Bool bLoaded = pImplLib->mbLoaded;
2326     pImplLib->mbLoaded = sal_True;
2327     if( !bLoaded && xNameAccess->hasElements() )
2328     {
2329         if( pImplLib->mbPasswordProtected )
2330         {
2331             implLoadPasswordLibrary( pImplLib, Name );
2332             return;
2333         }
2334 
2335         sal_Bool bLink = pImplLib->mbLink;
2336         sal_Bool bStorage = mxStorage.is() && !bLink;
2337 
2338         uno::Reference< embed::XStorage > xLibrariesStor;
2339         uno::Reference< embed::XStorage > xLibraryStor;
2340         if( bStorage )
2341         {
2342             try {
2343                 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2344                 OSL_ENSURE( xLibrariesStor.is(), "The method must either throw exception or return a storage!\n" );
2345                 if ( !xLibrariesStor.is() )
2346                     throw uno::RuntimeException();
2347 
2348                 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2349                 OSL_ENSURE( xLibraryStor.is(), "The method must either throw exception or return a storage!\n" );
2350                 if ( !xLibrariesStor.is() )
2351                     throw uno::RuntimeException();
2352             }
2353             catch( uno::Exception& )
2354             {
2355             #if OSL_DEBUG_LEVEL > 0
2356                 Any aError( ::cppu::getCaughtException() );
2357                 ::rtl::OStringBuffer aMessage;
2358                 aMessage.append( "couln't open sub storage for library '" );
2359                 aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
2360                 aMessage.append( "'.\n\nException:" );
2361                 aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
2362                 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
2363             #endif
2364                 return;
2365             }
2366         }
2367 
2368         Sequence< OUString > aNames = pImplLib->getElementNames();
2369         sal_Int32 nNameCount = aNames.getLength();
2370         const OUString* pNames = aNames.getConstArray();
2371         for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2372         {
2373             OUString aElementName = pNames[ i ];
2374 
2375             OUString aFile;
2376             uno::Reference< io::XInputStream > xInStream;
2377 
2378             if( bStorage )
2379             {
2380                 uno::Reference< io::XStream > xElementStream;
2381 
2382                 aFile = aElementName;
2383                 aFile += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
2384 
2385                 try {
2386                     xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2387                 } catch( uno::Exception& )
2388                 {}
2389 
2390                 if( !xElementStream.is() )
2391                 {
2392                     // Check for EA2 document version with wrong extensions
2393                     aFile = aElementName;
2394                     aFile += String( RTL_CONSTASCII_USTRINGPARAM(".") );
2395                     aFile += maLibElementFileExtension;
2396                     try {
2397                         xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2398                     } catch( uno::Exception& )
2399                     {}
2400                 }
2401 
2402                 if ( xElementStream.is() )
2403                     xInStream = xElementStream->getInputStream();
2404 
2405                 if ( !xInStream.is() )
2406                 {
2407                 #if OSL_DEBUG_LEVEL > 0
2408                     ::rtl::OStringBuffer aMessage;
2409                     aMessage.append( "couln't open library element stream - attempted to open library '" );
2410                     aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
2411                     aMessage.append( "'." );
2412                     OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
2413                 #endif
2414                     return;
2415                 }
2416             }
2417             else
2418             {
2419                 String aLibDirPath = pImplLib->maStorageURL;
2420                 INetURLObject aElementInetObj( aLibDirPath );
2421                 aElementInetObj.insertName( aElementName, sal_False,
2422                     INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2423                 aElementInetObj.setExtension( maLibElementFileExtension );
2424                 aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
2425             }
2426 
2427             Reference< XNameContainer > xLib( pImplLib );
2428             Any aAny = importLibraryElement( xLib, aElementName,
2429                                              aFile, xInStream );
2430             if( pImplLib->hasByName( aElementName ) )
2431             {
2432                 if( aAny.hasValue() )
2433                     pImplLib->maNameContainer.replaceByName( aElementName, aAny );
2434             }
2435             else
2436             {
2437                 pImplLib->maNameContainer.insertByName( aElementName, aAny );
2438             }
2439         }
2440 
2441         pImplLib->implSetModified( sal_False );
2442     }
2443 }
2444 
2445 // Methods XLibraryContainer2
2446 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2447     throw (NoSuchElementException, RuntimeException)
2448 {
2449     LibraryContainerMethodGuard aGuard( *this );
2450     SfxLibrary* pImplLib = getImplLib( Name );
2451     sal_Bool bRet = pImplLib->mbLink;
2452     return bRet;
2453 }
2454 
2455 OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2456     throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2457 {
2458     LibraryContainerMethodGuard aGuard( *this );
2459     SfxLibrary* pImplLib = getImplLib( Name );
2460     sal_Bool bLink = pImplLib->mbLink;
2461     if( !bLink )
2462         throw IllegalArgumentException();
2463     OUString aRetStr = pImplLib->maLibInfoFileURL;
2464     return aRetStr;
2465 }
2466 
2467 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2468     throw (NoSuchElementException, RuntimeException)
2469 {
2470     LibraryContainerMethodGuard aGuard( *this );
2471     SfxLibrary* pImplLib = getImplLib( Name );
2472     sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2473     return bRet;
2474 }
2475 
2476 void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2477     throw (NoSuchElementException, RuntimeException)
2478 {
2479     LibraryContainerMethodGuard aGuard( *this );
2480     SfxLibrary* pImplLib = getImplLib( Name );
2481     if( pImplLib->mbLink )
2482     {
2483         if( pImplLib->mbReadOnlyLink != bReadOnly )
2484         {
2485             pImplLib->mbReadOnlyLink = bReadOnly;
2486             pImplLib->implSetModified( sal_True );
2487             maModifiable.setModified( sal_True );
2488         }
2489     }
2490     else
2491     {
2492         if( pImplLib->mbReadOnly != bReadOnly )
2493         {
2494             pImplLib->mbReadOnly = bReadOnly;
2495             pImplLib->implSetModified( sal_True );
2496         }
2497     }
2498 }
2499 
2500 void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2501     throw (NoSuchElementException, ElementExistException, RuntimeException)
2502 {
2503     LibraryContainerMethodGuard aGuard( *this );
2504     if( maNameContainer.hasByName( NewName ) )
2505         throw ElementExistException();
2506 
2507     // Get and hold library before removing
2508     Any aLibAny = maNameContainer.getByName( Name ) ;
2509 
2510     // #i24094 Maybe lib is not loaded!
2511     Reference< XNameAccess > xNameAccess;
2512     aLibAny >>= xNameAccess;
2513     SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2514     if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2515         return;     // Lib with unverified password cannot be renamed
2516     loadLibrary( Name );
2517 
2518     // Remove from container
2519     maNameContainer.removeByName( Name );
2520     maModifiable.setModified( sal_True );
2521 
2522     // Rename library folder, but not for linked libraries
2523     bool bMovedSuccessful = true;
2524 
2525     // Rename files
2526     sal_Bool bStorage = mxStorage.is();
2527     if( !bStorage && !pImplLib->mbLink )
2528     {
2529         bMovedSuccessful = false;
2530 
2531         OUString aLibDirPath = pImplLib->maStorageURL;
2532 
2533         INetURLObject aDestInetObj( String(maLibraryPath).GetToken(1) );
2534         aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
2535             sal_True, INetURLObject::ENCODE_ALL );
2536         OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
2537 
2538         // Store new URL
2539         OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2540         checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2541             pImplLib->maUnexpandedStorageURL );
2542 
2543         try
2544         {
2545             if( mxSFI->isFolder( aLibDirPath ) )
2546             {
2547                 if( !mxSFI->isFolder( aDestDirPath ) )
2548                     mxSFI->createFolder( aDestDirPath );
2549 
2550                 // Move index file
2551                 try
2552                 {
2553                     if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2554                         mxSFI->kill( pImplLib->maLibInfoFileURL );
2555                     mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2556                 }
2557                 catch( Exception& )
2558                 {
2559                 }
2560 
2561                 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2562                 sal_Int32 nNameCount = aElementNames.getLength();
2563                 const OUString* pNames = aElementNames.getConstArray();
2564                 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2565                 {
2566                     OUString aElementName = pNames[ i ];
2567 
2568                     INetURLObject aElementInetObj( aLibDirPath );
2569                     aElementInetObj.insertName( aElementName, sal_False,
2570                         INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2571                     aElementInetObj.setExtension( maLibElementFileExtension );
2572                     String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2573 
2574                     INetURLObject aElementDestInetObj( aDestDirPath );
2575                     aElementDestInetObj.insertName( aElementName, sal_False,
2576                         INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2577                     aElementDestInetObj.setExtension( maLibElementFileExtension );
2578                     String aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2579 
2580                     try
2581                     {
2582                         if( mxSFI->exists( aDestElementPath ) )
2583                             mxSFI->kill( aDestElementPath );
2584                         mxSFI->move( aElementPath, aDestElementPath );
2585                     }
2586                     catch( Exception& )
2587                     {
2588                     }
2589                 }
2590                 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2591 
2592                 // Delete folder if empty
2593                 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2594                 sal_Int32 nCount = aContentSeq.getLength();
2595                 if( !nCount )
2596                 {
2597                     mxSFI->kill( aLibDirPath );
2598                 }
2599 
2600                 bMovedSuccessful = true;
2601                 pImplLib->implSetModified( sal_True );
2602             }
2603         }
2604         catch( Exception& )
2605         {
2606             // Restore old library
2607             maNameContainer.insertByName( Name, aLibAny ) ;
2608         }
2609     }
2610 
2611     if( bStorage && !pImplLib->mbLink )
2612         pImplLib->implSetModified( sal_True );
2613 
2614     if( bMovedSuccessful )
2615         maNameContainer.insertByName( NewName, aLibAny ) ;
2616 
2617 }
2618 
2619 
2620 // Methods XInitialization
2621 void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2622     throw (Exception, RuntimeException)
2623 {
2624     LibraryContainerMethodGuard aGuard( *this );
2625     sal_Int32 nArgCount = _rArguments.getLength();
2626     if ( nArgCount == 1 )
2627     {
2628         OUString sInitialDocumentURL;
2629         Reference< XStorageBasedDocument > xDocument;
2630         if ( _rArguments[0] >>= sInitialDocumentURL )
2631         {
2632             initializeFromDocumentURL( sInitialDocumentURL );
2633             return;
2634         }
2635 
2636         if ( _rArguments[0] >>= xDocument )
2637         {
2638             initializeFromDocument( xDocument );
2639             return;
2640         }
2641     }
2642 
2643     throw IllegalArgumentException();
2644 }
2645 
2646 void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const ::rtl::OUString& _rInitialDocumentURL )
2647 {
2648     init( _rInitialDocumentURL, NULL );
2649 }
2650 
2651 void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
2652 {
2653     // check whether this is a valid OfficeDocument, and obtain the document's root storage
2654     Reference< XStorage > xDocStorage;
2655     try
2656     {
2657         Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2658         if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.OfficeDocument" ) ) ) )
2659             xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
2660 
2661         Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2662         Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2663 
2664         mxOwnerDocument = xDocument;
2665         startComponentListening( xDocComponent );
2666     }
2667     catch( const Exception& ) { }
2668 
2669     if ( !xDocStorage.is() )
2670         throw IllegalArgumentException();
2671 
2672     init( OUString(), xDocStorage );
2673 }
2674 
2675 // OEventListenerAdapter
2676 void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2677 {
2678 #if OSL_DEBUG_LEVEL > 0
2679     Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2680     OSL_ENSURE( ( xDocument == _rSource.Source ) && xDocument.is(), "SfxLibraryContainer::_disposing: where does this come from?" );
2681 #else
2682     (void)_rSource;
2683 #endif
2684     dispose();
2685 }
2686 
2687 // OComponentHelper
2688 void SAL_CALL SfxLibraryContainer::disposing()
2689 {
2690     Reference< XModel > xModel = mxOwnerDocument;
2691     EventObject aEvent( xModel.get() );
2692     maVBAScriptListeners.disposing( aEvent );
2693     stopAllComponentListening();
2694     mxOwnerDocument = WeakReference< XModel >();
2695 }
2696 
2697 // Methods XLibraryContainerPassword
2698 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
2699     throw (NoSuchElementException, RuntimeException)
2700 {
2701     LibraryContainerMethodGuard aGuard( *this );
2702     return sal_False;
2703 }
2704 
2705 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
2706     throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2707 {
2708     LibraryContainerMethodGuard aGuard( *this );
2709     throw IllegalArgumentException();
2710 }
2711 
2712 sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword
2713     ( const OUString&, const OUString& )
2714         throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2715 {
2716     LibraryContainerMethodGuard aGuard( *this );
2717     throw IllegalArgumentException();
2718 }
2719 
2720 void SAL_CALL SfxLibraryContainer::changeLibraryPassword(
2721     const OUString&, const OUString&, const OUString& )
2722         throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2723 {
2724     LibraryContainerMethodGuard aGuard( *this );
2725     throw IllegalArgumentException();
2726 }
2727 
2728 // Methods XContainer
2729 void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
2730     throw (RuntimeException)
2731 {
2732     LibraryContainerMethodGuard aGuard( *this );
2733     maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
2734     maNameContainer.addContainerListener( xListener );
2735 }
2736 
2737 void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
2738     throw (RuntimeException)
2739 {
2740     LibraryContainerMethodGuard aGuard( *this );
2741     maNameContainer.removeContainerListener( xListener );
2742 }
2743 
2744 // Methods XLibraryContainerExport
2745 void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2746     const Reference< XInteractionHandler >& Handler )
2747         throw ( uno::Exception, NoSuchElementException, RuntimeException)
2748 {
2749     LibraryContainerMethodGuard aGuard( *this );
2750     SfxLibrary* pImplLib = getImplLib( Name );
2751 
2752     Reference< XSimpleFileAccess > xToUseSFI;
2753     if( Handler.is() )
2754     {
2755         xToUseSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
2756             ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
2757         if( xToUseSFI.is() )
2758             xToUseSFI->setInteractionHandler( Handler );
2759     }
2760 
2761     // Maybe lib is not loaded?!
2762     loadLibrary( Name );
2763 
2764     uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
2765     if( pImplLib->mbPasswordProtected )
2766         implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2767     else
2768         implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2769 
2770     ::xmlscript::LibDescriptor aLibDesc;
2771     aLibDesc.aName = Name;
2772     aLibDesc.bLink = false;             // Link status gets lost?
2773     aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2774     aLibDesc.bPreload = false;          // Preload status gets lost?
2775     aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2776     aLibDesc.aElementNames = pImplLib->getElementNames();
2777 
2778     implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2779 }
2780 
2781 OUString SfxLibraryContainer::expand_url( const OUString& url )
2782     throw(::com::sun::star::uno::RuntimeException)
2783 {
2784     if (0 == url.compareToAscii( RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ))
2785     {
2786         if( !mxMacroExpander.is() )
2787         {
2788             Reference< XPropertySet > xProps( mxMSF, UNO_QUERY );
2789             OSL_ASSERT( xProps.is() );
2790             if( xProps.is() )
2791             {
2792                 Reference< XComponentContext > xContext;
2793                 xProps->getPropertyValue(
2794                     OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
2795                 OSL_ASSERT( xContext.is() );
2796                 if( xContext.is() )
2797                 {
2798                     Reference< util::XMacroExpander > xExpander;
2799                     xContext->getValueByName(
2800                         OUSTR("/singletons/com.sun.star.util.theMacroExpander") ) >>= xExpander;
2801                     if(! xExpander.is())
2802                     {
2803                         throw uno::DeploymentException(
2804                             OUSTR("no macro expander singleton available!"), Reference< XInterface >() );
2805                     }
2806                     MutexGuard guard( Mutex::getGlobalMutex() );
2807                     if( !mxMacroExpander.is() )
2808                     {
2809                         mxMacroExpander = xExpander;
2810                     }
2811                 }
2812             }
2813         }
2814 
2815         if( !mxMacroExpander.is() )
2816             return url;
2817 
2818         // cut protocol
2819         OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
2820         // decode uric class chars
2821         macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
2822         // expand macro string
2823         OUString ret( mxMacroExpander->expandMacros( macro ) );
2824         return ret;
2825     }
2826     else if( mxStringSubstitution.is() )
2827     {
2828         OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2829         return ret;
2830     }
2831     else
2832     {
2833         return url;
2834     }
2835 }
2836 
2837 //XLibraryContainer3
2838 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2839     throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2840 {
2841     LibraryContainerMethodGuard aGuard( *this );
2842     SfxLibrary* pImplLib = getImplLib( Name );
2843     sal_Bool bLink = pImplLib->mbLink;
2844     if( !bLink )
2845         throw IllegalArgumentException();
2846     OUString aRetStr = pImplLib->maOrignialStorageURL;
2847     return aRetStr;
2848 }
2849 
2850 
2851 // XVBACompatibility
2852 ::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException)
2853 {
2854     return mbVBACompat;
2855 }
2856 
2857 void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException)
2858 {
2859     /*  The member variable mbVBACompat must be set first, the following call
2860         to getBasicManager() may call getVBACompatibilityMode() which returns
2861         this value. */
2862     mbVBACompat = _vbacompatmodeon;
2863     if( BasicManager* pBasMgr = getBasicManager() )
2864     {
2865         // get the standard library
2866         String aLibName = pBasMgr->GetName();
2867         if ( aLibName.Len() == 0 )
2868             aLibName = String( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2869 
2870         if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2871             pBasic->SetVBAEnabled( _vbacompatmodeon );
2872 
2873         /*  If in VBA compatibility mode, force creation of the VBA Globals
2874             object. Each application will create an instance of its own
2875             implementation and store it in its Basic manager. Implementations
2876             will do all necessary additional initialization, such as
2877             registering the global "This***Doc" UNO constant, starting the
2878             document events processor etc.
2879          */
2880         if( mbVBACompat ) try
2881         {
2882             Reference< XModel > xModel( mxOwnerDocument );   // weak-ref -> ref
2883             Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
2884             xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
2885         }
2886         catch( Exception& )
2887         {
2888         }
2889     }
2890 }
2891 
2892 sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() throw (RuntimeException)
2893 {
2894     LibraryContainerMethodGuard aGuard( *this );
2895     return mnRunningVBAScripts;
2896 }
2897 
2898 void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
2899 {
2900     maVBAScriptListeners.addTypedListener( rxListener );
2901 }
2902 
2903 void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
2904 {
2905     maVBAScriptListeners.removeTypedListener( rxListener );
2906 }
2907 
2908 void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const ::rtl::OUString& rModuleName ) throw (RuntimeException)
2909 {
2910     // own lock for accessing the number of running scripts
2911     enterMethod();
2912     switch( nIdentifier )
2913     {
2914         case vba::VBAScriptEventId::SCRIPT_STARTED:
2915             ++mnRunningVBAScripts;
2916         break;
2917         case vba::VBAScriptEventId::SCRIPT_STOPPED:
2918             --mnRunningVBAScripts;
2919         break;
2920     }
2921     leaveMethod();
2922 
2923     Reference< XModel > xModel = mxOwnerDocument;  // weak-ref -> ref
2924     Reference< XInterface > xSender( xModel, UNO_QUERY_THROW );
2925     vba::VBAScriptEvent aEvent( xSender, nIdentifier, rModuleName );
2926     maVBAScriptListeners.notify( aEvent );
2927 }
2928 
2929 // Methods XServiceInfo
2930 ::sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const ::rtl::OUString& _rServiceName )
2931     throw (RuntimeException)
2932 {
2933     LibraryContainerMethodGuard aGuard( *this );
2934     Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
2935     const OUString* pSupportedServices = aSupportedServices.getConstArray();
2936     for ( sal_Int32 i=0; i<aSupportedServices.getLength(); ++i, ++pSupportedServices )
2937         if ( *pSupportedServices == _rServiceName )
2938             return sal_True;
2939     return sal_False;
2940 }
2941 
2942 //============================================================================
2943 
2944 // Implementation class SfxLibrary
2945 
2946 // Ctor
2947 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
2948     const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI )
2949         : OComponentHelper( m_aMutex )
2950         , mxMSF( xMSF )
2951         , mxSFI( xSFI )
2952         , mrModifiable( _rModifiable )
2953         , maNameContainer( aType )
2954         , mbLoaded( sal_True )
2955         , mbIsModified( sal_True )
2956         , mbInitialised( sal_False )
2957         , mbLink( sal_False )
2958         , mbReadOnly( sal_False )
2959         , mbReadOnlyLink( sal_False )
2960         , mbPreload( sal_False )
2961         , mbPasswordProtected( sal_False )
2962         , mbPasswordVerified( sal_False )
2963         , mbDoc50Password( sal_False )
2964         , mbSharedIndexFile( sal_False )
2965         , mbExtension( sal_False )
2966 {
2967 }
2968 
2969 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
2970     const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI,
2971     const OUString& aLibInfoFileURL, const OUString& aStorageURL, sal_Bool ReadOnly )
2972         : OComponentHelper( m_aMutex )
2973         , mxMSF( xMSF )
2974         , mxSFI( xSFI )
2975         , mrModifiable( _rModifiable )
2976         , maNameContainer( aType )
2977         , mbLoaded( sal_False )
2978         , mbIsModified( sal_True )
2979         , mbInitialised( sal_False )
2980         , maLibInfoFileURL( aLibInfoFileURL )
2981         , maStorageURL( aStorageURL )
2982         , mbLink( sal_True )
2983         , mbReadOnly( sal_False )
2984         , mbReadOnlyLink( ReadOnly )
2985         , mbPreload( sal_False )
2986         , mbPasswordProtected( sal_False )
2987         , mbPasswordVerified( sal_False )
2988         , mbDoc50Password( sal_False )
2989         , mbSharedIndexFile( sal_False )
2990         , mbExtension( sal_False )
2991 {
2992 }
2993 
2994 void SfxLibrary::implSetModified( sal_Bool _bIsModified )
2995 {
2996     if ( mbIsModified == _bIsModified )
2997         return;
2998     mbIsModified = _bIsModified;
2999     if ( mbIsModified )
3000         mrModifiable.setModified( sal_True );
3001 }
3002 
3003 // Methods XInterface
3004 Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
3005     throw( RuntimeException )
3006 {
3007     Any aRet;
3008 
3009     /*
3010     if( mbReadOnly )
3011     {
3012         aRet = Any( ::cppu::queryInterface( rType,
3013             static_cast< XContainer * >( this ),
3014             static_cast< XNameAccess * >( this ) ) );
3015     }
3016     else
3017     {
3018     */
3019         aRet = Any( ::cppu::queryInterface( rType,
3020             static_cast< XContainer * >( this ),
3021             static_cast< XNameContainer * >( this ),
3022             static_cast< XNameAccess * >( this ),
3023             static_cast< XElementAccess * >( this ),
3024             static_cast< XChangesNotifier * >( this ) ) );
3025     //}
3026     if( !aRet.hasValue() )
3027         aRet = OComponentHelper::queryInterface( rType );
3028     return aRet;
3029 }
3030 
3031 // Methods XElementAccess
3032 Type SfxLibrary::getElementType()
3033     throw(RuntimeException)
3034 {
3035     return maNameContainer.getElementType();
3036 }
3037 
3038 sal_Bool SfxLibrary::hasElements()
3039     throw(RuntimeException)
3040 {
3041     sal_Bool bRet = maNameContainer.hasElements();
3042     return bRet;
3043 }
3044 
3045 // Methods XNameAccess
3046 Any SfxLibrary::getByName( const OUString& aName )
3047     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3048 {
3049     impl_checkLoaded();
3050 
3051     Any aRetAny = maNameContainer.getByName( aName ) ;
3052     return aRetAny;
3053 }
3054 
3055 Sequence< OUString > SfxLibrary::getElementNames()
3056     throw(RuntimeException)
3057 {
3058     return maNameContainer.getElementNames();
3059 }
3060 
3061 sal_Bool SfxLibrary::hasByName( const OUString& aName )
3062     throw(RuntimeException)
3063 {
3064     sal_Bool bRet = maNameContainer.hasByName( aName );
3065     return bRet;
3066 }
3067 
3068 void SfxLibrary::impl_checkReadOnly()
3069 {
3070     if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3071         throw IllegalArgumentException(
3072             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Library is readonly." ) ),
3073             // TODO: resource
3074             *this, 0
3075         );
3076 }
3077 
3078 void SfxLibrary::impl_checkLoaded()
3079 {
3080     if ( !mbLoaded )
3081         throw WrappedTargetException(
3082             ::rtl::OUString(),
3083             *this,
3084             makeAny( LibraryNotLoadedException(
3085                 ::rtl::OUString(),
3086                 *this
3087             ) )
3088         );
3089 }
3090 
3091 // Methods XNameReplace
3092 void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3093     throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
3094 {
3095     impl_checkReadOnly();
3096     impl_checkLoaded();
3097 
3098     OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::replaceByName: replacing element is invalid!" );
3099 
3100     maNameContainer.replaceByName( aName, aElement );
3101     implSetModified( sal_True );
3102 }
3103 
3104 
3105 // Methods XNameContainer
3106 void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3107     throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
3108 {
3109     impl_checkReadOnly();
3110     impl_checkLoaded();
3111 
3112     OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::insertByName: to-be-inserted element is invalid!" );
3113 
3114     maNameContainer.insertByName( aName, aElement );
3115     implSetModified( sal_True );
3116 }
3117 
3118 void SfxLibrary::impl_removeWithoutChecks( const ::rtl::OUString& _rElementName )
3119 {
3120     maNameContainer.removeByName( _rElementName );
3121     implSetModified( sal_True );
3122 
3123     // Remove element file
3124     if( maStorageURL.getLength() )
3125     {
3126         INetURLObject aElementInetObj( maStorageURL );
3127         aElementInetObj.insertName( _rElementName, sal_False,
3128             INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
3129         aElementInetObj.setExtension( maLibElementFileExtension );
3130         OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
3131 
3132         try
3133         {
3134             if( mxSFI->exists( aFile ) )
3135                 mxSFI->kill( aFile );
3136         }
3137         catch( Exception& )
3138         {
3139             DBG_UNHANDLED_EXCEPTION();
3140         }
3141     }
3142 }
3143 
3144 void SfxLibrary::removeByName( const OUString& Name )
3145     throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3146 {
3147     impl_checkReadOnly();
3148     impl_checkLoaded();
3149     impl_removeWithoutChecks( Name );
3150 }
3151 
3152 // XTypeProvider
3153 Sequence< Type > SfxLibrary::getTypes()
3154     throw( RuntimeException )
3155 {
3156     static OTypeCollection * s_pTypes_NameContainer = 0;
3157     {
3158         if( !s_pTypes_NameContainer )
3159         {
3160             MutexGuard aGuard( Mutex::getGlobalMutex() );
3161             if( !s_pTypes_NameContainer )
3162             {
3163                 static OTypeCollection s_aTypes_NameContainer(
3164                     ::getCppuType( (const Reference< XNameContainer > *)0 ),
3165                     ::getCppuType( (const Reference< XContainer > *)0 ),
3166                     ::getCppuType( (const Reference< XChangesNotifier > *)0 ),
3167                     OComponentHelper::getTypes() );
3168                 s_pTypes_NameContainer = &s_aTypes_NameContainer;
3169             }
3170         }
3171         return s_pTypes_NameContainer->getTypes();
3172     }
3173 }
3174 
3175 
3176 Sequence< sal_Int8 > SfxLibrary::getImplementationId()
3177     throw( RuntimeException )
3178 {
3179     static OImplementationId * s_pId_NameContainer = 0;
3180     {
3181         if( !s_pId_NameContainer )
3182         {
3183             MutexGuard aGuard( Mutex::getGlobalMutex() );
3184             if( !s_pId_NameContainer )
3185             {
3186                 static OImplementationId s_aId_NameContainer;
3187                 s_pId_NameContainer = &s_aId_NameContainer;
3188             }
3189         }
3190         return s_pId_NameContainer->getImplementationId();
3191     }
3192 }
3193 
3194 // Methods XContainer
3195 void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
3196     throw (RuntimeException)
3197 {
3198     maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3199     maNameContainer.addContainerListener( xListener );
3200 }
3201 
3202 void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
3203     throw (RuntimeException)
3204 {
3205     maNameContainer.removeContainerListener( xListener );
3206 }
3207 
3208 // Methods XChangesNotifier
3209 void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
3210     throw (RuntimeException)
3211 {
3212     maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3213     maNameContainer.addChangesListener( xListener );
3214 }
3215 
3216 void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
3217     throw (RuntimeException)
3218 {
3219     maNameContainer.removeChangesListener( xListener );
3220 }
3221 
3222 //============================================================================
3223 // Implementation class ScriptExtensionIterator
3224 
3225 static rtl::OUString aBasicLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.basic-library" ) );
3226 static rtl::OUString aDialogLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.dialog-library" ) );
3227 
3228 ScriptExtensionIterator::ScriptExtensionIterator( void )
3229     : m_eState( USER_EXTENSIONS )
3230     , m_bUserPackagesLoaded( false )
3231     , m_bSharedPackagesLoaded( false )
3232     , m_bBundledPackagesLoaded( false )
3233     , m_iUserPackage( 0 )
3234     , m_iSharedPackage( 0 )
3235     , m_iBundledPackage( 0 )
3236     , m_pScriptSubPackageIterator( NULL )
3237 {
3238     Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
3239     Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
3240     OSL_ASSERT( xProps.is() );
3241     if (xProps.is())
3242     {
3243         xProps->getPropertyValue(
3244             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext;
3245         OSL_ASSERT( m_xContext.is() );
3246     }
3247     if( !m_xContext.is() )
3248     {
3249         throw RuntimeException(
3250             ::rtl::OUString::createFromAscii( "ScriptExtensionIterator::init(), no XComponentContext" ),
3251             Reference< XInterface >() );
3252     }
3253 }
3254 
3255 rtl::OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
3256 {
3257     rtl::OUString aRetLib;
3258 
3259     while( !aRetLib.getLength() && m_eState != END_REACHED )
3260     {
3261         switch( m_eState )
3262         {
3263             case USER_EXTENSIONS:
3264             {
3265                 Reference< deployment::XPackage > xScriptPackage =
3266                     implGetNextUserScriptPackage( rbPureDialogLib );
3267                 if( !xScriptPackage.is() )
3268                     break;
3269 
3270                 aRetLib = xScriptPackage->getURL();
3271                 break;
3272             }
3273 
3274             case SHARED_EXTENSIONS:
3275             {
3276                 Reference< deployment::XPackage > xScriptPackage =
3277                     implGetNextSharedScriptPackage( rbPureDialogLib );
3278                 if( !xScriptPackage.is() )
3279                     break;
3280 
3281                 aRetLib = xScriptPackage->getURL();
3282                 break;
3283             }
3284             case BUNDLED_EXTENSIONS:
3285             {
3286                 Reference< deployment::XPackage > xScriptPackage =
3287                     implGetNextBundledScriptPackage( rbPureDialogLib );
3288                 if( !xScriptPackage.is() )
3289                     break;
3290 
3291                 aRetLib = xScriptPackage->getURL();
3292                 break;
3293             }
3294             case END_REACHED:
3295                 VOS_ENSURE( false, "ScriptExtensionIterator::nextBasicOrDialogLibrary(): Invalid case END_REACHED" );
3296                 break;
3297         }
3298     }
3299 
3300     return aRetLib;
3301 }
3302 
3303 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
3304     : m_xMainPackage( xMainPackage )
3305     , m_bIsValid( false )
3306     , m_bIsBundle( false )
3307     , m_nSubPkgCount( 0 )
3308     , m_iNextSubPkg( 0 )
3309 {
3310     Reference< deployment::XPackage > xScriptPackage;
3311     if( !m_xMainPackage.is() )
3312         return;
3313 
3314     // Check if parent package is registered
3315     beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3316         ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3317     bool bRegistered = false;
3318     if( option.IsPresent )
3319     {
3320         beans::Ambiguous<sal_Bool> const & reg = option.Value;
3321         if( !reg.IsAmbiguous && reg.Value )
3322             bRegistered = true;
3323     }
3324     if( bRegistered )
3325     {
3326         m_bIsValid = true;
3327         if( m_xMainPackage->isBundle() )
3328         {
3329             m_bIsBundle = true;
3330             m_aSubPkgSeq = m_xMainPackage->getBundle
3331                 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
3332             m_nSubPkgCount = m_aSubPkgSeq.getLength();
3333         }
3334     }
3335 }
3336 
3337 Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage
3338     ( bool& rbPureDialogLib )
3339 {
3340     rbPureDialogLib = false;
3341 
3342     Reference< deployment::XPackage > xScriptPackage;
3343     if( !m_bIsValid )
3344         return xScriptPackage;
3345 
3346     if( m_bIsBundle )
3347     {
3348         const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3349         sal_Int32 iPkg;
3350         for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3351         {
3352             const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3353             xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3354             if( xScriptPackage.is() )
3355                 break;
3356         }
3357         m_iNextSubPkg = iPkg + 1;
3358     }
3359     else
3360     {
3361         xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3362         m_bIsValid = false;     // No more script packages
3363     }
3364 
3365     return xScriptPackage;
3366 }
3367 
3368 Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage
3369     ( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
3370 {
3371     Reference< deployment::XPackage > xScriptPackage;
3372 
3373     if( xPackage.is() )
3374     {
3375         const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
3376         rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
3377         if( aMediaType.equals( aBasicLibMediaType ) )
3378         {
3379             xScriptPackage = xPackage;
3380         }
3381         else if( aMediaType.equals( aDialogLibMediaType ) )
3382         {
3383             rbPureDialogLib = true;
3384             xScriptPackage = xPackage;
3385         }
3386     }
3387 
3388     return xScriptPackage;
3389 }
3390 
3391 Reference< deployment::XPackage > ScriptExtensionIterator::implGetScriptPackageFromPackage
3392     ( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
3393 {
3394     rbPureDialogLib = false;
3395 
3396     Reference< deployment::XPackage > xScriptPackage;
3397     if( !xPackage.is() )
3398         return xScriptPackage;
3399 
3400     // Check if parent package is registered
3401     beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
3402         ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3403     bool bRegistered = false;
3404     if( option.IsPresent )
3405     {
3406         beans::Ambiguous<sal_Bool> const & reg = option.Value;
3407         if( !reg.IsAmbiguous && reg.Value )
3408             bRegistered = true;
3409     }
3410     if( bRegistered )
3411     {
3412         if( xPackage->isBundle() )
3413         {
3414             Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
3415                 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
3416             sal_Int32 nPkgCount = aPkgSeq.getLength();
3417             const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
3418             for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
3419             {
3420                 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3421                 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
3422                 rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
3423                 if( aMediaType.equals( aBasicLibMediaType ) )
3424                 {
3425                     xScriptPackage = xSubPkg;
3426                     break;
3427                 }
3428                 else if( aMediaType.equals( aDialogLibMediaType ) )
3429                 {
3430                     rbPureDialogLib = true;
3431                     xScriptPackage = xSubPkg;
3432                     break;
3433                 }
3434             }
3435         }
3436         else
3437         {
3438             const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
3439             rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
3440             if( aMediaType.equals( aBasicLibMediaType ) )
3441             {
3442                 xScriptPackage = xPackage;
3443             }
3444             else if( aMediaType.equals( aDialogLibMediaType ) )
3445             {
3446                 rbPureDialogLib = true;
3447                 xScriptPackage = xPackage;
3448             }
3449         }
3450     }
3451 
3452     return xScriptPackage;
3453 }
3454 
3455 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage
3456     ( bool& rbPureDialogLib )
3457 {
3458     Reference< deployment::XPackage > xScriptPackage;
3459 
3460     if( !m_bUserPackagesLoaded )
3461     {
3462         try
3463         {
3464             Reference< XExtensionManager > xManager =
3465                 ExtensionManager::get( m_xContext );
3466             m_aUserPackagesSeq = xManager->getDeployedExtensions
3467                 (rtl::OUString::createFromAscii("user"),
3468                  Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
3469         }
3470         catch( com::sun::star::uno::DeploymentException& )
3471         {
3472             // Special Office installations may not contain deployment code
3473             m_eState = END_REACHED;
3474             return xScriptPackage;
3475         }
3476 
3477         m_bUserPackagesLoaded = true;
3478     }
3479 
3480     if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3481     {
3482         m_eState = SHARED_EXTENSIONS;       // Later: SHARED_MODULE
3483     }
3484     else
3485     {
3486         if( m_pScriptSubPackageIterator == NULL )
3487         {
3488             const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3489             Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3490             VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextUserScriptPackage(): Invalid package" );
3491             m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3492         }
3493 
3494         if( m_pScriptSubPackageIterator != NULL )
3495         {
3496             xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3497             if( !xScriptPackage.is() )
3498             {
3499                 delete m_pScriptSubPackageIterator;
3500                 m_pScriptSubPackageIterator = NULL;
3501                 m_iUserPackage++;
3502             }
3503         }
3504     }
3505 
3506     return xScriptPackage;
3507 }
3508 
3509 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage
3510     ( bool& rbPureDialogLib )
3511 {
3512     Reference< deployment::XPackage > xScriptPackage;
3513 
3514     if( !m_bSharedPackagesLoaded )
3515     {
3516         try
3517         {
3518             Reference< XExtensionManager > xSharedManager =
3519                 ExtensionManager::get( m_xContext );
3520             m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions
3521                 (rtl::OUString::createFromAscii("shared"),
3522                  Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
3523         }
3524         catch( com::sun::star::uno::DeploymentException& )
3525         {
3526             // Special Office installations may not contain deployment code
3527             return xScriptPackage;
3528         }
3529 
3530         m_bSharedPackagesLoaded = true;
3531     }
3532 
3533     if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3534     {
3535         m_eState = BUNDLED_EXTENSIONS;
3536     }
3537     else
3538     {
3539         if( m_pScriptSubPackageIterator == NULL )
3540         {
3541             const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3542             Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3543             VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextSharedScriptPackage(): Invalid package" );
3544             m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3545         }
3546 
3547         if( m_pScriptSubPackageIterator != NULL )
3548         {
3549             xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3550             if( !xScriptPackage.is() )
3551             {
3552                 delete m_pScriptSubPackageIterator;
3553                 m_pScriptSubPackageIterator = NULL;
3554                 m_iSharedPackage++;
3555             }
3556         }
3557     }
3558 
3559     return xScriptPackage;
3560 }
3561 
3562 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage
3563     ( bool& rbPureDialogLib )
3564 {
3565     Reference< deployment::XPackage > xScriptPackage;
3566 
3567     if( !m_bBundledPackagesLoaded )
3568     {
3569         try
3570         {
3571             Reference< XExtensionManager > xManager =
3572                 ExtensionManager::get( m_xContext );
3573             m_aBundledPackagesSeq = xManager->getDeployedExtensions
3574                 (rtl::OUString::createFromAscii("bundled"),
3575                  Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
3576         }
3577         catch( com::sun::star::uno::DeploymentException& )
3578         {
3579             // Special Office installations may not contain deployment code
3580             return xScriptPackage;
3581         }
3582 
3583         m_bBundledPackagesLoaded = true;
3584     }
3585 
3586     if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3587     {
3588         m_eState = END_REACHED;
3589     }
3590     else
3591     {
3592         if( m_pScriptSubPackageIterator == NULL )
3593         {
3594             const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3595             Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3596             VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextBundledScriptPackage(): Invalid package" );
3597             m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3598         }
3599 
3600         if( m_pScriptSubPackageIterator != NULL )
3601         {
3602             xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3603             if( !xScriptPackage.is() )
3604             {
3605                 delete m_pScriptSubPackageIterator;
3606                 m_pScriptSubPackageIterator = NULL;
3607                 m_iBundledPackage++;
3608             }
3609         }
3610     }
3611 
3612     return xScriptPackage;
3613 }
3614 
3615 }   // namespace basic
3616