diff options
Diffstat (limited to 'svl/source/fsstor/fsstorage.cxx')
-rw-r--r-- | svl/source/fsstor/fsstorage.cxx | 1614 |
1 files changed, 1614 insertions, 0 deletions
diff --git a/svl/source/fsstor/fsstorage.cxx b/svl/source/fsstor/fsstorage.cxx new file mode 100644 index 000000000000..73460ef3d277 --- /dev/null +++ b/svl/source/fsstor/fsstorage.cxx @@ -0,0 +1,1614 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/ucb/XProgressHandler.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> + +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_ +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#endif +#include <com/sun/star/ucb/IOErrorCode.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/io/IOException.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> + + +#ifndef _COMPHELPER_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <comphelper/storagehelper.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/exc_hlp.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/ucbhelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <unotools/streamwrap.hxx> +#include <ucbhelper/fileidentifierconverter.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <ucbhelper/content.hxx> + +#include "fsstorage.hxx" +#include "oinputstreamcontainer.hxx" +#include "ostreamcontainer.hxx" + +using namespace ::com::sun::star; + +//========================================================= + +// TODO: move to a standard helper +sal_Bool isLocalFile_Impl( ::rtl::OUString aURL ) +{ + ::rtl::OUString aSystemPath; + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + throw uno::RuntimeException(); + + uno::Reference< ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + try + { + aSystemPath = ::ucbhelper::getSystemPathFromFileURL( xManager, aURL ); + } + catch ( uno::Exception& ) + { + } + + return ( aSystemPath.getLength() != 0 ); +} + + +//========================================================= + +struct FSStorage_Impl +{ + ::rtl::OUString m_aURL; + + ::ucbhelper::Content* m_pContent; + sal_Int32 m_nMode; + + ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners + ::cppu::OTypeCollection* m_pTypeCollection; + + uno::Reference< lang::XMultiServiceFactory > m_xFactory; + + + FSStorage_Impl( const ::rtl::OUString& aURL, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory ) + : m_aURL( aURL ) + , m_pContent( NULL ) + , m_nMode( nMode ) + , m_pListenersContainer( NULL ) + , m_pTypeCollection( NULL ) + , m_xFactory( xFactory ) + { + OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" ); + } + + FSStorage_Impl( const ::ucbhelper::Content& aContent, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory ) + : m_aURL( aContent.getURL() ) + , m_pContent( new ::ucbhelper::Content( aContent ) ) + , m_nMode( nMode ) + , m_pListenersContainer( NULL ) + , m_pTypeCollection( NULL ) + , m_xFactory( xFactory ) + { + OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" ); + } + + ~FSStorage_Impl(); +}; + +//========================================================= + +FSStorage_Impl::~FSStorage_Impl() +{ + if ( m_pListenersContainer ) + delete m_pListenersContainer; + if ( m_pTypeCollection ) + delete m_pTypeCollection; + if ( m_pContent ) + delete m_pContent; +} + +//===================================================== +// FSStorage implementation +//===================================================== + +//----------------------------------------------- +FSStorage::FSStorage( const ::ucbhelper::Content& aContent, + sal_Int32 nMode, + uno::Sequence< beans::PropertyValue >, + uno::Reference< lang::XMultiServiceFactory > xFactory ) +: m_pImpl( new FSStorage_Impl( aContent, nMode, xFactory ) ) +{ + // TODO: use properties + if ( !xFactory.is() ) + throw uno::RuntimeException(); + + GetContent(); +} + +//----------------------------------------------- +FSStorage::~FSStorage() +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + m_refCount++; // to call dispose + try { + dispose(); + } + catch( uno::RuntimeException& ) + {} + } +} + +//----------------------------------------------- +sal_Bool FSStorage::MakeFolderNoUI( const String& rFolder, sal_Bool ) +{ + INetURLObject aURL( rFolder ); + ::rtl::OUString aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); + aURL.removeSegment(); + ::ucbhelper::Content aParent; + ::ucbhelper::Content aResultContent; + + if ( ::ucbhelper::Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ), + uno::Reference< ucb::XCommandEnvironment >(), + aParent ) ) + return ::utl::UCBContentHelper::MakeFolder( aParent, aTitle, aResultContent, sal_False ); + + return sal_False; +} + +//----------------------------------------------- +::ucbhelper::Content* FSStorage::GetContent() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_pImpl->m_pContent ) + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + + try + { + m_pImpl->m_pContent = new ::ucbhelper::Content( m_pImpl->m_aURL, xDummyEnv ); + } + catch( uno::Exception& ) + { + } + } + + return m_pImpl->m_pContent; +} + +//----------------------------------------------- +void FSStorage::CopyStreamToSubStream( const ::rtl::OUString& aSourceURL, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewEntryName ) +{ + if ( !xDest.is() ) + throw uno::RuntimeException(); + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv ); + uno::Reference< io::XInputStream > xSourceInput = aSourceContent.openStream(); + + if ( !xSourceInput.is() ) + throw io::IOException(); // TODO: error handling + + uno::Reference< io::XStream > xSubStream = xDest->openStreamElement( + aNewEntryName, + embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + if ( !xSubStream.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XOutputStream > xDestOutput = xSubStream->getOutputStream(); + if ( !xDestOutput.is() ) + throw uno::RuntimeException(); + + ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput, xDestOutput ); + xDestOutput->closeOutput(); +} + +//----------------------------------------------- +void FSStorage::CopyContentToStorage_Impl( ::ucbhelper::Content* pContent, const uno::Reference< embed::XStorage >& xDest ) +{ + if ( !pContent ) + throw uno::RuntimeException(); + + // get list of contents of the Content + // create cursor for access to children + uno::Sequence< ::rtl::OUString > aProps( 2 ); + ::rtl::OUString* pProps = aProps.getArray(); + pProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" ); + pProps[1] = ::rtl::OUString::createFromAscii( "IsFolder" ); + ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; + + try + { + uno::Reference< sdbc::XResultSet > xResultSet = pContent->createCursor( aProps, eInclude ); + uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY ); + uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY ); + if ( xResultSet.is() ) + { + // go through the list: insert files as streams, insert folders as substorages using recursion + while ( xResultSet->next() ) + { + ::rtl::OUString aSourceURL( xRow->getString( 1 ) ); + sal_Bool bIsFolder( xRow->getBoolean(2) ); + + // TODO/LATER: not sure whether the entry name must be encoded + ::rtl::OUString aNewEntryName( INetURLObject( aSourceURL ).getName( INetURLObject::LAST_SEGMENT, + true, + INetURLObject::NO_DECODE ) ); + if ( bIsFolder ) + { + uno::Reference< embed::XStorage > xSubStorage = xDest->openStorageElement( aNewEntryName, + embed::ElementModes::READWRITE ); + if ( !xSubStorage.is() ) + throw uno::RuntimeException(); + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv ); + CopyContentToStorage_Impl( &aSourceContent, xSubStorage ); + } + else + { + CopyStreamToSubStream( aSourceURL, xDest, aNewEntryName ); + } + } + } + + uno::Reference< embed::XTransactedObject > xTransact( xDest, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + } + catch( ucb::InteractiveIOException& r ) + { + if ( r.Code == ucb::IOErrorCode_NOT_EXISTING ) + OSL_ENSURE( sal_False, "The folder does not exist!\n" ); + else + throw; + } +} + +//____________________________________________________________________________________________________ +// XInterface +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Any SAL_CALL FSStorage::queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aReturn; + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<lang::XTypeProvider*> ( this ) + , static_cast<embed::XStorage*> ( this ) + , static_cast<embed::XHierarchicalStorageAccess*> ( this ) + , static_cast<container::XNameAccess*> ( this ) + , static_cast<container::XElementAccess*> ( this ) + , static_cast<lang::XComponent*> ( this ) + , static_cast<beans::XPropertySet*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + + return OWeakObject::queryInterface( rType ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::acquire() throw() +{ + OWeakObject::acquire(); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::release() throw() +{ + OWeakObject::release(); +} + +//____________________________________________________________________________________________________ +// XTypeProvider +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes() + throw( uno::RuntimeException ) +{ + if ( m_pImpl->m_pTypeCollection == NULL ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pImpl->m_pTypeCollection == NULL ) + { + m_pImpl->m_pTypeCollection = new ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL ) + , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL ) + , ::getCppuType( ( const uno::Reference< embed::XHierarchicalStorageAccess >* )NULL ) + , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) ); + } + } + + return m_pImpl->m_pTypeCollection->getTypes() ; +} + +//----------------------------------------------- +uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId() + throw( uno::RuntimeException ) +{ + static ::cppu::OImplementationId* pID = NULL ; + + if ( pID == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; + + if ( pID == NULL ) + { + static ::cppu::OImplementationId aID( sal_False ) ; + pID = &aID ; + } + } + + return pID->getImplementationId() ; + +} + +//____________________________________________________________________________________________________ +// XStorage +//____________________________________________________________________________________________________ + +//----------------------------------------------- +void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest ) + throw ( embed::InvalidStorageException, + io::IOException, + lang::IllegalArgumentException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) ) + throw lang::IllegalArgumentException(); // TODO: + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + try + { + CopyContentToStorage_Impl( GetContent(), xDest ); + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement( + const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aFileURL( m_pImpl->m_aURL ); + aFileURL.Append( aStreamName ); + + if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::NOCREATE ) + && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any + uno::Reference< io::XStream > xResult; + try + { + if ( nOpenMode & embed::ElementModes::WRITE ) + { + if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( + m_pImpl->m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), + uno::UNO_QUERY_THROW ); + xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ); + } + else + { + // TODO: test whether it really works for http and fwp + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), + STREAM_STD_WRITE ); + if ( pStream ) + { + if ( !pStream->GetError() ) + xResult = uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) ); + else + delete pStream; + } + } + + if ( !xResult.is() ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) ) + { + uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW ); + xTrunc->truncate(); + } + } + else + { + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) + || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: access denied + + ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< io::XInputStream > xInStream = aResultContent.openStream(); + xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) ); + } + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( packages::WrongPasswordException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return xResult; +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement( + const ::rtl::OUString&, sal_Int32, const ::rtl::OUString& ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + throw packages::NoEncryptionException(); +} + +//----------------------------------------------- +uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement( + const ::rtl::OUString& aStorName, sal_Int32 nStorageMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + if ( ( nStorageMode & embed::ElementModes::WRITE ) + && !( m_pImpl->m_nMode & embed::ElementModes::WRITE ) ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aFolderURL( m_pImpl->m_aURL ); + aFolderURL.Append( aStorName ); + + sal_Bool bFolderExists = ::utl::UCBContentHelper::IsFolder( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ); + if ( !bFolderExists && ::utl::UCBContentHelper::IsDocument( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: + + if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists ) + throw io::IOException(); // TODO: + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any + uno::Reference< embed::XStorage > xResult; + try + { + if ( nStorageMode & embed::ElementModes::WRITE ) + { + if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists ) + { + ::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ); + bFolderExists = + MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :( + } + else if ( !bFolderExists ) + { + bFolderExists = + MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :( + } + } + else if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) ) + throw io::IOException(); // TODO: access denied + + if ( !bFolderExists ) + throw io::IOException(); // there is no such folder + + ::ucbhelper::Content aResultContent( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + xResult = uno::Reference< embed::XStorage >( + static_cast< OWeakObject* >( new FSStorage( aResultContent, + nStorageMode, + uno::Sequence< beans::PropertyValue >(), + m_pImpl->m_xFactory ) ), + uno::UNO_QUERY ); + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return xResult; +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const ::rtl::OUString& aStreamName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aFileURL( m_pImpl->m_aURL ); + aFileURL.Append( aStreamName ); + + uno::Reference < io::XStream > xTempResult; + try + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< io::XInputStream > xInStream = aResultContent.openStream(); + + xTempResult = uno::Reference < io::XStream >( + m_pImpl->m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), + uno::UNO_QUERY_THROW ); + uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream(); + uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream(); + + if ( !xTempOut.is() || !xTempIn.is() ) + throw io::IOException(); + + ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut ); + xTempOut->closeOutput(); + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( packages::WrongPasswordException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return xTempResult; +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement( + const ::rtl::OUString&, + const ::rtl::OUString& ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + throw packages::NoEncryptionException(); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::copyLastCommitTo( + const uno::Reference< embed::XStorage >& xTargetStorage ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + copyToStorage( xTargetStorage ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::copyStorageElementLastCommitTo( + const ::rtl::OUString& aStorName, + const uno::Reference< embed::XStorage >& xTargetStorage ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ), + uno::UNO_QUERY_THROW ); + xSourceStor->copyToStorage( xTargetStorage ); +} + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::isStreamElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw embed::InvalidStorageException(); // TODO: error handling + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aElementName ); + + return !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); +} + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::isStorageElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw embed::InvalidStorageException(); // TODO: error handling + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aElementName ); + + return ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::removeElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aElementName ); + + if ( !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) + && !::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw container::NoSuchElementException(); // TODO: + + ::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aOldURL( m_pImpl->m_aURL ); + aOldURL.Append( aElementName ); + + INetURLObject aNewURL( m_pImpl->m_aURL ); + aNewURL.Append( aNewName ); + + if ( !::utl::UCBContentHelper::IsFolder( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) + && !::utl::UCBContentHelper::IsDocument( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw container::NoSuchElementException(); // TODO: + + if ( ::utl::UCBContentHelper::IsFolder( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) + || ::utl::UCBContentHelper::IsDocument( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw container::ElementExistException(); // TODO: + + try + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + + if ( !GetContent()->transferContent( aSourceContent, + ::ucbhelper::InsertOperation_MOVE, + aNewName, + ucb::NameClash::ERROR ) ) + throw io::IOException(); // TODO: error handling + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( container::NoSuchElementException& ) + { + throw; + } + catch( container::ElementExistException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } +} + +//----------------------------------------------- +void SAL_CALL FSStorage::copyElementTo( const ::rtl::OUString& aElementName, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !xDest.is() ) + throw uno::RuntimeException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aOwnURL( m_pImpl->m_aURL ); + aOwnURL.Append( aElementName ); + + if ( xDest->hasByName( aNewName ) ) + throw container::ElementExistException(); // TODO: + + try + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + if ( ::utl::UCBContentHelper::IsFolder( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + ::ucbhelper::Content aSourceContent( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< embed::XStorage > xDestSubStor( + xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ), + uno::UNO_QUERY_THROW ); + + CopyContentToStorage_Impl( &aSourceContent, xDestSubStor ); + } + else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + CopyStreamToSubStream( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDest, aNewName ); + } + else + throw container::NoSuchElementException(); // TODO: + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( container::NoSuchElementException& ) + { + throw; + } + catch( container::ElementExistException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } +} + +//----------------------------------------------- +void SAL_CALL FSStorage::moveElementTo( const ::rtl::OUString& aElementName, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + copyElementTo( aElementName, xDest, aNewName ); + + INetURLObject aOwnURL( m_pImpl->m_aURL ); + aOwnURL.Append( aElementName ); + if ( !::utl::UCBContentHelper::Kill( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: error handling +} + +//____________________________________________________________________________________________________ +// XNameAccess +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Any SAL_CALL FSStorage::getByName( const ::rtl::OUString& aName ) + throw ( container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + if ( !aName.getLength() ) + throw lang::IllegalArgumentException(); + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aName ); + + uno::Any aResult; + try + { + if ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + aResult <<= openStorageElement( aName, embed::ElementModes::READ ); + } + else if ( ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + aResult <<= openStreamElement( aName, embed::ElementModes::READ ); + } + else + throw container::NoSuchElementException(); // TODO: + } + catch( container::NoSuchElementException& ) + { + throw; + } + catch( lang::WrappedTargetException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open element!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + + return aResult; +} + + +//----------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL FSStorage::getElementNames() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + uno::Sequence< ::rtl::OUString > aProps( 1 ); + ::rtl::OUString* pProps = aProps.getArray(); + pProps[0] = ::rtl::OUString::createFromAscii( "Title" ); + ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; + + uno::Sequence< ::rtl::OUString > aResult; + sal_Int32 nSize = 0; + + try + { + uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude ); + uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY ); + uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY ); + if ( xResultSet.is() ) + { + // go through the list + while ( xResultSet->next() ) + { + ::rtl::OUString aName( xRow->getString( 1 ) ); + aResult.realloc( ++nSize ); + aResult[nSize-1] = aName; + } + } + } + catch( ucb::InteractiveIOException& r ) + { + if ( r.Code == ucb::IOErrorCode_NOT_EXISTING ) + OSL_ENSURE( sal_False, "The folder does not exist!\n" ); + else + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + } + catch( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + + return aResult; +} + + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::hasByName( const ::rtl::OUString& aName ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + try + { + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + if ( !aName.getLength() ) + throw lang::IllegalArgumentException(); + } + catch( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aName ); + + return ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) + || ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ); +} + +//----------------------------------------------- +uno::Type SAL_CALL FSStorage::getElementType() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + // it is a multitype container + return uno::Type(); +} + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::hasElements() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + uno::Sequence< ::rtl::OUString > aProps( 1 ); + aProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" ); + ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; + + try + { + uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude ); + return ( xResultSet.is() && xResultSet->next() ); + } + catch( uno::Exception& ) + { + throw uno::RuntimeException(); + } +} + + +//____________________________________________________________________________________________________ +// XDisposable +//____________________________________________________________________________________________________ + +//----------------------------------------------- +void SAL_CALL FSStorage::dispose() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( m_pImpl->m_pListenersContainer ) + { + lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) ); + m_pImpl->m_pListenersContainer->disposeAndClear( aSource ); + } + + delete m_pImpl; + m_pImpl = NULL; +} + +//----------------------------------------------- +void SAL_CALL FSStorage::addEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !m_pImpl->m_pListenersContainer ) + m_pImpl->m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pImpl->m_pListenersContainer->addInterface( xListener ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::removeEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( m_pImpl->m_pListenersContainer ) + m_pImpl->m_pListenersContainer->removeInterface( xListener ); +} + +//____________________________________________________________________________________________________ +// XPropertySet +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: + return uno::Reference< beans::XPropertySetInfo >(); +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& ) + throw ( beans::UnknownPropertyException, + beans::PropertyVetoException, + lang::IllegalArgumentException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( aPropertyName.equalsAscii( "URL" ) || aPropertyName.equalsAscii( "OpenMode" ) ) + throw beans::PropertyVetoException(); // TODO + else + throw beans::UnknownPropertyException(); // TODO +} + + +//----------------------------------------------- +uno::Any SAL_CALL FSStorage::getPropertyValue( const ::rtl::OUString& aPropertyName ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( aPropertyName.equalsAscii( "URL" ) ) + return uno::makeAny( m_pImpl->m_aURL ); + else if ( aPropertyName.equalsAscii( "OpenMode" ) ) + return uno::makeAny( m_pImpl->m_nMode ); + + throw beans::UnknownPropertyException(); // TODO +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::addPropertyChangeListener( + const ::rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::removePropertyChangeListener( + const ::rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::addVetoableChangeListener( + const ::rtl::OUString& /*PropertyName*/, + const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::removeVetoableChangeListener( + const ::rtl::OUString& /*PropertyName*/, + const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + +//____________________________________________________________________________________________________ +// XHierarchicalStorageAccess +//____________________________________________________________________________________________________ +//----------------------------------------------- +uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( sStreamPath.toChar() == '/' ) + throw lang::IllegalArgumentException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aBaseURL( m_pImpl->m_aURL ); + if ( !aBaseURL.setFinalSlash() ) + throw uno::RuntimeException(); + + INetURLObject aFileURL = INetURLObject::GetAbsURL( + aBaseURL.GetMainURL( INetURLObject::NO_DECODE ), + sStreamPath ); + + if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::NOCREATE ) + && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any + uno::Reference< io::XStream > xResult; + try + { + if ( nOpenMode & embed::ElementModes::WRITE ) + { + if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( + m_pImpl->m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< io::XStream > xStream = + xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ); + + xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) ); + } + else + { + // TODO: test whether it really works for http and fwp + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), + STREAM_STD_WRITE ); + if ( pStream ) + { + if ( !pStream->GetError() ) + { + uno::Reference< io::XStream > xStream = + uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) ); + xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) ); + } + else + delete pStream; + } + } + + if ( !xResult.is() ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) ) + { + uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW ); + xTrunc->truncate(); + } + } + else + { + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) + || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: access denied + + ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< io::XInputStream > xInStream = aResultContent.openStream(); + xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) ); + } + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( packages::WrongPasswordException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW ); +} + +//----------------------------------------------- +uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const ::rtl::OUString& /*sPassword*/ ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + throw packages::NoEncryptionException(); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aBaseURL( m_pImpl->m_aURL ); + if ( !aBaseURL.setFinalSlash() ) + throw uno::RuntimeException(); + + INetURLObject aFileURL = INetURLObject::GetAbsURL( + aBaseURL.GetMainURL( INetURLObject::NO_DECODE ), + sStreamPath ); + + if ( !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw lang::IllegalArgumentException(); + else + throw container::NoSuchElementException(); // TODO: + } + + if ( !::utl::UCBContentHelper::Kill( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: error handling +} + + |