1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_unotools.hxx" 30 31 #include <unotools/ucblockbytes.hxx> 32 #include <unotools/ucbstreamhelper.hxx> 33 #include <comphelper/processfactory.hxx> 34 #include <com/sun/star/ucb/CommandAbortedException.hpp> 35 36 #ifndef _COM_SUN_STAR_UCB_XCOMMANDENVIRONMENT_HDL_ 37 #include <com/sun/star/ucb/XCommandEnvironment.hdl> 38 #endif 39 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 40 #include <com/sun/star/io/XActiveDataStreamer.hpp> 41 42 #include <ucbhelper/contentbroker.hxx> 43 #include <ucbhelper/content.hxx> 44 #include <tools/debug.hxx> 45 #include <unotools/streamwrap.hxx> 46 47 using namespace ::com::sun::star::uno; 48 using namespace ::com::sun::star::io; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::ucb; 51 using namespace ::com::sun::star::task; 52 using namespace ::com::sun::star::lang; 53 using namespace ::com::sun::star::beans; 54 55 namespace utl 56 { 57 58 static SvStream* lcl_CreateStream( const String& rFileName, StreamMode eOpenMode, 59 Reference < XInteractionHandler > xInteractionHandler, 60 UcbLockBytesHandler* pHandler, sal_Bool /*bForceSynchron*/, sal_Bool bEnsureFileExists ) 61 { 62 SvStream* pStream = NULL; 63 ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); 64 if ( pBroker ) 65 { 66 UcbLockBytesRef xLockBytes; 67 if ( eOpenMode & STREAM_WRITE ) 68 { 69 sal_Bool bTruncate = ( eOpenMode & STREAM_TRUNC ) != 0; 70 if ( bTruncate ) 71 { 72 try 73 { 74 // truncate is implemented with deleting the original file 75 ::ucbhelper::Content aCnt( rFileName, Reference < XCommandEnvironment >() ); 76 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); 77 } 78 79 catch ( CommandAbortedException& ) 80 { 81 // couldn't truncate/delete 82 } 83 catch ( ContentCreationException& ) 84 { 85 } 86 catch ( Exception& ) 87 { 88 } 89 } 90 91 if ( bEnsureFileExists || bTruncate ) 92 { 93 try 94 { 95 // make sure that the desired file exists before trying to open 96 SvMemoryStream aStream(0,0); 97 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream ); 98 Reference< XInputStream > xInput( pInput ); 99 100 ::ucbhelper::Content aContent( rFileName, Reference < XCommandEnvironment >() ); 101 InsertCommandArgument aInsertArg; 102 aInsertArg.Data = xInput; 103 104 aInsertArg.ReplaceExisting = sal_False; 105 Any aCmdArg; 106 aCmdArg <<= aInsertArg; 107 aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg ); 108 } 109 110 // it is NOT an error when the stream already exists and no truncation was desired 111 catch ( CommandAbortedException& ) 112 { 113 // currently never an error is detected ! 114 } 115 catch ( ContentCreationException& ) 116 { 117 } 118 catch ( Exception& ) 119 { 120 } 121 } 122 } 123 124 try 125 { 126 // create LockBytes using UCB 127 ::ucbhelper::Content aContent( rFileName, Reference < XCommandEnvironment >() ); 128 xLockBytes = UcbLockBytes::CreateLockBytes( aContent.get(), Sequence < PropertyValue >(), 129 eOpenMode, xInteractionHandler, pHandler ); 130 if ( xLockBytes.Is() ) 131 { 132 pStream = new SvStream( xLockBytes ); 133 pStream->SetBufferSize( 4096 ); 134 pStream->SetError( xLockBytes->GetError() ); 135 } 136 } 137 catch ( CommandAbortedException& ) 138 { 139 } 140 catch ( ContentCreationException& ) 141 { 142 } 143 catch ( Exception& ) 144 { 145 } 146 } 147 else 148 // if no UCB is present at least conventional file io is supported 149 pStream = new SvFileStream( rFileName, eOpenMode ); 150 151 return pStream; 152 } 153 154 //============================================================================ 155 156 SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode, 157 UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron ) 158 { 159 return lcl_CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron, sal_True /* bEnsureFileExists */ ); 160 } 161 162 SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode, 163 Reference < XInteractionHandler > xInteractionHandler, 164 UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron ) 165 { 166 return lcl_CreateStream( rFileName, eOpenMode, xInteractionHandler, pHandler, bForceSynchron, sal_True /* bEnsureFileExists */ ); 167 } 168 169 SvStream* UcbStreamHelper::CreateStream( const String& rFileName, StreamMode eOpenMode, 170 sal_Bool bFileExists, 171 UcbLockBytesHandler* pHandler, sal_Bool bForceSynchron ) 172 { 173 return lcl_CreateStream( rFileName, eOpenMode, Reference < XInteractionHandler >(), pHandler, bForceSynchron, !bFileExists ); 174 } 175 176 SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream ) 177 { 178 SvStream* pStream = NULL; 179 UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream ); 180 if ( xLockBytes.Is() ) 181 { 182 pStream = new SvStream( xLockBytes ); 183 pStream->SetBufferSize( 4096 ); 184 pStream->SetError( xLockBytes->GetError() ); 185 } 186 187 return pStream; 188 } 189 190 SvStream* UcbStreamHelper::CreateStream( Reference < XStream > xStream ) 191 { 192 SvStream* pStream = NULL; 193 if ( xStream->getOutputStream().is() ) 194 { 195 UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream ); 196 if ( xLockBytes.Is() ) 197 { 198 pStream = new SvStream( xLockBytes ); 199 pStream->SetBufferSize( 4096 ); 200 pStream->SetError( xLockBytes->GetError() ); 201 } 202 } 203 else 204 return CreateStream( xStream->getInputStream() ); 205 206 return pStream; 207 } 208 209 SvStream* UcbStreamHelper::CreateStream( Reference < XInputStream > xStream, sal_Bool bCloseStream ) 210 { 211 SvStream* pStream = NULL; 212 UcbLockBytesRef xLockBytes = UcbLockBytes::CreateInputLockBytes( xStream ); 213 if ( xLockBytes.Is() ) 214 { 215 if ( !bCloseStream ) 216 xLockBytes->setDontClose_Impl(); 217 218 pStream = new SvStream( xLockBytes ); 219 pStream->SetBufferSize( 4096 ); 220 pStream->SetError( xLockBytes->GetError() ); 221 } 222 223 return pStream; 224 }; 225 226 SvStream* UcbStreamHelper::CreateStream( Reference < XStream > xStream, sal_Bool bCloseStream ) 227 { 228 SvStream* pStream = NULL; 229 if ( xStream->getOutputStream().is() ) 230 { 231 UcbLockBytesRef xLockBytes = UcbLockBytes::CreateLockBytes( xStream ); 232 if ( xLockBytes.Is() ) 233 { 234 if ( !bCloseStream ) 235 xLockBytes->setDontClose_Impl(); 236 237 pStream = new SvStream( xLockBytes ); 238 pStream->SetBufferSize( 4096 ); 239 pStream->SetError( xLockBytes->GetError() ); 240 } 241 } 242 else 243 return CreateStream( xStream->getInputStream(), bCloseStream ); 244 245 return pStream; 246 }; 247 248 } 249