Bump version to 5.0-43
[LibreOffice.git] / basic / source / uno / namecont.cxx
blobc23c09e68ed6b4d1336bcd49796c7b4012d9a358
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 bool isCopyStorage = !mbOldInfoFormat && !mbOasis2OOoFormat
1954 && !pImplLib->isLoadedStorable()
1955 && xSourceLibrariesStor.is() /* null for user profile */;
1956 if (isCopyStorage)
1960 xSourceLibrariesStor->isStorageElement(rLib.aName);
1962 catch (container::NoSuchElementException const&)
1964 isCopyStorage = false;
1967 if (isCopyStorage)
1971 xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
1973 catch( const uno::Exception& )
1975 DBG_UNHANDLED_EXCEPTION();
1976 // TODO: error handling?
1979 else
1981 uno::Reference< embed::XStorage > xLibraryStor;
1982 if( bStorage )
1986 xLibraryStor = xTargetLibrariesStor->openStorageElement(
1987 rLib.aName,
1988 embed::ElementModes::READWRITE );
1990 catch(const uno::Exception& )
1992 #if OSL_DEBUG_LEVEL > 0
1993 Any aError( ::cppu::getCaughtException() );
1994 SAL_WARN(
1995 "basic",
1996 "couldn't create sub storage for library \""
1997 << rLib.aName << "\". Exception: "
1998 << comphelper::anyToString(aError));
1999 #endif
2000 throw;
2004 // Maybe lib is not loaded?!
2005 if( bComplete )
2007 loadLibrary( rLib.aName );
2009 if( pImplLib->mbPasswordProtected )
2011 implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
2012 // TODO: Check return value
2014 else
2016 implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
2018 implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
2019 if( bStorage )
2023 uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
2024 xTransact->commit();
2026 catch(const uno::Exception& )
2028 DBG_UNHANDLED_EXCEPTION();
2029 // TODO: error handling
2030 throw;
2034 maModifiable.setModified( true );
2035 pImplLib->implSetModified( false );
2038 // For container info ReadOnly refers to mbReadOnlyLink
2039 rLib.bReadOnly = pImplLib->mbReadOnlyLink;
2042 // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
2043 // then we need to clean up the temporary storage we used for this
2044 if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
2046 SAL_WARN_IF(
2047 !xSourceLibrariesStor.is(), "basic",
2048 ("SfxLibrariesContainer::storeLibraries_impl: unexpected: we should"
2049 " have a source storage here!"));
2052 // for this, we first remove everything from the source storage, then copy the complete content
2053 // from the temporary target storage. From then on, what used to be the "source storage" becomes
2054 // the "targt storage" for all subsequent operations.
2056 // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
2057 // open references to it.)
2059 if ( xSourceLibrariesStor.is() )
2061 // remove
2062 const Sequence< OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
2063 for ( const OUString* pRemoveName = aRemoveNames.getConstArray();
2064 pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
2065 ++pRemoveName
2068 xSourceLibrariesStor->removeElement( *pRemoveName );
2071 // copy
2072 const Sequence< OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
2073 for ( const OUString* pCopyName = aCopyNames.getConstArray();
2074 pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
2075 ++pCopyName
2078 xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
2082 // close and remove temp target
2083 xTargetLibrariesStor->dispose();
2084 i_rStorage->removeElement( sTempTargetStorName );
2085 xTargetLibrariesStor.clear();
2086 sTempTargetStorName.clear();
2088 // adjust target
2089 xTargetLibrariesStor = xSourceLibrariesStor;
2090 xSourceLibrariesStor.clear();
2092 catch( const Exception& )
2094 DBG_UNHANDLED_EXCEPTION();
2095 throw;
2099 if( !mbOldInfoFormat && !maModifiable.isModified() )
2101 return;
2103 maModifiable.setModified( false );
2104 mbOldInfoFormat = false;
2106 // Write library container info
2107 // Create sax writer
2108 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
2110 // Write info file
2111 uno::Reference< io::XOutputStream > xOut;
2112 uno::Reference< io::XStream > xInfoStream;
2113 if( bStorage )
2115 OUString aStreamName( maInfoFileName );
2116 aStreamName += "-lc.xml";
2120 xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
2121 uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
2122 SAL_WARN_IF(
2123 !xProps.is(), "basic",
2124 "The stream must implement XPropertySet!");
2125 if ( !xProps.is() )
2127 throw uno::RuntimeException();
2129 OUString aMime( "text/xml" );
2130 xProps->setPropertyValue("MediaType", uno::makeAny( aMime ) );
2132 // #87671 Allow encryption
2133 xProps->setPropertyValue("UseCommonStoragePasswordEncryption", uno::makeAny( sal_True ) );
2135 xOut = xInfoStream->getOutputStream();
2137 catch(const uno::Exception& )
2139 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
2142 else
2144 // Create Output stream
2145 INetURLObject aLibInfoInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2146 aLibInfoInetObj.insertName( maInfoFileName, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
2147 aLibInfoInetObj.setExtension( OUString("xlc") );
2148 OUString aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2152 if( mxSFI->exists( aLibInfoPath ) )
2154 mxSFI->kill( aLibInfoPath );
2156 xOut = mxSFI->openFileWrite( aLibInfoPath );
2158 catch(const Exception& )
2160 xOut.clear();
2161 SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
2162 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
2166 if( !xOut.is() )
2168 SAL_WARN("basic", "couldn't open output stream");
2169 return;
2172 xWriter->setOutputStream( xOut );
2176 xmlscript::exportLibraryContainer( xWriter, pLibArray.get() );
2177 if ( bStorage )
2179 uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
2180 SAL_WARN_IF(
2181 !xTransact.is(), "basic",
2182 "The storage must implement XTransactedObject!");
2183 if ( !xTransact.is() )
2185 throw uno::RuntimeException();
2187 xTransact->commit();
2190 catch(const uno::Exception& )
2192 SAL_WARN("basic", "Problem during storing of libraries!");
2193 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
2198 // Methods XElementAccess
2199 Type SAL_CALL SfxLibraryContainer::getElementType()
2200 throw(RuntimeException, std::exception)
2202 LibraryContainerMethodGuard aGuard( *this );
2203 return maNameContainer.getElementType();
2206 sal_Bool SfxLibraryContainer::hasElements()
2207 throw(RuntimeException, std::exception)
2209 LibraryContainerMethodGuard aGuard( *this );
2210 bool bRet = maNameContainer.hasElements();
2211 return bRet;
2214 // Methods XNameAccess
2215 Any SfxLibraryContainer::getByName( const OUString& aName )
2216 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2218 LibraryContainerMethodGuard aGuard( *this );
2219 Any aRetAny = maNameContainer.getByName( aName ) ;
2220 return aRetAny;
2223 Sequence< OUString > SfxLibraryContainer::getElementNames()
2224 throw(RuntimeException, std::exception)
2226 LibraryContainerMethodGuard aGuard( *this );
2227 return maNameContainer.getElementNames();
2230 sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
2231 throw(RuntimeException, std::exception)
2233 LibraryContainerMethodGuard aGuard( *this );
2234 return maNameContainer.hasByName( aName ) ;
2237 // Methods XLibraryContainer
2238 Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
2239 throw(IllegalArgumentException, ElementExistException, RuntimeException, std::exception)
2241 LibraryContainerMethodGuard aGuard( *this );
2242 SfxLibrary* pNewLib = implCreateLibrary( Name );
2243 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2245 createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
2247 Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
2248 Any aElement;
2249 aElement <<= xNameAccess;
2250 maNameContainer.insertByName( Name, aElement );
2251 maModifiable.setModified( true );
2252 Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
2253 return xRet;
2256 Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
2257 ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
2258 throw(IllegalArgumentException, ElementExistException, RuntimeException, std::exception)
2260 LibraryContainerMethodGuard aGuard( *this );
2261 // TODO: Check other reasons to force ReadOnly status
2262 //if( !ReadOnly )
2266 OUString aLibInfoFileURL;
2267 OUString aLibDirURL;
2268 OUString aUnexpandedStorageURL;
2269 checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
2272 SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
2273 pNewLib->maLibElementFileExtension = maLibElementFileExtension;
2274 pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
2275 pNewLib->maOriginalStorageURL = StorageURL;
2277 OUString aInitFileName;
2278 uno::Reference< embed::XStorage > xDummyStor;
2279 ::xmlscript::LibDescriptor aLibDesc;
2280 implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
2281 implImportLibDescriptor( pNewLib, aLibDesc );
2283 Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
2284 Any aElement;
2285 aElement <<= xRet;
2286 maNameContainer.insertByName( Name, aElement );
2287 maModifiable.setModified( true );
2289 OUString aUserSearchStr("vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE");
2290 OUString aSharedSearchStr("vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE");
2291 OUString aBundledSearchStr("vnd.sun.star.expand:$BUNDLED_EXTENSIONS");
2292 if( StorageURL.indexOf( aUserSearchStr ) != -1 )
2294 pNewLib->mbExtension = true;
2296 else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
2298 pNewLib->mbExtension = true;
2299 pNewLib->mbReadOnly = true;
2302 return xRet;
2305 void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
2306 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2308 LibraryContainerMethodGuard aGuard( *this );
2309 // Get and hold library before removing
2310 Any aLibAny = maNameContainer.getByName( Name ) ;
2311 Reference< XNameAccess > xNameAccess;
2312 aLibAny >>= xNameAccess;
2313 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2314 if( pImplLib->mbReadOnly && !pImplLib->mbLink )
2316 throw IllegalArgumentException();
2318 // Remove from container
2319 maNameContainer.removeByName( Name );
2320 maModifiable.setModified( true );
2322 // Delete library files, but not for linked libraries
2323 if( !pImplLib->mbLink )
2325 if( mxStorage.is() )
2327 return;
2329 if( xNameAccess->hasElements() )
2331 Sequence< OUString > aNames = pImplLib->getElementNames();
2332 sal_Int32 nNameCount = aNames.getLength();
2333 const OUString* pNames = aNames.getConstArray();
2334 for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
2336 pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
2340 // Delete index file
2341 createAppLibraryFolder( pImplLib, Name );
2342 OUString aLibInfoPath = pImplLib->maLibInfoFileURL;
2345 if( mxSFI->exists( aLibInfoPath ) )
2347 mxSFI->kill( aLibInfoPath );
2350 catch(const Exception& ) {}
2352 // Delete folder if empty
2353 INetURLObject aInetObj( maLibraryPath.getToken(1, (sal_Unicode)';') );
2354 aInetObj.insertName( Name, true, INetURLObject::LAST_SEGMENT,
2355 true, INetURLObject::ENCODE_ALL );
2356 OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
2360 if( mxSFI->isFolder( aLibDirPath ) )
2362 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2363 sal_Int32 nCount = aContentSeq.getLength();
2364 if( !nCount )
2366 mxSFI->kill( aLibDirPath );
2370 catch(const Exception& )
2376 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
2377 throw(NoSuchElementException, RuntimeException, std::exception)
2379 LibraryContainerMethodGuard aGuard( *this );
2380 SfxLibrary* pImplLib = getImplLib( Name );
2381 bool bRet = pImplLib->mbLoaded;
2382 return bRet;
2386 void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
2387 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2389 LibraryContainerMethodGuard aGuard( *this );
2390 Any aLibAny = maNameContainer.getByName( Name ) ;
2391 Reference< XNameAccess > xNameAccess;
2392 aLibAny >>= xNameAccess;
2393 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2395 bool bLoaded = pImplLib->mbLoaded;
2396 pImplLib->mbLoaded = true;
2397 if( !bLoaded && xNameAccess->hasElements() )
2399 if( pImplLib->mbPasswordProtected )
2401 implLoadPasswordLibrary( pImplLib, Name );
2402 return;
2405 bool bLink = pImplLib->mbLink;
2406 bool bStorage = mxStorage.is() && !bLink;
2408 uno::Reference< embed::XStorage > xLibrariesStor;
2409 uno::Reference< embed::XStorage > xLibraryStor;
2410 if( bStorage )
2414 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
2415 SAL_WARN_IF(
2416 !xLibrariesStor.is(), "basic",
2417 ("The method must either throw exception or return a"
2418 " storage!"));
2419 if ( !xLibrariesStor.is() )
2421 throw uno::RuntimeException();
2424 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
2425 SAL_WARN_IF(
2426 !xLibraryStor.is(), "basic",
2427 ("The method must either throw exception or return a"
2428 " storage!"));
2429 if ( !xLibrariesStor.is() )
2431 throw uno::RuntimeException();
2434 catch(const uno::Exception& )
2436 #if OSL_DEBUG_LEVEL > 0
2437 Any aError( ::cppu::getCaughtException() );
2438 SAL_WARN(
2439 "basic",
2440 "couldn't open sub storage for library \"" << Name
2441 << "\". Exception: "
2442 << comphelper::anyToString(aError));
2443 #endif
2444 throw;
2448 Sequence< OUString > aNames = pImplLib->getElementNames();
2449 sal_Int32 nNameCount = aNames.getLength();
2450 const OUString* pNames = aNames.getConstArray();
2451 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2453 OUString aElementName = pNames[ i ];
2455 OUString aFile;
2456 uno::Reference< io::XInputStream > xInStream;
2458 if( bStorage )
2460 uno::Reference< io::XStream > xElementStream;
2462 aFile = aElementName;
2463 aFile += ".xml";
2467 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2469 catch(const uno::Exception& )
2472 if( !xElementStream.is() )
2474 // Check for EA2 document version with wrong extensions
2475 aFile = aElementName;
2476 aFile += ".";
2477 aFile += maLibElementFileExtension;
2480 xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
2482 catch(const uno::Exception& )
2486 if ( xElementStream.is() )
2488 xInStream = xElementStream->getInputStream();
2490 if ( !xInStream.is() )
2492 SAL_WARN(
2493 "basic",
2494 "couldn't open library element stream - attempted to"
2495 " open library \"" << Name << '"');
2496 throw RuntimeException("couln't open library element stream", *this);
2499 else
2501 OUString aLibDirPath = pImplLib->maStorageURL;
2502 INetURLObject aElementInetObj( aLibDirPath );
2503 aElementInetObj.insertName( aElementName, false,
2504 INetURLObject::LAST_SEGMENT, true,
2505 INetURLObject::ENCODE_ALL );
2506 aElementInetObj.setExtension( maLibElementFileExtension );
2507 aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
2510 Reference< XNameContainer > xLib( pImplLib );
2511 Any aAny = importLibraryElement( xLib, aElementName,
2512 aFile, xInStream );
2513 if( pImplLib->hasByName( aElementName ) )
2515 if( aAny.hasValue() )
2517 pImplLib->maNameContainer.replaceByName( aElementName, aAny );
2520 else
2522 pImplLib->maNameContainer.insertNoCheck(aElementName, aAny);
2525 pImplLib->implSetModified( false );
2529 // Methods XLibraryContainer2
2530 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
2531 throw (NoSuchElementException, RuntimeException, std::exception)
2533 LibraryContainerMethodGuard aGuard( *this );
2534 SfxLibrary* pImplLib = getImplLib( Name );
2535 bool bRet = pImplLib->mbLink;
2536 return bRet;
2539 OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
2540 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2542 LibraryContainerMethodGuard aGuard( *this );
2543 SfxLibrary* pImplLib = getImplLib( Name );
2544 bool bLink = pImplLib->mbLink;
2545 if( !bLink )
2547 throw IllegalArgumentException();
2549 OUString aRetStr = pImplLib->maLibInfoFileURL;
2550 return aRetStr;
2553 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
2554 throw (NoSuchElementException, RuntimeException, std::exception)
2556 LibraryContainerMethodGuard aGuard( *this );
2557 SfxLibrary* pImplLib = getImplLib( Name );
2558 bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
2559 return bRet;
2562 void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
2563 throw (NoSuchElementException, RuntimeException, std::exception)
2565 LibraryContainerMethodGuard aGuard( *this );
2566 SfxLibrary* pImplLib = getImplLib( Name );
2567 if( pImplLib->mbLink )
2569 if( pImplLib->mbReadOnlyLink != bool(bReadOnly) )
2571 pImplLib->mbReadOnlyLink = bReadOnly;
2572 pImplLib->implSetModified( true );
2573 maModifiable.setModified( true );
2576 else
2578 if( pImplLib->mbReadOnly != bool(bReadOnly) )
2580 pImplLib->mbReadOnly = bReadOnly;
2581 pImplLib->implSetModified( true );
2586 void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
2587 throw (NoSuchElementException, ElementExistException, RuntimeException, std::exception)
2589 LibraryContainerMethodGuard aGuard( *this );
2590 if( maNameContainer.hasByName( NewName ) )
2592 throw ElementExistException();
2594 // Get and hold library before removing
2595 Any aLibAny = maNameContainer.getByName( Name ) ;
2597 // #i24094 Maybe lib is not loaded!
2598 Reference< XNameAccess > xNameAccess;
2599 aLibAny >>= xNameAccess;
2600 SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
2601 if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
2603 return; // Lib with unverified password cannot be renamed
2605 loadLibrary( Name );
2607 // Remove from container
2608 maNameContainer.removeByName( Name );
2609 maModifiable.setModified( true );
2611 // Rename library folder, but not for linked libraries
2612 bool bMovedSuccessful = true;
2614 // Rename files
2615 bool bStorage = mxStorage.is();
2616 if( !bStorage && !pImplLib->mbLink )
2618 bMovedSuccessful = false;
2620 OUString aLibDirPath = pImplLib->maStorageURL;
2622 INetURLObject aDestInetObj( maLibraryPath.getToken(1, (sal_Unicode)';'));
2623 aDestInetObj.insertName( NewName, true, INetURLObject::LAST_SEGMENT,
2624 true, INetURLObject::ENCODE_ALL );
2625 OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
2627 // Store new URL
2628 OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
2629 checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
2630 pImplLib->maUnexpandedStorageURL );
2634 if( mxSFI->isFolder( aLibDirPath ) )
2636 if( !mxSFI->isFolder( aDestDirPath ) )
2638 mxSFI->createFolder( aDestDirPath );
2640 // Move index file
2643 if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
2645 mxSFI->kill( pImplLib->maLibInfoFileURL );
2647 mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
2649 catch(const Exception& )
2653 Sequence< OUString > aElementNames = xNameAccess->getElementNames();
2654 sal_Int32 nNameCount = aElementNames.getLength();
2655 const OUString* pNames = aElementNames.getConstArray();
2656 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
2658 OUString aElementName = pNames[ i ];
2660 INetURLObject aElementInetObj( aLibDirPath );
2661 aElementInetObj.insertName( aElementName, false,
2662 INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
2663 aElementInetObj.setExtension( maLibElementFileExtension );
2664 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2666 INetURLObject aElementDestInetObj( aDestDirPath );
2667 aElementDestInetObj.insertName( aElementName, false,
2668 INetURLObject::LAST_SEGMENT, true,
2669 INetURLObject::ENCODE_ALL );
2670 aElementDestInetObj.setExtension( maLibElementFileExtension );
2671 OUString aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
2675 if( mxSFI->exists( aDestElementPath ) )
2677 mxSFI->kill( aDestElementPath );
2679 mxSFI->move( aElementPath, aDestElementPath );
2681 catch(const Exception& )
2685 pImplLib->storeResourcesAsURL( aDestDirPath, NewName );
2687 // Delete folder if empty
2688 Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
2689 sal_Int32 nCount = aContentSeq.getLength();
2690 if( !nCount )
2692 mxSFI->kill( aLibDirPath );
2695 bMovedSuccessful = true;
2696 pImplLib->implSetModified( true );
2699 catch(const Exception& )
2701 // Restore old library
2702 maNameContainer.insertByName( Name, aLibAny ) ;
2706 if( bStorage && !pImplLib->mbLink )
2708 pImplLib->implSetModified( true );
2710 if( bMovedSuccessful )
2712 maNameContainer.insertByName( NewName, aLibAny ) ;
2717 // Methods XInitialization
2718 void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
2719 throw (Exception, RuntimeException, std::exception)
2721 LibraryContainerMethodGuard aGuard( *this );
2722 sal_Int32 nArgCount = _rArguments.getLength();
2723 if ( nArgCount == 1 )
2725 OUString sInitialDocumentURL;
2726 Reference< XStorageBasedDocument > xDocument;
2727 if ( _rArguments[0] >>= sInitialDocumentURL )
2729 initializeFromDocumentURL( sInitialDocumentURL );
2730 return;
2733 if ( _rArguments[0] >>= xDocument )
2735 initializeFromDocument( xDocument );
2736 return;
2740 throw IllegalArgumentException();
2743 void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const OUString& _rInitialDocumentURL )
2745 init( _rInitialDocumentURL, NULL );
2748 void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
2750 // check whether this is a valid OfficeDocument, and obtain the document's root storage
2751 Reference< XStorage > xDocStorage;
2754 Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
2755 if ( xSI->supportsService("com.sun.star.document.OfficeDocument"))
2757 xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );
2759 Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
2760 Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );
2762 mxOwnerDocument = xDocument;
2763 startComponentListening( xDocComponent );
2765 catch( const Exception& ) { }
2767 if ( !xDocStorage.is() )
2769 throw IllegalArgumentException();
2771 init( OUString(), xDocStorage );
2774 // OEventListenerAdapter
2775 void SfxLibraryContainer::_disposing( const EventObject& _rSource )
2777 #if OSL_DEBUG_LEVEL > 0
2778 Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
2779 SAL_WARN_IF(
2780 xDocument != _rSource.Source || !xDocument.is(), "basic",
2781 "SfxLibraryContainer::_disposing: where does this come from?");
2782 #else
2783 (void)_rSource;
2784 #endif
2785 dispose();
2788 // OComponentHelper
2789 void SAL_CALL SfxLibraryContainer::disposing()
2791 Reference< XModel > xModel = mxOwnerDocument;
2792 EventObject aEvent( xModel.get() );
2793 maVBAScriptListeners.disposing( aEvent );
2794 stopAllComponentListening();
2795 mxOwnerDocument = WeakReference< XModel >();
2798 // Methods XLibraryContainerPassword
2799 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
2800 throw (NoSuchElementException, RuntimeException, std::exception)
2802 LibraryContainerMethodGuard aGuard( *this );
2803 return sal_False;
2806 sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
2807 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2809 LibraryContainerMethodGuard aGuard( *this );
2810 throw IllegalArgumentException();
2813 sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword( const OUString&, const OUString& )
2814 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2816 LibraryContainerMethodGuard aGuard( *this );
2817 throw IllegalArgumentException();
2820 void SAL_CALL SfxLibraryContainer::changeLibraryPassword(const OUString&, const OUString&, const OUString& )
2821 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2823 LibraryContainerMethodGuard aGuard( *this );
2824 throw IllegalArgumentException();
2827 // Methods XContainer
2828 void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
2829 throw (RuntimeException, std::exception)
2831 LibraryContainerMethodGuard aGuard( *this );
2832 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
2833 maNameContainer.addContainerListener( xListener );
2836 void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
2837 throw (RuntimeException, std::exception)
2839 LibraryContainerMethodGuard aGuard( *this );
2840 maNameContainer.removeContainerListener( xListener );
2843 // Methods XLibraryContainerExport
2844 void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
2845 const Reference< XInteractionHandler >& Handler )
2846 throw ( uno::Exception, NoSuchElementException, RuntimeException, std::exception)
2848 LibraryContainerMethodGuard aGuard( *this );
2849 SfxLibrary* pImplLib = getImplLib( Name );
2851 Reference< XSimpleFileAccess3 > xToUseSFI;
2852 if( Handler.is() )
2854 xToUseSFI = ucb::SimpleFileAccess::create( mxContext );
2855 xToUseSFI->setInteractionHandler( Handler );
2858 // Maybe lib is not loaded?!
2859 loadLibrary( Name );
2861 uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
2862 if( pImplLib->mbPasswordProtected )
2864 implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2866 else
2868 implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
2870 ::xmlscript::LibDescriptor aLibDesc;
2871 aLibDesc.aName = Name;
2872 aLibDesc.bLink = false; // Link status gets lost?
2873 aLibDesc.bReadOnly = pImplLib->mbReadOnly;
2874 aLibDesc.bPreload = false; // Preload status gets lost?
2875 aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
2876 aLibDesc.aElementNames = pImplLib->getElementNames();
2878 implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
2881 OUString SfxLibraryContainer::expand_url( const OUString& url )
2882 throw(::com::sun::star::uno::RuntimeException)
2884 if (url.startsWithIgnoreAsciiCase( "vnd.sun.star.expand:" ))
2886 return comphelper::getExpandedUri(mxContext, url);
2888 else if( mxStringSubstitution.is() )
2890 OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
2891 return ret;
2893 else
2895 return url;
2899 //XLibraryContainer3
2900 OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
2901 throw (IllegalArgumentException, NoSuchElementException, RuntimeException, std::exception)
2903 LibraryContainerMethodGuard aGuard( *this );
2904 SfxLibrary* pImplLib = getImplLib( Name );
2905 bool bLink = pImplLib->mbLink;
2906 if( !bLink )
2908 throw IllegalArgumentException();
2910 OUString aRetStr = pImplLib->maOriginalStorageURL;
2911 return aRetStr;
2915 // XVBACompatibility
2916 sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException, std::exception)
2918 return mbVBACompat;
2921 void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( sal_Bool _vbacompatmodeon ) throw (RuntimeException, std::exception)
2923 /* The member variable mbVBACompat must be set first, the following call
2924 to getBasicManager() may call getVBACompatibilityMode() which returns
2925 this value. */
2926 mbVBACompat = _vbacompatmodeon;
2927 if( BasicManager* pBasMgr = getBasicManager() )
2929 // get the standard library
2930 OUString aLibName = pBasMgr->GetName();
2931 if ( aLibName.isEmpty())
2933 aLibName = "Standard";
2935 if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
2937 pBasic->SetVBAEnabled( _vbacompatmodeon );
2939 /* If in VBA compatibility mode, force creation of the VBA Globals
2940 object. Each application will create an instance of its own
2941 implementation and store it in its Basic manager. Implementations
2942 will do all necessary additional initialization, such as
2943 registering the global "This***Doc" UNO constant, starting the
2944 document events processor etc.
2946 if( mbVBACompat ) try
2948 Reference< XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
2949 Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
2950 xFactory->createInstance("ooo.vba.VBAGlobals");
2952 catch(const Exception& )
2958 void SAL_CALL SfxLibraryContainer::setProjectName( const OUString& _projectname ) throw (RuntimeException, std::exception)
2960 msProjectName = _projectname;
2961 BasicManager* pBasMgr = getBasicManager();
2962 // Temporary HACK
2963 // Some parts of the VBA handling ( e.g. in core basic )
2964 // code expect the name of the VBA project to be set as the name of
2965 // the basic manager. Provide fail back here.
2966 if( pBasMgr )
2968 pBasMgr->SetName( msProjectName );
2972 sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() throw (RuntimeException, std::exception)
2974 LibraryContainerMethodGuard aGuard( *this );
2975 return mnRunningVBAScripts;
2978 void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException, std::exception)
2980 maVBAScriptListeners.addTypedListener( rxListener );
2983 void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException, std::exception)
2985 maVBAScriptListeners.removeTypedListener( rxListener );
2988 void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const OUString& rModuleName ) throw (RuntimeException, std::exception)
2990 // own lock for accessing the number of running scripts
2991 enterMethod();
2992 switch( nIdentifier )
2994 case vba::VBAScriptEventId::SCRIPT_STARTED:
2995 ++mnRunningVBAScripts;
2996 break;
2997 case vba::VBAScriptEventId::SCRIPT_STOPPED:
2998 --mnRunningVBAScripts;
2999 break;
3001 leaveMethod();
3003 Reference< XModel > xModel = mxOwnerDocument; // weak-ref -> ref
3004 vba::VBAScriptEvent aEvent( Reference<XInterface>(xModel, UNO_QUERY), nIdentifier, rModuleName );
3005 maVBAScriptListeners.notify( aEvent );
3008 // Methods XServiceInfo
3009 sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const OUString& _rServiceName )
3010 throw (RuntimeException, std::exception)
3012 return cppu::supportsService(this, _rServiceName);
3015 // Implementation class SfxLibrary
3017 // Ctor
3018 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3019 const Reference< XComponentContext >& xContext, const Reference< XSimpleFileAccess3 >& xSFI )
3020 : OComponentHelper( m_aMutex )
3021 , mxContext( xContext )
3022 , mxSFI( xSFI )
3023 , mrModifiable( _rModifiable )
3024 , maNameContainer( aType )
3025 , mbLoaded( true )
3026 , mbIsModified( true )
3027 , mbInitialised( false )
3028 , mbLink( false )
3029 , mbReadOnly( false )
3030 , mbReadOnlyLink( false )
3031 , mbPreload( false )
3032 , mbPasswordProtected( false )
3033 , mbPasswordVerified( false )
3034 , mbDoc50Password( false )
3035 , mbSharedIndexFile( false )
3036 , mbExtension( false )
3040 SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
3041 const Reference< XComponentContext >& xContext, const Reference< XSimpleFileAccess3 >& xSFI,
3042 const OUString& aLibInfoFileURL, const OUString& aStorageURL, bool ReadOnly )
3043 : OComponentHelper( m_aMutex )
3044 , mxContext( xContext )
3045 , mxSFI( xSFI )
3046 , mrModifiable( _rModifiable )
3047 , maNameContainer( aType )
3048 , mbLoaded( false )
3049 , mbIsModified( true )
3050 , mbInitialised( false )
3051 , maLibInfoFileURL( aLibInfoFileURL )
3052 , maStorageURL( aStorageURL )
3053 , mbLink( true )
3054 , mbReadOnly( false )
3055 , mbReadOnlyLink( ReadOnly )
3056 , mbPreload( false )
3057 , mbPasswordProtected( false )
3058 , mbPasswordVerified( false )
3059 , mbDoc50Password( false )
3060 , mbSharedIndexFile( false )
3061 , mbExtension( false )
3065 bool SfxLibrary::isLoadedStorable()
3067 return mbLoaded && (!mbPasswordProtected || mbPasswordVerified);
3070 void SfxLibrary::implSetModified( bool _bIsModified )
3072 if ( mbIsModified == _bIsModified )
3074 return;
3076 mbIsModified = _bIsModified;
3077 if ( mbIsModified )
3079 mrModifiable.setModified( true );
3083 // Methods XInterface
3084 Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
3085 throw( RuntimeException, std::exception )
3087 Any aRet;
3089 aRet = Any(
3090 ::cppu::queryInterface(
3091 rType,
3092 static_cast< XContainer * >( this ),
3093 static_cast< XNameContainer * >( this ),
3094 static_cast< XNameAccess * >( this ),
3095 static_cast< XElementAccess * >( this ),
3096 static_cast< XChangesNotifier * >( this ) ) );
3097 if( !aRet.hasValue() )
3099 aRet = OComponentHelper::queryInterface( rType );
3101 return aRet;
3104 // Methods XElementAccess
3105 Type SfxLibrary::getElementType()
3106 throw(RuntimeException, std::exception)
3108 return maNameContainer.getElementType();
3111 sal_Bool SfxLibrary::hasElements()
3112 throw(RuntimeException, std::exception)
3114 bool bRet = maNameContainer.hasElements();
3115 return bRet;
3118 // Methods XNameAccess
3119 Any SfxLibrary::getByName( const OUString& aName )
3120 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3122 impl_checkLoaded();
3124 Any aRetAny = maNameContainer.getByName( aName ) ;
3125 return aRetAny;
3128 Sequence< OUString > SfxLibrary::getElementNames()
3129 throw(RuntimeException, std::exception)
3131 return maNameContainer.getElementNames();
3134 sal_Bool SfxLibrary::hasByName( const OUString& aName )
3135 throw(RuntimeException, std::exception)
3137 bool bRet = maNameContainer.hasByName( aName );
3138 return bRet;
3141 void SfxLibrary::impl_checkReadOnly()
3143 if( mbReadOnly || (mbLink && mbReadOnlyLink) )
3145 throw IllegalArgumentException(
3146 "Library is readonly.",
3147 // TODO: resource
3148 *this, 0
3153 void SfxLibrary::impl_checkLoaded()
3155 if ( !mbLoaded )
3157 throw WrappedTargetException(
3158 OUString(),
3159 *this,
3160 makeAny( LibraryNotLoadedException(
3161 OUString(),
3162 *this
3168 // Methods XNameReplace
3169 void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
3170 throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3172 impl_checkReadOnly();
3173 impl_checkLoaded();
3175 SAL_WARN_IF(
3176 !isLibraryElementValid(aElement), "basic",
3177 "SfxLibrary::replaceByName: replacing element is invalid!");
3179 maNameContainer.replaceByName( aName, aElement );
3180 implSetModified( true );
3184 // Methods XNameContainer
3185 void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
3186 throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
3188 impl_checkReadOnly();
3189 impl_checkLoaded();
3191 SAL_WARN_IF(
3192 !isLibraryElementValid(aElement), "basic",
3193 "SfxLibrary::insertByName: to-be-inserted element is invalid!");
3195 maNameContainer.insertByName( aName, aElement );
3196 implSetModified( true );
3199 void SfxLibrary::impl_removeWithoutChecks( const OUString& _rElementName )
3201 maNameContainer.removeByName( _rElementName );
3202 implSetModified( true );
3204 // Remove element file
3205 if( !maStorageURL.isEmpty() )
3207 INetURLObject aElementInetObj( maStorageURL );
3208 aElementInetObj.insertName( _rElementName, false,
3209 INetURLObject::LAST_SEGMENT, true,
3210 INetURLObject::ENCODE_ALL );
3211 aElementInetObj.setExtension( maLibElementFileExtension );
3212 OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
3216 if( mxSFI->exists( aFile ) )
3218 mxSFI->kill( aFile );
3221 catch(const Exception& )
3223 DBG_UNHANDLED_EXCEPTION();
3228 void SfxLibrary::removeByName( const OUString& Name )
3229 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3231 impl_checkReadOnly();
3232 impl_checkLoaded();
3233 impl_removeWithoutChecks( Name );
3236 // XTypeProvider
3237 Sequence< Type > SfxLibrary::getTypes()
3238 throw( RuntimeException, std::exception )
3240 static OTypeCollection * s_pTypes_NameContainer = 0;
3242 if( !s_pTypes_NameContainer )
3244 MutexGuard aGuard( Mutex::getGlobalMutex() );
3245 if( !s_pTypes_NameContainer )
3247 static OTypeCollection s_aTypes_NameContainer(
3248 cppu::UnoType<XNameContainer>::get(),
3249 cppu::UnoType<XContainer>::get(),
3250 cppu::UnoType<XChangesNotifier>::get(),
3251 OComponentHelper::getTypes() );
3252 s_pTypes_NameContainer = &s_aTypes_NameContainer;
3255 return s_pTypes_NameContainer->getTypes();
3260 Sequence< sal_Int8 > SfxLibrary::getImplementationId()
3261 throw( RuntimeException, std::exception )
3263 return css::uno::Sequence<sal_Int8>();
3266 // Methods XContainer
3267 void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
3268 throw (RuntimeException, std::exception)
3270 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3271 maNameContainer.addContainerListener( xListener );
3274 void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
3275 throw (RuntimeException, std::exception)
3277 maNameContainer.removeContainerListener( xListener );
3280 // Methods XChangesNotifier
3281 void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
3282 throw (RuntimeException, std::exception)
3284 maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
3285 maNameContainer.addChangesListener( xListener );
3288 void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
3289 throw (RuntimeException, std::exception)
3291 maNameContainer.removeChangesListener( xListener );
3295 // Implementation class ScriptExtensionIterator
3297 #define sBasicLibMediaType "application/vnd.sun.star.basic-library"
3298 #define sDialogLibMediaType "application/vnd.sun.star.dialog-library"
3300 ScriptExtensionIterator::ScriptExtensionIterator()
3301 : m_xContext( comphelper::getProcessComponentContext() )
3302 , m_eState( USER_EXTENSIONS )
3303 , m_bUserPackagesLoaded( false )
3304 , m_bSharedPackagesLoaded( false )
3305 , m_bBundledPackagesLoaded( false )
3306 , m_iUserPackage( 0 )
3307 , m_iSharedPackage( 0 )
3308 , m_iBundledPackage( 0 )
3309 , m_pScriptSubPackageIterator( NULL )
3312 OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
3314 OUString aRetLib;
3316 while( aRetLib.isEmpty() && m_eState != END_REACHED )
3318 switch( m_eState )
3320 case USER_EXTENSIONS:
3322 Reference< deployment::XPackage > xScriptPackage =
3323 implGetNextUserScriptPackage( rbPureDialogLib );
3324 if( !xScriptPackage.is() )
3326 break;
3328 aRetLib = xScriptPackage->getURL();
3329 break;
3332 case SHARED_EXTENSIONS:
3334 Reference< deployment::XPackage > xScriptPackage =
3335 implGetNextSharedScriptPackage( rbPureDialogLib );
3336 if( !xScriptPackage.is() )
3338 break;
3340 aRetLib = xScriptPackage->getURL();
3341 break;
3343 case BUNDLED_EXTENSIONS:
3345 Reference< deployment::XPackage > xScriptPackage =
3346 implGetNextBundledScriptPackage( rbPureDialogLib );
3347 if( !xScriptPackage.is() )
3349 break;
3351 aRetLib = xScriptPackage->getURL();
3352 break;
3354 case END_REACHED:
3355 SAL_WARN(
3356 "basic",
3357 ("ScriptExtensionIterator::nextBasicOrDialogLibrary():"
3358 " Invalid case END_REACHED"));
3359 break;
3363 return aRetLib;
3366 ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
3367 : m_xMainPackage( xMainPackage )
3368 , m_bIsValid( false )
3369 , m_bIsBundle( false )
3370 , m_nSubPkgCount( 0 )
3371 , m_iNextSubPkg( 0 )
3373 Reference< deployment::XPackage > xScriptPackage;
3374 if( !m_xMainPackage.is() )
3376 return;
3378 // Check if parent package is registered
3379 beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
3380 ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
3381 bool bRegistered = false;
3382 if( option.IsPresent )
3384 beans::Ambiguous<sal_Bool> const & reg = option.Value;
3385 if( !reg.IsAmbiguous && reg.Value )
3387 bRegistered = true;
3390 if( bRegistered )
3392 m_bIsValid = true;
3393 if( m_xMainPackage->isBundle() )
3395 m_bIsBundle = true;
3396 m_aSubPkgSeq = m_xMainPackage->getBundle( Reference<task::XAbortChannel>(),
3397 Reference<ucb::XCommandEnvironment>() );
3398 m_nSubPkgCount = m_aSubPkgSeq.getLength();
3403 Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage( bool& rbPureDialogLib )
3405 rbPureDialogLib = false;
3407 Reference< deployment::XPackage > xScriptPackage;
3408 if( !m_bIsValid )
3410 return xScriptPackage;
3412 if( m_bIsBundle )
3414 const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
3415 sal_Int32 iPkg;
3416 for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
3418 const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
3419 xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
3420 if( xScriptPackage.is() )
3422 break;
3425 m_iNextSubPkg = iPkg + 1;
3427 else
3429 xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
3430 m_bIsValid = false; // No more script packages
3433 return xScriptPackage;
3436 Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage ( const Reference< deployment::XPackage >& rPackage,
3437 bool& rbPureDialogLib )
3439 Reference< deployment::XPackage > xScriptPackage;
3441 if( rPackage.is() )
3443 const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = rPackage->getPackageType();
3444 OUString aMediaType = xPackageTypeInfo->getMediaType();
3445 if ( aMediaType == sBasicLibMediaType )
3447 xScriptPackage = rPackage;
3449 else if ( aMediaType == sDialogLibMediaType )
3451 rbPureDialogLib = true;
3452 xScriptPackage = rPackage;
3456 return xScriptPackage;
3459 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage( bool& rbPureDialogLib )
3461 Reference< deployment::XPackage > xScriptPackage;
3463 if( !m_bUserPackagesLoaded )
3467 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3468 m_aUserPackagesSeq = xManager->getDeployedExtensions(OUString("user"),
3469 Reference< task::XAbortChannel >(),
3470 Reference< ucb::XCommandEnvironment >() );
3472 catch(const com::sun::star::uno::DeploymentException& )
3474 // Special Office installations may not contain deployment code
3475 m_eState = END_REACHED;
3476 return xScriptPackage;
3479 m_bUserPackagesLoaded = true;
3482 if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
3484 m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
3486 else
3488 if( m_pScriptSubPackageIterator == NULL )
3490 const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
3491 Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
3492 SAL_WARN_IF(
3493 !xPackage.is(), "basic",
3494 ("ScriptExtensionIterator::implGetNextUserScriptPackage():"
3495 " Invalid package"));
3496 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3499 if( m_pScriptSubPackageIterator != NULL )
3501 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3502 if( !xScriptPackage.is() )
3504 delete m_pScriptSubPackageIterator;
3505 m_pScriptSubPackageIterator = NULL;
3506 m_iUserPackage++;
3511 return xScriptPackage;
3514 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage( bool& rbPureDialogLib )
3516 Reference< deployment::XPackage > xScriptPackage;
3518 if( !m_bSharedPackagesLoaded )
3522 Reference< XExtensionManager > xSharedManager = ExtensionManager::get( m_xContext );
3523 m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions(OUString("shared"),
3524 Reference< task::XAbortChannel >(),
3525 Reference< ucb::XCommandEnvironment >() );
3527 catch(const com::sun::star::uno::DeploymentException& )
3529 // Special Office installations may not contain deployment code
3530 return xScriptPackage;
3533 m_bSharedPackagesLoaded = true;
3536 if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
3538 m_eState = BUNDLED_EXTENSIONS;
3540 else
3542 if( m_pScriptSubPackageIterator == NULL )
3544 const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
3545 Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
3546 SAL_WARN_IF(
3547 !xPackage.is(), "basic",
3548 ("ScriptExtensionIterator::implGetNextSharedScriptPackage():"
3549 " Invalid package"));
3550 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3553 if( m_pScriptSubPackageIterator != NULL )
3555 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3556 if( !xScriptPackage.is() )
3558 delete m_pScriptSubPackageIterator;
3559 m_pScriptSubPackageIterator = NULL;
3560 m_iSharedPackage++;
3565 return xScriptPackage;
3568 Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage( bool& rbPureDialogLib )
3570 Reference< deployment::XPackage > xScriptPackage;
3572 if( !m_bBundledPackagesLoaded )
3576 Reference< XExtensionManager > xManager = ExtensionManager::get( m_xContext );
3577 m_aBundledPackagesSeq = xManager->getDeployedExtensions(OUString("bundled"),
3578 Reference< task::XAbortChannel >(),
3579 Reference< ucb::XCommandEnvironment >() );
3581 catch(const com::sun::star::uno::DeploymentException& )
3583 // Special Office installations may not contain deployment code
3584 return xScriptPackage;
3587 m_bBundledPackagesLoaded = true;
3590 if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
3592 m_eState = END_REACHED;
3594 else
3596 if( m_pScriptSubPackageIterator == NULL )
3598 const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
3599 Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
3600 SAL_WARN_IF(
3601 !xPackage.is(), "basic",
3602 ("ScriptExtensionIterator::implGetNextBundledScriptPackage():"
3603 " Invalid package"));
3604 m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
3607 if( m_pScriptSubPackageIterator != NULL )
3609 xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
3610 if( !xScriptPackage.is() )
3612 delete m_pScriptSubPackageIterator;
3613 m_pScriptSubPackageIterator = NULL;
3614 m_iBundledPackage++;
3619 return xScriptPackage;
3622 } // namespace basic
3624 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */