xref: /trunk/main/basic/source/uno/namecont.cxx (revision cdf0e10c)
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