LCOV - code coverage report
Current view: top level - basic/source/uno - namecont.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 869 1626 53.4 %
Date: 2015-06-13 12:38:46 Functions: 79 119 66.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11