summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2006-11-08 10:54:13 +0000
committerKurt Zenker <kz@openoffice.org>2006-11-08 10:54:13 +0000
commit57318c9249396898253ddc22b739f70c7ad9969e (patch)
tree31538d63e2287e4ba9bd8529f1a53a1a24f0b8a6 /basic
parent6586c6149a78b6b4428f434e72e682badc6ea11d (diff)
INTEGRATION: CWS basmgr01 (1.1.2); FILE ADDED
2006/10/04 12:33:48 fs 1.1.2.2: #i69957# lifetime control: BasicManager instances are kept in the responsibility of the BasicManagerRepository 2006/09/28 20:13:29 fs 1.1.2.1: #i69957# moved herein from sfx2/source/appl - base class for script/dialog library containers
Diffstat (limited to 'basic')
-rw-r--r--basic/source/uno/namecont.cxx2599
1 files changed, 2599 insertions, 0 deletions
diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx
new file mode 100644
index 000000000000..ce910c81d8b1
--- /dev/null
+++ b/basic/source/uno/namecont.cxx
@@ -0,0 +1,2599 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: namecont.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: kz $ $Date: 2006-11-08 11:54:13 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
+#include <com/sun/star/container/XNameContainer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CONTAINER_XCONTAINER_HPP_
+#include <com/sun/star/container/XContainer.hpp>
+#endif
+#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
+#include <com/sun/star/embed/ElementModes.hpp>
+#endif
+#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#endif
+
+#ifndef __RSC //autogen
+#include <tools/errinf.hxx>
+#endif
+#ifndef _OSL_MUTEX_HXX_
+#include <osl/mutex.hxx>
+#endif
+#ifndef _RTL_URI_HXX_
+#include <rtl/uri.hxx>
+#endif
+
+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
+#include <comphelper/processfactory.hxx>
+#endif
+#ifndef INCLUDED_COMPHELPER_ANYTOSTRING_HXX
+#include <comphelper/anytostring.hxx>
+#endif
+
+#include "namecont.hxx"
+
+#ifndef _URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#ifndef _UTL_STREAM_WRAPPER_HXX_
+#include <unotools/streamwrap.hxx>
+#endif
+#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
+#include <svtools/pathoptions.hxx>
+#endif
+#ifndef _SFXECODE_HXX
+#include <svtools/sfxecode.hxx>
+#endif
+#ifndef _EHDL_HXX
+#include <svtools/ehdl.hxx>
+#endif
+#ifndef _BASMGR_HXX
+#include "basmgr.hxx"
+#endif
+
+#ifndef _COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP_
+#include <com/sun/star/xml/sax/XParser.hpp>
+#endif
+#ifndef _COM_SUN_STAR_XML_SAX_INPUTSOURCE_HPP_
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
+#include <com/sun/star/io/XOutputStream.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UNO_DEPLOYMENTEXCEPTION_HPP_
+#include <com/sun/star/uno/DeploymentException.hpp>
+#endif
+
+#ifndef _COMPHELPER_STORAGEHELPER_HXX
+#include <comphelper/storagehelper.hxx>
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include <comphelper/anytostring.hxx>
+#endif
+#ifndef _CPPUHELPER_EXC_HLP_HXX_
+#include <cppuhelper/exc_hlp.hxx>
+#endif
+
+namespace basic
+{
+
+using namespace com::sun::star::container;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::io;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::script;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::xml::sax;
+using namespace com::sun::star::util;
+using namespace com::sun::star::task;
+using namespace com::sun::star;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+
+// #i34411: Flag for error handling during migration
+static bool GbMigrationSuppressErrors = false;
+
+//============================================================================
+// Implementation class NameContainer
+
+// Methods XElementAccess
+Type NameContainer::getElementType()
+ throw(RuntimeException)
+{
+ return mType;
+}
+
+sal_Bool NameContainer::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = (mnElementCount > 0);
+ return bRet;
+}
+
+// Methods XNameAccess
+Any NameContainer::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ if( aIt == mHashMap.end() )
+ {
+ throw NoSuchElementException();
+ }
+ sal_Int32 iHashResult = (*aIt).second;
+ Any aRetAny = mValues.getConstArray()[ iHashResult ];
+ return aRetAny;
+}
+
+Sequence< OUString > NameContainer::getElementNames()
+ throw(RuntimeException)
+{
+ return mNames;
+}
+
+sal_Bool NameContainer::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ sal_Bool bRet = ( aIt != mHashMap.end() );
+ return bRet;
+}
+
+
+// Methods XNameReplace
+void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Type aAnyType = aElement.getValueType();
+ if( mType != aAnyType )
+ throw IllegalArgumentException();
+
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ if( aIt == mHashMap.end() )
+ {
+ throw NoSuchElementException();
+ }
+ sal_Int32 iHashResult = (*aIt).second;
+ Any aOldElement = mValues.getConstArray()[ iHashResult ];
+ mValues.getArray()[ iHashResult ] = aElement;
+
+
+ // Fire event
+ ContainerEvent aEvent;
+ aEvent.Source = mpxEventSource;
+ aEvent.Accessor <<= aName;
+ aEvent.Element = aElement;
+ aEvent.ReplacedElement = aOldElement;
+
+ OInterfaceIteratorHelper aIterator( maListenerContainer );
+ while( aIterator.hasMoreElements() )
+ {
+ Reference< XInterface > xIface = aIterator.next();
+ Reference< XContainerListener > xListener( xIface, UNO_QUERY );
+ try
+ {
+ xListener->elementReplaced( aEvent );
+ }
+ catch(RuntimeException&)
+ {
+ aIterator.remove();
+ }
+ }
+}
+
+
+// Methods XNameContainer
+void NameContainer::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ Type aAnyType = aElement.getValueType();
+ if( mType != aAnyType )
+ throw IllegalArgumentException();
+
+ NameContainerNameMap::iterator aIt = mHashMap.find( aName );
+ if( aIt != mHashMap.end() )
+ {
+ throw ElementExistException();
+ }
+
+ sal_Int32 nCount = mNames.getLength();
+ mNames.realloc( nCount + 1 );
+ mValues.realloc( nCount + 1 );
+ mNames.getArray()[ nCount ] = aName;
+ mValues.getArray()[ nCount ] = aElement;
+
+ mHashMap[ aName ] = nCount;
+ mnElementCount++;
+
+
+ // Fire event
+ ContainerEvent aEvent;
+ aEvent.Source = mpxEventSource;
+ aEvent.Accessor <<= aName;
+ aEvent.Element = aElement;
+
+ OInterfaceIteratorHelper aIterator( maListenerContainer );
+ while( aIterator.hasMoreElements() )
+ {
+ Reference< XInterface > xIface = aIterator.next();
+ Reference< XContainerListener > xListener( xIface, UNO_QUERY );
+ try
+ {
+ xListener->elementInserted( aEvent );
+ }
+ catch(RuntimeException&)
+ {
+ aIterator.remove();
+ }
+ }
+}
+
+void NameContainer::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ NameContainerNameMap::iterator aIt = mHashMap.find( Name );
+ if( aIt == mHashMap.end() )
+ {
+ throw NoSuchElementException();
+ }
+
+ sal_Int32 iHashResult = (*aIt).second;
+ Any aOldElement = mValues.getConstArray()[ iHashResult ];
+ mHashMap.erase( aIt );
+ sal_Int32 iLast = mNames.getLength() - 1;
+ if( iLast != iHashResult )
+ {
+ OUString* pNames = mNames.getArray();
+ Any* pValues = mValues.getArray();
+ pNames[ iHashResult ] = pNames[ iLast ];
+ pValues[ iHashResult ] = pValues[ iLast ];
+ mHashMap[ pNames[ iHashResult ] ] = iHashResult;
+ }
+ mNames.realloc( iLast );
+ mValues.realloc( iLast );
+ mnElementCount--;
+
+
+ // Fire event
+ ContainerEvent aEvent;
+ aEvent.Source = mpxEventSource;
+ aEvent.Accessor <<= Name;
+ aEvent.Element = aOldElement;
+
+ OInterfaceIteratorHelper aIterator( maListenerContainer );
+ while( aIterator.hasMoreElements() )
+ {
+ Reference< XInterface > xIface = aIterator.next();
+ Reference< XContainerListener > xListener( xIface, UNO_QUERY );
+ try
+ {
+ xListener->elementRemoved( aEvent );
+ }
+ catch(RuntimeException&)
+ {
+ aIterator.remove();
+ }
+ }
+}
+
+
+// Methods XContainer
+void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ if( !xListener.is() )
+ throw RuntimeException();
+ Reference< XInterface > xIface( xListener, UNO_QUERY );
+ maListenerContainer.addInterface( xIface );
+}
+
+void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ if( !xListener.is() )
+ throw RuntimeException();
+ Reference< XInterface > xIface( xListener, UNO_QUERY );
+ maListenerContainer.removeInterface( xIface );
+}
+
+//============================================================================
+
+// Implementation class SfxLibraryContainer
+
+// Ctor
+SfxLibraryContainer::SfxLibraryContainer( void )
+ : maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
+ , mbModified( sal_False )
+ , mbOldInfoFormat( sal_False )
+ , mbOasis2OOoFormat( sal_False )
+ , mpBasMgr( NULL )
+ , mbOwnBasMgr( sal_False )
+{
+ mxMSF = comphelper::getProcessServiceFactory();
+ if( !mxMSF.is() )
+ {
+ OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
+ }
+
+ mxSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ if( !mxSFI.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create SimpleFileAccess component\n" );
+ }
+
+ mxStringSubstitution = Reference< XStringSubstitution >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.util.PathSubstitution" ) ), UNO_QUERY );
+ if( !mxStringSubstitution.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create PathSubstitution component\n" );
+ }
+}
+
+SfxLibraryContainer::~SfxLibraryContainer()
+{
+ if( mbOwnBasMgr )
+ BasicManager::LegacyDeleteBasicManager( mpBasMgr );
+}
+
+sal_Bool SfxLibraryContainer::isContainerModified()
+{
+ if ( mbModified )
+ return sal_True;
+
+ // the library container is not modified, go through the libraries and check whether they are modified
+ Sequence< OUString > aNames = maNameContainer.getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aName = pNames[ i ];
+ SfxLibrary* pImplLib = getImplLib( aName );
+ if( pImplLib->mbModified )
+ {
+ if ( aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ) ) )
+ {
+ // this is a workaround that has to be implemented because
+ // empty standard library should stay marked as modified
+ // but should not be treated as modified while it is empty
+ if ( pImplLib->hasElements() )
+ return sal_True;
+ }
+ else
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+void SfxLibraryContainer::setContainerModified( sal_Bool bModified )
+{
+ mbModified = bModified;
+}
+
+
+static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
+ const INetURLObject& rTargetFolderInetObj,
+ const OUString& rCheckFileName,
+ const OUString& rCheckExtension,
+ Reference< XSimpleFileAccess > xSFI )
+{
+ INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
+ aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ aTargetFolderInetObj.setExtension( rCheckExtension );
+ OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( !xSFI->exists( aTargetFile ) )
+ {
+ INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
+ aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ aSourceFolderInetObj.setExtension( rCheckExtension );
+ OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ xSFI->copy( aSourceFile, aTargetFile );
+ }
+}
+
+static void createVariableURL( OUString& rStr, const OUString& rLibName,
+ const OUString& rInfoFileName, bool bUser )
+{
+ if( bUser )
+ rStr = OUString::createFromAscii( "$(USER)/basic/" );
+ else
+ rStr = OUString::createFromAscii( "$(INST)/share/basic/" );
+
+ rStr += rLibName;
+ rStr += OUString::createFromAscii( "/" );
+ rStr += rInfoFileName;
+ rStr += OUString::createFromAscii( ".xlb/" );
+}
+
+sal_Bool SfxLibraryContainer::init(
+ const OUString& aInitialisationParam,
+ const OUString& aInfoFileName,
+ const OUString& aOldInfoFileName,
+ const OUString& aLibElementFileExtension,
+ const OUString& aLibrariesDir,
+ const uno::Reference< embed::XStorage >& xInitStorage )
+{
+ uno::Reference< embed::XStorage > xStorage = xInitStorage;
+
+ maInitialisationParam = aInitialisationParam;
+ maInfoFileName = aInfoFileName;
+ maOldInfoFileName = aOldInfoFileName;
+ maLibElementFileExtension = aLibElementFileExtension;
+ maLibrariesDir = aLibrariesDir;
+
+ meInitMode = DEFAULT;
+ INetURLObject aInitUrlInetObj( maInitialisationParam );
+ OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( aInitFileName.getLength() )
+ {
+ // We need a BasicManager to avoid problems
+ StarBASIC* pBas = new StarBASIC();
+ mpBasMgr = new BasicManager( pBas );
+ mbOwnBasMgr = sal_True;
+
+ OUString aExtension = aInitUrlInetObj.getExtension();
+ if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
+ {
+ meInitMode = CONTAINER_INIT_FILE;
+ INetURLObject aLibPathInetObj( aInitUrlInetObj );
+ aLibPathInetObj.removeSegment();
+ maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
+ {
+ meInitMode = LIBRARY_INIT_FILE;
+ uno::Reference< embed::XStorage > xDummyStor;
+ ::xmlscript::LibDescriptor aLibDesc;
+ sal_Bool bReadIndexFile = implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
+ return bReadIndexFile;
+ }
+ else
+ {
+ // Decide between old and new document
+ sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
+ if ( bOldStorage )
+ {
+ meInitMode = OLD_BASIC_STORAGE;
+ importFromOldStorage( aInitFileName );
+ return sal_True;
+ }
+ else
+ {
+ meInitMode = OFFICE_DOCUMENT;
+ try
+ {
+ xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
+ }
+ catch ( uno::Exception& )
+ {
+ // TODO: error handling
+ }
+//REMOVE xStorage = new SotStorage( sal_True, aInitFileName );
+ }
+ }
+ }
+ else
+ {
+ // Default pathes
+ maLibraryPath = SvtPathOptions().GetBasicPath();
+ }
+
+ Reference< XParser > xParser( mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
+ if( !xParser.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax parser component\n" );
+ return sal_False;
+ }
+
+ uno::Reference< io::XInputStream > xInput;
+
+ mxStorage = xStorage;
+ sal_Bool bStorage = mxStorage.is();
+
+
+ // #110009: Scope to force the StorageRefs to be destructed and
+ // so the streams to be closed before the preload opertation
+ {
+ // #110009
+
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ String aFileName;
+
+ int nPassCount = 1;
+ if( !bStorage && meInitMode == DEFAULT )
+ nPassCount = 2;
+ for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
+ {
+ if( bStorage )
+ {
+ OSL_ENSURE( meInitMode == DEFAULT || meInitMode == OFFICE_DOCUMENT,
+ "### Wrong InitMode for document\n" );
+ try
+ {
+ uno::Reference< io::XStream > xStream;
+ xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+//REMOVE xLibrariesStor = xStorage->OpenSotStorage( maLibrariesDir, STREAM_READ | STREAM_NOCREATE );
+ //if ( !xLibrariesStor.is() )
+ // TODO: the method must either return a storage or throw an exception
+ //throw uno::RuntimeException();
+
+ if ( xLibrariesStor.is() )
+ {
+ aFileName = maInfoFileName;
+ aFileName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
+
+ try
+ {
+ xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if( !xStream.is() )
+ {
+ mbOldInfoFormat = true;
+
+ // Check old version
+ aFileName = maOldInfoFileName;
+ aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ try
+ {
+ xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {}
+
+ if( !xStream.is() )
+ {
+ // Check for EA2 document version with wrong extensions
+ aFileName = maOldInfoFileName;
+ aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xli") );
+ xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
+ }
+ }
+ }
+
+ if ( xStream.is() )
+ xInput = xStream->getInputStream();
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: error handling?
+ }
+ }
+ else
+ {
+ INetURLObject* pLibInfoInetObj = NULL;
+ if( meInitMode == CONTAINER_INIT_FILE )
+ {
+ aFileName = aInitFileName;
+ }
+ else
+ {
+ if( nPass == 1 )
+ pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(0) );
+ else
+ pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(1) );
+ pLibInfoInetObj->insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ pLibInfoInetObj->setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
+ aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ try
+ {
+ xInput = mxSFI->openFileRead( aFileName );
+ }
+ catch( Exception& )
+ {
+ xInput.clear();
+ if( nPass == 0 )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+
+ // Old variant?
+ if( !xInput.is() && nPass == 0 )
+ {
+ INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
+ aLibInfoInetObj.insertName( maOldInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xli") ) );
+ aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ try
+ {
+ xInput = mxSFI->openFileRead( aFileName );
+ mbOldInfoFormat = true;
+ }
+ catch( Exception& )
+ {
+ xInput.clear();
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+
+ delete pLibInfoInetObj;
+ }
+
+ if( xInput.is() )
+ {
+ InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = aFileName;
+
+ // start parsing
+ ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();
+
+ try
+ {
+ xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
+ xParser->parseStream( source );
+ }
+ catch ( xml::sax::SAXException& e )
+ {
+ OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return sal_False;
+ }
+ catch ( io::IOException& e )
+ {
+ OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return sal_False;
+ }
+
+ sal_Int32 nLibCount = pLibArray->mnLibCount;
+ for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
+ {
+ ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];
+
+ // Check storage URL
+ OUString aStorageURL = rLib.aStorageURL;
+ if( !bStorage && !aStorageURL.getLength() && nPass == 0 )
+ {
+ String aLibraryPath;
+ if( meInitMode == CONTAINER_INIT_FILE )
+ aLibraryPath = maLibraryPath;
+ else
+ aLibraryPath = String(maLibraryPath).GetToken(1);
+ INetURLObject aInetObj( aLibraryPath );
+
+ aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aLibDirPath ) )
+ {
+ createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
+ mbModified = sal_True;
+ }
+ else if( rLib.bLink )
+ {
+ // Check "share" path
+ INetURLObject aShareInetObj( String(maLibraryPath).GetToken(0) );
+ aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aShareLibDirPath ) )
+ {
+ createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
+ mbModified = sal_True;
+ }
+ else
+ {
+ // #i25537: Ignore lib if library folder does not really exist
+ continue;
+ }
+ }
+ }
+
+ OUString aLibName = rLib.aName;
+
+ // If the same library name is used by the shared and the
+ // user lib container index files the user file wins
+ if( nPass == 1 && hasByName( aLibName ) )
+ continue;
+
+ SfxLibrary* pImplLib;
+ if( rLib.bLink )
+ {
+ Reference< XNameAccess > xLib =
+ createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
+ pImplLib = static_cast< SfxLibrary* >( xLib.get() );
+ }
+ else
+ {
+ Reference< XNameContainer > xLib = createLibrary( aLibName );
+ pImplLib = static_cast< SfxLibrary* >( xLib.get() );
+ pImplLib->mbLoaded = sal_False;
+ pImplLib->mbReadOnly = rLib.bReadOnly;
+ if( !bStorage )
+ checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
+ pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
+ }
+ mbModified = sal_False;
+
+ // Read library info files
+ if( !mbOldInfoFormat )
+ {
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( !pImplLib->mbInitialised && bStorage )
+ {
+ try {
+ xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
+ embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( 0, "### couln't open sub storage for library\n" );
+ }
+ }
+
+ // Link is already initialised in createLibraryLink()
+ if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
+ {
+ OUString aIndexFileName;
+ sal_Bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
+ if( bLoaded && aLibName != rLib.aName )
+ {
+ OSL_ENSURE( 0, "Different library names in library"
+ " container and library info files!\n" );
+ }
+ if( GbMigrationSuppressErrors && !bLoaded )
+ removeLibrary( aLibName );
+ }
+ }
+ else if( !bStorage )
+ {
+ // Write new index file immediately because otherwise
+ // the library elements will be lost when storing into
+ // the new info format
+ uno::Reference< embed::XStorage > xTmpStorage;
+ implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
+ }
+
+ implImportLibDescriptor( pImplLib, rLib );
+
+ if( nPass == 1 )
+ {
+ pImplLib->mbSharedIndexFile = sal_True;
+ pImplLib->mbReadOnly = sal_True;
+ }
+ }
+
+ // Keep flag for documents to force writing the new index files
+ if( !bStorage )
+ mbOldInfoFormat = sal_False;
+
+ delete pLibArray;
+ }
+ // Only in the first pass it's an error when no index file is found
+ else if( nPass == 0 )
+ {
+ return sal_False;
+ }
+ }
+
+ // #110009: END Scope to force the StorageRefs to be destructed
+ }
+ // #110009
+
+ // #110009 Preload?
+ {
+ Sequence< OUString > aNames = maNameContainer.getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aName = pNames[ i ];
+ SfxLibrary* pImplLib = getImplLib( aName );
+ if( pImplLib->mbPreload )
+ loadLibrary( aName );
+ }
+ }
+
+ // #118803# upgrade installation 7.0 -> 8.0
+ if( meInitMode == DEFAULT )
+ {
+ INetURLObject aUserBasicInetObj( String(maLibraryPath).GetToken(1) );
+ OUString aStandardStr( RTL_CONSTASCII_USTRINGPARAM("Standard") );
+
+ static char strPrevFolderName_1[] = "__basic_70";
+ static char strPrevFolderName_2[] = "__basic_70_2";
+ INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
+ aPrevUserBasicInetObj_1.removeSegment();
+ INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
+ aPrevUserBasicInetObj_1.Append( strPrevFolderName_1 );
+ aPrevUserBasicInetObj_2.Append( strPrevFolderName_2 );
+
+ INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
+ String aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ bool bSecondTime = false;
+ if( mxSFI->isFolder( aPrevFolder ) )
+ {
+ // #110101 Check if Standard folder exists and is complete
+ INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
+ aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
+ aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( mxSFI->isFolder( aPrevStandardFolder ) )
+ {
+ OUString aXlbExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
+ OUString aCheckFileName;
+
+ // Check if script.xlb exists
+ aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("script") );
+ checkAndCopyFileImpl( aUserBasicStandardInetObj,
+ aPrevUserBasicStandardInetObj,
+ aCheckFileName, aXlbExtension, mxSFI );
+
+ // Check if dialog.xlb exists
+ aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("dialog") );
+ checkAndCopyFileImpl( aUserBasicStandardInetObj,
+ aPrevUserBasicStandardInetObj,
+ aCheckFileName, aXlbExtension, mxSFI );
+
+ // Check if module1.xba exists
+ OUString aXbaExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xba") ) );
+ aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("Module1") );
+ checkAndCopyFileImpl( aUserBasicStandardInetObj,
+ aPrevUserBasicStandardInetObj,
+ aCheckFileName, aXbaExtension, mxSFI );
+ }
+ else
+ {
+ String aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ mxSFI->copy( aStandardFolder, aPrevStandardFolder );
+ }
+
+ String aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
+ mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
+ }
+ else
+ {
+ bSecondTime = true;
+ aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
+ aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ if( mxSFI->isFolder( aPrevFolder ) )
+ {
+ SfxLibraryContainer* pPrevCont = createInstanceImpl();
+ Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );
+
+ // Rename previous basic folder to make storage URLs correct during initialisation
+ String aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
+ aUserBasicTmpInetObj.removeSegment();
+ aUserBasicTmpInetObj.Append( "__basic_tmp" );
+ String aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ bool bMoveOk = true;
+ try
+ { mxSFI->move( aFolderUserBasic, aFolderTmp ); }
+ catch( CommandAbortedException& )
+ { bMoveOk = false; }
+ catch( Exception& )
+ { bMoveOk = false; }
+ if( bMoveOk )
+ {
+ try
+ { mxSFI->move( aPrevFolder, aFolderUserBasic ); }
+ catch( CommandAbortedException& )
+ { bMoveOk = false; }
+ catch( Exception& )
+ { bMoveOk = false; }
+ if( !bMoveOk )
+ {
+ // Move back user/basic folder
+ try
+ { mxSFI->move( aFolderTmp, aFolderUserBasic ); }
+ catch( CommandAbortedException& ) {}
+ catch( Exception& ) {}
+ }
+ }
+
+ if( bMoveOk )
+ {
+ INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
+ aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ aPrevUserBasicLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
+ OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ Sequence<Any> aInitSeq( 1 );
+ aInitSeq.getArray()[0] <<= aLibInfoFileName;
+ GbMigrationSuppressErrors = true;
+ pPrevCont->initialize( aInitSeq );
+ GbMigrationSuppressErrors = false;
+
+ // Rename folders back
+ mxSFI->move( aFolderUserBasic, aPrevFolder );
+ mxSFI->move( aFolderTmp, aFolderUserBasic );
+
+ // Detect old share/basic folder to destinguish
+ // between own links and links to wizards
+ INetURLObject aPrevOrgShareFolderInetObj;
+ if( pPrevCont->hasByName( aStandardStr ) )
+ {
+ SfxLibrary* pImplLib = pPrevCont->getImplLib( aStandardStr );
+ aPrevOrgShareFolderInetObj = INetURLObject( pImplLib->maStorageURL );
+ for( int i = 0 ; i < 3 ; ++ i )
+ aPrevOrgShareFolderInetObj.removeSegment();
+ aPrevOrgShareFolderInetObj.Append( "share" );
+ aPrevOrgShareFolderInetObj.Append( "basic" );
+ }
+
+ Sequence< OUString > aNames = pPrevCont->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 nNameCount = aNames.getLength();
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aLibName = pNames[ i ];
+ if( hasByName( aLibName ) )
+ {
+ if( aLibName == aStandardStr )
+ {
+ SfxLibrary* pImplLib = getImplLib( aStandardStr );
+ INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
+ String aStandardFolder = pImplLib->maStorageURL;
+ mxSFI->kill( aStandardFolder );
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
+ if( pImplLib->mbLink )
+ {
+ INetURLObject aPrevLinkInetObj( pImplLib->maStorageURL );
+ for( int j = 0 ; j < 3 ; ++ j )
+ aPrevLinkInetObj.removeSegment();
+ aPrevLinkInetObj.Append( "share" );
+ aPrevLinkInetObj.Append( "basic" );
+ if( aPrevLinkInetObj != aPrevOrgShareFolderInetObj )
+ createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
+ }
+ else
+ {
+ // Move folder if not already done
+ INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
+ aUserBasicLibFolderInetObj.Append( aLibName );
+ String aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
+ aPrevUserBasicLibFolderInetObj.Append( aLibName );
+ String aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
+ mxSFI->move( aPrevLibFolder, aLibFolder );
+
+ if( aLibName == aStandardStr )
+ maNameContainer.removeByName( aLibName );
+
+ // Create library
+ Reference< XNameContainer > xLib = createLibrary( aLibName );
+ SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
+ pNewLib->mbLoaded = false;
+ pNewLib->mbModified = false;
+ checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
+ pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );
+
+ uno::Reference< embed::XStorage > xDummyStor;
+ ::xmlscript::LibDescriptor aLibDesc;
+ /*sal_Bool bReadIndexFile =*/ implLoadLibraryIndexFile
+ ( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
+ implImportLibDescriptor( pNewLib, aLibDesc );
+ }
+ }
+ mxSFI->kill( aPrevFolder );
+ } // if( bMoveOk )
+ }
+ }
+
+ return sal_True;
+}
+
+// Handle maLibInfoFileURL and maStorageURL correctly
+void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
+ OUString& aLibInfoFileURL, OUString& aStorageURL, OUString& aUnexpandedStorageURL )
+{
+ OUString aExpandedSourceURL = expand_url( aSourceURL );
+ if( aExpandedSourceURL != aSourceURL )
+ aUnexpandedStorageURL = aSourceURL;
+
+ INetURLObject aInetObj( aExpandedSourceURL );
+ OUString aExtension = aInetObj.getExtension();
+ if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
+ {
+ // URL to xlb file
+ aLibInfoFileURL = aExpandedSourceURL;
+ aInetObj.removeSegment();
+ aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ // URL to library folder
+ aStorageURL = aExpandedSourceURL;
+ aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
+ aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+}
+
+SfxLibrary* SfxLibraryContainer::getImplLib( const String& rLibraryName )
+{
+ Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+ return pImplLib;
+}
+
+
+// Storing with password encryption
+
+// Empty implementation, avoids unneccesary implementation in dlgcont.cxx
+sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
+ SfxLibrary*,
+ const OUString&,
+ const uno::Reference< embed::XStorage >& )
+{
+ return sal_False;
+}
+
+sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
+ SfxLibrary* /*pLib*/,
+ const ::rtl::OUString& /*aName*/,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
+ const ::rtl::OUString& /*aTargetURL*/,
+ const Reference< XSimpleFileAccess > /*xToUseSFI*/ )
+{
+ return sal_False;
+}
+
+sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
+ SfxLibrary* /*pLib*/,
+ const OUString& /*Name*/,
+ sal_Bool /*bVerifyPasswordOnly*/ )
+throw(WrappedTargetException, RuntimeException)
+{
+ return sal_True;
+}
+
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand"
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+OUString SfxLibraryContainer::createAppLibraryFolder
+ ( SfxLibrary* pLib, const OUString& aName )
+{
+ OUString aLibDirPath = pLib->maStorageURL;
+ if( !aLibDirPath.getLength() )
+ {
+ INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
+ aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
+ pLib->maStorageURL, pLib->maUnexpandedStorageURL );
+ aLibDirPath = pLib->maStorageURL;
+ }
+
+ if( !mxSFI->isFolder( aLibDirPath ) )
+ {
+ try
+ {
+ mxSFI->createFolder( aLibDirPath );
+ }
+ catch( Exception& )
+ {}
+ }
+
+ return aLibDirPath;
+}
+
+// Storing
+void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
+ const OUString& aName, const uno::Reference< embed::XStorage >& xStorage )
+{
+ OUString aDummyLocation;
+ Reference< XSimpleFileAccess > xDummySFA;
+ implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA );
+}
+
+// New variant for library export
+void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
+ const OUString& aName, const uno::Reference< embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI )
+{
+ sal_Bool bLink = pLib->mbLink;
+ sal_Bool bStorage = xStorage.is() && !bLink;
+
+ Sequence< OUString > aElementNames = pLib->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+
+ if( bStorage )
+ {
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ OUString aStreamName = aElementName;
+ aStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ Any aElement = pLib->getByName( aElementName );
+ if( isLibraryElementValid( aElement ) )
+ {
+ try {
+ uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
+ aStreamName,
+ embed::ElementModes::READWRITE );
+ //if ( !xElementStream.is() )
+ // throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception
+
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+
+ uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
+ OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
+ //if ( !xProps.is() ) //TODO
+ // throw uno::RuntimeException();
+
+ if ( xProps.is() )
+ {
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // #87671 Allow encryption
+//REMOVE aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
+ xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
+
+ Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
+ writeLibraryElement( aElement, aElementName, xOutput );
+ // writeLibraryElement closes the stream
+ // xOutput->closeOutput();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of library!\n" );
+ // TODO: error handling?
+ }
+ }
+ }
+ }
+ else
+ {
+ // Export?
+ bool bExport = aTargetURL.getLength();
+ try
+ {
+ Reference< XSimpleFileAccess > xSFI = mxSFI;
+ if( xToUseSFI.is() )
+ xSFI = xToUseSFI;
+
+ OUString aLibDirPath;
+ if( bExport )
+ {
+ INetURLObject aInetObj( aTargetURL );
+ aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ if( !xSFI->isFolder( aLibDirPath ) )
+ xSFI->createFolder( aLibDirPath );
+ }
+ else
+ {
+ aLibDirPath = createAppLibraryFolder( pLib, aName );
+ }
+
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ Any aElement = pLib->getByName( aElementName );
+ if( isLibraryElementValid( aElement ) )
+ {
+ // TODO: Check modified
+ try
+ {
+ if( xSFI->exists( aElementPath ) )
+ xSFI->kill( aElementPath );
+ Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
+ writeLibraryElement( aElement, aElementName, xOutput );
+ xOutput->closeOutput();
+ }
+ catch( Exception& )
+ {
+ if( bExport )
+ throw;
+
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ if( bExport )
+ throw;
+ }
+ }
+}
+
+void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
+ const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage )
+{
+ OUString aDummyLocation;
+ Reference< XSimpleFileAccess > xDummySFA;
+ implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
+}
+
+// New variant for library export
+void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
+ const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage,
+ const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI )
+{
+ // Create sax writer
+ Reference< XExtendedDocumentHandler > xHandler(
+ mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
+ if( !xHandler.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
+ return;
+ }
+
+ sal_Bool bLink = pLib->mbLink;
+ sal_Bool bStorage = xStorage.is() && !bLink;
+
+ // Write info file
+ uno::Reference< io::XOutputStream > xOut;
+ uno::Reference< io::XStream > xInfoStream;
+ if( bStorage )
+ {
+ OUString aStreamName( maInfoFileName );
+ aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
+
+ try {
+ xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
+ OSL_ENSURE( xInfoStream.is(), "No stream!\n" );
+ uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
+ //if ( !xProps.is() )
+ // throw uno::RuntimeException(); // TODO
+
+ if ( xProps.is() )
+ {
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // #87671 Allow encryption
+//REMOVE aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
+ xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
+
+ xOut = xInfoStream->getOutputStream();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of library index file!\n" );
+ // TODO: error handling?
+ }
+ }
+ else
+ {
+ // Export?
+ bool bExport = aTargetURL.getLength();
+ Reference< XSimpleFileAccess > xSFI = mxSFI;
+ if( xToUseSFI.is() )
+ xSFI = xToUseSFI;
+
+ OUString aLibInfoPath;
+ if( bExport )
+ {
+ INetURLObject aInetObj( aTargetURL );
+ aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ if( !xSFI->isFolder( aLibDirPath ) )
+ xSFI->createFolder( aLibDirPath );
+
+ aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
+ aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ createAppLibraryFolder( pLib, rLib.aName );
+ aLibInfoPath = pLib->maLibInfoFileURL;
+ }
+
+ try
+ {
+ if( xSFI->exists( aLibInfoPath ) )
+ xSFI->kill( aLibInfoPath );
+ xOut = xSFI->openFileWrite( aLibInfoPath );
+ }
+ catch( Exception& )
+ {
+ if( bExport )
+ throw;
+
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ if( !xOut.is() )
+ {
+ OSL_ENSURE( 0, "### couln't open output stream\n" );
+ return;
+ }
+
+ Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
+ xSource->setOutputStream( xOut );
+
+ xmlscript::exportLibrary( xHandler, rLib );
+}
+
+
+sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile( SfxLibrary* pLib,
+ ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, const OUString& aIndexFileName )
+{
+ Reference< XParser > xParser( mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
+ if( !xParser.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax parser component\n" );
+ return sal_False;
+ }
+
+ sal_Bool bLink = sal_False;
+ sal_Bool bStorage = sal_False;
+ if( pLib )
+ {
+ bLink = pLib->mbLink;
+ bStorage = xStorage.is() && !bLink;
+ }
+
+ // Read info file
+ uno::Reference< io::XInputStream > xInput;
+ String aLibInfoPath;
+ if( bStorage )
+ {
+ aLibInfoPath = maInfoFileName;
+ aLibInfoPath += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );
+
+ try {
+ uno::Reference< io::XStream > xInfoStream =
+ xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
+ xInput = xInfoStream->getInputStream();
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ else
+ {
+ // Create Input stream
+ //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!
+
+ if( pLib )
+ {
+ createAppLibraryFolder( pLib, rLib.aName );
+ aLibInfoPath = pLib->maLibInfoFileURL;
+ }
+ else
+ aLibInfoPath = aIndexFileName;
+
+ try
+ {
+ xInput = mxSFI->openFileRead( aLibInfoPath );
+ }
+ catch( Exception& )
+ {
+ xInput.clear();
+ if( !GbMigrationSuppressErrors )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ }
+ if( !xInput.is() )
+ {
+ // OSL_ENSURE( 0, "### couln't open input stream\n" );
+ return sal_False;
+ }
+
+ InputSource source;
+ source.aInputStream = xInput;
+ source.sSystemId = aLibInfoPath;
+
+ // start parsing
+ try {
+ xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
+ xParser->parseStream( source );
+ }
+ catch( Exception& )
+ {
+ // throw WrappedTargetException( OUString::createFromAscii( "parsing error!\n" ),
+ // Reference< XInterface >(),
+ // makeAny( e ) );
+ OSL_ENSURE( 0, "Parsing error\n" );
+ SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ return sal_False;
+ }
+
+ if( !pLib )
+ {
+ Reference< XNameContainer > xLib = createLibrary( rLib.aName );
+ pLib = static_cast< SfxLibrary* >( xLib.get() );
+ pLib->mbLoaded = sal_False;
+ rLib.aStorageURL = aIndexFileName;
+ checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
+ pLib->maUnexpandedStorageURL );
+
+ implImportLibDescriptor( pLib, rLib );
+ }
+
+ return sal_True;
+}
+
+void SfxLibraryContainer::implImportLibDescriptor
+ ( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib )
+{
+ if( !pLib->mbInitialised )
+ {
+ sal_Int32 nElementCount = rLib.aElementNames.getLength();
+ const OUString* pElementNames = rLib.aElementNames.getConstArray();
+ Any aDummyElement = createEmptyLibraryElement();
+ for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
+ {
+ pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
+ }
+ pLib->mbPasswordProtected = rLib.bPasswordProtected;
+ pLib->mbReadOnly = rLib.bReadOnly;
+ pLib->mbPreload = rLib.bPreload;
+ pLib->mbModified = sal_False;
+
+ pLib->mbInitialised = sal_True;
+ }
+}
+
+
+void SfxLibraryContainer::storeLibraries( sal_Bool bComplete )
+{
+ uno::Reference< embed::XStorage > xStorage;
+ storeLibraries_Impl( xStorage, bComplete );
+}
+
+void SfxLibraryContainer::storeLibrariesToStorage( const uno::Reference< embed::XStorage >& xStorage )
+{
+ sal_Bool bComplete = sal_True;
+ storeLibraries_Impl( xStorage, bComplete );
+}
+
+// Methods of new XLibraryStorage interface?
+void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& xStorage, sal_Bool bComplete )
+{
+ Sequence< OUString > aNames = maNameContainer.getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ sal_Int32 i, nNameCount = aNames.getLength();
+
+ // Don't count libs from shared index file
+ sal_Int32 nLibsToSave = nNameCount;
+ for( i = 0 ; i < nNameCount ; i++ )
+ {
+ SfxLibrary* pImplLib = getImplLib( pNames[ i ] );
+ if( pImplLib->mbSharedIndexFile )
+ nLibsToSave--;
+ }
+ if( !nLibsToSave )
+ return;
+
+ ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray( nLibsToSave );
+
+ // Write to storage?
+ sal_Bool bStorage = xStorage.is();
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ uno::Reference< embed::XStorage > xSourceLibrariesStor;
+ if( bStorage )
+ {
+ // Don't write if only empty standard lib exists
+ if( nNameCount == 1 )
+ {
+ // Must be standard lib
+ Any aLibAny = maNameContainer.getByName( pNames[0] );
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ if( !xNameAccess->hasElements() )
+ return;
+ }
+
+ try {
+ xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+ }
+ catch( uno::Exception& )
+ {
+ uno::Any exc( cppu::getCaughtException() ); // cppuhelper/exc_hlp.hxx
+ ::rtl::OUString msg( ::comphelper::anyToString(exc) ); // comphelper/anytostring.hxx
+ OSL_ENSURE( 0, rtl::OUStringToOString( msg, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ return;
+ }
+
+ try {
+ xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ int iArray = 0;
+ for( i = 0 ; i < nNameCount ; i++ )
+ {
+ SfxLibrary* pImplLib = getImplLib( pNames[ i ] );
+ if( pImplLib->mbSharedIndexFile )
+ continue;
+ ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[iArray];
+ rLib.aName = pNames[ i ];
+ iArray++;
+
+ rLib.bLink = pImplLib->mbLink;
+ if( !bStorage || pImplLib->mbLink )
+ {
+ rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
+ pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
+ }
+ rLib.bReadOnly = pImplLib->mbReadOnly;
+ rLib.bPreload = pImplLib->mbPreload;
+ rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
+ rLib.aElementNames = pImplLib->getElementNames();
+
+ if( pImplLib->mbModified || bComplete )
+ {
+ // Can we copy the storage?
+ if( !mbOldInfoFormat && !pImplLib->mbModified && !mbOasis2OOoFormat && xSourceLibrariesStor.is() )
+ {
+ try {
+ xSourceLibrariesStor->copyElementTo( rLib.aName, xLibrariesStor, rLib.aName );
+ } catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
+ // TODO: error handling?
+ }
+ }
+ else
+ {
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( bStorage )
+ {
+ try {
+ xLibraryStor = xLibrariesStor->openStorageElement(
+ rLib.aName,
+ embed::ElementModes::READWRITE );
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( 0, "### couln't create sub storage for library\n" );
+ return;
+ }
+ }
+
+ // Maybe lib is not loaded?!
+ if( bComplete )
+ loadLibrary( rLib.aName );
+
+ if( pImplLib->mbPasswordProtected )
+ implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor );
+ // TODO: Check return value
+ else
+ implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );
+
+ implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
+ if( bStorage )
+ {
+ try {
+ uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY );
+ OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
+ if ( !xTransact.is() )
+ throw uno::RuntimeException();
+
+ xTransact->commit();
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
+ // TODO: error handling
+ }
+ }
+ }
+
+ mbModified = sal_True;
+ pImplLib->mbModified = sal_False;
+ }
+
+ // For container info ReadOnly refers to mbReadOnlyLink
+ rLib.bReadOnly = pImplLib->mbReadOnlyLink;
+ }
+
+ if( !mbOldInfoFormat && !mbModified )
+ return;
+ mbModified = sal_False;
+ mbOldInfoFormat = sal_False;
+
+ // Write library container info
+ // Create sax writer
+ Reference< XExtendedDocumentHandler > xHandler(
+ mxMSF->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
+ if( !xHandler.is() )
+ {
+ OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
+ return;
+ }
+
+ // Write info file
+ uno::Reference< io::XOutputStream > xOut;
+ uno::Reference< io::XStream > xInfoStream;
+ if( bStorage )
+ {
+ OUString aStreamName( maInfoFileName );
+ aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );
+
+ try {
+ xInfoStream = xLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
+ uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
+ OSL_ENSURE ( xProps.is(), "The stream must implement XPropertySet!\n" );
+ if ( !xProps.is() )
+ throw uno::RuntimeException();
+
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );
+
+ // #87671 Allow encryption
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("UseCommonStoragePasswordEncryption") );
+ xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
+
+ xOut = xInfoStream->getOutputStream();
+ }
+ catch( uno::Exception& )
+ {
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ else
+ {
+ // Create Output stream
+ INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
+ aLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
+ String aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ try
+ {
+ if( mxSFI->exists( aLibInfoPath ) )
+ mxSFI->kill( aLibInfoPath );
+ xOut = mxSFI->openFileWrite( aLibInfoPath );
+ }
+ catch( Exception& )
+ {
+ xOut.clear();
+ SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+
+ }
+ if( !xOut.is() )
+ {
+ OSL_ENSURE( 0, "### couln't open output stream\n" );
+ return;
+ }
+
+ Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
+ xSource->setOutputStream( xOut );
+
+ try
+ {
+ xmlscript::exportLibraryContainer( xHandler, pLibArray );
+ if ( bStorage )
+ {
+ uno::Reference< embed::XTransactedObject > xTransact( xLibrariesStor, uno::UNO_QUERY );
+ OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
+ if ( !xTransact.is() )
+ throw uno::RuntimeException();
+
+ xTransact->commit();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
+ ULONG nErrorCode = ERRCODE_IO_GENERAL;
+ ErrorHandler::HandleError( nErrorCode );
+ }
+
+ delete pLibArray;
+}
+
+
+// Methods XElementAccess
+Type SfxLibraryContainer::getElementType()
+ throw(RuntimeException)
+{
+ return maNameContainer.getElementType();
+}
+
+sal_Bool SfxLibraryContainer::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = maNameContainer.hasElements();
+ return bRet;
+}
+
+// Methods XNameAccess
+Any SfxLibraryContainer::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any aRetAny = maNameContainer.getByName( aName ) ;
+ return aRetAny;
+}
+
+Sequence< OUString > SfxLibraryContainer::getElementNames()
+ throw(RuntimeException)
+{
+ return maNameContainer.getElementNames();
+}
+
+sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = maNameContainer.hasByName( aName ) ;
+ return bRet;
+}
+
+// Methods XLibraryContainer
+Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
+ throw(IllegalArgumentException, ElementExistException, RuntimeException)
+{
+ SfxLibrary* pNewLib = implCreateLibrary();
+ pNewLib->maLibElementFileExtension = maLibElementFileExtension;
+
+ createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );
+
+ Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
+ Any aElement;
+ aElement <<= xNameAccess;
+ maNameContainer.insertByName( Name, aElement );
+ mbModified = sal_True;
+ Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
+ return xRet;
+}
+
+Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
+ ( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
+ throw(IllegalArgumentException, ElementExistException, RuntimeException)
+{
+ // TODO: Check other reasons to force ReadOnly status
+ //if( !ReadOnly )
+ //{
+ //}
+
+ OUString aLibInfoFileURL;
+ OUString aLibDirURL;
+ OUString aUnexpandedStorageURL;
+ checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );
+
+
+ SfxLibrary* pNewLib = implCreateLibraryLink( aLibInfoFileURL, aLibDirURL, ReadOnly );
+ pNewLib->maLibElementFileExtension = maLibElementFileExtension;
+ pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
+
+ OUString aInitFileName;
+ uno::Reference< embed::XStorage > xDummyStor;
+ ::xmlscript::LibDescriptor aLibDesc;
+ /*sal_Bool bReadIndexFile = */implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
+ implImportLibDescriptor( pNewLib, aLibDesc );
+
+ Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
+ Any aElement;
+ aElement <<= xRet;
+ maNameContainer.insertByName( Name, aElement );
+ mbModified = sal_True;
+ return xRet;
+}
+
+void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ // Get and hold library before removing
+ Any aLibAny = maNameContainer.getByName( Name ) ;
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+ if( pImplLib->mbReadOnly && !pImplLib->mbLink )
+ throw IllegalArgumentException();
+
+ // Remove from container
+ maNameContainer.removeByName( Name );
+ mbModified = sal_True;
+
+ // Delete library files, but not for linked libraries
+ if( !pImplLib->mbLink )
+ {
+ if( mxStorage.is() )
+ return;
+ if( xNameAccess->hasElements() )
+ {
+ Sequence< OUString > aNames = pImplLib->getElementNames();
+ sal_Int32 nNameCount = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+ pImplLib->removeByName( aElementName );
+ }
+ }
+
+ // Delete index file
+ createAppLibraryFolder( pImplLib, Name );
+ String aLibInfoPath = pImplLib->maLibInfoFileURL;
+ try
+ {
+ if( mxSFI->exists( aLibInfoPath ) )
+ mxSFI->kill( aLibInfoPath );
+ }
+ catch( Exception& ) {}
+
+ // Delete folder if empty
+ INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
+ aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ try
+ {
+ if( mxSFI->isFolder( aLibDirPath ) )
+ {
+ Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
+ sal_Int32 nCount = aContentSeq.getLength();
+ if( !nCount )
+ mxSFI->kill( aLibDirPath );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
+ throw(NoSuchElementException, RuntimeException)
+{
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbLoaded;
+ return bRet;
+}
+
+
+void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any aLibAny = maNameContainer.getByName( Name ) ;
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+
+ sal_Bool bLoaded = pImplLib->mbLoaded;
+ pImplLib->mbLoaded = sal_True;
+ if( !bLoaded && xNameAccess->hasElements() )
+ {
+ if( pImplLib->mbPasswordProtected )
+ {
+ implLoadPasswordLibrary( pImplLib, Name );
+ return;
+ }
+
+ sal_Bool bLink = pImplLib->mbLink;
+ sal_Bool bStorage = mxStorage.is() && !bLink;
+
+ uno::Reference< embed::XStorage > xLibrariesStor;
+ uno::Reference< embed::XStorage > xLibraryStor;
+ if( bStorage )
+ {
+ try {
+ xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
+ OSL_ENSURE( xLibrariesStor.is(), "The method must either throw exception or return a storage!\n" );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+
+ xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
+ OSL_ENSURE( xLibraryStor.is(), "The method must either throw exception or return a storage!\n" );
+ if ( !xLibrariesStor.is() )
+ throw uno::RuntimeException();
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( 0, "### couln't open sub storage for library\n" );
+ return;
+ }
+ }
+
+ Sequence< OUString > aNames = pImplLib->getElementNames();
+ sal_Int32 nNameCount = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ OUString aFile;
+ uno::Reference< io::XInputStream > xInStream;
+
+ if( bStorage )
+ {
+ uno::Reference< io::XStream > xElementStream;
+
+ aFile = aElementName;
+ aFile += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );
+
+ try {
+ xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {}
+
+ if( !xElementStream.is() )
+ {
+ // Check for EA2 document version with wrong extensions
+ aFile = aElementName;
+ aFile += String( RTL_CONSTASCII_USTRINGPARAM(".") );
+ aFile += maLibElementFileExtension;
+ try {
+ xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
+ } catch( uno::Exception& )
+ {}
+ }
+
+ if ( xElementStream.is() )
+ xInStream = xElementStream->getInputStream();
+
+ if ( !xInStream.is() )
+ {
+ OSL_ENSURE( 0, "### couln't open library element stream\n" );
+ return;
+ }
+ }
+ else
+ {
+ String aLibDirPath = pImplLib->maStorageURL;
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+
+ Any aAny = importLibraryElement( aFile, xInStream );
+ if( pImplLib->hasByName( aElementName ) )
+ {
+ if( aAny.hasValue() )
+ pImplLib->maNameContainer.replaceByName( aElementName, aAny );
+ }
+ else
+ {
+ pImplLib->maNameContainer.insertByName( aElementName, aAny );
+ }
+ }
+
+ pImplLib->mbModified = sal_False;
+ }
+}
+
+// Methods XLibraryContainer2
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
+ throw (NoSuchElementException, RuntimeException)
+{
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbLink;
+ return bRet;
+}
+
+OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bLink = pImplLib->mbLink;
+ if( !bLink )
+ throw IllegalArgumentException();
+ OUString aRetStr = pImplLib->maLibInfoFileURL;
+ return aRetStr;
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
+ throw (NoSuchElementException, RuntimeException)
+{
+ SfxLibrary* pImplLib = getImplLib( Name );
+ sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
+ return bRet;
+}
+
+void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
+ throw (NoSuchElementException, RuntimeException)
+{
+ SfxLibrary* pImplLib = getImplLib( Name );
+ if( pImplLib->mbLink )
+ {
+ if( pImplLib->mbReadOnlyLink != bReadOnly )
+ {
+ pImplLib->mbReadOnlyLink = bReadOnly;
+ pImplLib->mbModified = sal_True;
+ mbModified = sal_True;
+ }
+ }
+ else
+ {
+ if( pImplLib->mbReadOnly != bReadOnly )
+ {
+ pImplLib->mbReadOnly = bReadOnly;
+ pImplLib->mbModified = sal_True;
+ }
+ }
+}
+
+void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
+ throw (NoSuchElementException, ElementExistException, RuntimeException)
+{
+ if( maNameContainer.hasByName( NewName ) )
+ throw ElementExistException();
+
+ // Get and hold library before removing
+ Any aLibAny = maNameContainer.getByName( Name ) ;
+
+ // #i24094 Maybe lib is not loaded!
+ Reference< XNameAccess > xNameAccess;
+ aLibAny >>= xNameAccess;
+ SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
+ if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
+ return; // Lib with unverified password cannot be renamed
+ loadLibrary( Name );
+
+ // Remove from container
+ maNameContainer.removeByName( Name );
+ mbModified = sal_True;
+
+ // Rename library folder, but not for linked libraries
+ bool bMovedSuccessful = true;
+
+ // Rename files
+ sal_Bool bStorage = mxStorage.is();
+ if( !bStorage && !pImplLib->mbLink )
+ {
+ bMovedSuccessful = false;
+
+ OUString aLibDirPath = pImplLib->maStorageURL;
+
+ INetURLObject aDestInetObj( String(maLibraryPath).GetToken(1) );
+ aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
+ sal_True, INetURLObject::ENCODE_ALL );
+ OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ // Store new URL
+ OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
+ checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
+ pImplLib->maUnexpandedStorageURL );
+
+ try
+ {
+ if( mxSFI->isFolder( aLibDirPath ) )
+ {
+ if( !mxSFI->isFolder( aDestDirPath ) )
+ mxSFI->createFolder( aDestDirPath );
+
+ // Move index file
+ try
+ {
+ if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
+ mxSFI->kill( pImplLib->maLibInfoFileURL );
+ mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
+ }
+ catch( Exception& )
+ {
+ }
+
+ Sequence< OUString > aElementNames = xNameAccess->getElementNames();
+ sal_Int32 nNameCount = aElementNames.getLength();
+ const OUString* pNames = aElementNames.getConstArray();
+ for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
+ {
+ OUString aElementName = pNames[ i ];
+
+ INetURLObject aElementInetObj( aLibDirPath );
+ aElementInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ INetURLObject aElementDestInetObj( aDestDirPath );
+ aElementDestInetObj.insertName( aElementName, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementDestInetObj.setExtension( maLibElementFileExtension );
+ String aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ try
+ {
+ if( mxSFI->exists( aDestElementPath ) )
+ mxSFI->kill( aDestElementPath );
+ mxSFI->move( aElementPath, aDestElementPath );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ // Delete folder if empty
+ Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
+ sal_Int32 nCount = aContentSeq.getLength();
+ if( !nCount )
+ {
+ mxSFI->kill( aLibDirPath );
+ }
+
+ bMovedSuccessful = true;
+ pImplLib->mbModified = true;
+ }
+ }
+ catch( Exception& )
+ {
+ // Restore old library
+ maNameContainer.insertByName( Name, aLibAny ) ;
+ }
+ }
+
+ if( bStorage && !pImplLib->mbLink )
+ pImplLib->mbModified = true;
+
+ if( bMovedSuccessful )
+ maNameContainer.insertByName( NewName, aLibAny ) ;
+
+}
+
+
+// Methods XLibraryContainerPassword
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
+ throw (NoSuchElementException, RuntimeException)
+{
+ sal_Bool bRet = sal_False;
+ return bRet;
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ throw IllegalArgumentException();
+}
+
+sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword
+ ( const OUString&, const OUString& )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ throw IllegalArgumentException();
+}
+
+void SAL_CALL SfxLibraryContainer::changeLibraryPassword(
+ const OUString&, const OUString&, const OUString& )
+ throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
+{
+ throw IllegalArgumentException();
+}
+
+// Methods XContainer
+void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
+ maNameContainer.addContainerListener( xListener );
+}
+
+void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ maNameContainer.removeContainerListener( xListener );
+}
+
+// Methods XLibraryContainerExport
+void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
+ const Reference< XInteractionHandler >& Handler )
+ throw ( uno::Exception, NoSuchElementException, RuntimeException)
+{
+ SfxLibrary* pImplLib = getImplLib( Name );
+
+ Reference< XSimpleFileAccess > xToUseSFI;
+ if( Handler.is() )
+ {
+ xToUseSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
+ ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ if( xToUseSFI.is() )
+ xToUseSFI->setInteractionHandler( Handler );
+ }
+
+ // Maybe lib is not loaded?!
+ loadLibrary( Name );
+
+ uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
+ if( pImplLib->mbPasswordProtected )
+ implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI );
+ else
+ implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI );
+
+ ::xmlscript::LibDescriptor aLibDesc;
+ aLibDesc.aName = Name;
+ aLibDesc.bLink = false; // Link status gets lost?
+ aLibDesc.bReadOnly = pImplLib->mbReadOnly;
+ aLibDesc.bPreload = false; // Preload status gets lost?
+ aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
+ aLibDesc.aElementNames = pImplLib->getElementNames();
+
+ implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
+}
+
+OUString SfxLibraryContainer::expand_url( const OUString& url )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (0 == url.compareToAscii( RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ))
+ {
+ if( !mxMacroExpander.is() )
+ {
+ Reference< XPropertySet > xProps( mxMSF, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if( xProps.is() )
+ {
+ Reference< XComponentContext > xContext;
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ if( xContext.is() )
+ {
+ Reference< util::XMacroExpander > xExpander;
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.util.theMacroExpander") ) >>= xExpander;
+ if(! xExpander.is())
+ {
+ throw DeploymentException(
+ OUSTR("no macro expander singleton available!"), Reference< XInterface >() );
+ }
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !mxMacroExpander.is() )
+ {
+ mxMacroExpander = xExpander;
+ }
+ }
+ }
+ }
+
+ if( !mxMacroExpander.is() )
+ return url;
+
+ // cut protocol
+ OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
+ // decode uric class chars
+ macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ OUString ret( mxMacroExpander->expandMacros( macro ) );
+ return ret;
+ }
+ else if( mxStringSubstitution.is() )
+ {
+ OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
+ return ret;
+ }
+ else
+ {
+ return url;
+ }
+}
+
+
+//============================================================================
+
+// Implementation class SfxLibrary
+
+// Ctor
+SfxLibrary::SfxLibrary( Type aType,
+ Reference< XMultiServiceFactory > xMSF,
+ Reference< XSimpleFileAccess > xSFI )
+ : OComponentHelper( m_aMutex )
+ , mxMSF( xMSF )
+ , mxSFI( xSFI )
+ , maNameContainer( aType )
+ , mbLoaded( sal_True )
+ , mbModified( sal_True )
+ , mbInitialised( sal_False )
+ , mbLink( sal_False )
+ , mbReadOnly( sal_False )
+ , mbReadOnlyLink( sal_False )
+ , mbPreload( sal_False )
+ , mbPasswordProtected( sal_False )
+ , mbPasswordVerified( sal_False )
+ , mbDoc50Password( sal_False )
+ , mbSharedIndexFile( sal_False )
+{
+}
+
+SfxLibrary::SfxLibrary( Type aType,
+ Reference< XMultiServiceFactory > xMSF,
+ Reference< XSimpleFileAccess > xSFI ,
+ const OUString& aLibInfoFileURL,
+ const OUString& aStorageURL, sal_Bool ReadOnly )
+ : OComponentHelper( m_aMutex )
+ , mxMSF( xMSF )
+ , mxSFI( xSFI )
+ , maNameContainer( aType )
+ , mbLoaded( sal_False )
+ , mbModified( sal_True )
+ , mbInitialised( sal_False )
+ , maLibInfoFileURL( aLibInfoFileURL )
+ , maStorageURL( aStorageURL )
+ , mbLink( sal_True )
+ , mbReadOnly( sal_False )
+ , mbReadOnlyLink( ReadOnly )
+ , mbPreload( sal_False )
+ , mbPasswordProtected( sal_False )
+ , mbPasswordVerified( sal_False )
+ , mbDoc50Password( sal_False )
+ , mbSharedIndexFile( sal_False )
+{
+}
+
+
+// Methods XInterface
+Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet;
+
+ /*
+ if( mbReadOnly )
+ {
+ aRet = Any( ::cppu::queryInterface( rType,
+ static_cast< XContainer * >( this ),
+ static_cast< XNameAccess * >( this ) ) );
+ }
+ else
+ {
+ */
+ aRet = Any( ::cppu::queryInterface( rType,
+ static_cast< XContainer * >( this ),
+ static_cast< XNameContainer * >( this ),
+ static_cast< XNameAccess * >( this ) ) );
+ //}
+ if( !aRet.hasValue() )
+ aRet = OComponentHelper::queryInterface( rType );
+ return aRet;
+}
+
+// Methods XElementAccess
+Type SfxLibrary::getElementType()
+ throw(RuntimeException)
+{
+ return maNameContainer.getElementType();
+}
+
+sal_Bool SfxLibrary::hasElements()
+ throw(RuntimeException)
+{
+ sal_Bool bRet = maNameContainer.hasElements();
+ return bRet;
+}
+
+// Methods XNameAccess
+Any SfxLibrary::getByName( const OUString& aName )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any aRetAny = maNameContainer.getByName( aName ) ;
+ return aRetAny;
+}
+
+Sequence< OUString > SfxLibrary::getElementNames()
+ throw(RuntimeException)
+{
+ return maNameContainer.getElementNames();
+}
+
+sal_Bool SfxLibrary::hasByName( const OUString& aName )
+ throw(RuntimeException)
+{
+ sal_Bool bRet = maNameContainer.hasByName( aName );
+ return bRet;
+}
+
+// Methods XNameReplace
+void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ if( mbReadOnly || (mbLink && mbReadOnlyLink) )
+ throw RuntimeException();
+
+ maNameContainer.replaceByName( aName, aElement );
+ mbModified = sal_True;
+}
+
+
+// Methods XNameContainer
+void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
+ throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
+{
+ if( mbReadOnly || (mbLink && mbReadOnlyLink) )
+ throw RuntimeException();
+
+ maNameContainer.insertByName( aName, aElement );
+ mbModified = sal_True;
+}
+
+void SfxLibrary::removeByName( const OUString& Name )
+ throw(NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ if( mbReadOnly || (mbLink && mbReadOnlyLink) )
+ throw RuntimeException();
+
+ maNameContainer.removeByName( Name );
+ mbModified = sal_True;
+
+ // Remove element file
+ if( maStorageURL.getLength() )
+ {
+ INetURLObject aElementInetObj( maStorageURL );
+ aElementInetObj.insertName( Name, sal_False,
+ INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
+ aElementInetObj.setExtension( maLibElementFileExtension );
+ OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ try
+ {
+ if( mxSFI->exists( aFile ) )
+ mxSFI->kill( aFile );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+}
+
+// XTypeProvider
+Sequence< Type > SfxLibrary::getTypes()
+ throw( RuntimeException )
+{
+ static OTypeCollection * s_pTypes_NameContainer = 0;
+ {
+ if( !s_pTypes_NameContainer )
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( !s_pTypes_NameContainer )
+ {
+ static OTypeCollection s_aTypes_NameContainer(
+ ::getCppuType( (const Reference< XNameContainer > *)0 ),
+ ::getCppuType( (const Reference< XContainer > *)0 ),
+ OComponentHelper::getTypes() );
+ s_pTypes_NameContainer = &s_aTypes_NameContainer;
+ }
+ }
+ return s_pTypes_NameContainer->getTypes();
+ }
+}
+
+
+Sequence< sal_Int8 > SfxLibrary::getImplementationId()
+ throw( RuntimeException )
+{
+ static OImplementationId * s_pId_NameContainer = 0;
+ {
+ if( !s_pId_NameContainer )
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if( !s_pId_NameContainer )
+ {
+ static OImplementationId s_aId_NameContainer;
+ s_pId_NameContainer = &s_aId_NameContainer;
+ }
+ }
+ return s_pId_NameContainer->getImplementationId();
+ }
+}
+
+
+//============================================================================
+
+// Methods XContainer
+void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
+ maNameContainer.addContainerListener( xListener );
+}
+
+void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
+ throw (RuntimeException)
+{
+ maNameContainer.removeContainerListener( xListener );
+}
+
+//============================================================================
+
+} // namespace basic