diff options
author | RĂ¼diger Timm <rt@openoffice.org> | 2008-08-27 06:52:22 +0000 |
---|---|---|
committer | RĂ¼diger Timm <rt@openoffice.org> | 2008-08-27 06:52:22 +0000 |
commit | 59925494766487efa612395ded18dfa11f3f4638 (patch) | |
tree | 4bbae5b5fb22b5d45c9b11827ffa4e9de2aac01b /sfx2/source | |
parent | e6cd9608cd609a85a8fe7c0592a8c797b142afb8 (diff) |
INTEGRATION: CWS mav37_DEV300 (1.203.26); FILE MERGED
2008/08/14 14:03:52 mav 1.203.26.3: #i92735# Use copy mechanics in future
2008/08/14 12:31:24 mav 1.203.26.2: #i92735# use temporary file as a workaround
2008/08/14 10:34:50 mav 1.203.26.1: #i92735# SimpleFileAccess uses system locking always, get rid of it
Diffstat (limited to 'sfx2/source')
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 103 |
1 files changed, 69 insertions, 34 deletions
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 0f517daf87..a5cbfd9889 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: docfile.cxx,v $ - * $Revision: 1.203 $ + * $Revision: 1.204 $ * * This file is part of OpenOffice.org. * @@ -903,52 +903,90 @@ uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage() if ( GetError() ) return uno::Reference< embed::XStorage >(); + ::rtl::OUString aOutputURL = GetOutputStorageURL_Impl(); + + SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False ); + SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False ); + sal_Bool bRename = pRename ? pRename->GetValue() : FALSE; + sal_Bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename; + // the target file must be truncated before a storage based on it is created - try { - uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); - uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + try + { + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), uno::UNO_QUERY_THROW ); - SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False ); - SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False ); - sal_Bool bRename = pRename ? pRename->GetValue() : FALSE; - sal_Bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename; + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aContent = ::ucbhelper::Content( aOutputURL, xDummyEnv ); - ::rtl::OUString aOutputURL = GetOutputStorageURL_Impl(); + uno::Reference< io::XStream > xStream; + sal_Bool bDeleteOnFailure = sal_False; - // TODO/LATER: nonatomar operation - sal_Bool bExists = xSimpleFileAccess->exists( aOutputURL ); - if ( !bOverWrite && bExists ) - throw ::com::sun::star::ucb::NameClashException(); + try + { + xStream = aContent.openWriteableStreamNoLock(); - uno::Reference< io::XStream > xStream; + if ( !bOverWrite ) + { + // the stream should not exist, it should not be possible to open it + if ( xStream->getOutputStream().is() ) + xStream->getOutputStream()->closeOutput(); + if ( xStream->getInputStream().is() ) + xStream->getInputStream()->closeInput(); - if ( BasedOnOriginalFile_Impl() ) + xStream = uno::Reference< io::XStream >(); + SetError( ERRCODE_IO_GENERAL ); + } + } + catch ( ucb::InteractiveIOException const & e ) { - // the storage will be based on original file, the wrapper should be used - xStream = new OPostponedTruncationFileStream( aOutputURL, xFactory, xSimpleFileAccess, sal_True ); + if ( e.Code == ucb::IOErrorCode_NOT_EXISTING ) + { + // Create file... + SvMemoryStream aStream(0,0); + uno::Reference< io::XInputStream > xInput( new ::utl::OInputStreamWrapper( aStream ) ); + ucb::InsertCommandArgument aInsertArg; + aInsertArg.Data = xInput; + aInsertArg.ReplaceExisting = sal_False; + aContent.executeCommand( rtl::OUString::createFromAscii( "insert" ), uno::makeAny( aInsertArg ) ); + + // Try to open one more time + xStream = aContent.openWriteableStreamNoLock(); + bDeleteOnFailure = sal_True; + } + else + throw; } - else + + if ( xStream.is() ) { - // the storage will be based on the temporary file, the stream can be truncated directly - xStream = xSimpleFileAccess->openFileReadWrite( aOutputURL ); - uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream(); - uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY ); - if ( !xTruncate.is() ) - throw uno::RuntimeException(); + if ( BasedOnOriginalFile_Impl() ) + { + // the storage will be based on original file, the wrapper should be used + xStream = new OPostponedTruncationFileStream( aOutputURL, xFactory, xSimpleFileAccess, xStream, bDeleteOnFailure ); + } + else + { + // the storage will be based on the temporary file, the stream can be truncated directly + uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream(); + uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY ); + if ( !xTruncate.is() ) + throw uno::RuntimeException(); - xTruncate->truncate(); - xOutStream->flush(); - } + xTruncate->truncate(); + xOutStream->flush(); + } - pImp->xStream = xStream; - GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( xStream ) ) ); + pImp->xStream = xStream; + GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( xStream ) ) ); + } } catch( uno::Exception& ) { - DBG_ERROR( "Can't truncate target stream!\n" ); - SetError( ERRCODE_IO_GENERAL ); + // TODO/LATER: try to use the temporary file in case the target content can not be opened, it might happen in case of some FS, the copy functionality might work in this case + SetError( ERRCODE_IO_GENERAL ); } } @@ -1561,8 +1599,6 @@ sal_Bool SfxMedium::StorageCommit_Impl() if ( pImp->xStorage.is() ) { - StorageBackup_Impl(); - if ( !GetError() ) { uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY ); @@ -1620,7 +1656,6 @@ sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource, sal_Bool bResult = sal_False; Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv; Reference< XOutputStream > aDestStream; - Reference< XSimpleFileAccess > aSimpleAccess; ::ucbhelper::Content aOriginalContent; // actualy it should work even for contents different from file content |