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