Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / basic / source / uno / namecont.cxx
blobc9a67b64e6279ec641266185a73b146c03f79c89
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/container/XNameContainer.hpp>
21 #include <com/sun/star/container/XContainer.hpp>
22 #include <com/sun/star/embed/ElementModes.hpp>
23 #include <com/sun/star/embed/XTransactedObject.hpp>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <vcl/svapp.hxx>
26 #include <osl/mutex.hxx>
27 #include <tools/errinf.hxx>
28 #include <rtl/ustring.hxx>
29 #include <rtl/uri.hxx>
30 #include <rtl/strbuf.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <comphelper/anytostring.hxx>
34 #include "namecont.hxx"
35 #include <basic/basicmanagerrepository.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <tools/urlobj.hxx>
38 #include <unotools/streamwrap.hxx>
39 #include <unotools/pathoptions.hxx>
40 #include <svtools/sfxecode.hxx>
41 #include <svtools/ehdl.hxx>
42 #include <basic/basmgr.hxx>
43 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
44 #include <com/sun/star/xml/sax/Parser.hpp>
45 #include <com/sun/star/xml/sax/InputSource.hpp>
46 #include <com/sun/star/io/XOutputStream.hpp>
47 #include <com/sun/star/xml/sax/Writer.hpp>
48 #include <com/sun/star/io/XInputStream.hpp>
49 #include <com/sun/star/io/XActiveDataSource.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/uno/DeploymentException.hpp>
52 #include <com/sun/star/lang/DisposedException.hpp>
53 #include <com/sun/star/script/LibraryNotLoadedException.hpp>
54 #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
55 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
56 #include <com/sun/star/util/PathSubstitution.hpp>
57 #include <com/sun/star/deployment/ExtensionManager.hpp>
58 #include <comphelper/processfactory.hxx>
59 #include <comphelper/storagehelper.hxx>
60 #include <cppuhelper/exc_hlp.hxx>
61 #include <basic/sbmod.hxx>
62 #include <boost/scoped_ptr.hpp>
64 namespace basic
67 using namespace com::sun::star::document;
68 using namespace com::sun::star::container;
69 using namespace com::sun::star::uno;
70 using namespace com::sun::star::lang;
71 using namespace com::sun::star::io;
72 using namespace com::sun::star::ucb;
73 using namespace com::sun::star::script;
74 using namespace com::sun::star::beans;
75 using namespace com::sun::star::xml::sax;
76 using namespace com::sun::star::util;
77 using namespace com::sun::star::task;
78 using namespace com::sun::star::embed;
79 using namespace com::sun::star::frame;
80 using namespace com::sun::star::deployment;
81 using namespace com::sun::star;
82 using namespace cppu;
83 using namespace osl;
85 using com::sun::star::uno::Reference;
87 using ::rtl::Uri;
89 // #i34411: Flag for error handling during migration
90 static bool GbMigrationSuppressErrors = false;
92 //============================================================================
93 // Implementation class NameContainer
95 // Methods XElementAccess
96 Type NameContainer::getElementType()
97 throw(RuntimeException)
99 return mType;
102 sal_Bool NameContainer::hasElements()
103 throw(RuntimeException)
105 sal_Bool bRet = (mnElementCount > 0);
106 return bRet;
109 // Methods XNameAccess
110 Any NameContainer::getByName( const OUString& aName )
111 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
113 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
114 if( aIt == mHashMap.end() )
116 throw NoSuchElementException();
118 sal_Int32 iHashResult = (*aIt).second;
119 Any aRetAny = mValues.getConstArray()[ iHashResult ];
120 return aRetAny;
123 Sequence< OUString > NameContainer::getElementNames()
124 throw(RuntimeException)
126 return mNames;
129 sal_Bool NameContainer::hasByName( const OUString& aName )
130 throw(RuntimeException)
132 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
133 sal_Bool bRet = ( aIt != mHashMap.end() );
134 return bRet;
138 // Methods XNameReplace
139 void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
140 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
142 Type aAnyType = aElement.getValueType();
143 if( mType != aAnyType )
145 throw IllegalArgumentException();
147 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
148 if( aIt == mHashMap.end() )
150 throw NoSuchElementException();
152 sal_Int32 iHashResult = (*aIt).second;
153 Any aOldElement = mValues.getConstArray()[ iHashResult ];
154 mValues.getArray()[ iHashResult ] = aElement;
157 // Fire event
158 if( maContainerListeners.getLength() > 0 )
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 );
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 )
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 );
185 // Methods XNameContainer
186 void NameContainer::insertByName( const OUString& aName, const Any& aElement )
187 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
189 Type aAnyType = aElement.getValueType();
190 if( mType != aAnyType )
192 throw IllegalArgumentException();
194 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
195 if( aIt != mHashMap.end() )
197 throw ElementExistException();
200 sal_Int32 nCount = mNames.getLength();
201 mNames.realloc( nCount + 1 );
202 mValues.realloc( nCount + 1 );
203 mNames.getArray()[ nCount ] = aName;
204 mValues.getArray()[ nCount ] = aElement;
206 mHashMap[ aName ] = nCount;
207 mnElementCount++;
209 // Fire event
210 if( maContainerListeners.getLength() > 0 )
212 ContainerEvent aEvent;
213 aEvent.Source = mpxEventSource;
214 aEvent.Accessor <<= aName;
215 aEvent.Element = aElement;
216 maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
219 /* After the container event has been fired (one listener will update the
220 core Basic manager), fire change event. Listeners can rely that the
221 Basic source code of the core Basic manager is up-to-date. */
222 if( maChangesListeners.getLength() > 0 )
224 ChangesEvent aEvent;
225 aEvent.Source = mpxEventSource;
226 aEvent.Base <<= aEvent.Source;
227 aEvent.Changes.realloc( 1 );
228 aEvent.Changes[ 0 ].Accessor <<= aName;
229 aEvent.Changes[ 0 ].Element <<= aElement;
230 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
234 void NameContainer::removeByName( const OUString& aName )
235 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
237 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
238 if( aIt == mHashMap.end() )
240 OUString sMessage = OUStringBuffer().append('"')
241 .append(aName).append("\" not found")
242 .makeStringAndClear();
243 throw NoSuchElementException(sMessage, uno::Reference< uno::XInterface >());
246 sal_Int32 iHashResult = (*aIt).second;
247 Any aOldElement = mValues.getConstArray()[ iHashResult ];
248 mHashMap.erase( aIt );
249 sal_Int32 iLast = mNames.getLength() - 1;
250 if( iLast != iHashResult )
252 OUString* pNames = mNames.getArray();
253 Any* pValues = mValues.getArray();
254 pNames[ iHashResult ] = pNames[ iLast ];
255 pValues[ iHashResult ] = pValues[ iLast ];
256 mHashMap[ pNames[ iHashResult ] ] = iHashResult;
258 mNames.realloc( iLast );
259 mValues.realloc( iLast );
260 mnElementCount--;
262 // Fire event
263 if( maContainerListeners.getLength() > 0 )
265 ContainerEvent aEvent;
266 aEvent.Source = mpxEventSource;
267 aEvent.Accessor <<= aName;
268 aEvent.Element = aOldElement;
269 maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
272 /* After the container event has been fired (one listener will update the
273 core Basic manager), fire change event. Listeners can rely that the
274 Basic source code of the core Basic manager is up-to-date. */
275 if( maChangesListeners.getLength() > 0 )
277 ChangesEvent aEvent;
278 aEvent.Source = mpxEventSource;
279 aEvent.Base <<= aEvent.Source;
280 aEvent.Changes.realloc( 1 );
281 aEvent.Changes[ 0 ].Accessor <<= aName;
282 // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
283 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
284 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
289 // Methods XContainer
290 void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
291 throw (RuntimeException)
293 if( !xListener.is() )
295 throw RuntimeException("addContainerListener called with null xListener",
296 static_cast< cppu::OWeakObject * >(this));
298 Reference< XInterface > xIface( xListener, UNO_QUERY );
299 maContainerListeners.addInterface( xIface );
302 void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
303 throw (RuntimeException)
305 if( !xListener.is() )
307 throw RuntimeException();
309 Reference< XInterface > xIface( xListener, UNO_QUERY );
310 maContainerListeners.removeInterface( xIface );
313 // Methods XChangesNotifier
314 void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener )
315 throw (RuntimeException)
317 if( !xListener.is() )
319 throw RuntimeException();
321 Reference< XInterface > xIface( xListener, UNO_QUERY );
322 maChangesListeners.addInterface( xIface );
325 void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener )
326 throw (RuntimeException)
328 if( !xListener.is() )
330 throw RuntimeException();
332 Reference< XInterface > xIface( xListener, UNO_QUERY );
333 maChangesListeners.removeInterface( xIface );
336 //============================================================================
337 // ModifiableHelper
339 void ModifiableHelper::setModified( sal_Bool _bModified )
341 if ( _bModified == mbModified )
343 return;
345 mbModified = _bModified;
347 if ( m_aModifyListeners.getLength() == 0 )
349 return;
351 EventObject aModifyEvent( m_rEventSource );
352 m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
355 //============================================================================
357 VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex& rMutex ) :
358 VBAScriptListenerContainer_BASE( rMutex )
362 bool VBAScriptListenerContainer::implTypedNotify( const Reference< vba::XVBAScriptListener >& rxListener, const vba::VBAScriptEvent& rEvent )
363 throw (Exception)
365 rxListener->notifyVBAScriptEvent( rEvent );
366 return true; // notify all other listeners too
369 //============================================================================
371 // Implementation class SfxLibraryContainer
372 DBG_NAME( SfxLibraryContainer )
374 // Ctor
375 SfxLibraryContainer::SfxLibraryContainer( void )
376 : SfxLibraryContainer_BASE( maMutex )
378 , maVBAScriptListeners( maMutex )
379 , mnRunningVBAScripts( 0 )
380 , mbVBACompat( sal_False )
381 , maModifiable( *this, maMutex )
382 , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
383 , mbOldInfoFormat( false )
384 , mbOasis2OOoFormat( false )
385 , mpBasMgr( NULL )
386 , mbOwnBasMgr( false )
388 DBG_CTOR( SfxLibraryContainer, NULL );
390 mxMSF = comphelper::getProcessServiceFactory();
391 SAL_WARN_IF(!mxMSF.is(), "basic", "couldn't get ProcessServiceFactory");
393 mxSFI = ucb::SimpleFileAccess::create( comphelper::getComponentContext(mxMSF) );
395 mxStringSubstitution = util::PathSubstitution::create( comphelper::getComponentContext(mxMSF) );
398 SfxLibraryContainer::~SfxLibraryContainer()
400 if( mbOwnBasMgr )
402 BasicManager::LegacyDeleteBasicManager( mpBasMgr );
404 DBG_DTOR( SfxLibraryContainer, NULL );
407 void SfxLibraryContainer::checkDisposed() const
409 if ( isDisposed() )
411 throw DisposedException( OUString(),
412 *const_cast< SfxLibraryContainer* >( this ) );
416 void SfxLibraryContainer::enterMethod()
418 maMutex.acquire();
419 checkDisposed();
422 void SfxLibraryContainer::leaveMethod()
424 maMutex.release();
427 BasicManager* SfxLibraryContainer::getBasicManager( void )
429 if ( mpBasMgr )
431 return mpBasMgr;
433 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
434 SAL_WARN_IF(
435 !xDocument.is(), "basic",
436 ("SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager"
437 " without document!"));
438 if ( xDocument.is() )
440 mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );
442 return mpBasMgr;
445 // Methods XStorageBasedLibraryContainer
446 Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage() throw (RuntimeException)
448 LibraryContainerMethodGuard aGuard( *this );
449 return mxStorage;
452 void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage )
453 throw (IllegalArgumentException, RuntimeException)
455 LibraryContainerMethodGuard aGuard( *this );
456 if ( !_rxRootStorage.is() )
458 throw IllegalArgumentException();
460 mxStorage = _rxRootStorage;
461 onNewRootStorage();
464 void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage )
465 throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
467 LibraryContainerMethodGuard aGuard( *this );
468 if ( !_rxRootStorage.is() )
470 throw IllegalArgumentException();
474 storeLibraries_Impl( _rxRootStorage, true );
476 catch( const Exception& )
478 throw WrappedTargetException( OUString(),
479 *this, ::cppu::getCaughtException() );
484 // Methods XModifiable
485 sal_Bool SfxLibraryContainer::isModified()
486 throw (RuntimeException)
488 LibraryContainerMethodGuard aGuard( *this );
489 if ( maModifiable.isModified() )
491 return sal_True;
493 // the library container is not modified, go through the libraries and check whether they are modified
494 Sequence< OUString > aNames = maNameContainer.getElementNames();
495 const OUString* pNames = aNames.getConstArray();
496 sal_Int32 nNameCount = aNames.getLength();
498 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
500 OUString aName = pNames[ i ];
501 SfxLibrary* pImplLib = getImplLib( aName );
502 if( pImplLib->isModified() )
504 if ( aName == "Standard" )
506 // this is a workaround that has to be implemented because
507 // empty standard library should stay marked as modified
508 // but should not be treated as modified while it is empty
509 if ( pImplLib->hasElements() )
510 return sal_True;
512 else
514 return sal_True;
519 return sal_False;
522 void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified )
523 throw (PropertyVetoException, RuntimeException)
525 LibraryContainerMethodGuard aGuard( *this );
526 maModifiable.setModified( _bModified );
529 void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener )
530 throw (RuntimeException)
532 LibraryContainerMethodGuard aGuard( *this );
533 maModifiable.addModifyListener( _rxListener );
536 void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener )
537 throw (RuntimeException)
539 LibraryContainerMethodGuard aGuard( *this );
540 maModifiable.removeModifyListener( _rxListener );
543 // Methods XPersistentLibraryContainer
544 Any SAL_CALL SfxLibraryContainer::getRootLocation() throw (RuntimeException)
546 LibraryContainerMethodGuard aGuard( *this );
547 return makeAny( getRootStorage() );
550 OUString SAL_CALL SfxLibraryContainer::getContainerLocationName() throw (RuntimeException)
552 LibraryContainerMethodGuard aGuard( *this );
553 return maLibrariesDir;
556 void SAL_CALL SfxLibraryContainer::storeLibraries( )
557 throw (WrappedTargetException, RuntimeException)
559 LibraryContainerMethodGuard aGuard( *this );
562 storeLibraries_Impl( mxStorage, mxStorage.is() );
563 // we need to store *all* libraries if and only if we are based on a storage:
564 // in this case, storeLibraries_Impl will remove the source storage, after loading
565 // all libraries, so we need to force them to be stored, again
567 catch( const Exception& )
569 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
573 static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
574 const INetURLObject& rTargetFolderInetObj,
575 const OUString& rCheckFileName,
576 const OUString& rCheckExtension,
577 Reference< XSimpleFileAccess3 > xSFI )
579 INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
580 aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
581 sal_True, INetURLObject::ENCODE_ALL );
582 aTargetFolderInetObj.setExtension( rCheckExtension );
583 OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
584 if( !xSFI->exists( aTargetFile ) )
586 INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
587 aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
588 sal_True, INetURLObject::ENCODE_ALL );
589 aSourceFolderInetObj.setExtension( rCheckExtension );
590 OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
591 xSFI->copy( aSourceFile, aTargetFile );
595 static void createVariableURL( OUString& rStr, const OUString& rLibName,
596 const OUString& rInfoFileName, bool bUser )
598 if( bUser )
600 rStr = OUString("$(USER)/basic/");
602 else
604 rStr = OUString("$(INST)/share/basic/");
606 rStr += rLibName;
607 rStr += "/";
608 rStr += rInfoFileName;
609 rStr += ".xlb/";
612 void SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
614 // this might be called from within the ctor, and the impl_init might (indirectly) create
615 // an UNO reference to ourself.
616 // Ensure that we're not destroyed while we're in here
617 osl_atomic_increment( &m_refCount );
618 init_Impl( rInitialDocumentURL, rxInitialStorage );
619 osl_atomic_decrement( &m_refCount );
622 void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL,
623 const uno::Reference< embed::XStorage >& rxInitialStorage )
625 uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
627 maInitialDocumentURL = rInitialDocumentURL;
628 maInfoFileName = OUString::createFromAscii( getInfoFileName() );
629 maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
630 maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
631 maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );
633 meInitMode = DEFAULT;
634 INetURLObject aInitUrlInetObj( maInitialDocumentURL );
635 OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
636 if( !aInitFileName.isEmpty() )
638 // We need a BasicManager to avoid problems
639 StarBASIC* pBas = new StarBASIC();
640 mpBasMgr = new BasicManager( pBas );
641 mbOwnBasMgr = true;
643 OUString aExtension = aInitUrlInetObj.getExtension();
644 if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
646 meInitMode = CONTAINER_INIT_FILE;
647 INetURLObject aLibPathInetObj( aInitUrlInetObj );
648 aLibPathInetObj.removeSegment();
649 maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
651 else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
653 meInitMode = LIBRARY_INIT_FILE;
654 uno::Reference< embed::XStorage > xDummyStor;
655 ::xmlscript::LibDescriptor aLibDesc;
656 implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
657 return;
659 else
661 // Decide between old and new document
662 sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
663 if ( bOldStorage )
665 meInitMode = OLD_BASIC_STORAGE;
666 importFromOldStorage( aInitFileName );
667 return;
669 else
671 meInitMode = OFFICE_DOCUMENT;
674 xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
676 catch (const uno::Exception& )
678 // TODO: error handling
683 else
685 // Default paths
686 maLibraryPath = SvtPathOptions().GetBasicPath();
689 Reference< XParser > xParser = xml::sax::Parser::create(comphelper::getComponentContext(mxMSF));
691 uno::Reference< io::XInputStream > xInput;
693 mxStorage = xStorage;
694 bool bStorage = mxStorage.is();
697 // #110009: Scope to force the StorageRefs to be destructed and
698 // so the streams to be closed before the preload operation
701 uno::Reference< embed::XStorage > xLibrariesStor;
702 OUString aFileName;
704 int nPassCount = 1;
705 if( !bStorage && meInitMode == DEFAULT )
707 nPassCount = 2;
709 for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
711 if( bStorage )
713 SAL_WARN_IF(
714 meInitMode != DEFAULT && meInitMode != OFFICE_DOCUMENT, "basic",
715 "Wrong InitMode for document");
718 uno::Reference< io::XStream > xStream;
719 xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
721 if ( xLibrariesStor.is() )
723 aFileName = maInfoFileName;
724 aFileName += "-lc.xml";
728 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
730 catch(const uno::Exception& )
733 if( !xStream.is() )
735 mbOldInfoFormat = true;
737 // Check old version
738 aFileName = maOldInfoFileName;
739 aFileName += ".xml";
743 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
745 catch(const uno::Exception& )
748 if( !xStream.is() )
750 // Check for EA2 document version with wrong extensions
751 aFileName = maOldInfoFileName;
752 aFileName += ".xli";
753 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
758 if ( xStream.is() )
760 xInput = xStream->getInputStream();
763 catch(const uno::Exception& )
765 // TODO: error handling?
768 else
770 INetURLObject* pLibInfoInetObj = NULL;
771 if( meInitMode == CONTAINER_INIT_FILE )
773 aFileName = aInitFileName;
775 else
777 if( nPass == 1 )
779 pLibInfoInetObj = new INetURLObject( maLibraryPath.getToken(0, (sal_Unicode)';') );
781 else
783 pLibInfoInetObj = new INetURLObject( maLibraryPath.getToken(1, (sal_Unicode)';') );
785 pLibInfoInetObj->insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
786 pLibInfoInetObj->setExtension( OUString("xlc") );
787 aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
792 xInput = mxSFI->openFileRead( aFileName );
794 catch(const Exception& )
796 // Silently tolerate empty or missing files
797 xInput.clear();
800 // Old variant?
801 if( !xInput.is() && nPass == 0 )
803 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
804 aLibInfoInetObj.insertName( maOldInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
805 aLibInfoInetObj.setExtension( OUString( "xli") );
806 aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
810 xInput = mxSFI->openFileRead( aFileName );
811 mbOldInfoFormat = true;
813 catch(const Exception& )
815 xInput.clear();
819 delete pLibInfoInetObj;
822 if( xInput.is() )
824 InputSource source;
825 source.aInputStream = xInput;
826 source.sSystemId = aFileName;
828 // start parsing
829 ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();
833 xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
834 xParser->parseStream( source );
836 catch ( const xml::sax::SAXException& e )
838 SAL_WARN("basic", e.Message);
839 return;
841 catch ( const io::IOException& e )
843 SAL_WARN("basic", e.Message);
844 return;
847 sal_Int32 nLibCount = pLibArray->mnLibCount;
848 for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
850 ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
852 // Check storage URL
853 OUString aStorageURL = rLib.aStorageURL;
854 if( !bStorage && aStorageURL.isEmpty() && nPass == 0 )
856 OUString aLibraryPath;
857 if( meInitMode == CONTAINER_INIT_FILE )
859 aLibraryPath = maLibraryPath;
861 else
863 aLibraryPath = maLibraryPath.getToken(1, (sal_Unicode)';');
865 INetURLObject aInetObj( aLibraryPath );
867 aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
868 sal_True, INetURLObject::ENCODE_ALL );
869 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
870 if( mxSFI->isFolder( aLibDirPath ) )
872 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
873 maModifiable.setModified( sal_True );
875 else if( rLib.bLink )
877 // Check "share" path
878 INetURLObject aShareInetObj( maLibraryPath.getToken(0, (sal_Unicode)';') );
879 aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
880 sal_True, INetURLObject::ENCODE_ALL );
881 OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
882 if( mxSFI->isFolder( aShareLibDirPath ) )
884 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
885 maModifiable.setModified( sal_True );
887 else
889 // #i25537: Ignore lib if library folder does not really exist
890 continue;
895 OUString aLibName = rLib.aName;
897 // If the same library name is used by the shared and the
898 // user lib container index files the user file wins
899 if( nPass == 1 && hasByName( aLibName ) )
901 continue;
903 SfxLibrary* pImplLib;
904 if( rLib.bLink )
906 Reference< XNameAccess > xLib =
907 createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
908 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
910 else
912 Reference< XNameContainer > xLib = createLibrary( aLibName );
913 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
914 pImplLib->mbLoaded = sal_False;
915 pImplLib->mbReadOnly = rLib.bReadOnly;
916 if( !bStorage )
918 checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
919 pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
922 maModifiable.setModified( sal_False );
924 // Read library info files
925 if( !mbOldInfoFormat )
927 uno::Reference< embed::XStorage > xLibraryStor;
928 if( !pImplLib->mbInitialised && bStorage )
932 xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
933 embed::ElementModes::READ );
935 catch(const uno::Exception& )
937 #if OSL_DEBUG_LEVEL > 0
938 Any aError( ::cppu::getCaughtException() );
939 SAL_WARN(
940 "basic",
941 "couldn't open sub storage for library \""
942 << rLib.aName << "\". Exception: "
943 << comphelper::anyToString(aError));
944 #endif
948 // Link is already initialised in createLibraryLink()
949 if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
951 OUString aIndexFileName;
952 bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
953 SAL_WARN_IF(
954 bLoaded && aLibName != rLib.aName, "basic",
955 ("Different library names in library container and"
956 " library info files!"));
957 if( GbMigrationSuppressErrors && !bLoaded )
959 removeLibrary( aLibName );
963 else if( !bStorage )
965 // Write new index file immediately because otherwise
966 // the library elements will be lost when storing into
967 // the new info format
968 uno::Reference< embed::XStorage > xTmpStorage;
969 implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
972 implImportLibDescriptor( pImplLib, rLib );
974 if( nPass == 1 )
976 pImplLib->mbSharedIndexFile = true;
977 pImplLib->mbReadOnly = sal_True;
981 // Keep flag for documents to force writing the new index files
982 if( !bStorage )
984 mbOldInfoFormat = false;
986 delete pLibArray;
990 // #110009: END Scope to force the StorageRefs to be destructed
993 if( !bStorage && meInitMode == DEFAULT )
997 implScanExtensions();
999 catch(const uno::Exception& )
1001 // TODO: error handling?
1002 SAL_WARN("basic", "Cannot access extensions!");
1006 // Preload?
1008 Sequence< OUString > aNames = maNameContainer.getElementNames();
1009 const OUString* pNames = aNames.getConstArray();
1010 sal_Int32 nNameCount = aNames.getLength();
1011 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1013 OUString aName = pNames[ i ];
1014 SfxLibrary* pImplLib = getImplLib( aName );
1015 if( pImplLib->mbPreload )
1017 loadLibrary( aName );
1022 if( meInitMode == DEFAULT )
1024 INetURLObject aUserBasicInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
1025 OUString aStandardStr( RTL_CONSTASCII_USTRINGPARAM("Standard") );
1027 static char const strPrevFolderName_1[] = "__basic_80";
1028 static char const strPrevFolderName_2[] = "__basic_80_2";
1029 INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
1030 aPrevUserBasicInetObj_1.removeSegment();
1031 INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
1032 aPrevUserBasicInetObj_1.Append( rtl::OString( strPrevFolderName_1 ));
1033 aPrevUserBasicInetObj_2.Append( rtl::OString( strPrevFolderName_2 ));
1035 // #i93163
1036 bool bCleanUp = false;
1039 INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
1040 OUString aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1041 if( mxSFI->isFolder( aPrevFolder ) )
1043 // Check if Standard folder exists and is complete
1044 INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
1045 aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1046 sal_True, INetURLObject::ENCODE_ALL );
1047 INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
1048 aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
1049 sal_True, INetURLObject::ENCODE_ALL );
1050 OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1051 if( mxSFI->isFolder( aPrevStandardFolder ) )
1053 OUString aXlbExtension( "xlb" );
1054 OUString aCheckFileName;
1056 // Check if script.xlb exists
1057 aCheckFileName = OUString("script");
1058 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1059 aPrevUserBasicStandardInetObj,
1060 aCheckFileName, aXlbExtension, mxSFI );
1062 // Check if dialog.xlb exists
1063 aCheckFileName = OUString("dialog");
1064 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1065 aPrevUserBasicStandardInetObj,
1066 aCheckFileName, aXlbExtension, mxSFI );
1068 // Check if module1.xba exists
1069 OUString aXbaExtension("xba");
1070 aCheckFileName = OUString("Module1");
1071 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1072 aPrevUserBasicStandardInetObj,
1073 aCheckFileName, aXbaExtension, mxSFI );
1075 else
1077 OUString aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1078 mxSFI->copy( aStandardFolder, aPrevStandardFolder );
1081 OUString aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1082 mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
1084 else
1086 aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
1087 aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1089 if( mxSFI->isFolder( aPrevFolder ) )
1091 SfxLibraryContainer* pPrevCont = createInstanceImpl();
1092 Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
1094 // Rename previous basic folder to make storage URLs correct during initialisation
1095 OUString aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1096 INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
1097 aUserBasicTmpInetObj.removeSegment();
1098 aUserBasicTmpInetObj.Append( rtl::OString( "__basic_tmp" ));
1099 OUString aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
1101 mxSFI->move( aFolderUserBasic, aFolderTmp );
1104 mxSFI->move( aPrevFolder, aFolderUserBasic );
1106 catch(const Exception& )
1108 // Move back user/basic folder
1111 mxSFI->kill( aFolderUserBasic );
1113 catch(const Exception& )
1115 mxSFI->move( aFolderTmp, aFolderUserBasic );
1116 throw;
1119 INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
1120 aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT,
1121 sal_True, INetURLObject::ENCODE_ALL );
1122 aPrevUserBasicLibInfoInetObj.setExtension( OUString("xlc"));
1123 OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
1124 Sequence<Any> aInitSeq( 1 );
1125 aInitSeq.getArray()[0] <<= aLibInfoFileName;
1126 GbMigrationSuppressErrors = true;
1127 pPrevCont->initialize( aInitSeq );
1128 GbMigrationSuppressErrors = false;
1130 // Rename folders back
1131 mxSFI->move( aFolderUserBasic, aPrevFolder );
1132 mxSFI->move( aFolderTmp, aFolderUserBasic );
1134 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
1135 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
1136 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
1137 OUString aInstSearchStr("$(INST)");
1139 Sequence< OUString > aNames = pPrevCont->getElementNames();
1140 const OUString* pNames = aNames.getConstArray();
1141 sal_Int32 nNameCount = aNames.getLength();
1143 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1145 OUString aLibName = pNames[ i ];
1146 if( hasByName( aLibName ) )
1148 if( aLibName == aStandardStr )
1150 SfxLibrary* pImplLib = getImplLib( aStandardStr );
1151 INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
1152 OUString aStandardFolder = pImplLib->maStorageURL;
1153 mxSFI->kill( aStandardFolder );
1155 else
1157 continue;
1161 SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
1162 if( pImplLib->mbLink )
1164 OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
1165 bool bCreateLink = true;
1166 if( aStorageURL.indexOf( aUserSearchStr ) != -1 ||
1167 aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
1168 aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
1169 aStorageURL.indexOf( aInstSearchStr ) != -1 )
1171 bCreateLink = false;
1173 if( bCreateLink )
1175 createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
1178 else
1180 // Move folder if not already done
1181 INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
1182 aUserBasicLibFolderInetObj.Append( aLibName );
1183 OUString aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1185 INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
1186 aPrevUserBasicLibFolderInetObj.Append( aLibName );
1187 OUString aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1189 if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
1191 mxSFI->move( aPrevLibFolder, aLibFolder );
1194 if( aLibName == aStandardStr )
1196 maNameContainer.removeByName( aLibName );
1199 // Create library
1200 Reference< XNameContainer > xLib = createLibrary( aLibName );
1201 SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
1202 pNewLib->mbLoaded = false;
1203 pNewLib->implSetModified( sal_False );
1204 checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
1205 pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
1207 uno::Reference< embed::XStorage > xDummyStor;
1208 ::xmlscript::LibDescriptor aLibDesc;
1209 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
1210 implImportLibDescriptor( pNewLib, aLibDesc );
1213 mxSFI->kill( aPrevFolder );
1216 catch(const Exception& e)
1218 bCleanUp = true;
1219 SAL_WARN("basic", "Upgrade of Basic installation failed somehow: " << e.Message);
1222 // #i93163
1223 if( bCleanUp )
1225 static const char strErrorSavFolderName[] = "__basic_80_err";
1226 INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
1227 aPrevUserBasicInetObj_Err.removeSegment();
1228 aPrevUserBasicInetObj_Err.Append( rtl::OString( strErrorSavFolderName ));
1229 OUString aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );
1231 bool bSaved = false;
1234 OUString aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
1235 if( mxSFI->isFolder( aPrevFolder_1 ) )
1237 mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
1238 bSaved = true;
1241 catch(const Exception& )
1245 OUString aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1246 if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
1248 mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
1250 else
1252 mxSFI->kill( aPrevFolder_2 );
1255 catch(const Exception& )
1261 void SfxLibraryContainer::implScanExtensions( void )
1263 ScriptExtensionIterator aScriptIt;
1264 OUString aLibURL;
1266 bool bPureDialogLib = false;
1267 while ( !(aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).isEmpty())
1269 if( bPureDialogLib && maInfoFileName == "script" )
1271 continue;
1273 // Extract lib name
1274 sal_Int32 nLen = aLibURL.getLength();
1275 sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
1276 sal_Int32 nReduceCopy = 0;
1277 if( indexLastSlash == nLen - 1 )
1279 nReduceCopy = 1;
1280 indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
1283 OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
1285 // If a library of the same exists the existing library wins
1286 if( hasByName( aLibName ) )
1288 continue;
1290 // Add index file to URL
1291 OUString aIndexFileURL = aLibURL;
1292 if( nReduceCopy == 0 )
1294 aIndexFileURL += "/";
1296 aIndexFileURL += maInfoFileName;
1297 aIndexFileURL += OUString(".xlb");
1299 // Create link
1300 const bool bReadOnly = false;
1301 Reference< XNameAccess > xLib = createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
1305 // Handle maLibInfoFileURL and maStorageURL correctly
1306 void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
1307 OUString& aLibInfoFileURL, OUString& aStorageURL,
1308 OUString& aUnexpandedStorageURL )
1310 OUString aExpandedSourceURL = expand_url( aSourceURL );
1311 if( aExpandedSourceURL != aSourceURL )
1313 aUnexpandedStorageURL = aSourceURL;
1315 INetURLObject aInetObj( aExpandedSourceURL );
1316 OUString aExtension = aInetObj.getExtension();
1317 if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
1319 // URL to xlb file
1320 aLibInfoFileURL = aExpandedSourceURL;
1321 aInetObj.removeSegment();
1322 aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1324 else
1326 // URL to library folder
1327 aStorageURL = aExpandedSourceURL;
1328 aInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1329 aInetObj.setExtension( OUString("xlb") );
1330 aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1334 SfxLibrary* SfxLibraryContainer::getImplLib( const OUString& rLibraryName )
1336 Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
1337 Reference< XNameAccess > xNameAccess;
1338 aLibAny >>= xNameAccess;
1339 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
1340 return pImplLib;
1344 // Storing with password encryption
1346 // Empty implementation, avoids unneccesary implementation in dlgcont.cxx
1347 sal_Bool SfxLibraryContainer::implStorePasswordLibrary( SfxLibrary*,
1348 const OUString&,
1349 const uno::Reference< embed::XStorage >&,
1350 const uno::Reference< task::XInteractionHandler >& )
1352 return sal_False;
1355 sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
1356 SfxLibrary* /*pLib*/,
1357 const OUString& /*aName*/,
1358 const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
1359 const OUString& /*aTargetURL*/,
1360 const Reference< XSimpleFileAccess3 > /*xToUseSFI*/,
1361 const uno::Reference< task::XInteractionHandler >& )
1363 return sal_False;
1366 sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
1367 SfxLibrary* /*pLib*/,
1368 const OUString& /*Name*/,
1369 sal_Bool /*bVerifyPasswordOnly*/ )
1370 throw(WrappedTargetException, RuntimeException)
1372 return sal_True;
1377 #define EXPAND_PROTOCOL "vnd.sun.star.expand"
1379 OUString SfxLibraryContainer::createAppLibraryFolder( SfxLibrary* pLib, const OUString& aName )
1381 OUString aLibDirPath = pLib->maStorageURL;
1382 if( aLibDirPath.isEmpty() )
1384 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
1385 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1386 checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
1387 pLib->maStorageURL, pLib->maUnexpandedStorageURL );
1388 aLibDirPath = pLib->maStorageURL;
1391 if( !mxSFI->isFolder( aLibDirPath ) )
1395 mxSFI->createFolder( aLibDirPath );
1397 catch(const Exception& )
1401 return aLibDirPath;
1404 // Storing
1405 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1406 const OUString& aName,
1407 const uno::Reference< embed::XStorage >& xStorage )
1409 OUString aDummyLocation;
1410 Reference< XSimpleFileAccess3 > xDummySFA;
1411 Reference< XInteractionHandler > xDummyHandler;
1412 implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
1415 // New variant for library export
1416 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1417 const OUString& aName,
1418 const uno::Reference< embed::XStorage >& xStorage,
1419 const OUString& aTargetURL,
1420 Reference< XSimpleFileAccess3 > xToUseSFI,
1421 const Reference< XInteractionHandler >& xHandler )
1423 sal_Bool bLink = pLib->mbLink;
1424 bool bStorage = xStorage.is() && !bLink;
1426 Sequence< OUString > aElementNames = pLib->getElementNames();
1427 sal_Int32 nNameCount = aElementNames.getLength();
1428 const OUString* pNames = aElementNames.getConstArray();
1430 if( bStorage )
1432 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1434 OUString aElementName = pNames[ i ];
1435 OUString aStreamName = aElementName;
1436 aStreamName += ".xml";
1438 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1440 SAL_WARN(
1441 "basic",
1442 "invalid library element \"" << aElementName << '"');
1443 continue;
1447 uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
1448 aStreamName,
1449 embed::ElementModes::READWRITE );
1450 // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1452 OUString aMime( "text/xml" );
1454 uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1455 SAL_WARN_IF(
1456 !xProps.is(), "basic",
1457 "The StorageStream must implement XPropertySet interface!");
1458 //if ( !xProps.is() ) //TODO
1460 if ( xProps.is() )
1462 xProps->setPropertyValue( OUString("MediaType"), uno::makeAny( aMime ) );
1464 // #87671 Allow encryption
1465 xProps->setPropertyValue( OUString("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
1467 Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
1468 Reference< XNameContainer > xLib( pLib );
1469 writeLibraryElement( xLib, aElementName, xOutput );
1472 catch(const uno::Exception& )
1474 SAL_WARN("basic", "Problem during storing of library!");
1475 // TODO: error handling?
1478 pLib->storeResourcesToStorage( xStorage );
1480 else
1482 // Export?
1483 bool bExport = !aTargetURL.isEmpty();
1486 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
1487 if( xToUseSFI.is() )
1489 xSFI = xToUseSFI;
1491 OUString aLibDirPath;
1492 if( bExport )
1494 INetURLObject aInetObj( aTargetURL );
1495 aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1496 aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1498 if( !xSFI->isFolder( aLibDirPath ) )
1500 xSFI->createFolder( aLibDirPath );
1502 pLib->storeResourcesToURL( aLibDirPath, xHandler );
1504 else
1506 aLibDirPath = createAppLibraryFolder( pLib, aName );
1507 pLib->storeResources();
1510 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1512 OUString aElementName = pNames[ i ];
1514 INetURLObject aElementInetObj( aLibDirPath );
1515 aElementInetObj.insertName( aElementName, sal_False,
1516 INetURLObject::LAST_SEGMENT, sal_True,
1517 INetURLObject::ENCODE_ALL );
1518 aElementInetObj.setExtension( maLibElementFileExtension );
1519 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
1521 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1523 SAL_WARN(
1524 "basic",
1525 "invalid library element \"" << aElementName << '"');
1526 continue;
1529 // TODO: Check modified
1532 if( xSFI->exists( aElementPath ) )
1534 xSFI->kill( aElementPath );
1536 Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
1537 Reference< XNameContainer > xLib( pLib );
1538 writeLibraryElement( xLib, aElementName, xOutput );
1539 xOutput->closeOutput();
1541 catch(const Exception& )
1543 if( bExport )
1545 throw;
1547 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
1548 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1549 ErrorHandler::HandleError( nErrorCode );
1553 catch(const Exception& )
1555 if( bExport )
1557 throw;
1563 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1564 const ::xmlscript::LibDescriptor& rLib,
1565 const uno::Reference< embed::XStorage >& xStorage )
1567 OUString aDummyLocation;
1568 Reference< XSimpleFileAccess3 > xDummySFA;
1569 implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
1572 // New variant for library export
1573 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1574 const ::xmlscript::LibDescriptor& rLib,
1575 const uno::Reference< embed::XStorage >& xStorage,
1576 const ::rtl::OUString& aTargetURL,
1577 Reference< XSimpleFileAccess3 > xToUseSFI )
1579 // Create sax writer
1580 Reference< XWriter > xWriter = xml::sax::Writer::create(comphelper::getComponentContext(mxMSF));
1582 sal_Bool bLink = pLib->mbLink;
1583 bool bStorage = xStorage.is() && !bLink;
1585 // Write info file
1586 uno::Reference< io::XOutputStream > xOut;
1587 uno::Reference< io::XStream > xInfoStream;
1588 if( bStorage )
1590 OUString aStreamName( maInfoFileName );
1591 aStreamName += "-lb.xml";
1595 xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
1596 SAL_WARN_IF(!xInfoStream.is(), "basic", "No stream!");
1597 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
1598 // throw uno::RuntimeException(); // TODO
1600 if ( xProps.is() )
1602 OUString aMime("text/xml");
1603 xProps->setPropertyValue( OUString("MediaType"), uno::makeAny( aMime ) );
1605 // #87671 Allow encryption
1606 xProps->setPropertyValue( OUString("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
1608 xOut = xInfoStream->getOutputStream();
1611 catch(const uno::Exception& )
1613 SAL_WARN("basic", "Problem during storing of library index file!");
1614 // TODO: error handling?
1617 else
1619 // Export?
1620 bool bExport = !aTargetURL.isEmpty();
1621 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
1622 if( xToUseSFI.is() )
1624 xSFI = xToUseSFI;
1626 OUString aLibInfoPath;
1627 if( bExport )
1629 INetURLObject aInetObj( aTargetURL );
1630 aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1631 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1632 if( !xSFI->isFolder( aLibDirPath ) )
1634 xSFI->createFolder( aLibDirPath );
1636 aInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
1637 aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
1638 aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1640 else
1642 createAppLibraryFolder( pLib, rLib.aName );
1643 aLibInfoPath = pLib->maLibInfoFileURL;
1648 if( xSFI->exists( aLibInfoPath ) )
1650 xSFI->kill( aLibInfoPath );
1652 xOut = xSFI->openFileWrite( aLibInfoPath );
1654 catch(const Exception& )
1656 if( bExport )
1658 throw;
1660 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
1661 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1662 ErrorHandler::HandleError( nErrorCode );
1665 if( !xOut.is() )
1667 SAL_WARN("basic", "couldn't open output stream");
1668 return;
1670 xWriter->setOutputStream( xOut );
1671 xmlscript::exportLibrary( xWriter, rLib );
1675 bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib,
1676 ::xmlscript::LibDescriptor& rLib,
1677 const uno::Reference< embed::XStorage >& xStorage,
1678 const OUString& aIndexFileName )
1680 Reference< XParser > xParser = xml::sax::Parser::create(comphelper::getComponentContext(mxMSF));
1682 sal_Bool bLink = sal_False;
1683 bool bStorage = false;
1684 if( pLib )
1686 bLink = pLib->mbLink;
1687 bStorage = xStorage.is() && !bLink;
1690 // Read info file
1691 uno::Reference< io::XInputStream > xInput;
1692 OUString aLibInfoPath;
1693 if( bStorage )
1695 aLibInfoPath = maInfoFileName;
1696 aLibInfoPath += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
1700 uno::Reference< io::XStream > xInfoStream =
1701 xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
1702 xInput = xInfoStream->getInputStream();
1704 catch(const uno::Exception& )
1707 else
1709 // Create Input stream
1710 //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1712 if( pLib )
1714 createAppLibraryFolder( pLib, rLib.aName );
1715 aLibInfoPath = pLib->maLibInfoFileURL;
1717 else
1719 aLibInfoPath = aIndexFileName;
1723 xInput = mxSFI->openFileRead( aLibInfoPath );
1725 catch(const Exception& )
1727 xInput.clear();
1728 if( !GbMigrationSuppressErrors )
1730 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1731 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1732 ErrorHandler::HandleError( nErrorCode );
1736 if( !xInput.is() )
1738 return false;
1741 InputSource source;
1742 source.aInputStream = xInput;
1743 source.sSystemId = aLibInfoPath;
1745 // start parsing
1748 xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
1749 xParser->parseStream( source );
1751 catch(const Exception& )
1753 SAL_WARN("basic", "Parsing error");
1754 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1755 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
1756 ErrorHandler::HandleError( nErrorCode );
1757 return false;
1760 if( !pLib )
1762 Reference< XNameContainer > xLib = createLibrary( rLib.aName );
1763 pLib = static_cast< SfxLibrary* >( xLib.get() );
1764 pLib->mbLoaded = sal_False;
1765 rLib.aStorageURL = aIndexFileName;
1766 checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
1767 pLib->maUnexpandedStorageURL );
1769 implImportLibDescriptor( pLib, rLib );
1772 return true;
1775 void SfxLibraryContainer::implImportLibDescriptor( SfxLibrary* pLib,
1776 ::xmlscript::LibDescriptor& rLib )
1778 if( !pLib->mbInitialised )
1780 sal_Int32 nElementCount = rLib.aElementNames.getLength();
1781 const OUString* pElementNames = rLib.aElementNames.getConstArray();
1782 Any aDummyElement = createEmptyLibraryElement();
1783 for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
1785 pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
1787 pLib->mbPasswordProtected = rLib.bPasswordProtected;
1788 pLib->mbReadOnly = rLib.bReadOnly;
1789 pLib->mbPreload = rLib.bPreload;
1790 pLib->implSetModified( sal_False );
1791 pLib->mbInitialised = true;
1796 // Methods of new XLibraryStorage interface?
1797 void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage,
1798 bool bComplete )
1800 const Sequence< OUString > aNames = maNameContainer.getElementNames();
1801 sal_Int32 nNameCount = aNames.getLength();
1802 const OUString* pName = aNames.getConstArray();
1803 const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
1805 // Don't count libs from shared index file
1806 sal_Int32 nLibsToSave = nNameCount;
1807 for( ; pName != pNamesEnd; ++pName )
1809 SfxLibrary* pImplLib = getImplLib( *pName );
1810 if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
1812 nLibsToSave--;
1815 if( !nLibsToSave )
1817 return;
1819 boost::scoped_ptr< ::xmlscript::LibDescriptorArray > pLibArray(new ::xmlscript::LibDescriptorArray(nLibsToSave));
1821 // Write to storage?
1822 bool bStorage = i_rStorage.is();
1823 uno::Reference< embed::XStorage > xSourceLibrariesStor;
1824 uno::Reference< embed::XStorage > xTargetLibrariesStor;
1825 OUString sTempTargetStorName;
1826 const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
1827 if ( bStorage )
1829 // Don't write if only empty standard lib exists
1830 if ( ( nNameCount == 1 ) && ( aNames[0] == "Standard" ) )
1832 Any aLibAny = maNameContainer.getByName( aNames[0] );
1833 Reference< XNameAccess > xNameAccess;
1834 aLibAny >>= xNameAccess;
1835 if ( ! ( xNameAccess->hasElements() || ( bInplaceStorage && isModified() ) ) )
1837 return;
1841 // create the empty target storage
1844 OUString sTargetLibrariesStoreName;
1845 if ( bInplaceStorage )
1847 // create a temporary target storage
1848 const OUStringBuffer aTempTargetNameBase = maLibrariesDir + OUString( "_temp_" );
1849 sal_Int32 index = 0;
1852 OUStringBuffer aTempTargetName( aTempTargetNameBase );
1853 aTempTargetName.append( index++ );
1855 sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
1856 if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1858 break;
1861 while ( true );
1862 sTempTargetStorName = sTargetLibrariesStoreName;
1864 else
1866 sTargetLibrariesStoreName = maLibrariesDir;
1867 if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1869 i_rStorage->removeElement( sTargetLibrariesStoreName );
1873 xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
1875 catch( const uno::Exception& )
1877 DBG_UNHANDLED_EXCEPTION();
1878 return;
1881 // open the source storage which might be used to copy yet-unmodified libraries
1884 if ( mxStorage->hasByName( maLibrariesDir ) || bInplaceStorage )
1886 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir,
1887 bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
1890 catch( const uno::Exception& )
1892 DBG_UNHANDLED_EXCEPTION();
1893 return;
1897 int iArray = 0;
1898 pName = aNames.getConstArray();
1899 ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
1900 for( ; pName != pNamesEnd; ++pName )
1902 SfxLibrary* pImplLib = getImplLib( *pName );
1903 if( pImplLib->mbSharedIndexFile )
1905 continue;
1907 const bool bExtensionLib = pImplLib->mbExtension;
1908 ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
1909 aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
1910 if( !bExtensionLib )
1912 iArray++;
1914 rLib.aName = *pName;
1916 rLib.bLink = pImplLib->mbLink;
1917 if( !bStorage || pImplLib->mbLink )
1919 rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
1920 pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
1922 rLib.bReadOnly = pImplLib->mbReadOnly;
1923 rLib.bPreload = pImplLib->mbPreload;
1924 rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
1925 rLib.aElementNames = pImplLib->getElementNames();
1927 if( pImplLib->implIsModified() || bComplete )
1929 // Can we simply copy the storage?
1930 if( !mbOldInfoFormat && !pImplLib->implIsModified() && !mbOasis2OOoFormat && xSourceLibrariesStor.is() )
1934 xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
1936 catch( const uno::Exception& )
1938 DBG_UNHANDLED_EXCEPTION();
1939 // TODO: error handling?
1942 else
1944 uno::Reference< embed::XStorage > xLibraryStor;
1945 if( bStorage )
1949 xLibraryStor = xTargetLibrariesStor->openStorageElement(
1950 rLib.aName,
1951 embed::ElementModes::READWRITE );
1953 catch(const uno::Exception& )
1955 #if OSL_DEBUG_LEVEL > 0
1956 Any aError( ::cppu::getCaughtException() );
1957 SAL_WARN(
1958 "basic",
1959 "couldn't create sub storage for library \""
1960 << rLib.aName << "\". Exception: "
1961 << comphelper::anyToString(aError));
1962 #endif
1963 return;
1967 // Maybe lib is not loaded?!
1968 if( bComplete )
1970 loadLibrary( rLib.aName );
1972 if( pImplLib->mbPasswordProtected )
1974 implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
1975 // TODO: Check return value
1977 else
1979 implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
1981 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
1982 if( bStorage )
1986 uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
1987 xTransact->commit();
1989 catch(const uno::Exception& )
1991 DBG_UNHANDLED_EXCEPTION();
1992 // TODO: error handling
1996 maModifiable.setModified( sal_True );
1997 pImplLib->implSetModified( sal_False );
2000 // For container info ReadOnly refers to mbReadOnlyLink
2001 rLib.bReadOnly = pImplLib->mbReadOnlyLink;
2004 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
2005 // then we need to clean up the temporary storage we used for this
2006 if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
2008 SAL_WARN_IF(
2009 !xSourceLibrariesStor.is(), "basic",
2010 ("SfxLibrariesContainer::storeLibraries_impl: unexpected: we should"
2011 " have a source storage here!"));
2014 // for this, we first remove everything from the source storage, then copy the complete content
2015 // from the temporary target storage. From then on, what used to be the "source storage" becomes
2016 // the "targt storage" for all subsequent operations.
2018 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
2019 // open references to it.)
2021 if ( xSourceLibrariesStor.is() )
2023 // remove
2024 const Sequence< OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
2025 for ( const OUString* pRemoveName = aRemoveNames.getConstArray();
2026 pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
2027 ++pRemoveName
2030 xSourceLibrariesStor->removeElement( *pRemoveName );
2033 // copy
2034 const Sequence< OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
2035 for ( const OUString* pCopyName = aCopyNames.getConstArray();
2036 pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
2037 ++pCopyName
2040 xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
2044 // close and remove temp target
2045 xTargetLibrariesStor->dispose();
2046 i_rStorage->removeElement( sTempTargetStorName );
2047 xTargetLibrariesStor.clear();
2048 sTempTargetStorName = OUString();
2050 // adjust target
2051 xTargetLibrariesStor = xSourceLibrariesStor;
2052 xSourceLibrariesStor.clear();
2054 catch( const Exception& )
2056 DBG_UNHANDLED_EXCEPTION();
2060 if( !mbOldInfoFormat && !maModifiable.isModified() )
2062 return;
2064 maModifiable.setModified( sal_False );
2065 mbOldInfoFormat = false;
2067 // Write library container info
2068 // Create sax writer
2069 Reference< XWriter > xWriter = xml::sax::Writer::create(comphelper::getComponentContext(mxMSF));
2071 // Write info file
2072 uno::Reference< io::XOutputStream > xOut;
2073 uno::Reference< io::XStream > xInfoStream;
2074 if( bStorage )
2076 OUString aStreamName( maInfoFileName );
2077 aStreamName += "-lc.xml";
2081 xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2082 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
2083 SAL_WARN_IF(
2084 !xProps.is(), "basic",
2085 "The stream must implement XPropertySet!");
2086 if ( !xProps.is() )
2088 throw uno::RuntimeException();
2090 OUString aMime( "text/xml" );
2091 xProps->setPropertyValue( OUString("MediaType"), uno::makeAny( aMime ) );
2093 // #87671 Allow encryption
2094 xProps->setPropertyValue( OUString("UseCommonStoragePasswordEncryption"), uno::makeAny( sal_True ) );
2096 xOut = xInfoStream->getOutputStream();
2098 catch(const uno::Exception& )
2100 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2101 ErrorHandler::HandleError( nErrorCode );
2104 else
2106 // Create Output stream
2107 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2108 aLibInfoInetObj.insertName( maInfoFileName, sal_False, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2109 aLibInfoInetObj.setExtension( OUString("xlc") );
2110 OUString aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2114 if( mxSFI->exists( aLibInfoPath ) )
2116 mxSFI->kill( aLibInfoPath );
2118 xOut = mxSFI->openFileWrite( aLibInfoPath );
2120 catch(const Exception& )
2122 xOut.clear();
2123 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2124 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2125 ErrorHandler::HandleError( nErrorCode );
2129 if( !xOut.is() )
2131 SAL_WARN("basic", "couldn't open output stream");
2132 return;
2135 xWriter->setOutputStream( xOut );
2139 xmlscript::exportLibraryContainer( xWriter, pLibArray.get() );
2140 if ( bStorage )
2142 uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
2143 SAL_WARN_IF(
2144 !xTransact.is(), "basic",
2145 "The storage must implement XTransactedObject!");
2146 if ( !xTransact.is() )
2148 throw uno::RuntimeException();
2150 xTransact->commit();
2153 catch(const uno::Exception& )
2155 SAL_WARN("basic", "Problem during storing of libraries!");
2156 sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
2157 ErrorHandler::HandleError( nErrorCode );
2162 // Methods XElementAccess
2163 Type SAL_CALL SfxLibraryContainer::getElementType()
2164 throw(RuntimeException)
2166 LibraryContainerMethodGuard aGuard( *this );
2167 return maNameContainer.getElementType();
2170 sal_Bool SfxLibraryContainer::hasElements()
2171 throw(RuntimeException)
2173 LibraryContainerMethodGuard aGuard( *this );
2174 sal_Bool bRet = maNameContainer.hasElements();
2175 return bRet;
2178 // Methods XNameAccess
2179 Any SfxLibraryContainer::getByName( const OUString& aName )
2180 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2182 LibraryContainerMethodGuard aGuard( *this );
2183 Any aRetAny = maNameContainer.getByName( aName ) ;
2184 return aRetAny;
2187 Sequence< OUString > SfxLibraryContainer::getElementNames()
2188 throw(RuntimeException)
2190 LibraryContainerMethodGuard aGuard( *this );
2191 return maNameContainer.getElementNames();
2194 sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
2195 throw(RuntimeException)
2197 LibraryContainerMethodGuard aGuard( *this );
2198 return maNameContainer.hasByName( aName ) ;
2201 // Methods XLibraryContainer
2202 Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
2203 throw(IllegalArgumentException, ElementExistException, RuntimeException)
2205 LibraryContainerMethodGuard aGuard( *this );
2206 SfxLibrary* pNewLib = implCreateLibrary( Name );
2207 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2209 createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2211 Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
2212 Any aElement;
2213 aElement <<= xNameAccess;
2214 maNameContainer.insertByName( Name, aElement );
2215 maModifiable.setModified( sal_True );
2216 Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2217 return xRet;
2220 Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
2221 ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2222 throw(IllegalArgumentException, ElementExistException, RuntimeException)
2224 LibraryContainerMethodGuard aGuard( *this );
2225 // TODO: Check other reasons to force ReadOnly status
2226 //if( !ReadOnly )
2230 OUString aLibInfoFileURL;
2231 OUString aLibDirURL;
2232 OUString aUnexpandedStorageURL;
2233 checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2236 SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2237 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2238 pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2239 pNewLib->maOriginalStorageURL = StorageURL;
2241 OUString aInitFileName;
2242 uno::Reference< embed::XStorage > xDummyStor;
2243 ::xmlscript::LibDescriptor aLibDesc;
2244 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
2245 implImportLibDescriptor( pNewLib, aLibDesc );
2247 Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
2248 Any aElement;
2249 aElement <<= xRet;
2250 maNameContainer.insertByName( Name, aElement );
2251 maModifiable.setModified( sal_True );
2253 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
2254 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
2255 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
2256 if( StorageURL.indexOf( aUserSearchStr ) != -1 )
2258 pNewLib->mbExtension = true;
2260 else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
2262 pNewLib->mbExtension = true;
2263 pNewLib->mbReadOnly = sal_True;
2266 return xRet;
2269 void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2270 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2272 LibraryContainerMethodGuard aGuard( *this );
2273 // Get and hold library before removing
2274 Any aLibAny = maNameContainer.getByName( Name ) ;
2275 Reference< XNameAccess > xNameAccess;
2276 aLibAny >>= xNameAccess;
2277 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2278 if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2280 throw IllegalArgumentException();
2282 // Remove from container
2283 maNameContainer.removeByName( Name );
2284 maModifiable.setModified( sal_True );
2286 // Delete library files, but not for linked libraries
2287 if( !pImplLib->mbLink )
2289 if( mxStorage.is() )
2291 return;
2293 if( xNameAccess->hasElements() )
2295 Sequence< OUString > aNames = pImplLib->getElementNames();
2296 sal_Int32 nNameCount = aNames.getLength();
2297 const OUString* pNames = aNames.getConstArray();
2298 for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2300 pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
2304 // Delete index file
2305 createAppLibraryFolder( pImplLib, Name );
2306 OUString aLibInfoPath = pImplLib->maLibInfoFileURL;
2309 if( mxSFI->exists( aLibInfoPath ) )
2311 mxSFI->kill( aLibInfoPath );
2314 catch(const Exception& ) {}
2316 // Delete folder if empty
2317 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2318 aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
2319 sal_True, INetURLObject::ENCODE_ALL );
2320 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
2324 if( mxSFI->isFolder( aLibDirPath ) )
2326 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2327 sal_Int32 nCount = aContentSeq.getLength();
2328 if( !nCount )
2330 mxSFI->kill( aLibDirPath );
2334 catch(const Exception& )
2340 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2341 throw(NoSuchElementException, RuntimeException)
2343 LibraryContainerMethodGuard aGuard( *this );
2344 SfxLibrary* pImplLib = getImplLib( Name );
2345 sal_Bool bRet = pImplLib->mbLoaded;
2346 return bRet;
2350 void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2351 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2353 LibraryContainerMethodGuard aGuard( *this );
2354 Any aLibAny = maNameContainer.getByName( Name ) ;
2355 Reference< XNameAccess > xNameAccess;
2356 aLibAny >>= xNameAccess;
2357 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2359 sal_Bool bLoaded = pImplLib->mbLoaded;
2360 pImplLib->mbLoaded = sal_True;
2361 if( !bLoaded && xNameAccess->hasElements() )
2363 if( pImplLib->mbPasswordProtected )
2365 implLoadPasswordLibrary( pImplLib, Name );
2366 return;
2369 sal_Bool bLink = pImplLib->mbLink;
2370 bool bStorage = mxStorage.is() && !bLink;
2372 uno::Reference< embed::XStorage > xLibrariesStor;
2373 uno::Reference< embed::XStorage > xLibraryStor;
2374 if( bStorage )
2378 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2379 SAL_WARN_IF(
2380 !xLibrariesStor.is(), "basic",
2381 ("The method must either throw exception or return a"
2382 " storage!"));
2383 if ( !xLibrariesStor.is() )
2385 throw uno::RuntimeException();
2388 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2389 SAL_WARN_IF(
2390 !xLibraryStor.is(), "basic",
2391 ("The method must either throw exception or return a"
2392 " storage!"));
2393 if ( !xLibrariesStor.is() )
2395 throw uno::RuntimeException();
2398 catch(const uno::Exception& )
2400 #if OSL_DEBUG_LEVEL > 0
2401 Any aError( ::cppu::getCaughtException() );
2402 SAL_WARN(
2403 "basic",
2404 "couldn't open sub storage for library \"" << Name
2405 << "\". Exception: "
2406 << comphelper::anyToString(aError));
2407 #endif
2408 return;
2412 Sequence< OUString > aNames = pImplLib->getElementNames();
2413 sal_Int32 nNameCount = aNames.getLength();
2414 const OUString* pNames = aNames.getConstArray();
2415 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2417 OUString aElementName = pNames[ i ];
2419 OUString aFile;
2420 uno::Reference< io::XInputStream > xInStream;
2422 if( bStorage )
2424 uno::Reference< io::XStream > xElementStream;
2426 aFile = aElementName;
2427 aFile += ".xml";
2431 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2433 catch(const uno::Exception& )
2436 if( !xElementStream.is() )
2438 // Check for EA2 document version with wrong extensions
2439 aFile = aElementName;
2440 aFile += ".";
2441 aFile += maLibElementFileExtension;
2444 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2446 catch(const uno::Exception& )
2450 if ( xElementStream.is() )
2452 xInStream = xElementStream->getInputStream();
2454 if ( !xInStream.is() )
2456 SAL_WARN(
2457 "basic",
2458 "couldn't open library element stream - attempted to"
2459 " open library \"" << Name << '"');
2460 return;
2463 else
2465 OUString aLibDirPath = pImplLib->maStorageURL;
2466 INetURLObject aElementInetObj( aLibDirPath );
2467 aElementInetObj.insertName( aElementName, sal_False,
2468 INetURLObject::LAST_SEGMENT, sal_True,
2469 INetURLObject::ENCODE_ALL );
2470 aElementInetObj.setExtension( maLibElementFileExtension );
2471 aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
2474 Reference< XNameContainer > xLib( pImplLib );
2475 Any aAny = importLibraryElement( xLib, aElementName,
2476 aFile, xInStream );
2477 if( pImplLib->hasByName( aElementName ) )
2479 if( aAny.hasValue() )
2481 pImplLib->maNameContainer.replaceByName( aElementName, aAny );
2484 else
2486 pImplLib->maNameContainer.insertByName( aElementName, aAny );
2489 pImplLib->implSetModified( sal_False );
2493 // Methods XLibraryContainer2
2494 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2495 throw (NoSuchElementException, RuntimeException)
2497 LibraryContainerMethodGuard aGuard( *this );
2498 SfxLibrary* pImplLib = getImplLib( Name );
2499 sal_Bool bRet = pImplLib->mbLink;
2500 return bRet;
2503 OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2504 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2506 LibraryContainerMethodGuard aGuard( *this );
2507 SfxLibrary* pImplLib = getImplLib( Name );
2508 sal_Bool bLink = pImplLib->mbLink;
2509 if( !bLink )
2511 throw IllegalArgumentException();
2513 OUString aRetStr = pImplLib->maLibInfoFileURL;
2514 return aRetStr;
2517 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2518 throw (NoSuchElementException, RuntimeException)
2520 LibraryContainerMethodGuard aGuard( *this );
2521 SfxLibrary* pImplLib = getImplLib( Name );
2522 sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2523 return bRet;
2526 void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2527 throw (NoSuchElementException, RuntimeException)
2529 LibraryContainerMethodGuard aGuard( *this );
2530 SfxLibrary* pImplLib = getImplLib( Name );
2531 if( pImplLib->mbLink )
2533 if( pImplLib->mbReadOnlyLink != bReadOnly )
2535 pImplLib->mbReadOnlyLink = bReadOnly;
2536 pImplLib->implSetModified( sal_True );
2537 maModifiable.setModified( sal_True );
2540 else
2542 if( pImplLib->mbReadOnly != bReadOnly )
2544 pImplLib->mbReadOnly = bReadOnly;
2545 pImplLib->implSetModified( sal_True );
2550 void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2551 throw (NoSuchElementException, ElementExistException, RuntimeException)
2553 LibraryContainerMethodGuard aGuard( *this );
2554 if( maNameContainer.hasByName( NewName ) )
2556 throw ElementExistException();
2558 // Get and hold library before removing
2559 Any aLibAny = maNameContainer.getByName( Name ) ;
2561 // #i24094 Maybe lib is not loaded!
2562 Reference< XNameAccess > xNameAccess;
2563 aLibAny >>= xNameAccess;
2564 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2565 if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2567 return; // Lib with unverified password cannot be renamed
2569 loadLibrary( Name );
2571 // Remove from container
2572 maNameContainer.removeByName( Name );
2573 maModifiable.setModified( sal_True );
2575 // Rename library folder, but not for linked libraries
2576 bool bMovedSuccessful = true;
2578 // Rename files
2579 bool bStorage = mxStorage.is();
2580 if( !bStorage && !pImplLib->mbLink )
2582 bMovedSuccessful = false;
2584 OUString aLibDirPath = pImplLib->maStorageURL;
2586 INetURLObject aDestInetObj( maLibraryPath.getToken(1, (sal_Unicode)';'));
2587 aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
2588 sal_True, INetURLObject::ENCODE_ALL );
2589 OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
2591 // Store new URL
2592 OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2593 checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2594 pImplLib->maUnexpandedStorageURL );
2598 if( mxSFI->isFolder( aLibDirPath ) )
2600 if( !mxSFI->isFolder( aDestDirPath ) )
2602 mxSFI->createFolder( aDestDirPath );
2604 // Move index file
2607 if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2609 mxSFI->kill( pImplLib->maLibInfoFileURL );
2611 mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2613 catch(const Exception& )
2617 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2618 sal_Int32 nNameCount = aElementNames.getLength();
2619 const OUString* pNames = aElementNames.getConstArray();
2620 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2622 OUString aElementName = pNames[ i ];
2624 INetURLObject aElementInetObj( aLibDirPath );
2625 aElementInetObj.insertName( aElementName, sal_False,
2626 INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
2627 aElementInetObj.setExtension( maLibElementFileExtension );
2628 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2630 INetURLObject aElementDestInetObj( aDestDirPath );
2631 aElementDestInetObj.insertName( aElementName, sal_False,
2632 INetURLObject::LAST_SEGMENT, sal_True,
2633 INetURLObject::ENCODE_ALL );
2634 aElementDestInetObj.setExtension( maLibElementFileExtension );
2635 OUString aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2639 if( mxSFI->exists( aDestElementPath ) )
2641 mxSFI->kill( aDestElementPath );
2643 mxSFI->move( aElementPath, aDestElementPath );
2645 catch(const Exception& )
2649 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2651 // Delete folder if empty
2652 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2653 sal_Int32 nCount = aContentSeq.getLength();
2654 if( !nCount )
2656 mxSFI->kill( aLibDirPath );
2659 bMovedSuccessful = true;
2660 pImplLib->implSetModified( sal_True );
2663 catch(const Exception& )
2665 // Restore old library
2666 maNameContainer.insertByName( Name, aLibAny ) ;
2670 if( bStorage && !pImplLib->mbLink )
2672 pImplLib->implSetModified( sal_True );
2674 if( bMovedSuccessful )
2676 maNameContainer.insertByName( NewName, aLibAny ) ;
2681 // Methods XInitialization
2682 void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2683 throw (Exception, RuntimeException)
2685 LibraryContainerMethodGuard aGuard( *this );
2686 sal_Int32 nArgCount = _rArguments.getLength();
2687 if ( nArgCount == 1 )
2689 OUString sInitialDocumentURL;
2690 Reference< XStorageBasedDocument > xDocument;
2691 if ( _rArguments[0] >>= sInitialDocumentURL )
2693 initializeFromDocumentURL( sInitialDocumentURL );
2694 return;
2697 if ( _rArguments[0] >>= xDocument )
2699 initializeFromDocument( xDocument );
2700 return;
2704 throw IllegalArgumentException();
2707 void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const OUString& _rInitialDocumentURL )
2709 init( _rInitialDocumentURL, NULL );
2712 void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
2714 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2715 Reference< XStorage > xDocStorage;
2718 Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2719 if ( xSI->supportsService( OUString("com.sun.star.document.OfficeDocument")))
2721 xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
2723 Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2724 Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2726 mxOwnerDocument = xDocument;
2727 startComponentListening( xDocComponent );
2729 catch( const Exception& ) { }
2731 if ( !xDocStorage.is() )
2733 throw IllegalArgumentException();
2735 init( OUString(), xDocStorage );
2738 // OEventListenerAdapter
2739 void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2741 #if OSL_DEBUG_LEVEL > 0
2742 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2743 SAL_WARN_IF(
2744 xDocument != _rSource.Source || !xDocument.is(), "basic",
2745 "SfxLibraryContainer::_disposing: where does this come from?");
2746 #else
2747 (void)_rSource;
2748 #endif
2749 dispose();
2752 // OComponentHelper
2753 void SAL_CALL SfxLibraryContainer::disposing()
2755 Reference< XModel > xModel = mxOwnerDocument;
2756 EventObject aEvent( xModel.get() );
2757 maVBAScriptListeners.disposing( aEvent );
2758 stopAllComponentListening();
2759 mxOwnerDocument = WeakReference< XModel >();
2762 // Methods XLibraryContainerPassword
2763 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
2764 throw (NoSuchElementException, RuntimeException)
2766 LibraryContainerMethodGuard aGuard( *this );
2767 return sal_False;
2770 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
2771 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2773 LibraryContainerMethodGuard aGuard( *this );
2774 throw IllegalArgumentException();
2777 sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword( const OUString&, const OUString& )
2778 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2780 LibraryContainerMethodGuard aGuard( *this );
2781 throw IllegalArgumentException();
2784 void SAL_CALL SfxLibraryContainer::changeLibraryPassword(const OUString&, const OUString&, const OUString& )
2785 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2787 LibraryContainerMethodGuard aGuard( *this );
2788 throw IllegalArgumentException();
2791 // Methods XContainer
2792 void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
2793 throw (RuntimeException)
2795 LibraryContainerMethodGuard aGuard( *this );
2796 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
2797 maNameContainer.addContainerListener( xListener );
2800 void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
2801 throw (RuntimeException)
2803 LibraryContainerMethodGuard aGuard( *this );
2804 maNameContainer.removeContainerListener( xListener );
2807 // Methods XLibraryContainerExport
2808 void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2809 const Reference< XInteractionHandler >& Handler )
2810 throw ( uno::Exception, NoSuchElementException, RuntimeException)
2812 LibraryContainerMethodGuard aGuard( *this );
2813 SfxLibrary* pImplLib = getImplLib( Name );
2815 Reference< XSimpleFileAccess3 > xToUseSFI;
2816 if( Handler.is() )
2818 xToUseSFI = ucb::SimpleFileAccess::create( comphelper::getComponentContext(mxMSF) );
2819 xToUseSFI->setInteractionHandler( Handler );
2822 // Maybe lib is not loaded?!
2823 loadLibrary( Name );
2825 uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
2826 if( pImplLib->mbPasswordProtected )
2828 implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2830 else
2832 implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2834 ::xmlscript::LibDescriptor aLibDesc;
2835 aLibDesc.aName = Name;
2836 aLibDesc.bLink = false; // Link status gets lost?
2837 aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2838 aLibDesc.bPreload = false; // Preload status gets lost?
2839 aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2840 aLibDesc.aElementNames = pImplLib->getElementNames();
2842 implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2845 OUString SfxLibraryContainer::expand_url( const OUString& url )
2846 throw(::com::sun::star::uno::RuntimeException)
2848 if (0 == url.compareToAscii( RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ))
2850 if( !mxMacroExpander.is() )
2852 Reference< XComponentContext > xContext(comphelper::getComponentContext( mxMSF ) );
2853 Reference< util::XMacroExpander > xExpander;
2854 xContext->getValueByName( OUString("/singletons/com.sun.star.util.theMacroExpander") ) >>= xExpander;
2855 if(! xExpander.is())
2857 throw uno::DeploymentException(
2858 OUString("no macro expander singleton available!"),
2859 Reference< XInterface >() );
2861 MutexGuard guard( Mutex::getGlobalMutex() );
2862 if( !mxMacroExpander.is() )
2864 mxMacroExpander = xExpander;
2868 if( !mxMacroExpander.is() )
2870 return url;
2872 // cut protocol
2873 OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
2874 // decode uric class chars
2875 macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
2876 // expand macro string
2877 OUString ret( mxMacroExpander->expandMacros( macro ) );
2878 return ret;
2880 else if( mxStringSubstitution.is() )
2882 OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2883 return ret;
2885 else
2887 return url;
2891 //XLibraryContainer3
2892 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2893 throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
2895 LibraryContainerMethodGuard aGuard( *this );
2896 SfxLibrary* pImplLib = getImplLib( Name );
2897 sal_Bool bLink = pImplLib->mbLink;
2898 if( !bLink )
2900 throw IllegalArgumentException();
2902 OUString aRetStr = pImplLib->maOriginalStorageURL;
2903 return aRetStr;
2907 // XVBACompatibility
2908 sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException)
2910 return mbVBACompat;
2913 void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException)
2915 /* The member variable mbVBACompat must be set first, the following call
2916 to getBasicManager() may call getVBACompatibilityMode() which returns
2917 this value. */
2918 mbVBACompat = _vbacompatmodeon;
2919 if( BasicManager* pBasMgr = getBasicManager() )
2921 // get the standard library
2922 OUString aLibName = pBasMgr->GetName();
2923 if ( aLibName.isEmpty())
2925 aLibName = "Standard";
2927 if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2929 pBasic->SetVBAEnabled( _vbacompatmodeon );
2931 /* If in VBA compatibility mode, force creation of the VBA Globals
2932 object. Each application will create an instance of its own
2933 implementation and store it in its Basic manager. Implementations
2934 will do all necessary additional initialization, such as
2935 registering the global "This***Doc" UNO constant, starting the
2936 document events processor etc.
2938 if( mbVBACompat ) try
2940 Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
2941 Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
2942 xFactory->createInstance( OUString( "ooo.vba.VBAGlobals"));
2944 catch(const Exception& )
2950 void SAL_CALL SfxLibraryContainer::setProjectName( const OUString& _projectname ) throw (RuntimeException)
2952 msProjectName = _projectname;
2953 BasicManager* pBasMgr = getBasicManager();
2954 // Temporary HACK
2955 // Some parts of the VBA handling ( e.g. in core basic )
2956 // code expect the name of the VBA project to be set as the name of
2957 // the basic manager. Provide fail back here.
2958 if( pBasMgr )
2960 pBasMgr->SetName( msProjectName );
2964 sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() throw (RuntimeException)
2966 LibraryContainerMethodGuard aGuard( *this );
2967 return mnRunningVBAScripts;
2970 void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
2972 maVBAScriptListeners.addTypedListener( rxListener );
2975 void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
2977 maVBAScriptListeners.removeTypedListener( rxListener );
2980 void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const OUString& rModuleName ) throw (RuntimeException)
2982 // own lock for accessing the number of running scripts
2983 enterMethod();
2984 switch( nIdentifier )
2986 case vba::VBAScriptEventId::SCRIPT_STARTED:
2987 ++mnRunningVBAScripts;
2988 break;
2989 case vba::VBAScriptEventId::SCRIPT_STOPPED:
2990 --mnRunningVBAScripts;
2991 break;
2993 leaveMethod();
2995 Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref
2996 Reference< XInterface > xSender( xModel, UNO_QUERY_THROW );
2997 vba::VBAScriptEvent aEvent( xSender, nIdentifier, rModuleName );
2998 maVBAScriptListeners.notify( aEvent );
3001 // Methods XServiceInfo
3002 sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const OUString& _rServiceName )
3003 throw (RuntimeException)
3005 LibraryContainerMethodGuard aGuard( *this );
3006 Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
3007 const OUString* pSupportedServices = aSupportedServices.getConstArray();
3008 for ( sal_Int32 i=0; i<aSupportedServices.getLength(); ++i, ++pSupportedServices )
3010 if ( *pSupportedServices == _rServiceName )
3012 return sal_True;
3015 return sal_False;
3018 //============================================================================
3020 // Implementation class SfxLibrary
3022 // Ctor
3023 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3024 const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess3 >& xSFI )
3025 : OComponentHelper( m_aMutex )
3026 , mxMSF( xMSF )
3027 , mxSFI( xSFI )
3028 , mrModifiable( _rModifiable )
3029 , maNameContainer( aType )
3030 , mbLoaded( sal_True )
3031 , mbIsModified( sal_True )
3032 , mbInitialised( false )
3033 , mbLink( sal_False )
3034 , mbReadOnly( sal_False )
3035 , mbReadOnlyLink( sal_False )
3036 , mbPreload( sal_False )
3037 , mbPasswordProtected( sal_False )
3038 , mbPasswordVerified( sal_False )
3039 , mbDoc50Password( false )
3040 , mbSharedIndexFile( false )
3041 , mbExtension( false )
3045 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3046 const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess3 >& xSFI,
3047 const OUString& aLibInfoFileURL, const OUString& aStorageURL, sal_Bool ReadOnly )
3048 : OComponentHelper( m_aMutex )
3049 , mxMSF( xMSF )
3050 , mxSFI( xSFI )
3051 , mrModifiable( _rModifiable )
3052 , maNameContainer( aType )
3053 , mbLoaded( sal_False )
3054 , mbIsModified( sal_True )
3055 , mbInitialised( false )
3056 , maLibInfoFileURL( aLibInfoFileURL )
3057 , maStorageURL( aStorageURL )
3058 , mbLink( sal_True )
3059 , mbReadOnly( sal_False )
3060 , mbReadOnlyLink( ReadOnly )
3061 , mbPreload( sal_False )
3062 , mbPasswordProtected( sal_False )
3063 , mbPasswordVerified( sal_False )
3064 , mbDoc50Password( false )
3065 , mbSharedIndexFile( false )
3066 , mbExtension( false )
3070 void SfxLibrary::implSetModified( sal_Bool _bIsModified )
3072 if ( mbIsModified == _bIsModified )
3074 return;
3076 mbIsModified = _bIsModified;
3077 if ( mbIsModified )
3079 mrModifiable.setModified( sal_True );
3083 // Methods XInterface
3084 Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
3085 throw( RuntimeException )
3087 Any aRet;
3089 aRet = Any(
3090 ::cppu::queryInterface(
3091 rType,
3092 static_cast< XContainer * >( this ),
3093 static_cast< XNameContainer * >( this ),
3094 static_cast< XNameAccess * >( this ),
3095 static_cast< XElementAccess * >( this ),
3096 static_cast< XChangesNotifier * >( this ) ) );
3097 if( !aRet.hasValue() )
3099 aRet = OComponentHelper::queryInterface( rType );
3101 return aRet;
3104 // Methods XElementAccess
3105 Type SfxLibrary::getElementType()
3106 throw(RuntimeException)
3108 return maNameContainer.getElementType();
3111 sal_Bool SfxLibrary::hasElements()
3112 throw(RuntimeException)
3114 sal_Bool bRet = maNameContainer.hasElements();
3115 return bRet;
3118 // Methods XNameAccess
3119 Any SfxLibrary::getByName( const OUString& aName )
3120 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3122 impl_checkLoaded();
3124 Any aRetAny = maNameContainer.getByName( aName ) ;
3125 return aRetAny;
3128 Sequence< OUString > SfxLibrary::getElementNames()
3129 throw(RuntimeException)
3131 return maNameContainer.getElementNames();
3134 sal_Bool SfxLibrary::hasByName( const OUString& aName )
3135 throw(RuntimeException)
3137 sal_Bool bRet = maNameContainer.hasByName( aName );
3138 return bRet;
3141 void SfxLibrary::impl_checkReadOnly()
3143 if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3145 throw IllegalArgumentException(
3146 OUString("Library is readonly."),
3147 // TODO: resource
3148 *this, 0
3153 void SfxLibrary::impl_checkLoaded()
3155 if ( !mbLoaded )
3157 throw WrappedTargetException(
3158 OUString(),
3159 *this,
3160 makeAny( LibraryNotLoadedException(
3161 OUString(),
3162 *this
3168 // Methods XNameReplace
3169 void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3170 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
3172 impl_checkReadOnly();
3173 impl_checkLoaded();
3175 SAL_WARN_IF(
3176 !isLibraryElementValid(aElement), "basic",
3177 "SfxLibrary::replaceByName: replacing element is invalid!");
3179 maNameContainer.replaceByName( aName, aElement );
3180 implSetModified( sal_True );
3184 // Methods XNameContainer
3185 void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3186 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
3188 impl_checkReadOnly();
3189 impl_checkLoaded();
3191 SAL_WARN_IF(
3192 !isLibraryElementValid(aElement), "basic",
3193 "SfxLibrary::insertByName: to-be-inserted element is invalid!");
3195 maNameContainer.insertByName( aName, aElement );
3196 implSetModified( sal_True );
3199 void SfxLibrary::impl_removeWithoutChecks( const OUString& _rElementName )
3201 maNameContainer.removeByName( _rElementName );
3202 implSetModified( sal_True );
3204 // Remove element file
3205 if( !maStorageURL.isEmpty() )
3207 INetURLObject aElementInetObj( maStorageURL );
3208 aElementInetObj.insertName( _rElementName, sal_False,
3209 INetURLObject::LAST_SEGMENT, sal_True,
3210 INetURLObject::ENCODE_ALL );
3211 aElementInetObj.setExtension( maLibElementFileExtension );
3212 OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
3216 if( mxSFI->exists( aFile ) )
3218 mxSFI->kill( aFile );
3221 catch(const Exception& )
3223 DBG_UNHANDLED_EXCEPTION();
3228 void SfxLibrary::removeByName( const OUString& Name )
3229 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3231 impl_checkReadOnly();
3232 impl_checkLoaded();
3233 impl_removeWithoutChecks( Name );
3236 // XTypeProvider
3237 Sequence< Type > SfxLibrary::getTypes()
3238 throw( RuntimeException )
3240 static OTypeCollection * s_pTypes_NameContainer = 0;
3242 if( !s_pTypes_NameContainer )
3244 MutexGuard aGuard( Mutex::getGlobalMutex() );
3245 if( !s_pTypes_NameContainer )
3247 static OTypeCollection s_aTypes_NameContainer(
3248 ::getCppuType( (const Reference< XNameContainer > *)0 ),
3249 ::getCppuType( (const Reference< XContainer > *)0 ),
3250 ::getCppuType( (const Reference< XChangesNotifier > *)0 ),
3251 OComponentHelper::getTypes() );
3252 s_pTypes_NameContainer = &s_aTypes_NameContainer;
3255 return s_pTypes_NameContainer->getTypes();
3260 Sequence< sal_Int8 > SfxLibrary::getImplementationId()
3261 throw( RuntimeException )
3263 static OImplementationId * s_pId_NameContainer = 0;
3265 if( !s_pId_NameContainer )
3267 MutexGuard aGuard( Mutex::getGlobalMutex() );
3268 if( !s_pId_NameContainer )
3270 static OImplementationId s_aId_NameContainer;
3271 s_pId_NameContainer = &s_aId_NameContainer;
3274 return s_pId_NameContainer->getImplementationId();
3278 // Methods XContainer
3279 void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
3280 throw (RuntimeException)
3282 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3283 maNameContainer.addContainerListener( xListener );
3286 void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
3287 throw (RuntimeException)
3289 maNameContainer.removeContainerListener( xListener );
3292 // Methods XChangesNotifier
3293 void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
3294 throw (RuntimeException)
3296 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3297 maNameContainer.addChangesListener( xListener );
3300 void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
3301 throw (RuntimeException)
3303 maNameContainer.removeChangesListener( xListener );
3306 //============================================================================
3307 // Implementation class ScriptExtensionIterator
3309 #define sBasicLibMediaType "application/vnd.sun.star.basic-library"
3310 #define sDialogLibMediaType "application/vnd.sun.star.dialog-library"
3312 ScriptExtensionIterator::ScriptExtensionIterator( void )
3313 : m_xContext( comphelper::getProcessComponentContext() )
3314 , m_eState( USER_EXTENSIONS )
3315 , m_bUserPackagesLoaded( false )
3316 , m_bSharedPackagesLoaded( false )
3317 , m_bBundledPackagesLoaded( false )
3318 , m_iUserPackage( 0 )
3319 , m_iSharedPackage( 0 )
3320 , m_iBundledPackage( 0 )
3321 , m_pScriptSubPackageIterator( NULL )
3324 OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
3326 OUString aRetLib;
3328 while( aRetLib.isEmpty() && m_eState != END_REACHED )
3330 switch( m_eState )
3332 case USER_EXTENSIONS:
3334 Reference< deployment::XPackage > xScriptPackage =
3335 implGetNextUserScriptPackage( rbPureDialogLib );
3336 if( !xScriptPackage.is() )
3338 break;
3340 aRetLib = xScriptPackage->getURL();
3341 break;
3344 case SHARED_EXTENSIONS:
3346 Reference< deployment::XPackage > xScriptPackage =
3347 implGetNextSharedScriptPackage( rbPureDialogLib );
3348 if( !xScriptPackage.is() )
3350 break;
3352 aRetLib = xScriptPackage->getURL();
3353 break;
3355 case BUNDLED_EXTENSIONS:
3357 Reference< deployment::XPackage > xScriptPackage =
3358 implGetNextBundledScriptPackage( rbPureDialogLib );
3359 if( !xScriptPackage.is() )
3361 break;
3363 aRetLib = xScriptPackage->getURL();
3364 break;
3366 case END_REACHED:
3367 SAL_WARN(
3368 "basic",
3369 ("ScriptExtensionIterator::nextBasicOrDialogLibrary():"
3370 " Invalid case END_REACHED"));
3371 break;
3375 return aRetLib;
3378 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
3379 : m_xMainPackage( xMainPackage )
3380 , m_bIsValid( false )
3381 , m_bIsBundle( false )
3382 , m_nSubPkgCount( 0 )
3383 , m_iNextSubPkg( 0 )
3385 Reference< deployment::XPackage > xScriptPackage;
3386 if( !m_xMainPackage.is() )
3388 return;
3390 // Check if parent package is registered
3391 beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3392 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3393 bool bRegistered = false;
3394 if( option.IsPresent )
3396 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3397 if( !reg.IsAmbiguous && reg.Value )
3399 bRegistered = true;
3402 if( bRegistered )
3404 m_bIsValid = true;
3405 if( m_xMainPackage->isBundle() )
3407 m_bIsBundle = true;
3408 m_aSubPkgSeq = m_xMainPackage->getBundle( Reference<task::XAbortChannel>(),
3409 Reference<ucb::XCommandEnvironment>() );
3410 m_nSubPkgCount = m_aSubPkgSeq.getLength();
3415 Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage( bool& rbPureDialogLib )
3417 rbPureDialogLib = false;
3419 Reference< deployment::XPackage > xScriptPackage;
3420 if( !m_bIsValid )
3422 return xScriptPackage;
3424 if( m_bIsBundle )
3426 const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3427 sal_Int32 iPkg;
3428 for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3430 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3431 xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3432 if( xScriptPackage.is() )
3434 break;
3437 m_iNextSubPkg = iPkg + 1;
3439 else
3441 xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3442 m_bIsValid = false; // No more script packages
3445 return xScriptPackage;
3448 Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage ( const Reference< deployment::XPackage > xPackage,
3449 bool& rbPureDialogLib )
3451 Reference< deployment::XPackage > xScriptPackage;
3453 if( xPackage.is() )
3455 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
3456 OUString aMediaType = xPackageTypeInfo->getMediaType();
3457 if ( aMediaType == sBasicLibMediaType )
3459 xScriptPackage = xPackage;
3461 else if ( aMediaType == sDialogLibMediaType )
3463 rbPureDialogLib = true;
3464 xScriptPackage = xPackage;
3468 return xScriptPackage;
3471 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage( bool& rbPureDialogLib )
3473 Reference< deployment::XPackage > xScriptPackage;
3475 if( !m_bUserPackagesLoaded )
3479 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3480 m_aUserPackagesSeq = xManager->getDeployedExtensions(OUString("user"),
3481 Reference< task::XAbortChannel >(),
3482 Reference< ucb::XCommandEnvironment >() );
3484 catch(const com::sun::star::uno::DeploymentException& )
3486 // Special Office installations may not contain deployment code
3487 m_eState = END_REACHED;
3488 return xScriptPackage;
3491 m_bUserPackagesLoaded = true;
3494 if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3496 m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
3498 else
3500 if( m_pScriptSubPackageIterator == NULL )
3502 const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3503 Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3504 SAL_WARN_IF(
3505 !xPackage.is(), "basic",
3506 ("ScriptExtensionIterator::implGetNextUserScriptPackage():"
3507 " Invalid package"));
3508 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3511 if( m_pScriptSubPackageIterator != NULL )
3513 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3514 if( !xScriptPackage.is() )
3516 delete m_pScriptSubPackageIterator;
3517 m_pScriptSubPackageIterator = NULL;
3518 m_iUserPackage++;
3523 return xScriptPackage;
3526 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage( bool& rbPureDialogLib )
3528 Reference< deployment::XPackage > xScriptPackage;
3530 if( !m_bSharedPackagesLoaded )
3534 Reference< XExtensionManager > xSharedManager = ExtensionManager::get( m_xContext );
3535 m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions(OUString("shared"),
3536 Reference< task::XAbortChannel >(),
3537 Reference< ucb::XCommandEnvironment >() );
3539 catch(const com::sun::star::uno::DeploymentException& )
3541 // Special Office installations may not contain deployment code
3542 return xScriptPackage;
3545 m_bSharedPackagesLoaded = true;
3548 if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3550 m_eState = BUNDLED_EXTENSIONS;
3552 else
3554 if( m_pScriptSubPackageIterator == NULL )
3556 const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3557 Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3558 SAL_WARN_IF(
3559 !xPackage.is(), "basic",
3560 ("ScriptExtensionIterator::implGetNextSharedScriptPackage():"
3561 " Invalid package"));
3562 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3565 if( m_pScriptSubPackageIterator != NULL )
3567 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3568 if( !xScriptPackage.is() )
3570 delete m_pScriptSubPackageIterator;
3571 m_pScriptSubPackageIterator = NULL;
3572 m_iSharedPackage++;
3577 return xScriptPackage;
3580 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage( bool& rbPureDialogLib )
3582 Reference< deployment::XPackage > xScriptPackage;
3584 if( !m_bBundledPackagesLoaded )
3588 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3589 m_aBundledPackagesSeq = xManager->getDeployedExtensions(OUString("bundled"),
3590 Reference< task::XAbortChannel >(),
3591 Reference< ucb::XCommandEnvironment >() );
3593 catch(const com::sun::star::uno::DeploymentException& )
3595 // Special Office installations may not contain deployment code
3596 return xScriptPackage;
3599 m_bBundledPackagesLoaded = true;
3602 if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3604 m_eState = END_REACHED;
3606 else
3608 if( m_pScriptSubPackageIterator == NULL )
3610 const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3611 Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3612 SAL_WARN_IF(
3613 !xPackage.is(), "basic",
3614 ("ScriptExtensionIterator::implGetNextBundledScriptPackage():"
3615 " Invalid package"));
3616 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3619 if( m_pScriptSubPackageIterator != NULL )
3621 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3622 if( !xScriptPackage.is() )
3624 delete m_pScriptSubPackageIterator;
3625 m_pScriptSubPackageIterator = NULL;
3626 m_iBundledPackage++;
3631 return xScriptPackage;
3634 } // namespace basic
3636 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */