bump product version to 5.0.4.1
[LibreOffice.git] / basic / source / uno / namecont.cxx
blobab47f0146db2faf68fa1213cb410cd70e49a3a23
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 <config_features.h>
21 #include <config_folders.h>
23 #include <com/sun/star/container/XNameContainer.hpp>
24 #include <com/sun/star/container/XContainer.hpp>
25 #include <com/sun/star/embed/ElementModes.hpp>
26 #include <com/sun/star/embed/XTransactedObject.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/lang/XServiceInfo.hpp>
29 #include <com/sun/star/ucb/ContentCreationException.hpp>
30 #include <vcl/svapp.hxx>
31 #include <osl/mutex.hxx>
32 #include <tools/errinf.hxx>
33 #include <rtl/ustring.hxx>
34 #include <rtl/strbuf.hxx>
35 #include <comphelper/getexpandeduri.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/anytostring.hxx>
39 #include "namecont.hxx"
40 #include <basic/basicmanagerrepository.hxx>
41 #include <tools/diagnose_ex.h>
42 #include <tools/urlobj.hxx>
43 #include <unotools/streamwrap.hxx>
44 #include <unotools/pathoptions.hxx>
45 #include <svtools/sfxecode.hxx>
46 #include <svtools/ehdl.hxx>
47 #include <basic/basmgr.hxx>
48 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
49 #include <com/sun/star/xml/sax/Parser.hpp>
50 #include <com/sun/star/xml/sax/InputSource.hpp>
51 #include <com/sun/star/io/XOutputStream.hpp>
52 #include <com/sun/star/xml/sax/Writer.hpp>
53 #include <com/sun/star/io/XInputStream.hpp>
54 #include <com/sun/star/io/XActiveDataSource.hpp>
55 #include <com/sun/star/beans/XPropertySet.hpp>
56 #include <com/sun/star/uno/DeploymentException.hpp>
57 #include <com/sun/star/lang/DisposedException.hpp>
58 #include <com/sun/star/script/LibraryNotLoadedException.hpp>
59 #include <com/sun/star/script/vba/VBAScriptEventId.hpp>
60 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
61 #include <com/sun/star/util/PathSubstitution.hpp>
62 #include <com/sun/star/deployment/ExtensionManager.hpp>
63 #include <comphelper/storagehelper.hxx>
64 #include <cppuhelper/exc_hlp.hxx>
65 #include <cppuhelper/queryinterface.hxx>
66 #include <cppuhelper/supportsservice.hxx>
67 #include <basic/sbmod.hxx>
68 #include <boost/scoped_ptr.hpp>
70 namespace basic
73 using namespace com::sun::star::document;
74 using namespace com::sun::star::container;
75 using namespace com::sun::star::uno;
76 using namespace com::sun::star::lang;
77 using namespace com::sun::star::io;
78 using namespace com::sun::star::ucb;
79 using namespace com::sun::star::script;
80 using namespace com::sun::star::beans;
81 using namespace com::sun::star::xml::sax;
82 using namespace com::sun::star::util;
83 using namespace com::sun::star::task;
84 using namespace com::sun::star::embed;
85 using namespace com::sun::star::frame;
86 using namespace com::sun::star::deployment;
87 using namespace com::sun::star;
88 using namespace cppu;
89 using namespace osl;
91 using com::sun::star::uno::Reference;
93 // #i34411: Flag for error handling during migration
94 static bool GbMigrationSuppressErrors = false;
97 // Implementation class NameContainer
99 // Methods XElementAccess
100 Type NameContainer::getElementType()
101 throw(RuntimeException, std::exception)
103 return mType;
106 sal_Bool NameContainer::hasElements()
107 throw(RuntimeException, std::exception)
109 bool bRet = (mnElementCount > 0);
110 return bRet;
113 // Methods XNameAccess
114 Any NameContainer::getByName( const OUString& aName )
115 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
117 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
118 if( aIt == mHashMap.end() )
120 throw NoSuchElementException();
122 sal_Int32 iHashResult = (*aIt).second;
123 Any aRetAny = mValues.getConstArray()[ iHashResult ];
124 return aRetAny;
127 Sequence< OUString > NameContainer::getElementNames()
128 throw(RuntimeException, std::exception)
130 return mNames;
133 sal_Bool NameContainer::hasByName( const OUString& aName )
134 throw(RuntimeException, std::exception)
136 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
137 bool bRet = ( aIt != mHashMap.end() );
138 return bRet;
142 // Methods XNameReplace
143 void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
144 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
146 Type aAnyType = aElement.getValueType();
147 if( mType != aAnyType )
149 throw IllegalArgumentException();
151 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
152 if( aIt == mHashMap.end() )
154 throw NoSuchElementException();
156 sal_Int32 iHashResult = (*aIt).second;
157 Any aOldElement = mValues.getConstArray()[ iHashResult ];
158 mValues.getArray()[ iHashResult ] = aElement;
161 // Fire event
162 if( maContainerListeners.getLength() > 0 )
164 ContainerEvent aEvent;
165 aEvent.Source = mpxEventSource;
166 aEvent.Accessor <<= aName;
167 aEvent.Element = aElement;
168 aEvent.ReplacedElement = aOldElement;
169 maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent );
172 /* After the container event has been fired (one listener will update the
173 core Basic manager), fire change event. Listeners can rely that the
174 Basic source code of the core Basic manager is up-to-date. */
175 if( maChangesListeners.getLength() > 0 )
177 ChangesEvent aEvent;
178 aEvent.Source = mpxEventSource;
179 aEvent.Base <<= aEvent.Source;
180 aEvent.Changes.realloc( 1 );
181 aEvent.Changes[ 0 ].Accessor <<= aName;
182 aEvent.Changes[ 0 ].Element <<= aElement;
183 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
184 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
188 void NameContainer::insertCheck(const OUString& aName, const Any& aElement)
189 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
191 NameContainerNameMap::iterator aIt = mHashMap.find(aName);
192 if( aIt != mHashMap.end() )
194 throw ElementExistException();
196 insertNoCheck(aName, aElement);
199 void NameContainer::insertNoCheck(const OUString& aName, const Any& aElement)
200 throw(IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
202 Type aAnyType = aElement.getValueType();
203 if( mType != aAnyType )
205 throw IllegalArgumentException();
208 sal_Int32 nCount = mNames.getLength();
209 mNames.realloc( nCount + 1 );
210 mValues.realloc( nCount + 1 );
211 mNames.getArray()[ nCount ] = aName;
212 mValues.getArray()[ nCount ] = aElement;
214 mHashMap[ aName ] = nCount;
215 mnElementCount++;
217 // Fire event
218 if( maContainerListeners.getLength() > 0 )
220 ContainerEvent aEvent;
221 aEvent.Source = mpxEventSource;
222 aEvent.Accessor <<= aName;
223 aEvent.Element = aElement;
224 maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
227 /* After the container event has been fired (one listener will update the
228 core Basic manager), fire change event. Listeners can rely that the
229 Basic source code of the core Basic manager is up-to-date. */
230 if( maChangesListeners.getLength() > 0 )
232 ChangesEvent aEvent;
233 aEvent.Source = mpxEventSource;
234 aEvent.Base <<= aEvent.Source;
235 aEvent.Changes.realloc( 1 );
236 aEvent.Changes[ 0 ].Accessor <<= aName;
237 aEvent.Changes[ 0 ].Element <<= aElement;
238 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
242 // Methods XNameContainer
243 void NameContainer::insertByName( const OUString& aName, const Any& aElement )
244 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
246 insertCheck(aName, aElement);
249 void NameContainer::removeByName( const OUString& aName )
250 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
252 NameContainerNameMap::iterator aIt = mHashMap.find( aName );
253 if( aIt == mHashMap.end() )
255 OUString sMessage = "\"" + aName + "\" not found";
256 throw NoSuchElementException(sMessage);
259 sal_Int32 iHashResult = (*aIt).second;
260 Any aOldElement = mValues.getConstArray()[ iHashResult ];
261 mHashMap.erase( aIt );
262 sal_Int32 iLast = mNames.getLength() - 1;
263 if( iLast != iHashResult )
265 OUString* pNames = mNames.getArray();
266 Any* pValues = mValues.getArray();
267 pNames[ iHashResult ] = pNames[ iLast ];
268 pValues[ iHashResult ] = pValues[ iLast ];
269 mHashMap[ pNames[ iHashResult ] ] = iHashResult;
271 mNames.realloc( iLast );
272 mValues.realloc( iLast );
273 mnElementCount--;
275 // Fire event
276 if( maContainerListeners.getLength() > 0 )
278 ContainerEvent aEvent;
279 aEvent.Source = mpxEventSource;
280 aEvent.Accessor <<= aName;
281 aEvent.Element = aOldElement;
282 maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
285 /* After the container event has been fired (one listener will update the
286 core Basic manager), fire change event. Listeners can rely that the
287 Basic source code of the core Basic manager is up-to-date. */
288 if( maChangesListeners.getLength() > 0 )
290 ChangesEvent aEvent;
291 aEvent.Source = mpxEventSource;
292 aEvent.Base <<= aEvent.Source;
293 aEvent.Changes.realloc( 1 );
294 aEvent.Changes[ 0 ].Accessor <<= aName;
295 // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
296 aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
297 maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
302 // Methods XContainer
303 void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
304 throw (RuntimeException, std::exception)
306 if( !xListener.is() )
308 throw RuntimeException("addContainerListener called with null xListener",
309 static_cast< cppu::OWeakObject * >(this));
311 maContainerListeners.addInterface( Reference<XInterface>(xListener, UNO_QUERY) );
314 void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
315 throw (RuntimeException, std::exception)
317 if( !xListener.is() )
319 throw RuntimeException();
321 maContainerListeners.removeInterface( Reference<XInterface>(xListener, UNO_QUERY) );
324 // Methods XChangesNotifier
325 void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener )
326 throw (RuntimeException, std::exception)
328 if( !xListener.is() )
330 throw RuntimeException();
332 maChangesListeners.addInterface( Reference<XInterface>(xListener, UNO_QUERY) );
335 void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener )
336 throw (RuntimeException, std::exception)
338 if( !xListener.is() )
340 throw RuntimeException();
342 maChangesListeners.removeInterface( Reference<XInterface>(xListener, UNO_QUERY) );
346 // ModifiableHelper
348 void ModifiableHelper::setModified( bool _bModified )
350 if ( _bModified == mbModified )
352 return;
354 mbModified = _bModified;
356 if ( m_aModifyListeners.getLength() == 0 )
358 return;
360 EventObject aModifyEvent( m_rEventSource );
361 m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
366 VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex& rMutex ) :
367 VBAScriptListenerContainer_BASE( rMutex )
371 bool VBAScriptListenerContainer::implTypedNotify( const Reference< vba::XVBAScriptListener >& rxListener, const vba::VBAScriptEvent& rEvent )
372 throw (Exception)
374 rxListener->notifyVBAScriptEvent( rEvent );
375 return true; // notify all other listeners too
378 // Ctor
379 SfxLibraryContainer::SfxLibraryContainer()
380 : SfxLibraryContainer_BASE( maMutex )
382 , maVBAScriptListeners( maMutex )
383 , mnRunningVBAScripts( 0 )
384 , mbVBACompat( false )
385 , maModifiable( *this, maMutex )
386 , maNameContainer( cppu::UnoType<XNameAccess>::get())
387 , mbOldInfoFormat( false )
388 , mbOasis2OOoFormat( false )
389 , mpBasMgr( NULL )
390 , mbOwnBasMgr( false )
391 , meInitMode(DEFAULT)
393 mxContext = comphelper::getProcessComponentContext();
395 mxSFI = ucb::SimpleFileAccess::create( mxContext );
397 mxStringSubstitution = util::PathSubstitution::create( mxContext );
400 SfxLibraryContainer::~SfxLibraryContainer()
402 if( mbOwnBasMgr )
404 BasicManager::LegacyDeleteBasicManager( mpBasMgr );
408 void SfxLibraryContainer::checkDisposed() const
410 if ( isDisposed() )
412 throw DisposedException( OUString(),
413 *const_cast< SfxLibraryContainer* >( this ) );
417 void SfxLibraryContainer::enterMethod()
419 Application::GetSolarMutex().acquire();
420 checkDisposed();
423 void SfxLibraryContainer::leaveMethod()
425 Application::GetSolarMutex().release();
428 BasicManager* SfxLibraryContainer::getBasicManager()
432 if ( mpBasMgr )
434 return mpBasMgr;
436 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
437 SAL_WARN_IF(
438 !xDocument.is(), "basic",
439 ("SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager"
440 " without document!"));
441 if ( xDocument.is() )
443 mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );
446 catch (const css::ucb::ContentCreationException& e)
448 SAL_WARN( "basic", "SfxLibraryContainer::getBasicManager : Caught exception: " << e.Message );
450 return mpBasMgr;
453 // Methods XStorageBasedLibraryContainer
454 Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage() throw (RuntimeException, std::exception)
456 LibraryContainerMethodGuard aGuard( *this );
457 return mxStorage;
460 void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage )
461 throw (IllegalArgumentException, RuntimeException, std::exception)
463 LibraryContainerMethodGuard aGuard( *this );
464 if ( !_rxRootStorage.is() )
466 throw IllegalArgumentException();
468 mxStorage = _rxRootStorage;
469 onNewRootStorage();
472 void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage )
473 throw (IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
475 LibraryContainerMethodGuard aGuard( *this );
476 if ( !_rxRootStorage.is() )
478 throw IllegalArgumentException();
482 storeLibraries_Impl( _rxRootStorage, true );
484 catch( const Exception& )
486 throw WrappedTargetException( OUString(),
487 *this, ::cppu::getCaughtException() );
492 // Methods XModifiable
493 sal_Bool SfxLibraryContainer::isModified()
494 throw (RuntimeException, std::exception)
496 LibraryContainerMethodGuard aGuard( *this );
497 if ( maModifiable.isModified() )
499 return sal_True;
501 // the library container is not modified, go through the libraries and check whether they are modified
502 Sequence< OUString > aNames = maNameContainer.getElementNames();
503 const OUString* pNames = aNames.getConstArray();
504 sal_Int32 nNameCount = aNames.getLength();
506 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
508 OUString aName = pNames[ i ];
511 SfxLibrary* pImplLib = getImplLib( aName );
512 if( pImplLib->isModified() )
514 if ( aName == "Standard" )
516 // this is a workaround that has to be implemented because
517 // empty standard library should stay marked as modified
518 // but should not be treated as modified while it is empty
519 if ( pImplLib->hasElements() )
520 return sal_True;
522 else
524 return sal_True;
528 catch(const css::container::NoSuchElementException&)
533 return sal_False;
536 void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified )
537 throw (PropertyVetoException, RuntimeException, std::exception)
539 LibraryContainerMethodGuard aGuard( *this );
540 maModifiable.setModified( _bModified );
543 void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener )
544 throw (RuntimeException, std::exception)
546 LibraryContainerMethodGuard aGuard( *this );
547 maModifiable.addModifyListener( _rxListener );
550 void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener )
551 throw (RuntimeException, std::exception)
553 LibraryContainerMethodGuard aGuard( *this );
554 maModifiable.removeModifyListener( _rxListener );
557 // Methods XPersistentLibraryContainer
558 Any SAL_CALL SfxLibraryContainer::getRootLocation() throw (RuntimeException, std::exception)
560 LibraryContainerMethodGuard aGuard( *this );
561 return makeAny( getRootStorage() );
564 OUString SAL_CALL SfxLibraryContainer::getContainerLocationName() throw (RuntimeException, std::exception)
566 LibraryContainerMethodGuard aGuard( *this );
567 return maLibrariesDir;
570 void SAL_CALL SfxLibraryContainer::storeLibraries( )
571 throw (WrappedTargetException, RuntimeException, std::exception)
573 LibraryContainerMethodGuard aGuard( *this );
576 storeLibraries_Impl( mxStorage, mxStorage.is() );
577 // we need to store *all* libraries if and only if we are based on a storage:
578 // in this case, storeLibraries_Impl will remove the source storage, after loading
579 // all libraries, so we need to force them to be stored, again
581 catch( const Exception& )
583 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
587 static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
588 const INetURLObject& rTargetFolderInetObj,
589 const OUString& rCheckFileName,
590 const OUString& rCheckExtension,
591 Reference< XSimpleFileAccess3 > xSFI )
593 INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
594 aTargetFolderInetObj.insertName( rCheckFileName, true, INetURLObject::LAST_SEGMENT,
595 true, INetURLObject::ENCODE_ALL );
596 aTargetFolderInetObj.setExtension( rCheckExtension );
597 OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
598 if( !xSFI->exists( aTargetFile ) )
600 INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
601 aSourceFolderInetObj.insertName( rCheckFileName, true, INetURLObject::LAST_SEGMENT,
602 true, INetURLObject::ENCODE_ALL );
603 aSourceFolderInetObj.setExtension( rCheckExtension );
604 OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
605 xSFI->copy( aSourceFile, aTargetFile );
609 static void createVariableURL( OUString& rStr, const OUString& rLibName,
610 const OUString& rInfoFileName, bool bUser )
612 if( bUser )
614 rStr = "$(USER)/basic/";
616 else
618 rStr = "$(INST)/" LIBO_SHARE_FOLDER "/basic/";
620 rStr += rLibName;
621 rStr += "/";
622 rStr += rInfoFileName;
623 rStr += ".xlb/";
626 void SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
628 // this might be called from within the ctor, and the impl_init might (indirectly) create
629 // an UNO reference to ourself.
630 // Ensure that we're not destroyed while we're in here
631 osl_atomic_increment( &m_refCount );
632 init_Impl( rInitialDocumentURL, rxInitialStorage );
633 osl_atomic_decrement( &m_refCount );
636 void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL,
637 const uno::Reference< embed::XStorage >& rxInitialStorage )
639 uno::Reference< embed::XStorage > xStorage = rxInitialStorage;
641 maInitialDocumentURL = rInitialDocumentURL;
642 maInfoFileName = OUString::createFromAscii( getInfoFileName() );
643 maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
644 maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
645 maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );
647 meInitMode = DEFAULT;
648 INetURLObject aInitUrlInetObj( maInitialDocumentURL );
649 OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
650 if( !aInitFileName.isEmpty() )
652 // We need a BasicManager to avoid problems
653 StarBASIC* pBas = new StarBASIC();
654 mpBasMgr = new BasicManager( pBas );
655 mbOwnBasMgr = true;
657 OUString aExtension = aInitUrlInetObj.getExtension();
658 if( aExtension == "xlc" )
660 meInitMode = CONTAINER_INIT_FILE;
661 INetURLObject aLibPathInetObj( aInitUrlInetObj );
662 aLibPathInetObj.removeSegment();
663 maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
665 else if( aExtension == "xlb" )
667 meInitMode = LIBRARY_INIT_FILE;
668 uno::Reference< embed::XStorage > xDummyStor;
669 ::xmlscript::LibDescriptor aLibDesc;
670 implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
671 return;
673 else
675 // Decide between old and new document
676 bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
677 if ( bOldStorage )
679 meInitMode = OLD_BASIC_STORAGE;
680 importFromOldStorage( aInitFileName );
681 return;
683 else
685 meInitMode = OFFICE_DOCUMENT;
688 xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
690 catch (const uno::Exception& )
692 // TODO: error handling
697 else
699 // Default paths
700 maLibraryPath = SvtPathOptions().GetBasicPath();
703 Reference< XParser > xParser = xml::sax::Parser::create(mxContext);
705 uno::Reference< io::XInputStream > xInput;
707 mxStorage = xStorage;
708 bool bStorage = mxStorage.is();
711 // #110009: Scope to force the StorageRefs to be destructed and
712 // so the streams to be closed before the preload operation
715 uno::Reference< embed::XStorage > xLibrariesStor;
716 OUString aFileName;
718 int nPassCount = 1;
719 if( !bStorage && meInitMode == DEFAULT )
721 nPassCount = 2;
723 for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
725 if( bStorage )
727 SAL_WARN_IF(
728 meInitMode != DEFAULT && meInitMode != OFFICE_DOCUMENT, "basic",
729 "Wrong InitMode for document");
732 uno::Reference< io::XStream > xStream;
733 xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
735 if ( xLibrariesStor.is() )
737 aFileName = maInfoFileName;
738 aFileName += "-lc.xml";
742 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
744 catch(const uno::Exception& )
747 if( !xStream.is() )
749 mbOldInfoFormat = true;
751 // Check old version
752 aFileName = maOldInfoFileName;
753 aFileName += ".xml";
757 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
759 catch(const uno::Exception& )
762 if( !xStream.is() )
764 // Check for EA2 document version with wrong extensions
765 aFileName = maOldInfoFileName;
766 aFileName += ".xli";
767 xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
772 if ( xStream.is() )
774 xInput = xStream->getInputStream();
777 catch(const uno::Exception& )
779 // TODO: error handling?
782 else
784 boost::scoped_ptr<INetURLObject> pLibInfoInetObj;
785 if( meInitMode == CONTAINER_INIT_FILE )
787 aFileName = aInitFileName;
789 else
791 if( nPass == 1 )
793 pLibInfoInetObj.reset(new INetURLObject( maLibraryPath.getToken(0, (sal_Unicode)';') ));
795 else
797 pLibInfoInetObj.reset(new INetURLObject( maLibraryPath.getToken(1, (sal_Unicode)';') ));
799 pLibInfoInetObj->insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
800 pLibInfoInetObj->setExtension( OUString("xlc") );
801 aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
806 xInput = mxSFI->openFileRead( aFileName );
808 catch(const Exception& )
810 // Silently tolerate empty or missing files
811 xInput.clear();
814 // Old variant?
815 if( !xInput.is() && nPass == 0 )
817 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
818 aLibInfoInetObj.insertName( maOldInfoFileName, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
819 aLibInfoInetObj.setExtension( OUString( "xli") );
820 aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
824 xInput = mxSFI->openFileRead( aFileName );
825 mbOldInfoFormat = true;
827 catch(const Exception& )
829 xInput.clear();
834 if( xInput.is() )
836 InputSource source;
837 source.aInputStream = xInput;
838 source.sSystemId = aFileName;
840 // start parsing
841 boost::scoped_ptr< ::xmlscript::LibDescriptorArray> pLibArray(new ::xmlscript::LibDescriptorArray());
845 xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray.get() ) );
846 xParser->parseStream( source );
848 catch ( const xml::sax::SAXException& e )
850 SAL_WARN("basic", e.Message);
851 return;
853 catch ( const io::IOException& e )
855 SAL_WARN("basic", e.Message);
856 return;
859 sal_Int32 nLibCount = pLibArray->mnLibCount;
860 for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
862 ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
864 // Check storage URL
865 OUString aStorageURL = rLib.aStorageURL;
866 if( !bStorage && aStorageURL.isEmpty() && nPass == 0 )
868 OUString aLibraryPath;
869 if( meInitMode == CONTAINER_INIT_FILE )
871 aLibraryPath = maLibraryPath;
873 else
875 aLibraryPath = maLibraryPath.getToken(1, (sal_Unicode)';');
877 INetURLObject aInetObj( aLibraryPath );
879 aInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT,
880 true, INetURLObject::ENCODE_ALL );
881 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
882 if( mxSFI->isFolder( aLibDirPath ) )
884 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
885 maModifiable.setModified( true );
887 else if( rLib.bLink )
889 // Check "share" path
890 INetURLObject aShareInetObj( maLibraryPath.getToken(0, (sal_Unicode)';') );
891 aShareInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT,
892 true, INetURLObject::ENCODE_ALL );
893 OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
894 if( mxSFI->isFolder( aShareLibDirPath ) )
896 createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
897 maModifiable.setModified( true );
899 else
901 // #i25537: Ignore lib if library folder does not really exist
902 continue;
907 OUString aLibName = rLib.aName;
909 // If the same library name is used by the shared and the
910 // user lib container index files the user file wins
911 if( nPass == 1 && hasByName( aLibName ) )
913 continue;
915 SfxLibrary* pImplLib;
916 if( rLib.bLink )
918 Reference< XNameAccess > xLib =
919 createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
920 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
922 else
924 Reference< XNameContainer > xLib = createLibrary( aLibName );
925 pImplLib = static_cast< SfxLibrary* >( xLib.get() );
926 pImplLib->mbLoaded = false;
927 pImplLib->mbReadOnly = rLib.bReadOnly;
928 if( !bStorage )
930 checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
931 pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
934 maModifiable.setModified( false );
936 // Read library info files
937 if( !mbOldInfoFormat )
939 uno::Reference< embed::XStorage > xLibraryStor;
940 if( !pImplLib->mbInitialised && bStorage )
944 xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
945 embed::ElementModes::READ );
947 catch(const uno::Exception& )
949 #if OSL_DEBUG_LEVEL > 0
950 Any aError( ::cppu::getCaughtException() );
951 SAL_WARN(
952 "basic",
953 "couldn't open sub storage for library \""
954 << rLib.aName << "\". Exception: "
955 << comphelper::anyToString(aError));
956 #endif
960 // Link is already initialised in createLibraryLink()
961 if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
963 OUString aIndexFileName;
964 bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
965 SAL_WARN_IF(
966 bLoaded && aLibName != rLib.aName, "basic",
967 ("Different library names in library container and"
968 " library info files!"));
969 if( GbMigrationSuppressErrors && !bLoaded )
971 removeLibrary( aLibName );
975 else if( !bStorage )
977 // Write new index file immediately because otherwise
978 // the library elements will be lost when storing into
979 // the new info format
980 uno::Reference< embed::XStorage > xTmpStorage;
981 implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
984 implImportLibDescriptor( pImplLib, rLib );
986 if( nPass == 1 )
988 pImplLib->mbSharedIndexFile = true;
989 pImplLib->mbReadOnly = true;
993 // Keep flag for documents to force writing the new index files
994 if( !bStorage )
996 mbOldInfoFormat = false;
1001 // #110009: END Scope to force the StorageRefs to be destructed
1004 if( !bStorage && meInitMode == DEFAULT )
1008 implScanExtensions();
1010 catch(const uno::Exception& )
1012 // TODO: error handling?
1013 SAL_WARN("basic", "Cannot access extensions!");
1017 // Preload?
1019 Sequence< OUString > aNames = maNameContainer.getElementNames();
1020 const OUString* pNames = aNames.getConstArray();
1021 sal_Int32 nNameCount = aNames.getLength();
1022 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1024 OUString aName = pNames[ i ];
1025 SfxLibrary* pImplLib = getImplLib( aName );
1026 if( pImplLib->mbPreload )
1028 loadLibrary( aName );
1033 if( meInitMode == DEFAULT )
1035 INetURLObject aUserBasicInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
1036 OUString aStandardStr("Standard");
1038 INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
1039 aPrevUserBasicInetObj_1.removeSegment();
1040 INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
1041 aPrevUserBasicInetObj_1.Append( "__basic_80" );
1042 aPrevUserBasicInetObj_2.Append( "__basic_80_2" );
1044 // #i93163
1045 bool bCleanUp = false;
1048 INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
1049 OUString aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1050 if( mxSFI->isFolder( aPrevFolder ) )
1052 // Check if Standard folder exists and is complete
1053 INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
1054 aUserBasicStandardInetObj.insertName( aStandardStr, true, INetURLObject::LAST_SEGMENT,
1055 true, INetURLObject::ENCODE_ALL );
1056 INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
1057 aPrevUserBasicStandardInetObj.insertName( aStandardStr, true, INetURLObject::LAST_SEGMENT,
1058 true, INetURLObject::ENCODE_ALL );
1059 OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1060 if( mxSFI->isFolder( aPrevStandardFolder ) )
1062 OUString aXlbExtension( "xlb" );
1063 OUString aCheckFileName;
1065 // Check if script.xlb exists
1066 aCheckFileName = "script";
1067 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1068 aPrevUserBasicStandardInetObj,
1069 aCheckFileName, aXlbExtension, mxSFI );
1071 // Check if dialog.xlb exists
1072 aCheckFileName = "dialog";
1073 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1074 aPrevUserBasicStandardInetObj,
1075 aCheckFileName, aXlbExtension, mxSFI );
1077 // Check if module1.xba exists
1078 OUString aXbaExtension("xba");
1079 aCheckFileName = "Module1";
1080 checkAndCopyFileImpl( aUserBasicStandardInetObj,
1081 aPrevUserBasicStandardInetObj,
1082 aCheckFileName, aXbaExtension, mxSFI );
1084 else
1086 OUString aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
1087 mxSFI->copy( aStandardFolder, aPrevStandardFolder );
1090 OUString aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1091 mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
1093 else
1095 aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
1096 aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1098 if( mxSFI->isFolder( aPrevFolder ) )
1100 SfxLibraryContainer* pPrevCont = createInstanceImpl();
1101 Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
1103 // Rename previous basic folder to make storage URLs correct during initialisation
1104 OUString aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
1105 INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
1106 aUserBasicTmpInetObj.removeSegment();
1107 aUserBasicTmpInetObj.Append( "__basic_tmp" );
1108 OUString aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
1110 mxSFI->move( aFolderUserBasic, aFolderTmp );
1113 mxSFI->move( aPrevFolder, aFolderUserBasic );
1115 catch(const Exception& )
1117 // Move back user/basic folder
1120 mxSFI->kill( aFolderUserBasic );
1122 catch(const Exception& )
1124 mxSFI->move( aFolderTmp, aFolderUserBasic );
1125 throw;
1128 INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
1129 aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT,
1130 true, INetURLObject::ENCODE_ALL );
1131 aPrevUserBasicLibInfoInetObj.setExtension( OUString("xlc"));
1132 OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
1133 Sequence<Any> aInitSeq( 1 );
1134 aInitSeq.getArray()[0] <<= aLibInfoFileName;
1135 GbMigrationSuppressErrors = true;
1136 pPrevCont->initialize( aInitSeq );
1137 GbMigrationSuppressErrors = false;
1139 // Rename folders back
1140 mxSFI->move( aFolderUserBasic, aPrevFolder );
1141 mxSFI->move( aFolderTmp, aFolderUserBasic );
1143 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
1144 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
1145 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
1146 OUString aInstSearchStr("$(INST)");
1148 Sequence< OUString > aNames = pPrevCont->getElementNames();
1149 const OUString* pNames = aNames.getConstArray();
1150 sal_Int32 nNameCount = aNames.getLength();
1152 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1154 OUString aLibName = pNames[ i ];
1155 if( hasByName( aLibName ) )
1157 if( aLibName == aStandardStr )
1159 SfxLibrary* pImplLib = getImplLib( aStandardStr );
1160 OUString aStandardFolder = pImplLib->maStorageURL;
1161 mxSFI->kill( aStandardFolder );
1163 else
1165 continue;
1169 SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
1170 if( pImplLib->mbLink )
1172 OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
1173 bool bCreateLink = true;
1174 if( aStorageURL.indexOf( aUserSearchStr ) != -1 ||
1175 aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
1176 aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
1177 aStorageURL.indexOf( aInstSearchStr ) != -1 )
1179 bCreateLink = false;
1181 if( bCreateLink )
1183 createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
1186 else
1188 // Move folder if not already done
1189 INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
1190 aUserBasicLibFolderInetObj.Append( aLibName );
1191 OUString aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1193 INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
1194 aPrevUserBasicLibFolderInetObj.Append( aLibName );
1195 OUString aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
1197 if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
1199 mxSFI->move( aPrevLibFolder, aLibFolder );
1202 if( aLibName == aStandardStr )
1204 maNameContainer.removeByName( aLibName );
1207 // Create library
1208 Reference< XNameContainer > xLib = createLibrary( aLibName );
1209 SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
1210 pNewLib->mbLoaded = false;
1211 pNewLib->implSetModified( false );
1212 checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
1213 pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
1215 uno::Reference< embed::XStorage > xDummyStor;
1216 ::xmlscript::LibDescriptor aLibDesc;
1217 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
1218 implImportLibDescriptor( pNewLib, aLibDesc );
1221 mxSFI->kill( aPrevFolder );
1224 catch(const Exception& e)
1226 bCleanUp = true;
1227 SAL_WARN("basic", "Upgrade of Basic installation failed somehow: " << e.Message);
1230 // #i93163
1231 if( bCleanUp )
1233 INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
1234 aPrevUserBasicInetObj_Err.removeSegment();
1235 aPrevUserBasicInetObj_Err.Append( "__basic_80_err" );
1236 OUString aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );
1238 bool bSaved = false;
1241 OUString aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
1242 if( mxSFI->isFolder( aPrevFolder_1 ) )
1244 mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
1245 bSaved = true;
1248 catch(const Exception& )
1252 OUString aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
1253 if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
1255 mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
1257 else
1259 mxSFI->kill( aPrevFolder_2 );
1262 catch(const Exception& )
1268 void SfxLibraryContainer::implScanExtensions()
1270 #if HAVE_FEATURE_EXTENSIONS
1271 ScriptExtensionIterator aScriptIt;
1272 OUString aLibURL;
1274 bool bPureDialogLib = false;
1275 while ( !(aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).isEmpty())
1277 if( bPureDialogLib && maInfoFileName == "script" )
1279 continue;
1281 // Extract lib name
1282 sal_Int32 nLen = aLibURL.getLength();
1283 sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
1284 sal_Int32 nReduceCopy = 0;
1285 if( indexLastSlash == nLen - 1 )
1287 nReduceCopy = 1;
1288 indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
1291 OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );
1293 // If a library of the same exists the existing library wins
1294 if( hasByName( aLibName ) )
1296 continue;
1298 // Add index file to URL
1299 OUString aIndexFileURL = aLibURL;
1300 if( nReduceCopy == 0 )
1302 aIndexFileURL += "/";
1304 aIndexFileURL += maInfoFileName + ".xlb";
1306 // Create link
1307 const bool bReadOnly = false;
1308 Reference< XNameAccess > xLib = createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
1310 #endif
1313 // Handle maLibInfoFileURL and maStorageURL correctly
1314 void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
1315 OUString& aLibInfoFileURL, OUString& aStorageURL,
1316 OUString& aUnexpandedStorageURL )
1318 OUString aExpandedSourceURL = expand_url( aSourceURL );
1319 if( aExpandedSourceURL != aSourceURL )
1321 aUnexpandedStorageURL = aSourceURL;
1323 INetURLObject aInetObj( aExpandedSourceURL );
1324 OUString aExtension = aInetObj.getExtension();
1325 if( aExtension == "xlb" )
1327 // URL to xlb file
1328 aLibInfoFileURL = aExpandedSourceURL;
1329 aInetObj.removeSegment();
1330 aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1332 else
1334 // URL to library folder
1335 aStorageURL = aExpandedSourceURL;
1336 aInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
1337 aInetObj.setExtension( OUString("xlb") );
1338 aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1342 SfxLibrary* SfxLibraryContainer::getImplLib( const OUString& rLibraryName )
1344 Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
1345 Reference< XNameAccess > xNameAccess;
1346 aLibAny >>= xNameAccess;
1347 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
1348 return pImplLib;
1352 // Storing with password encryption
1354 // Empty implementation, avoids unnecessary implementation in dlgcont.cxx
1355 bool SfxLibraryContainer::implStorePasswordLibrary( SfxLibrary*,
1356 const OUString&,
1357 const uno::Reference< embed::XStorage >&,
1358 const uno::Reference< task::XInteractionHandler >& )
1360 return false;
1363 bool SfxLibraryContainer::implStorePasswordLibrary(
1364 SfxLibrary* /*pLib*/,
1365 const OUString& /*aName*/,
1366 const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
1367 const OUString& /*aTargetURL*/,
1368 const Reference< XSimpleFileAccess3 >& /*xToUseSFI*/,
1369 const uno::Reference< task::XInteractionHandler >& )
1371 return false;
1374 bool SfxLibraryContainer::implLoadPasswordLibrary(
1375 SfxLibrary* /*pLib*/,
1376 const OUString& /*Name*/,
1377 bool /*bVerifyPasswordOnly*/ )
1378 throw(WrappedTargetException, RuntimeException)
1380 return true;
1383 OUString SfxLibraryContainer::createAppLibraryFolder( SfxLibrary* pLib, const OUString& aName )
1385 OUString aLibDirPath = pLib->maStorageURL;
1386 if( aLibDirPath.isEmpty() )
1388 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
1389 aInetObj.insertName( aName, true, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
1390 checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
1391 pLib->maStorageURL, pLib->maUnexpandedStorageURL );
1392 aLibDirPath = pLib->maStorageURL;
1395 if( !mxSFI->isFolder( aLibDirPath ) )
1399 mxSFI->createFolder( aLibDirPath );
1401 catch(const Exception& )
1405 return aLibDirPath;
1408 // Storing
1409 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1410 const OUString& aName,
1411 const uno::Reference< embed::XStorage >& xStorage )
1413 OUString aDummyLocation;
1414 Reference< XSimpleFileAccess3 > xDummySFA;
1415 Reference< XInteractionHandler > xDummyHandler;
1416 implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
1419 // New variant for library export
1420 void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
1421 const OUString& aName,
1422 const uno::Reference< embed::XStorage >& xStorage,
1423 const OUString& aTargetURL,
1424 const Reference< XSimpleFileAccess3 >& rToUseSFI,
1425 const Reference< XInteractionHandler >& xHandler )
1427 bool bLink = pLib->mbLink;
1428 bool bStorage = xStorage.is() && !bLink;
1430 Sequence< OUString > aElementNames = pLib->getElementNames();
1431 sal_Int32 nNameCount = aElementNames.getLength();
1432 const OUString* pNames = aElementNames.getConstArray();
1434 if( bStorage )
1436 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1438 OUString aElementName = pNames[ i ];
1439 OUString aStreamName = aElementName;
1440 aStreamName += ".xml";
1442 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1444 SAL_WARN(
1445 "basic",
1446 "invalid library element \"" << aElementName << '"');
1447 continue;
1451 uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
1452 aStreamName,
1453 embed::ElementModes::READWRITE );
1454 // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
1456 OUString aMime( "text/xml" );
1458 uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
1459 SAL_WARN_IF(
1460 !xProps.is(), "basic",
1461 "The StorageStream must implement XPropertySet interface!");
1462 //if ( !xProps.is() ) //TODO
1464 if ( xProps.is() )
1466 xProps->setPropertyValue("MediaType", uno::makeAny( aMime ) );
1468 // #87671 Allow encryption
1469 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::makeAny( sal_True ) );
1471 Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
1472 Reference< XNameContainer > xLib( pLib );
1473 writeLibraryElement( xLib, aElementName, xOutput );
1476 catch(const uno::Exception& )
1478 SAL_WARN("basic", "Problem during storing of library!");
1479 // TODO: error handling?
1482 pLib->storeResourcesToStorage( xStorage );
1484 else
1486 // Export?
1487 bool bExport = !aTargetURL.isEmpty();
1490 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
1491 if( rToUseSFI.is() )
1493 xSFI = rToUseSFI;
1495 OUString aLibDirPath;
1496 if( bExport )
1498 INetURLObject aInetObj( aTargetURL );
1499 aInetObj.insertName( aName, true, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
1500 aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1502 if( !xSFI->isFolder( aLibDirPath ) )
1504 xSFI->createFolder( aLibDirPath );
1506 pLib->storeResourcesToURL( aLibDirPath, xHandler );
1508 else
1510 aLibDirPath = createAppLibraryFolder( pLib, aName );
1511 pLib->storeResources();
1514 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
1516 OUString aElementName = pNames[ i ];
1518 INetURLObject aElementInetObj( aLibDirPath );
1519 aElementInetObj.insertName( aElementName, false,
1520 INetURLObject::LAST_SEGMENT, true,
1521 INetURLObject::ENCODE_ALL );
1522 aElementInetObj.setExtension( maLibElementFileExtension );
1523 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
1525 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
1527 SAL_WARN(
1528 "basic",
1529 "invalid library element \"" << aElementName << '"');
1530 continue;
1533 // TODO: Check modified
1536 if( xSFI->exists( aElementPath ) )
1538 xSFI->kill( aElementPath );
1540 Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
1541 Reference< XNameContainer > xLib( pLib );
1542 writeLibraryElement( xLib, aElementName, xOutput );
1543 xOutput->closeOutput();
1545 catch(const Exception& )
1547 if( bExport )
1549 throw;
1551 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
1552 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
1556 catch(const Exception& )
1558 if( bExport )
1560 throw;
1566 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1567 const ::xmlscript::LibDescriptor& rLib,
1568 const uno::Reference< embed::XStorage >& xStorage )
1570 OUString aDummyLocation;
1571 Reference< XSimpleFileAccess3 > xDummySFA;
1572 implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
1575 // New variant for library export
1576 void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
1577 const ::xmlscript::LibDescriptor& rLib,
1578 const uno::Reference< embed::XStorage >& xStorage,
1579 const OUString& aTargetURL,
1580 const Reference< XSimpleFileAccess3 >& rToUseSFI )
1582 // Create sax writer
1583 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
1585 bool bLink = pLib->mbLink;
1586 bool bStorage = xStorage.is() && !bLink;
1588 // Write info file
1589 uno::Reference< io::XOutputStream > xOut;
1590 uno::Reference< io::XStream > xInfoStream;
1591 if( bStorage )
1593 OUString aStreamName( maInfoFileName );
1594 aStreamName += "-lb.xml";
1598 xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
1599 SAL_WARN_IF(!xInfoStream.is(), "basic", "No stream!");
1600 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
1601 // throw uno::RuntimeException(); // TODO
1603 if ( xProps.is() )
1605 OUString aMime("text/xml");
1606 xProps->setPropertyValue("MediaType", uno::makeAny( aMime ) );
1608 // #87671 Allow encryption
1609 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::makeAny( sal_True ) );
1611 xOut = xInfoStream->getOutputStream();
1614 catch(const uno::Exception& )
1616 SAL_WARN("basic", "Problem during storing of library index file!");
1617 // TODO: error handling?
1620 else
1622 // Export?
1623 bool bExport = !aTargetURL.isEmpty();
1624 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
1625 if( rToUseSFI.is() )
1627 xSFI = rToUseSFI;
1629 OUString aLibInfoPath;
1630 if( bExport )
1632 INetURLObject aInetObj( aTargetURL );
1633 aInetObj.insertName( rLib.aName, true, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
1634 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1635 if( !xSFI->isFolder( aLibDirPath ) )
1637 xSFI->createFolder( aLibDirPath );
1639 aInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
1640 aInetObj.setExtension( OUString( "xlb" ) );
1641 aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
1643 else
1645 createAppLibraryFolder( pLib, rLib.aName );
1646 aLibInfoPath = pLib->maLibInfoFileURL;
1651 if( xSFI->exists( aLibInfoPath ) )
1653 xSFI->kill( aLibInfoPath );
1655 xOut = xSFI->openFileWrite( aLibInfoPath );
1657 catch(const Exception& )
1659 if( bExport )
1661 throw;
1663 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
1664 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
1667 if( !xOut.is() )
1669 SAL_WARN("basic", "couldn't open output stream");
1670 return;
1672 xWriter->setOutputStream( xOut );
1673 xmlscript::exportLibrary( xWriter, rLib );
1677 bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib,
1678 ::xmlscript::LibDescriptor& rLib,
1679 const uno::Reference< embed::XStorage >& xStorage,
1680 const OUString& aIndexFileName )
1682 Reference< XParser > xParser = xml::sax::Parser::create(mxContext);
1684 bool bStorage = false;
1685 if( pLib )
1687 bool bLink = pLib->mbLink;
1688 bStorage = xStorage.is() && !bLink;
1691 // Read info file
1692 uno::Reference< io::XInputStream > xInput;
1693 OUString aLibInfoPath;
1694 if( bStorage )
1696 aLibInfoPath = maInfoFileName;
1697 aLibInfoPath += "-lb.xml";
1701 uno::Reference< io::XStream > xInfoStream =
1702 xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
1703 xInput = xInfoStream->getInputStream();
1705 catch(const uno::Exception& )
1708 else
1710 // Create Input stream
1711 //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
1713 if( pLib )
1715 createAppLibraryFolder( pLib, rLib.aName );
1716 aLibInfoPath = pLib->maLibInfoFileURL;
1718 else
1720 aLibInfoPath = aIndexFileName;
1724 xInput = mxSFI->openFileRead( aLibInfoPath );
1726 catch(const Exception& )
1728 xInput.clear();
1729 if( !GbMigrationSuppressErrors )
1731 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
1732 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
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 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
1756 return false;
1759 if( !pLib )
1761 Reference< XNameContainer > xLib = createLibrary( rLib.aName );
1762 pLib = static_cast< SfxLibrary* >( xLib.get() );
1763 pLib->mbLoaded = false;
1764 rLib.aStorageURL = aIndexFileName;
1765 checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
1766 pLib->maUnexpandedStorageURL );
1768 implImportLibDescriptor( pLib, rLib );
1771 return true;
1774 void SfxLibraryContainer::implImportLibDescriptor( SfxLibrary* pLib,
1775 ::xmlscript::LibDescriptor& rLib )
1777 if( !pLib->mbInitialised )
1779 sal_Int32 nElementCount = rLib.aElementNames.getLength();
1780 const OUString* pElementNames = rLib.aElementNames.getConstArray();
1781 Any aDummyElement = createEmptyLibraryElement();
1782 for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
1784 pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
1786 pLib->mbPasswordProtected = rLib.bPasswordProtected;
1787 pLib->mbReadOnly = rLib.bReadOnly;
1788 pLib->mbPreload = rLib.bPreload;
1789 pLib->implSetModified( false );
1790 pLib->mbInitialised = true;
1795 // Methods of new XLibraryStorage interface?
1796 void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage,
1797 bool bComplete )
1799 const Sequence< OUString > aNames = maNameContainer.getElementNames();
1800 const sal_Int32 nNameCount = aNames.getLength();
1801 const OUString* pName = aNames.getConstArray();
1802 const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;
1804 // Don't count libs from shared index file
1805 sal_Int32 nLibsToSave = nNameCount;
1806 for( ; pName != pNamesEnd; ++pName )
1808 SfxLibrary* pImplLib = getImplLib( *pName );
1809 if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
1811 nLibsToSave--;
1814 // Write to storage?
1815 bool bStorage = i_rStorage.is();
1816 uno::Reference< embed::XStorage > xSourceLibrariesStor;
1817 uno::Reference< embed::XStorage > xTargetLibrariesStor;
1818 OUString sTempTargetStorName;
1819 const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
1821 if( nLibsToSave == 0 )
1823 if ( bInplaceStorage && mxStorage->hasByName(maLibrariesDir) )
1825 mxStorage->removeElement(maLibrariesDir);
1827 return;
1830 if ( bStorage )
1832 // Don't write if only empty standard lib exists
1833 if ( ( nLibsToSave == 1 ) && ( aNames[0] == "Standard" ) )
1835 Any aLibAny = maNameContainer.getByName( aNames[0] );
1836 Reference< XNameAccess > xNameAccess;
1837 aLibAny >>= xNameAccess;
1838 if ( ! xNameAccess->hasElements() )
1840 if ( bInplaceStorage && mxStorage->hasByName(maLibrariesDir) )
1842 mxStorage->removeElement(maLibrariesDir);
1844 return;
1848 // create the empty target storage
1851 OUString sTargetLibrariesStoreName;
1852 if ( bInplaceStorage )
1854 // create a temporary target storage
1855 const OUStringBuffer aTempTargetNameBase = maLibrariesDir + "_temp_";
1856 sal_Int32 index = 0;
1859 OUStringBuffer aTempTargetName( aTempTargetNameBase );
1860 aTempTargetName.append( index++ );
1862 sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
1863 if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1865 break;
1868 while ( true );
1869 sTempTargetStorName = sTargetLibrariesStoreName;
1871 else
1873 sTargetLibrariesStoreName = maLibrariesDir;
1874 if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
1876 i_rStorage->removeElement( sTargetLibrariesStoreName );
1880 xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
1882 catch( const uno::Exception& )
1884 DBG_UNHANDLED_EXCEPTION();
1885 return;
1888 // open the source storage which might be used to copy yet-unmodified libraries
1891 if ( mxStorage->hasByName( maLibrariesDir ) || bInplaceStorage )
1893 xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir,
1894 bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
1897 catch( const uno::Exception& )
1899 DBG_UNHANDLED_EXCEPTION();
1900 return;
1904 int iArray = 0;
1905 pName = aNames.getConstArray();
1906 ::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
1907 boost::scoped_ptr< ::xmlscript::LibDescriptorArray > pLibArray(new ::xmlscript::LibDescriptorArray(nLibsToSave));
1908 for( ; pName != pNamesEnd; ++pName )
1910 SfxLibrary* pImplLib = getImplLib( *pName );
1911 if( pImplLib->mbSharedIndexFile )
1913 continue;
1915 const bool bExtensionLib = pImplLib->mbExtension;
1916 ::xmlscript::LibDescriptor& rLib = bExtensionLib ?
1917 aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
1918 if( !bExtensionLib )
1920 iArray++;
1922 rLib.aName = *pName;
1924 rLib.bLink = pImplLib->mbLink;
1925 if( !bStorage || pImplLib->mbLink )
1927 rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
1928 pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
1930 rLib.bReadOnly = pImplLib->mbReadOnly;
1931 rLib.bPreload = pImplLib->mbPreload;
1932 rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
1933 rLib.aElementNames = pImplLib->getElementNames();
1935 if( pImplLib->implIsModified() || bComplete )
1937 // Testing pImplLib->implIsModified() is not reliable,
1938 // IMHO the value of pImplLib->implIsModified() should
1939 // reflect whether the library ( in-memory ) model
1940 // is in sync with the library container's own storage. Currently
1941 // whenever the library model is written to *any* storage
1942 // pImplLib->implSetModified( sal_False ) is called
1943 // The way the code works, especially the way that sfx uses
1944 // temp storage when saving ( and later sets the root storage of the
1945 // library container ) and similar madness in dbaccess means some surgery
1946 // is required to make it possible to successfully use this optimisation
1947 // It would be possible to do the implSetModified() call below only
1948 // conditionally, but that would require an additional boolean to be
1949 // passed in via the XStorageBasedDocument::storeLibrariesToStorage()...
1950 // fdo#68983: If there's a password and the password is not known, only
1951 // copying the storage works!
1952 // Can we simply copy the storage?
1953 if (!mbOldInfoFormat && !pImplLib->isLoadedStorable() &&
1954 !mbOasis2OOoFormat && xSourceLibrariesStor.is())
1958 xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
1960 catch( const uno::Exception& )
1962 DBG_UNHANDLED_EXCEPTION();
1963 // TODO: error handling?
1966 else
1968 uno::Reference< embed::XStorage > xLibraryStor;
1969 if( bStorage )
1973 xLibraryStor = xTargetLibrariesStor->openStorageElement(
1974 rLib.aName,
1975 embed::ElementModes::READWRITE );
1977 catch(const uno::Exception& )
1979 #if OSL_DEBUG_LEVEL > 0
1980 Any aError( ::cppu::getCaughtException() );
1981 SAL_WARN(
1982 "basic",
1983 "couldn't create sub storage for library \""
1984 << rLib.aName << "\". Exception: "
1985 << comphelper::anyToString(aError));
1986 #endif
1987 throw;
1991 // Maybe lib is not loaded?!
1992 if( bComplete )
1994 loadLibrary( rLib.aName );
1996 if( pImplLib->mbPasswordProtected )
1998 implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
1999 // TODO: Check return value
2001 else
2003 implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
2005 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
2006 if( bStorage )
2010 uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
2011 xTransact->commit();
2013 catch(const uno::Exception& )
2015 DBG_UNHANDLED_EXCEPTION();
2016 // TODO: error handling
2017 throw;
2021 maModifiable.setModified( true );
2022 pImplLib->implSetModified( false );
2025 // For container info ReadOnly refers to mbReadOnlyLink
2026 rLib.bReadOnly = pImplLib->mbReadOnlyLink;
2029 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
2030 // then we need to clean up the temporary storage we used for this
2031 if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
2033 SAL_WARN_IF(
2034 !xSourceLibrariesStor.is(), "basic",
2035 ("SfxLibrariesContainer::storeLibraries_impl: unexpected: we should"
2036 " have a source storage here!"));
2039 // for this, we first remove everything from the source storage, then copy the complete content
2040 // from the temporary target storage. From then on, what used to be the "source storage" becomes
2041 // the "targt storage" for all subsequent operations.
2043 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
2044 // open references to it.)
2046 if ( xSourceLibrariesStor.is() )
2048 // remove
2049 const Sequence< OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
2050 for ( const OUString* pRemoveName = aRemoveNames.getConstArray();
2051 pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
2052 ++pRemoveName
2055 xSourceLibrariesStor->removeElement( *pRemoveName );
2058 // copy
2059 const Sequence< OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
2060 for ( const OUString* pCopyName = aCopyNames.getConstArray();
2061 pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
2062 ++pCopyName
2065 xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
2069 // close and remove temp target
2070 xTargetLibrariesStor->dispose();
2071 i_rStorage->removeElement( sTempTargetStorName );
2072 xTargetLibrariesStor.clear();
2073 sTempTargetStorName.clear();
2075 // adjust target
2076 xTargetLibrariesStor = xSourceLibrariesStor;
2077 xSourceLibrariesStor.clear();
2079 catch( const Exception& )
2081 DBG_UNHANDLED_EXCEPTION();
2082 throw;
2086 if( !mbOldInfoFormat && !maModifiable.isModified() )
2088 return;
2090 maModifiable.setModified( false );
2091 mbOldInfoFormat = false;
2093 // Write library container info
2094 // Create sax writer
2095 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
2097 // Write info file
2098 uno::Reference< io::XOutputStream > xOut;
2099 uno::Reference< io::XStream > xInfoStream;
2100 if( bStorage )
2102 OUString aStreamName( maInfoFileName );
2103 aStreamName += "-lc.xml";
2107 xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2108 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
2109 SAL_WARN_IF(
2110 !xProps.is(), "basic",
2111 "The stream must implement XPropertySet!");
2112 if ( !xProps.is() )
2114 throw uno::RuntimeException();
2116 OUString aMime( "text/xml" );
2117 xProps->setPropertyValue("MediaType", uno::makeAny( aMime ) );
2119 // #87671 Allow encryption
2120 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::makeAny( sal_True ) );
2122 xOut = xInfoStream->getOutputStream();
2124 catch(const uno::Exception& )
2126 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
2129 else
2131 // Create Output stream
2132 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2133 aLibInfoInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
2134 aLibInfoInetObj.setExtension( OUString("xlc") );
2135 OUString aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2139 if( mxSFI->exists( aLibInfoPath ) )
2141 mxSFI->kill( aLibInfoPath );
2143 xOut = mxSFI->openFileWrite( aLibInfoPath );
2145 catch(const Exception& )
2147 xOut.clear();
2148 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2149 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
2153 if( !xOut.is() )
2155 SAL_WARN("basic", "couldn't open output stream");
2156 return;
2159 xWriter->setOutputStream( xOut );
2163 xmlscript::exportLibraryContainer( xWriter, pLibArray.get() );
2164 if ( bStorage )
2166 uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
2167 SAL_WARN_IF(
2168 !xTransact.is(), "basic",
2169 "The storage must implement XTransactedObject!");
2170 if ( !xTransact.is() )
2172 throw uno::RuntimeException();
2174 xTransact->commit();
2177 catch(const uno::Exception& )
2179 SAL_WARN("basic", "Problem during storing of libraries!");
2180 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
2185 // Methods XElementAccess
2186 Type SAL_CALL SfxLibraryContainer::getElementType()
2187 throw(RuntimeException, std::exception)
2189 LibraryContainerMethodGuard aGuard( *this );
2190 return maNameContainer.getElementType();
2193 sal_Bool SfxLibraryContainer::hasElements()
2194 throw(RuntimeException, std::exception)
2196 LibraryContainerMethodGuard aGuard( *this );
2197 bool bRet = maNameContainer.hasElements();
2198 return bRet;
2201 // Methods XNameAccess
2202 Any SfxLibraryContainer::getByName( const OUString& aName )
2203 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2205 LibraryContainerMethodGuard aGuard( *this );
2206 Any aRetAny = maNameContainer.getByName( aName ) ;
2207 return aRetAny;
2210 Sequence< OUString > SfxLibraryContainer::getElementNames()
2211 throw(RuntimeException, std::exception)
2213 LibraryContainerMethodGuard aGuard( *this );
2214 return maNameContainer.getElementNames();
2217 sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
2218 throw(RuntimeException, std::exception)
2220 LibraryContainerMethodGuard aGuard( *this );
2221 return maNameContainer.hasByName( aName ) ;
2224 // Methods XLibraryContainer
2225 Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
2226 throw(IllegalArgumentException, ElementExistException, RuntimeException, std::exception)
2228 LibraryContainerMethodGuard aGuard( *this );
2229 SfxLibrary* pNewLib = implCreateLibrary( Name );
2230 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2232 createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2234 Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
2235 Any aElement;
2236 aElement <<= xNameAccess;
2237 maNameContainer.insertByName( Name, aElement );
2238 maModifiable.setModified( true );
2239 Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2240 return xRet;
2243 Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
2244 ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2245 throw(IllegalArgumentException, ElementExistException, RuntimeException, std::exception)
2247 LibraryContainerMethodGuard aGuard( *this );
2248 // TODO: Check other reasons to force ReadOnly status
2249 //if( !ReadOnly )
2253 OUString aLibInfoFileURL;
2254 OUString aLibDirURL;
2255 OUString aUnexpandedStorageURL;
2256 checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2259 SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2260 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2261 pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2262 pNewLib->maOriginalStorageURL = StorageURL;
2264 OUString aInitFileName;
2265 uno::Reference< embed::XStorage > xDummyStor;
2266 ::xmlscript::LibDescriptor aLibDesc;
2267 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
2268 implImportLibDescriptor( pNewLib, aLibDesc );
2270 Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
2271 Any aElement;
2272 aElement <<= xRet;
2273 maNameContainer.insertByName( Name, aElement );
2274 maModifiable.setModified( true );
2276 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
2277 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
2278 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
2279 if( StorageURL.indexOf( aUserSearchStr ) != -1 )
2281 pNewLib->mbExtension = true;
2283 else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
2285 pNewLib->mbExtension = true;
2286 pNewLib->mbReadOnly = true;
2289 return xRet;
2292 void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2293 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2295 LibraryContainerMethodGuard aGuard( *this );
2296 // Get and hold library before removing
2297 Any aLibAny = maNameContainer.getByName( Name ) ;
2298 Reference< XNameAccess > xNameAccess;
2299 aLibAny >>= xNameAccess;
2300 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2301 if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2303 throw IllegalArgumentException();
2305 // Remove from container
2306 maNameContainer.removeByName( Name );
2307 maModifiable.setModified( true );
2309 // Delete library files, but not for linked libraries
2310 if( !pImplLib->mbLink )
2312 if( mxStorage.is() )
2314 return;
2316 if( xNameAccess->hasElements() )
2318 Sequence< OUString > aNames = pImplLib->getElementNames();
2319 sal_Int32 nNameCount = aNames.getLength();
2320 const OUString* pNames = aNames.getConstArray();
2321 for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2323 pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
2327 // Delete index file
2328 createAppLibraryFolder( pImplLib, Name );
2329 OUString aLibInfoPath = pImplLib->maLibInfoFileURL;
2332 if( mxSFI->exists( aLibInfoPath ) )
2334 mxSFI->kill( aLibInfoPath );
2337 catch(const Exception& ) {}
2339 // Delete folder if empty
2340 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2341 aInetObj.insertName( Name, true, INetURLObject::LAST_SEGMENT,
2342 true, INetURLObject::ENCODE_ALL );
2343 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
2347 if( mxSFI->isFolder( aLibDirPath ) )
2349 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2350 sal_Int32 nCount = aContentSeq.getLength();
2351 if( !nCount )
2353 mxSFI->kill( aLibDirPath );
2357 catch(const Exception& )
2363 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2364 throw(NoSuchElementException, RuntimeException, std::exception)
2366 LibraryContainerMethodGuard aGuard( *this );
2367 SfxLibrary* pImplLib = getImplLib( Name );
2368 bool bRet = pImplLib->mbLoaded;
2369 return bRet;
2373 void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2374 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2376 LibraryContainerMethodGuard aGuard( *this );
2377 Any aLibAny = maNameContainer.getByName( Name ) ;
2378 Reference< XNameAccess > xNameAccess;
2379 aLibAny >>= xNameAccess;
2380 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2382 bool bLoaded = pImplLib->mbLoaded;
2383 pImplLib->mbLoaded = true;
2384 if( !bLoaded && xNameAccess->hasElements() )
2386 if( pImplLib->mbPasswordProtected )
2388 implLoadPasswordLibrary( pImplLib, Name );
2389 return;
2392 bool bLink = pImplLib->mbLink;
2393 bool bStorage = mxStorage.is() && !bLink;
2395 uno::Reference< embed::XStorage > xLibrariesStor;
2396 uno::Reference< embed::XStorage > xLibraryStor;
2397 if( bStorage )
2401 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2402 SAL_WARN_IF(
2403 !xLibrariesStor.is(), "basic",
2404 ("The method must either throw exception or return a"
2405 " storage!"));
2406 if ( !xLibrariesStor.is() )
2408 throw uno::RuntimeException();
2411 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2412 SAL_WARN_IF(
2413 !xLibraryStor.is(), "basic",
2414 ("The method must either throw exception or return a"
2415 " storage!"));
2416 if ( !xLibrariesStor.is() )
2418 throw uno::RuntimeException();
2421 catch(const uno::Exception& )
2423 #if OSL_DEBUG_LEVEL > 0
2424 Any aError( ::cppu::getCaughtException() );
2425 SAL_WARN(
2426 "basic",
2427 "couldn't open sub storage for library \"" << Name
2428 << "\". Exception: "
2429 << comphelper::anyToString(aError));
2430 #endif
2431 throw;
2435 Sequence< OUString > aNames = pImplLib->getElementNames();
2436 sal_Int32 nNameCount = aNames.getLength();
2437 const OUString* pNames = aNames.getConstArray();
2438 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2440 OUString aElementName = pNames[ i ];
2442 OUString aFile;
2443 uno::Reference< io::XInputStream > xInStream;
2445 if( bStorage )
2447 uno::Reference< io::XStream > xElementStream;
2449 aFile = aElementName;
2450 aFile += ".xml";
2454 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2456 catch(const uno::Exception& )
2459 if( !xElementStream.is() )
2461 // Check for EA2 document version with wrong extensions
2462 aFile = aElementName;
2463 aFile += ".";
2464 aFile += maLibElementFileExtension;
2467 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2469 catch(const uno::Exception& )
2473 if ( xElementStream.is() )
2475 xInStream = xElementStream->getInputStream();
2477 if ( !xInStream.is() )
2479 SAL_WARN(
2480 "basic",
2481 "couldn't open library element stream - attempted to"
2482 " open library \"" << Name << '"');
2483 throw RuntimeException("couln't open library element stream", *this);
2486 else
2488 OUString aLibDirPath = pImplLib->maStorageURL;
2489 INetURLObject aElementInetObj( aLibDirPath );
2490 aElementInetObj.insertName( aElementName, false,
2491 INetURLObject::LAST_SEGMENT, true,
2492 INetURLObject::ENCODE_ALL );
2493 aElementInetObj.setExtension( maLibElementFileExtension );
2494 aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
2497 Reference< XNameContainer > xLib( pImplLib );
2498 Any aAny = importLibraryElement( xLib, aElementName,
2499 aFile, xInStream );
2500 if( pImplLib->hasByName( aElementName ) )
2502 if( aAny.hasValue() )
2504 pImplLib->maNameContainer.replaceByName( aElementName, aAny );
2507 else
2509 pImplLib->maNameContainer.insertNoCheck(aElementName, aAny);
2512 pImplLib->implSetModified( false );
2516 // Methods XLibraryContainer2
2517 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2518 throw (NoSuchElementException, RuntimeException, std::exception)
2520 LibraryContainerMethodGuard aGuard( *this );
2521 SfxLibrary* pImplLib = getImplLib( Name );
2522 bool bRet = pImplLib->mbLink;
2523 return bRet;
2526 OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2527 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2529 LibraryContainerMethodGuard aGuard( *this );
2530 SfxLibrary* pImplLib = getImplLib( Name );
2531 bool bLink = pImplLib->mbLink;
2532 if( !bLink )
2534 throw IllegalArgumentException();
2536 OUString aRetStr = pImplLib->maLibInfoFileURL;
2537 return aRetStr;
2540 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2541 throw (NoSuchElementException, RuntimeException, std::exception)
2543 LibraryContainerMethodGuard aGuard( *this );
2544 SfxLibrary* pImplLib = getImplLib( Name );
2545 bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2546 return bRet;
2549 void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2550 throw (NoSuchElementException, RuntimeException, std::exception)
2552 LibraryContainerMethodGuard aGuard( *this );
2553 SfxLibrary* pImplLib = getImplLib( Name );
2554 if( pImplLib->mbLink )
2556 if( pImplLib->mbReadOnlyLink != bool(bReadOnly) )
2558 pImplLib->mbReadOnlyLink = bReadOnly;
2559 pImplLib->implSetModified( true );
2560 maModifiable.setModified( true );
2563 else
2565 if( pImplLib->mbReadOnly != bool(bReadOnly) )
2567 pImplLib->mbReadOnly = bReadOnly;
2568 pImplLib->implSetModified( true );
2573 void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2574 throw (NoSuchElementException, ElementExistException, RuntimeException, std::exception)
2576 LibraryContainerMethodGuard aGuard( *this );
2577 if( maNameContainer.hasByName( NewName ) )
2579 throw ElementExistException();
2581 // Get and hold library before removing
2582 Any aLibAny = maNameContainer.getByName( Name ) ;
2584 // #i24094 Maybe lib is not loaded!
2585 Reference< XNameAccess > xNameAccess;
2586 aLibAny >>= xNameAccess;
2587 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2588 if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2590 return; // Lib with unverified password cannot be renamed
2592 loadLibrary( Name );
2594 // Remove from container
2595 maNameContainer.removeByName( Name );
2596 maModifiable.setModified( true );
2598 // Rename library folder, but not for linked libraries
2599 bool bMovedSuccessful = true;
2601 // Rename files
2602 bool bStorage = mxStorage.is();
2603 if( !bStorage && !pImplLib->mbLink )
2605 bMovedSuccessful = false;
2607 OUString aLibDirPath = pImplLib->maStorageURL;
2609 INetURLObject aDestInetObj( maLibraryPath.getToken(1, (sal_Unicode)';'));
2610 aDestInetObj.insertName( NewName, true, INetURLObject::LAST_SEGMENT,
2611 true, INetURLObject::ENCODE_ALL );
2612 OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
2614 // Store new URL
2615 OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2616 checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2617 pImplLib->maUnexpandedStorageURL );
2621 if( mxSFI->isFolder( aLibDirPath ) )
2623 if( !mxSFI->isFolder( aDestDirPath ) )
2625 mxSFI->createFolder( aDestDirPath );
2627 // Move index file
2630 if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2632 mxSFI->kill( pImplLib->maLibInfoFileURL );
2634 mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2636 catch(const Exception& )
2640 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2641 sal_Int32 nNameCount = aElementNames.getLength();
2642 const OUString* pNames = aElementNames.getConstArray();
2643 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2645 OUString aElementName = pNames[ i ];
2647 INetURLObject aElementInetObj( aLibDirPath );
2648 aElementInetObj.insertName( aElementName, false,
2649 INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
2650 aElementInetObj.setExtension( maLibElementFileExtension );
2651 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2653 INetURLObject aElementDestInetObj( aDestDirPath );
2654 aElementDestInetObj.insertName( aElementName, false,
2655 INetURLObject::LAST_SEGMENT, true,
2656 INetURLObject::ENCODE_ALL );
2657 aElementDestInetObj.setExtension( maLibElementFileExtension );
2658 OUString aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2662 if( mxSFI->exists( aDestElementPath ) )
2664 mxSFI->kill( aDestElementPath );
2666 mxSFI->move( aElementPath, aDestElementPath );
2668 catch(const Exception& )
2672 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2674 // Delete folder if empty
2675 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2676 sal_Int32 nCount = aContentSeq.getLength();
2677 if( !nCount )
2679 mxSFI->kill( aLibDirPath );
2682 bMovedSuccessful = true;
2683 pImplLib->implSetModified( true );
2686 catch(const Exception& )
2688 // Restore old library
2689 maNameContainer.insertByName( Name, aLibAny ) ;
2693 if( bStorage && !pImplLib->mbLink )
2695 pImplLib->implSetModified( true );
2697 if( bMovedSuccessful )
2699 maNameContainer.insertByName( NewName, aLibAny ) ;
2704 // Methods XInitialization
2705 void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2706 throw (Exception, RuntimeException, std::exception)
2708 LibraryContainerMethodGuard aGuard( *this );
2709 sal_Int32 nArgCount = _rArguments.getLength();
2710 if ( nArgCount == 1 )
2712 OUString sInitialDocumentURL;
2713 Reference< XStorageBasedDocument > xDocument;
2714 if ( _rArguments[0] >>= sInitialDocumentURL )
2716 initializeFromDocumentURL( sInitialDocumentURL );
2717 return;
2720 if ( _rArguments[0] >>= xDocument )
2722 initializeFromDocument( xDocument );
2723 return;
2727 throw IllegalArgumentException();
2730 void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const OUString& _rInitialDocumentURL )
2732 init( _rInitialDocumentURL, NULL );
2735 void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
2737 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2738 Reference< XStorage > xDocStorage;
2741 Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2742 if ( xSI->supportsService("com.sun.star.document.OfficeDocument"))
2744 xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
2746 Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2747 Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2749 mxOwnerDocument = xDocument;
2750 startComponentListening( xDocComponent );
2752 catch( const Exception& ) { }
2754 if ( !xDocStorage.is() )
2756 throw IllegalArgumentException();
2758 init( OUString(), xDocStorage );
2761 // OEventListenerAdapter
2762 void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2764 #if OSL_DEBUG_LEVEL > 0
2765 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2766 SAL_WARN_IF(
2767 xDocument != _rSource.Source || !xDocument.is(), "basic",
2768 "SfxLibraryContainer::_disposing: where does this come from?");
2769 #else
2770 (void)_rSource;
2771 #endif
2772 dispose();
2775 // OComponentHelper
2776 void SAL_CALL SfxLibraryContainer::disposing()
2778 Reference< XModel > xModel = mxOwnerDocument;
2779 EventObject aEvent( xModel.get() );
2780 maVBAScriptListeners.disposing( aEvent );
2781 stopAllComponentListening();
2782 mxOwnerDocument = WeakReference< XModel >();
2785 // Methods XLibraryContainerPassword
2786 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
2787 throw (NoSuchElementException, RuntimeException, std::exception)
2789 LibraryContainerMethodGuard aGuard( *this );
2790 return sal_False;
2793 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
2794 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2796 LibraryContainerMethodGuard aGuard( *this );
2797 throw IllegalArgumentException();
2800 sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword( const OUString&, const OUString& )
2801 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2803 LibraryContainerMethodGuard aGuard( *this );
2804 throw IllegalArgumentException();
2807 void SAL_CALL SfxLibraryContainer::changeLibraryPassword(const OUString&, const OUString&, const OUString& )
2808 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2810 LibraryContainerMethodGuard aGuard( *this );
2811 throw IllegalArgumentException();
2814 // Methods XContainer
2815 void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
2816 throw (RuntimeException, std::exception)
2818 LibraryContainerMethodGuard aGuard( *this );
2819 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
2820 maNameContainer.addContainerListener( xListener );
2823 void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
2824 throw (RuntimeException, std::exception)
2826 LibraryContainerMethodGuard aGuard( *this );
2827 maNameContainer.removeContainerListener( xListener );
2830 // Methods XLibraryContainerExport
2831 void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2832 const Reference< XInteractionHandler >& Handler )
2833 throw ( uno::Exception, NoSuchElementException, RuntimeException, std::exception)
2835 LibraryContainerMethodGuard aGuard( *this );
2836 SfxLibrary* pImplLib = getImplLib( Name );
2838 Reference< XSimpleFileAccess3 > xToUseSFI;
2839 if( Handler.is() )
2841 xToUseSFI = ucb::SimpleFileAccess::create( mxContext );
2842 xToUseSFI->setInteractionHandler( Handler );
2845 // Maybe lib is not loaded?!
2846 loadLibrary( Name );
2848 uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
2849 if( pImplLib->mbPasswordProtected )
2851 implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2853 else
2855 implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2857 ::xmlscript::LibDescriptor aLibDesc;
2858 aLibDesc.aName = Name;
2859 aLibDesc.bLink = false; // Link status gets lost?
2860 aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2861 aLibDesc.bPreload = false; // Preload status gets lost?
2862 aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2863 aLibDesc.aElementNames = pImplLib->getElementNames();
2865 implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2868 OUString SfxLibraryContainer::expand_url( const OUString& url )
2869 throw(::com::sun::star::uno::RuntimeException)
2871 if (url.startsWithIgnoreAsciiCase( "vnd.sun.star.expand:" ))
2873 return comphelper::getExpandedUri(mxContext, url);
2875 else if( mxStringSubstitution.is() )
2877 OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2878 return ret;
2880 else
2882 return url;
2886 //XLibraryContainer3
2887 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2888 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2890 LibraryContainerMethodGuard aGuard( *this );
2891 SfxLibrary* pImplLib = getImplLib( Name );
2892 bool bLink = pImplLib->mbLink;
2893 if( !bLink )
2895 throw IllegalArgumentException();
2897 OUString aRetStr = pImplLib->maOriginalStorageURL;
2898 return aRetStr;
2902 // XVBACompatibility
2903 sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException, std::exception)
2905 return mbVBACompat;
2908 void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( sal_Bool _vbacompatmodeon ) throw (RuntimeException, std::exception)
2910 /* The member variable mbVBACompat must be set first, the following call
2911 to getBasicManager() may call getVBACompatibilityMode() which returns
2912 this value. */
2913 mbVBACompat = _vbacompatmodeon;
2914 if( BasicManager* pBasMgr = getBasicManager() )
2916 // get the standard library
2917 OUString aLibName = pBasMgr->GetName();
2918 if ( aLibName.isEmpty())
2920 aLibName = "Standard";
2922 if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2924 pBasic->SetVBAEnabled( _vbacompatmodeon );
2926 /* If in VBA compatibility mode, force creation of the VBA Globals
2927 object. Each application will create an instance of its own
2928 implementation and store it in its Basic manager. Implementations
2929 will do all necessary additional initialization, such as
2930 registering the global "This***Doc" UNO constant, starting the
2931 document events processor etc.
2933 if( mbVBACompat ) try
2935 Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
2936 Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
2937 xFactory->createInstance("ooo.vba.VBAGlobals");
2939 catch(const Exception& )
2945 void SAL_CALL SfxLibraryContainer::setProjectName( const OUString& _projectname ) throw (RuntimeException, std::exception)
2947 msProjectName = _projectname;
2948 BasicManager* pBasMgr = getBasicManager();
2949 // Temporary HACK
2950 // Some parts of the VBA handling ( e.g. in core basic )
2951 // code expect the name of the VBA project to be set as the name of
2952 // the basic manager. Provide fail back here.
2953 if( pBasMgr )
2955 pBasMgr->SetName( msProjectName );
2959 sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() throw (RuntimeException, std::exception)
2961 LibraryContainerMethodGuard aGuard( *this );
2962 return mnRunningVBAScripts;
2965 void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException, std::exception)
2967 maVBAScriptListeners.addTypedListener( rxListener );
2970 void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException, std::exception)
2972 maVBAScriptListeners.removeTypedListener( rxListener );
2975 void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const OUString& rModuleName ) throw (RuntimeException, std::exception)
2977 // own lock for accessing the number of running scripts
2978 enterMethod();
2979 switch( nIdentifier )
2981 case vba::VBAScriptEventId::SCRIPT_STARTED:
2982 ++mnRunningVBAScripts;
2983 break;
2984 case vba::VBAScriptEventId::SCRIPT_STOPPED:
2985 --mnRunningVBAScripts;
2986 break;
2988 leaveMethod();
2990 Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref
2991 vba::VBAScriptEvent aEvent( Reference<XInterface>(xModel, UNO_QUERY), nIdentifier, rModuleName );
2992 maVBAScriptListeners.notify( aEvent );
2995 // Methods XServiceInfo
2996 sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const OUString& _rServiceName )
2997 throw (RuntimeException, std::exception)
2999 return cppu::supportsService(this, _rServiceName);
3002 // Implementation class SfxLibrary
3004 // Ctor
3005 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3006 const Reference< XComponentContext >& xContext, const Reference< XSimpleFileAccess3 >& xSFI )
3007 : OComponentHelper( m_aMutex )
3008 , mxContext( xContext )
3009 , mxSFI( xSFI )
3010 , mrModifiable( _rModifiable )
3011 , maNameContainer( aType )
3012 , mbLoaded( true )
3013 , mbIsModified( true )
3014 , mbInitialised( false )
3015 , mbLink( false )
3016 , mbReadOnly( false )
3017 , mbReadOnlyLink( false )
3018 , mbPreload( false )
3019 , mbPasswordProtected( false )
3020 , mbPasswordVerified( false )
3021 , mbDoc50Password( false )
3022 , mbSharedIndexFile( false )
3023 , mbExtension( false )
3027 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3028 const Reference< XComponentContext >& xContext, const Reference< XSimpleFileAccess3 >& xSFI,
3029 const OUString& aLibInfoFileURL, const OUString& aStorageURL, bool ReadOnly )
3030 : OComponentHelper( m_aMutex )
3031 , mxContext( xContext )
3032 , mxSFI( xSFI )
3033 , mrModifiable( _rModifiable )
3034 , maNameContainer( aType )
3035 , mbLoaded( false )
3036 , mbIsModified( true )
3037 , mbInitialised( false )
3038 , maLibInfoFileURL( aLibInfoFileURL )
3039 , maStorageURL( aStorageURL )
3040 , mbLink( true )
3041 , mbReadOnly( false )
3042 , mbReadOnlyLink( ReadOnly )
3043 , mbPreload( false )
3044 , mbPasswordProtected( false )
3045 , mbPasswordVerified( false )
3046 , mbDoc50Password( false )
3047 , mbSharedIndexFile( false )
3048 , mbExtension( false )
3052 bool SfxLibrary::isLoadedStorable()
3054 return mbLoaded && (!mbPasswordProtected || mbPasswordVerified);
3057 void SfxLibrary::implSetModified( bool _bIsModified )
3059 if ( mbIsModified == _bIsModified )
3061 return;
3063 mbIsModified = _bIsModified;
3064 if ( mbIsModified )
3066 mrModifiable.setModified( true );
3070 // Methods XInterface
3071 Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
3072 throw( RuntimeException, std::exception )
3074 Any aRet;
3076 aRet = Any(
3077 ::cppu::queryInterface(
3078 rType,
3079 static_cast< XContainer * >( this ),
3080 static_cast< XNameContainer * >( this ),
3081 static_cast< XNameAccess * >( this ),
3082 static_cast< XElementAccess * >( this ),
3083 static_cast< XChangesNotifier * >( this ) ) );
3084 if( !aRet.hasValue() )
3086 aRet = OComponentHelper::queryInterface( rType );
3088 return aRet;
3091 // Methods XElementAccess
3092 Type SfxLibrary::getElementType()
3093 throw(RuntimeException, std::exception)
3095 return maNameContainer.getElementType();
3098 sal_Bool SfxLibrary::hasElements()
3099 throw(RuntimeException, std::exception)
3101 bool bRet = maNameContainer.hasElements();
3102 return bRet;
3105 // Methods XNameAccess
3106 Any SfxLibrary::getByName( const OUString& aName )
3107 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3109 impl_checkLoaded();
3111 Any aRetAny = maNameContainer.getByName( aName ) ;
3112 return aRetAny;
3115 Sequence< OUString > SfxLibrary::getElementNames()
3116 throw(RuntimeException, std::exception)
3118 return maNameContainer.getElementNames();
3121 sal_Bool SfxLibrary::hasByName( const OUString& aName )
3122 throw(RuntimeException, std::exception)
3124 bool bRet = maNameContainer.hasByName( aName );
3125 return bRet;
3128 void SfxLibrary::impl_checkReadOnly()
3130 if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3132 throw IllegalArgumentException(
3133 "Library is readonly.",
3134 // TODO: resource
3135 *this, 0
3140 void SfxLibrary::impl_checkLoaded()
3142 if ( !mbLoaded )
3144 throw WrappedTargetException(
3145 OUString(),
3146 *this,
3147 makeAny( LibraryNotLoadedException(
3148 OUString(),
3149 *this
3155 // Methods XNameReplace
3156 void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3157 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3159 impl_checkReadOnly();
3160 impl_checkLoaded();
3162 SAL_WARN_IF(
3163 !isLibraryElementValid(aElement), "basic",
3164 "SfxLibrary::replaceByName: replacing element is invalid!");
3166 maNameContainer.replaceByName( aName, aElement );
3167 implSetModified( true );
3171 // Methods XNameContainer
3172 void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3173 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
3175 impl_checkReadOnly();
3176 impl_checkLoaded();
3178 SAL_WARN_IF(
3179 !isLibraryElementValid(aElement), "basic",
3180 "SfxLibrary::insertByName: to-be-inserted element is invalid!");
3182 maNameContainer.insertByName( aName, aElement );
3183 implSetModified( true );
3186 void SfxLibrary::impl_removeWithoutChecks( const OUString& _rElementName )
3188 maNameContainer.removeByName( _rElementName );
3189 implSetModified( true );
3191 // Remove element file
3192 if( !maStorageURL.isEmpty() )
3194 INetURLObject aElementInetObj( maStorageURL );
3195 aElementInetObj.insertName( _rElementName, false,
3196 INetURLObject::LAST_SEGMENT, true,
3197 INetURLObject::ENCODE_ALL );
3198 aElementInetObj.setExtension( maLibElementFileExtension );
3199 OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
3203 if( mxSFI->exists( aFile ) )
3205 mxSFI->kill( aFile );
3208 catch(const Exception& )
3210 DBG_UNHANDLED_EXCEPTION();
3215 void SfxLibrary::removeByName( const OUString& Name )
3216 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3218 impl_checkReadOnly();
3219 impl_checkLoaded();
3220 impl_removeWithoutChecks( Name );
3223 // XTypeProvider
3224 Sequence< Type > SfxLibrary::getTypes()
3225 throw( RuntimeException, std::exception )
3227 static OTypeCollection * s_pTypes_NameContainer = 0;
3229 if( !s_pTypes_NameContainer )
3231 MutexGuard aGuard( Mutex::getGlobalMutex() );
3232 if( !s_pTypes_NameContainer )
3234 static OTypeCollection s_aTypes_NameContainer(
3235 cppu::UnoType<XNameContainer>::get(),
3236 cppu::UnoType<XContainer>::get(),
3237 cppu::UnoType<XChangesNotifier>::get(),
3238 OComponentHelper::getTypes() );
3239 s_pTypes_NameContainer = &s_aTypes_NameContainer;
3242 return s_pTypes_NameContainer->getTypes();
3247 Sequence< sal_Int8 > SfxLibrary::getImplementationId()
3248 throw( RuntimeException, std::exception )
3250 return css::uno::Sequence<sal_Int8>();
3253 // Methods XContainer
3254 void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
3255 throw (RuntimeException, std::exception)
3257 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3258 maNameContainer.addContainerListener( xListener );
3261 void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
3262 throw (RuntimeException, std::exception)
3264 maNameContainer.removeContainerListener( xListener );
3267 // Methods XChangesNotifier
3268 void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
3269 throw (RuntimeException, std::exception)
3271 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3272 maNameContainer.addChangesListener( xListener );
3275 void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
3276 throw (RuntimeException, std::exception)
3278 maNameContainer.removeChangesListener( xListener );
3282 // Implementation class ScriptExtensionIterator
3284 #define sBasicLibMediaType "application/vnd.sun.star.basic-library"
3285 #define sDialogLibMediaType "application/vnd.sun.star.dialog-library"
3287 ScriptExtensionIterator::ScriptExtensionIterator()
3288 : m_xContext( comphelper::getProcessComponentContext() )
3289 , m_eState( USER_EXTENSIONS )
3290 , m_bUserPackagesLoaded( false )
3291 , m_bSharedPackagesLoaded( false )
3292 , m_bBundledPackagesLoaded( false )
3293 , m_iUserPackage( 0 )
3294 , m_iSharedPackage( 0 )
3295 , m_iBundledPackage( 0 )
3296 , m_pScriptSubPackageIterator( NULL )
3299 OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
3301 OUString aRetLib;
3303 while( aRetLib.isEmpty() && m_eState != END_REACHED )
3305 switch( m_eState )
3307 case USER_EXTENSIONS:
3309 Reference< deployment::XPackage > xScriptPackage =
3310 implGetNextUserScriptPackage( rbPureDialogLib );
3311 if( !xScriptPackage.is() )
3313 break;
3315 aRetLib = xScriptPackage->getURL();
3316 break;
3319 case SHARED_EXTENSIONS:
3321 Reference< deployment::XPackage > xScriptPackage =
3322 implGetNextSharedScriptPackage( rbPureDialogLib );
3323 if( !xScriptPackage.is() )
3325 break;
3327 aRetLib = xScriptPackage->getURL();
3328 break;
3330 case BUNDLED_EXTENSIONS:
3332 Reference< deployment::XPackage > xScriptPackage =
3333 implGetNextBundledScriptPackage( rbPureDialogLib );
3334 if( !xScriptPackage.is() )
3336 break;
3338 aRetLib = xScriptPackage->getURL();
3339 break;
3341 case END_REACHED:
3342 SAL_WARN(
3343 "basic",
3344 ("ScriptExtensionIterator::nextBasicOrDialogLibrary():"
3345 " Invalid case END_REACHED"));
3346 break;
3350 return aRetLib;
3353 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
3354 : m_xMainPackage( xMainPackage )
3355 , m_bIsValid( false )
3356 , m_bIsBundle( false )
3357 , m_nSubPkgCount( 0 )
3358 , m_iNextSubPkg( 0 )
3360 Reference< deployment::XPackage > xScriptPackage;
3361 if( !m_xMainPackage.is() )
3363 return;
3365 // Check if parent package is registered
3366 beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3367 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3368 bool bRegistered = false;
3369 if( option.IsPresent )
3371 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3372 if( !reg.IsAmbiguous && reg.Value )
3374 bRegistered = true;
3377 if( bRegistered )
3379 m_bIsValid = true;
3380 if( m_xMainPackage->isBundle() )
3382 m_bIsBundle = true;
3383 m_aSubPkgSeq = m_xMainPackage->getBundle( Reference<task::XAbortChannel>(),
3384 Reference<ucb::XCommandEnvironment>() );
3385 m_nSubPkgCount = m_aSubPkgSeq.getLength();
3390 Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage( bool& rbPureDialogLib )
3392 rbPureDialogLib = false;
3394 Reference< deployment::XPackage > xScriptPackage;
3395 if( !m_bIsValid )
3397 return xScriptPackage;
3399 if( m_bIsBundle )
3401 const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3402 sal_Int32 iPkg;
3403 for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3405 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3406 xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3407 if( xScriptPackage.is() )
3409 break;
3412 m_iNextSubPkg = iPkg + 1;
3414 else
3416 xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3417 m_bIsValid = false; // No more script packages
3420 return xScriptPackage;
3423 Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage ( const Reference< deployment::XPackage >& rPackage,
3424 bool& rbPureDialogLib )
3426 Reference< deployment::XPackage > xScriptPackage;
3428 if( rPackage.is() )
3430 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = rPackage->getPackageType();
3431 OUString aMediaType = xPackageTypeInfo->getMediaType();
3432 if ( aMediaType == sBasicLibMediaType )
3434 xScriptPackage = rPackage;
3436 else if ( aMediaType == sDialogLibMediaType )
3438 rbPureDialogLib = true;
3439 xScriptPackage = rPackage;
3443 return xScriptPackage;
3446 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage( bool& rbPureDialogLib )
3448 Reference< deployment::XPackage > xScriptPackage;
3450 if( !m_bUserPackagesLoaded )
3454 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3455 m_aUserPackagesSeq = xManager->getDeployedExtensions(OUString("user"),
3456 Reference< task::XAbortChannel >(),
3457 Reference< ucb::XCommandEnvironment >() );
3459 catch(const com::sun::star::uno::DeploymentException& )
3461 // Special Office installations may not contain deployment code
3462 m_eState = END_REACHED;
3463 return xScriptPackage;
3466 m_bUserPackagesLoaded = true;
3469 if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3471 m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
3473 else
3475 if( m_pScriptSubPackageIterator == NULL )
3477 const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3478 Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3479 SAL_WARN_IF(
3480 !xPackage.is(), "basic",
3481 ("ScriptExtensionIterator::implGetNextUserScriptPackage():"
3482 " Invalid package"));
3483 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3486 if( m_pScriptSubPackageIterator != NULL )
3488 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3489 if( !xScriptPackage.is() )
3491 delete m_pScriptSubPackageIterator;
3492 m_pScriptSubPackageIterator = NULL;
3493 m_iUserPackage++;
3498 return xScriptPackage;
3501 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage( bool& rbPureDialogLib )
3503 Reference< deployment::XPackage > xScriptPackage;
3505 if( !m_bSharedPackagesLoaded )
3509 Reference< XExtensionManager > xSharedManager = ExtensionManager::get( m_xContext );
3510 m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions(OUString("shared"),
3511 Reference< task::XAbortChannel >(),
3512 Reference< ucb::XCommandEnvironment >() );
3514 catch(const com::sun::star::uno::DeploymentException& )
3516 // Special Office installations may not contain deployment code
3517 return xScriptPackage;
3520 m_bSharedPackagesLoaded = true;
3523 if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3525 m_eState = BUNDLED_EXTENSIONS;
3527 else
3529 if( m_pScriptSubPackageIterator == NULL )
3531 const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3532 Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3533 SAL_WARN_IF(
3534 !xPackage.is(), "basic",
3535 ("ScriptExtensionIterator::implGetNextSharedScriptPackage():"
3536 " Invalid package"));
3537 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3540 if( m_pScriptSubPackageIterator != NULL )
3542 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3543 if( !xScriptPackage.is() )
3545 delete m_pScriptSubPackageIterator;
3546 m_pScriptSubPackageIterator = NULL;
3547 m_iSharedPackage++;
3552 return xScriptPackage;
3555 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage( bool& rbPureDialogLib )
3557 Reference< deployment::XPackage > xScriptPackage;
3559 if( !m_bBundledPackagesLoaded )
3563 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3564 m_aBundledPackagesSeq = xManager->getDeployedExtensions(OUString("bundled"),
3565 Reference< task::XAbortChannel >(),
3566 Reference< ucb::XCommandEnvironment >() );
3568 catch(const com::sun::star::uno::DeploymentException& )
3570 // Special Office installations may not contain deployment code
3571 return xScriptPackage;
3574 m_bBundledPackagesLoaded = true;
3577 if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3579 m_eState = END_REACHED;
3581 else
3583 if( m_pScriptSubPackageIterator == NULL )
3585 const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3586 Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3587 SAL_WARN_IF(
3588 !xPackage.is(), "basic",
3589 ("ScriptExtensionIterator::implGetNextBundledScriptPackage():"
3590 " Invalid package"));
3591 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3594 if( m_pScriptSubPackageIterator != NULL )
3596 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3597 if( !xScriptPackage.is() )
3599 delete m_pScriptSubPackageIterator;
3600 m_pScriptSubPackageIterator = NULL;
3601 m_iBundledPackage++;
3606 return xScriptPackage;
3609 } // namespace basic
3611 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */