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 #include <osl/mutex.hxx> 29 #include <osl/diagnose.h> 30 31 #include <uno/mapping.hxx> 32 33 #include <cppuhelper/factory.hxx> 34 #include <cppuhelper/implbase1.hxx> 35 36 #include <tools/ref.hxx> 37 #include <tools/urlobj.hxx> 38 #include <ucbhelper/content.hxx> 39 #include <unotools/streamwrap.hxx> 40 #include <tools/stream.hxx> 41 42 #include <com/sun/star/beans/Property.hpp> 43 #include <com/sun/star/beans/XPropertySet.hpp> 44 #include <com/sun/star/container/XChild.hpp> 45 #include <com/sun/star/io/XActiveDataSink.hpp> 46 #include <com/sun/star/io/XActiveDataSource.hpp> 47 #include <com/sun/star/io/XActiveDataStreamer.hpp> 48 #include <com/sun/star/sdbc/XResultSet.hpp> 49 #include <com/sun/star/ucb/CommandFailedException.hpp> 50 #include <com/sun/star/ucb/ContentInfo.hpp> 51 #include <com/sun/star/ucb/ContentInfoAttribute.hpp> 52 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 53 #include <com/sun/star/ucb/InteractiveIOException.hpp> 54 #include <com/sun/star/ucb/NameClash.hpp> 55 #include <com/sun/star/ucb/NameClashException.hpp> 56 #include <com/sun/star/ucb/OpenCommandArgument2.hpp> 57 #include <com/sun/star/ucb/OpenMode.hpp> 58 #include <com/sun/star/ucb/XCommandEnvironment.hpp> 59 #include <com/sun/star/ucb/XContent.hpp> 60 #include <com/sun/star/ucb/XContentAccess.hpp> 61 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp> 62 #include <com/sun/star/util/XMacroExpander.hpp> 63 64 #define IMPLEMENTATION_NAME "com.sun.star.comp.ucb.SimpleFileAccess" 65 #define SERVICE_NAME "com.sun.star.ucb.SimpleFileAccess" 66 67 using namespace ::com::sun::star::uno; 68 using namespace ::com::sun::star::lang; 69 using namespace ::com::sun::star::io; 70 using namespace ::com::sun::star::ucb; 71 using namespace ::com::sun::star::sdbc; 72 using namespace ::com::sun::star::task; 73 using namespace ::com::sun::star::util; 74 using namespace ::com::sun::star::beans; 75 using namespace ::com::sun::star::registry; 76 using namespace ::com::sun::star::container; 77 78 namespace io_FileAccess 79 { 80 81 82 //=========================================================================== 83 // Implementation XSimpleFileAccess 84 85 typedef cppu::WeakImplHelper1< XSimpleFileAccess3 > FileAccessHelper; 86 class OCommandEnvironment; 87 88 class OFileAccess : public FileAccessHelper 89 { 90 Reference< XMultiServiceFactory > mxSMgr; 91 Reference< XCommandEnvironment > mxEnvironment; 92 OCommandEnvironment* mpEnvironment; 93 94 void transferImpl( const rtl::OUString& rSource, const rtl::OUString& rDest, sal_Bool bMoveData ) 95 throw(CommandAbortedException, Exception, RuntimeException); 96 bool createNewFile( const rtl::OUString & rParentURL, 97 const rtl::OUString & rTitle, 98 const Reference< XInputStream >& data ) 99 throw ( Exception ); 100 101 public: 102 OFileAccess( const Reference< XMultiServiceFactory > & xSMgr ) 103 : mxSMgr( xSMgr), mpEnvironment( NULL ) {} 104 105 // Methods 106 virtual void SAL_CALL copy( const ::rtl::OUString& SourceURL, const ::rtl::OUString& DestURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 107 virtual void SAL_CALL move( const ::rtl::OUString& SourceURL, const ::rtl::OUString& DestURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 108 virtual void SAL_CALL kill( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 109 virtual sal_Bool SAL_CALL isFolder( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 110 virtual sal_Bool SAL_CALL isReadOnly( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 111 virtual void SAL_CALL setReadOnly( const ::rtl::OUString& FileURL, sal_Bool bReadOnly ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 112 virtual void SAL_CALL createFolder( const ::rtl::OUString& NewFolderURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 113 virtual sal_Int32 SAL_CALL getSize( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 114 virtual ::rtl::OUString SAL_CALL getContentType( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 115 virtual ::com::sun::star::util::DateTime SAL_CALL getDateTimeModified( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 116 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFolderContents( const ::rtl::OUString& FolderURL, sal_Bool bIncludeFolders ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 117 virtual sal_Bool SAL_CALL exists( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 118 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL openFileRead( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 119 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL openFileWrite( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 120 virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openFileReadWrite( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 121 virtual void SAL_CALL setInteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException); 122 virtual void SAL_CALL writeFile( const ::rtl::OUString& FileURL, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& data ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 123 virtual sal_Bool SAL_CALL isHidden( const ::rtl::OUString& FileURL ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 124 virtual void SAL_CALL setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden ) throw(::com::sun::star::ucb::CommandAbortedException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 125 }; 126 127 128 //=========================================================================== 129 // Implementation XActiveDataSink 130 131 typedef cppu::WeakImplHelper1< XActiveDataSink > ActiveDataSinkHelper; 132 133 class OActiveDataSink : public ActiveDataSinkHelper 134 { 135 Reference< XInputStream > mxStream; 136 137 public: 138 139 // Methods 140 virtual void SAL_CALL setInputStream( const Reference< XInputStream >& aStream ) 141 throw(RuntimeException); 142 virtual Reference< XInputStream > SAL_CALL getInputStream( ) 143 throw(RuntimeException); 144 }; 145 146 void OActiveDataSink::setInputStream( const Reference< XInputStream >& aStream ) 147 throw(RuntimeException) 148 { 149 mxStream = aStream; 150 } 151 152 Reference< XInputStream > OActiveDataSink::getInputStream() 153 throw(RuntimeException) 154 { 155 return mxStream; 156 } 157 158 159 //=========================================================================== 160 // Implementation XActiveDataSource 161 162 typedef cppu::WeakImplHelper1< XActiveDataSource > ActiveDataSourceHelper; 163 164 class OActiveDataSource : public ActiveDataSourceHelper 165 { 166 Reference< XOutputStream > mxStream; 167 168 public: 169 170 // Methods 171 virtual void SAL_CALL setOutputStream( const Reference< XOutputStream >& aStream ) 172 throw(RuntimeException); 173 virtual Reference< XOutputStream > SAL_CALL getOutputStream() 174 throw(RuntimeException); 175 }; 176 177 void OActiveDataSource::setOutputStream( const Reference< XOutputStream >& aStream ) 178 throw(RuntimeException) 179 { 180 mxStream = aStream; 181 } 182 183 Reference< XOutputStream > OActiveDataSource::getOutputStream() 184 throw(RuntimeException) 185 { 186 return mxStream; 187 } 188 189 190 //=========================================================================== 191 // Implementation XActiveDataStreamer 192 193 typedef cppu::WeakImplHelper1< XActiveDataStreamer > ActiveDataStreamerHelper; 194 195 class OActiveDataStreamer : public ActiveDataStreamerHelper 196 { 197 Reference< XStream > mxStream; 198 199 public: 200 201 // Methods 202 virtual void SAL_CALL setStream( const Reference< XStream >& aStream ) 203 throw(RuntimeException); 204 virtual Reference< XStream > SAL_CALL getStream() 205 throw(RuntimeException); 206 }; 207 208 void OActiveDataStreamer::setStream( const Reference< XStream >& aStream ) 209 throw(RuntimeException) 210 { 211 mxStream = aStream; 212 } 213 214 Reference< XStream > OActiveDataStreamer::getStream() 215 throw(RuntimeException) 216 { 217 return mxStream; 218 } 219 220 221 222 //=========================================================================== 223 // Implementation XCommandEnvironment 224 225 typedef cppu::WeakImplHelper1< XCommandEnvironment > CommandEnvironmentHelper; 226 227 class OCommandEnvironment : public CommandEnvironmentHelper 228 { 229 Reference< XInteractionHandler > mxInteraction; 230 231 public: 232 void setHandler( Reference< XInteractionHandler > xInteraction_ ) 233 { 234 mxInteraction = xInteraction_; 235 } 236 237 // Methods 238 virtual Reference< XInteractionHandler > SAL_CALL getInteractionHandler() 239 throw(RuntimeException); 240 virtual Reference< XProgressHandler > SAL_CALL getProgressHandler() 241 throw(RuntimeException); 242 }; 243 244 Reference< XInteractionHandler > OCommandEnvironment::getInteractionHandler() 245 throw(RuntimeException) 246 { 247 return mxInteraction; 248 } 249 250 Reference< XProgressHandler > OCommandEnvironment::getProgressHandler() 251 throw(RuntimeException) 252 { 253 Reference< XProgressHandler > xRet; 254 return xRet; 255 } 256 257 //=========================================================================== 258 259 void OFileAccess::transferImpl( const rtl::OUString& rSource, 260 const rtl::OUString& rDest, 261 sal_Bool bMoveData ) 262 throw(CommandAbortedException, Exception, RuntimeException) 263 { 264 // SfxContentHelper::Transfer_Impl 265 INetURLObject aSourceObj( rSource, INET_PROT_FILE ); 266 INetURLObject aDestObj( rDest, INET_PROT_FILE ); 267 String aName = aDestObj.getName( 268 INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); 269 String aDestURL; 270 String aSourceURL = aSourceObj.GetMainURL( INetURLObject::NO_DECODE ); 271 if ( aDestObj.removeSegment() ) 272 { 273 // hierarchical URL. 274 275 aDestObj.setFinalSlash(); 276 aDestURL = aDestObj.GetMainURL( INetURLObject::NO_DECODE ); 277 } 278 else 279 { 280 // non-hierachical URL 281 282 // #i29648# 283 // 284 #if 0 285 // Note: A hierachical UCB content implements interface XChild, which 286 // has a method getParent(). Unfortunately this does not always help 287 // here, because it is not guaranteed that a content object for a 288 // non-existing resource can be created. Thus, it will happen that an 289 // exception is thrown when trying to create a UCB content for the 290 // destination URL. 291 292 try 293 { 294 ucbhelper::Content aFullDest( 295 aDestObj.GetMainURL( 296 INetURLObject::NO_DECODE ), mxEnvironment ); 297 298 Reference< XChild > xChild( aFullDest.get(), UNO_QUERY_THROW ); 299 Reference< com::sun::star::ucb::XContent > 300 xParent( xChild->getParent(), UNO_QUERY_THROW ); 301 ucbhelper::Content aParent( xParent, mxEnvironment ); 302 303 aDestURL = aParent.getURL(); 304 305 rtl::OUString aNameTmp; 306 aFullDest.getPropertyValue( 307 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ) ) 308 >>= aNameTmp; 309 aName = aNameTmp; 310 } 311 catch ( Exception const & ) 312 { 313 throw RuntimeException( 314 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 315 "OFileAccess::transferrImpl - Unable to " 316 "obtain destination folder URL!" ) ), 317 static_cast< cppu::OWeakObject * >( this ) ); 318 } 319 #else 320 if ( aDestObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND ) 321 { 322 // Hack: Expand destination URL using Macro Expander and try again 323 // with the hopefully hierarchical expanded URL... 324 325 try 326 { 327 Reference< XComponentContext > xCtx; 328 Reference< XPropertySet > xPropSet( mxSMgr, UNO_QUERY_THROW ); 329 if ( xPropSet.is() ) 330 { 331 xPropSet->getPropertyValue( 332 rtl::OUString( 333 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) 334 >>= xCtx; 335 } 336 337 Reference< XMacroExpander > xExpander; 338 339 xCtx->getValueByName( 340 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 341 "/singletons/com.sun.star.util.theMacroExpander" ) ) ) 342 >>= xExpander; 343 344 OSL_ENSURE( xExpander.is(), 345 "Unable to obtain macro expander singleton!" ); 346 347 aDestURL = xExpander->expandMacros( 348 aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) ); 349 } 350 catch ( Exception const & ) 351 { 352 throw RuntimeException( 353 rtl::OUString( 354 RTL_CONSTASCII_USTRINGPARAM( 355 "OFileAccess::transferrImpl - Unable to obtain " 356 "destination folder URL!" ) ), 357 static_cast< cppu::OWeakObject * >( this ) ); 358 } 359 360 transferImpl( rSource, aDestURL, bMoveData ); 361 return; 362 } 363 364 throw RuntimeException( 365 rtl::OUString( 366 RTL_CONSTASCII_USTRINGPARAM( 367 "OFileAccess::transferrImpl - Unable to obtain " 368 "destination folder URL!" ) ), 369 static_cast< cppu::OWeakObject * >( this ) ); 370 #endif 371 } 372 373 ucbhelper::Content aDestPath( aDestURL, mxEnvironment ); 374 ucbhelper::Content aSrc ( aSourceURL, mxEnvironment ); 375 376 try 377 { 378 aDestPath.transferContent( aSrc, 379 bMoveData 380 ? ucbhelper::InsertOperation_MOVE 381 : ucbhelper::InsertOperation_COPY, 382 aName, 383 ::com::sun::star::ucb::NameClash::OVERWRITE ); 384 } 385 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 386 { 387 // Interaction Handler already handled the error that has occured... 388 } 389 } 390 391 void OFileAccess::copy( const rtl::OUString& SourceURL, const rtl::OUString& DestURL ) 392 throw(CommandAbortedException, Exception, RuntimeException) 393 { 394 transferImpl( SourceURL, DestURL, sal_False ); 395 } 396 397 void OFileAccess::move( const rtl::OUString& SourceURL, const rtl::OUString& DestURL ) 398 throw(CommandAbortedException, Exception, RuntimeException) 399 { 400 transferImpl( SourceURL, DestURL, sal_True ); 401 } 402 403 void OFileAccess::kill( const rtl::OUString& FileURL ) 404 throw(CommandAbortedException, Exception, RuntimeException) 405 { 406 // SfxContentHelper::Kill 407 INetURLObject aDeleteObj( FileURL, INET_PROT_FILE ); 408 ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 409 try 410 { 411 aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); 412 } 413 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 414 { 415 // Interaction Handler already handled the error that has occured... 416 } 417 } 418 419 sal_Bool OFileAccess::isFolder( const rtl::OUString& FileURL ) 420 throw(CommandAbortedException, Exception, RuntimeException) 421 { 422 sal_Bool bRet = sal_False; 423 try 424 { 425 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 426 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 427 bRet = aCnt.isFolder(); 428 } 429 catch (Exception &) {} 430 return bRet; 431 } 432 433 sal_Bool OFileAccess::isReadOnly( const rtl::OUString& FileURL ) 434 throw(CommandAbortedException, Exception, RuntimeException) 435 { 436 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 437 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 438 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ); 439 sal_Bool bRet = sal_False; 440 aRetAny >>= bRet; 441 return bRet; 442 } 443 444 void OFileAccess::setReadOnly( const rtl::OUString& FileURL, sal_Bool bReadOnly ) 445 throw(CommandAbortedException, Exception, RuntimeException) 446 { 447 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 448 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 449 Any aAny; 450 aAny <<= bReadOnly; 451 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), aAny ); 452 } 453 454 void OFileAccess::createFolder( const rtl::OUString& NewFolderURL ) 455 throw(CommandAbortedException, Exception, RuntimeException) 456 { 457 // Does the folder already exist? 458 if( !NewFolderURL.getLength() || isFolder( NewFolderURL ) ) 459 return; 460 461 // SfxContentHelper::MakeFolder 462 INetURLObject aURL( NewFolderURL, INET_PROT_FILE ); 463 String aNewFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE ); 464 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); 465 if ( aTitle.Len() ) 466 { 467 aURL.removeSegment(); 468 469 // Does the base folder exist? Otherwise create it first 470 String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE ); 471 if( !isFolder( aBaseFolderURLStr ) ) 472 { 473 createFolder( aBaseFolderURLStr ); 474 } 475 } 476 477 ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 478 479 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo(); 480 sal_Int32 nCount = aInfo.getLength(); 481 if ( nCount == 0 ) 482 return; 483 484 for ( sal_Int32 i = 0; i < nCount; ++i ) 485 { 486 // Simply look for the first KIND_FOLDER... 487 const ContentInfo & rCurr = aInfo[i]; 488 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER ) 489 { 490 // Make sure the only required bootstrap property is "Title", 491 const Sequence< Property > & rProps = rCurr.Properties; 492 if ( rProps.getLength() != 1 ) 493 continue; 494 495 if ( !rProps[ 0 ].Name.equalsAsciiL( 496 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 497 continue; 498 499 Sequence<rtl::OUString> aNames(1); 500 rtl::OUString* pNames = aNames.getArray(); 501 pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 502 Sequence< Any > aValues(1); 503 Any* pValues = aValues.getArray(); 504 pValues[0] = makeAny( rtl::OUString( aTitle ) ); 505 506 ucbhelper::Content aNew; 507 try 508 { 509 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) ) 510 continue; 511 512 // Success. We're done. 513 return; 514 } 515 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 516 { 517 // Interaction Handler already handled the error that has occured... 518 continue; 519 } 520 } 521 } 522 } 523 524 sal_Int32 OFileAccess::getSize( const rtl::OUString& FileURL ) 525 throw(CommandAbortedException, Exception, RuntimeException) 526 { 527 // SfxContentHelper::GetSize 528 sal_Int32 nSize = 0; 529 sal_Int64 nTemp = 0; 530 INetURLObject aObj( FileURL, INET_PROT_FILE ); 531 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 532 aCnt.getPropertyValue( rtl::OUString::createFromAscii( "Size" ) ) >>= nTemp; 533 nSize = (sal_Int32)nTemp; 534 return nSize; 535 } 536 537 rtl::OUString OFileAccess::getContentType( const rtl::OUString& FileURL ) 538 throw(CommandAbortedException, Exception, RuntimeException) 539 { 540 INetURLObject aObj( FileURL, INET_PROT_FILE ); 541 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 542 543 Reference< XContent > xContent = aCnt.get(); 544 rtl::OUString aTypeStr = xContent->getContentType(); 545 return aTypeStr; 546 } 547 548 DateTime OFileAccess::getDateTimeModified( const rtl::OUString& FileURL ) 549 throw(CommandAbortedException, Exception, RuntimeException) 550 { 551 INetURLObject aFileObj( FileURL, INET_PROT_FILE ); 552 DateTime aDateTime; 553 554 Reference< XCommandEnvironment > aCmdEnv; 555 ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); 556 aYoung.getPropertyValue( rtl::OUString::createFromAscii( "DateModified" ) ) >>= aDateTime; 557 return aDateTime; 558 } 559 560 561 DECLARE_LIST( StringList_Impl, rtl::OUString* ) 562 563 Sequence< rtl::OUString > OFileAccess::getFolderContents( const rtl::OUString& FolderURL, sal_Bool bIncludeFolders ) 564 throw(CommandAbortedException, Exception, RuntimeException) 565 { 566 // SfxContentHelper::GetFolderContents 567 568 StringList_Impl* pFiles = NULL; 569 INetURLObject aFolderObj( FolderURL, INET_PROT_FILE ); 570 571 ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 572 Reference< XResultSet > xResultSet; 573 Sequence< rtl::OUString > aProps(0); 574 //Sequence< rtl::OUString > aProps(1); 575 //rtl::OUString* pProps = aProps.getArray(); 576 //pProps[0] == rtl::OUString::createFromAscii( "Url" ); 577 578 ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY; 579 580 try 581 { 582 xResultSet = aCnt.createCursor( aProps, eInclude ); 583 } 584 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 585 { 586 // Interaction Handler already handled the error that has occured... 587 } 588 589 if ( xResultSet.is() ) 590 { 591 pFiles = new StringList_Impl; 592 Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); 593 594 while ( xResultSet->next() ) 595 { 596 rtl::OUString aId = xContentAccess->queryContentIdentifierString(); 597 INetURLObject aURL( aId, INET_PROT_FILE ); 598 rtl::OUString* pFile = new rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); 599 pFiles->Insert( pFile, LIST_APPEND ); 600 } 601 } 602 603 if ( pFiles ) 604 { 605 sal_uIntPtr nCount = pFiles->Count(); 606 Sequence < rtl::OUString > aRet( nCount ); 607 rtl::OUString* pRet = aRet.getArray(); 608 for ( sal_uInt16 i = 0; i < nCount; ++i ) 609 { 610 rtl::OUString* pFile = pFiles->GetObject(i); 611 pRet[i] = *( pFile ); 612 delete pFile; 613 } 614 delete pFiles; 615 return aRet; 616 } 617 else 618 return Sequence < rtl::OUString > (); 619 } 620 621 sal_Bool OFileAccess::exists( const rtl::OUString& FileURL ) 622 throw(CommandAbortedException, Exception, RuntimeException) 623 { 624 sal_Bool bRet = sal_False; 625 try 626 { 627 bRet = isFolder( FileURL ); 628 if( !bRet ) 629 { 630 Reference< XInputStream > xStream = openFileRead( FileURL ); 631 bRet = xStream.is(); 632 if( bRet ) 633 xStream->closeInput(); 634 } 635 } 636 catch (Exception &) {} 637 return bRet; 638 } 639 640 Reference< XInputStream > OFileAccess::openFileRead( const rtl::OUString& FileURL ) 641 throw(CommandAbortedException, Exception, RuntimeException) 642 { 643 Reference< XInputStream > xRet; 644 INetURLObject aObj( FileURL, INET_PROT_FILE ); 645 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 646 647 Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink()); 648 649 try 650 { 651 sal_Bool bRet = aCnt.openStream( xSink ); 652 if( bRet ) 653 xRet = xSink->getInputStream(); 654 } 655 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 656 { 657 // Interaction Handler already handled the error that has occured... 658 } 659 660 return xRet; 661 } 662 663 Reference< XOutputStream > OFileAccess::openFileWrite( const rtl::OUString& FileURL ) 664 throw(CommandAbortedException, Exception, RuntimeException) 665 { 666 Reference< XOutputStream > xRet; 667 Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL ); 668 if( xStream.is() ) 669 xRet = xStream->getOutputStream(); 670 return xRet; 671 } 672 673 Reference< XStream > OFileAccess::openFileReadWrite( const rtl::OUString& FileURL ) 674 throw(CommandAbortedException, Exception, RuntimeException) 675 { 676 Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer(); 677 Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink ); 678 679 OpenCommandArgument2 aArg; 680 aArg.Mode = OpenMode::DOCUMENT; 681 aArg.Priority = 0; // unused 682 aArg.Sink = xSink; 683 aArg.Properties = Sequence< Property >( 0 ); // unused 684 685 Any aCmdArg; 686 aCmdArg <<= aArg; 687 688 INetURLObject aFileObj( FileURL, INET_PROT_FILE ); 689 ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 690 691 // Be silent... 692 Reference< XInteractionHandler > xIH; 693 if ( mpEnvironment ) 694 { 695 xIH = mpEnvironment->getInteractionHandler(); 696 mpEnvironment->setHandler( 0 ); 697 } 698 699 try 700 { 701 aCnt.executeCommand( rtl::OUString::createFromAscii( "open" ), aCmdArg ); 702 } 703 catch ( InteractiveIOException const & e ) 704 { 705 if ( xIH.is() ) 706 mpEnvironment->setHandler( xIH ); 707 708 if ( e.Code == IOErrorCode_NOT_EXISTING ) 709 { 710 // Create file... 711 SvMemoryStream aStream(0,0); 712 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream ); 713 Reference< XInputStream > xInput( pInput ); 714 InsertCommandArgument aInsertArg; 715 aInsertArg.Data = xInput; 716 aInsertArg.ReplaceExisting = sal_False; 717 718 aCmdArg <<= aInsertArg; 719 aCnt.executeCommand( rtl::OUString::createFromAscii( "insert" ), aCmdArg ); 720 721 // Retry... 722 return openFileReadWrite( FileURL ); 723 } 724 725 throw; 726 } 727 728 if ( xIH.is() ) 729 mpEnvironment->setHandler( xIH ); 730 731 Reference< XStream > xRet = xSink->getStream(); 732 return xRet; 733 } 734 735 void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler ) 736 throw(RuntimeException) 737 { 738 if( !mpEnvironment ) 739 { 740 mpEnvironment = new OCommandEnvironment(); 741 mxEnvironment = (XCommandEnvironment*)mpEnvironment; 742 } 743 mpEnvironment->setHandler( Handler ); 744 } 745 746 bool OFileAccess::createNewFile( const rtl::OUString & rParentURL, 747 const rtl::OUString & rTitle, 748 const Reference< XInputStream >& data ) 749 throw ( Exception ) 750 { 751 ucbhelper::Content aParentCnt( rParentURL, mxEnvironment ); 752 753 Sequence< ContentInfo > aInfo = aParentCnt.queryCreatableContentsInfo(); 754 sal_Int32 nCount = aInfo.getLength(); 755 if ( nCount == 0 ) 756 return false; 757 758 for ( sal_Int32 i = 0; i < nCount; ++i ) 759 { 760 const ContentInfo & rCurr = aInfo[i]; 761 if ( ( rCurr.Attributes 762 & ContentInfoAttribute::KIND_DOCUMENT ) && 763 ( rCurr.Attributes 764 & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) ) 765 { 766 // Make sure the only required bootstrap property is 767 // "Title", 768 const Sequence< Property > & rProps = rCurr.Properties; 769 if ( rProps.getLength() != 1 ) 770 continue; 771 772 if ( !rProps[ 0 ].Name.equalsAsciiL( 773 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 774 continue; 775 776 Sequence<rtl::OUString> aNames(1); 777 rtl::OUString* pNames = aNames.getArray(); 778 pNames[0] = rtl::OUString( 779 RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 780 Sequence< Any > aValues(1); 781 Any* pValues = aValues.getArray(); 782 pValues[0] = makeAny( rtl::OUString( rTitle ) ); 783 784 try 785 { 786 ucbhelper::Content aNew; 787 if ( aParentCnt.insertNewContent( 788 rCurr.Type, aNames, aValues, data, aNew ) ) 789 return true; // success. 790 else 791 continue; 792 } 793 catch ( CommandFailedException const & ) 794 { 795 // Interaction Handler already handled the 796 // error that has occured... 797 continue; 798 } 799 } 800 } 801 802 return false; 803 } 804 805 void SAL_CALL OFileAccess::writeFile( const rtl::OUString& FileURL, 806 const Reference< XInputStream >& data ) 807 throw ( Exception, RuntimeException ) 808 { 809 INetURLObject aURL( FileURL, INET_PROT_FILE ); 810 try 811 { 812 ucbhelper::Content aCnt( 813 aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 814 815 try 816 { 817 aCnt.writeStream( data, sal_True /* bReplaceExisting */ ); 818 } 819 catch ( CommandFailedException const & ) 820 { 821 // Interaction Handler already handled the error that has occured... 822 } 823 } 824 catch ( ContentCreationException const & e ) 825 { 826 // Most probably file does not exist. Try to create. 827 if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED ) 828 { 829 INetURLObject aParentURLObj( aURL ); 830 if ( aParentURLObj.removeSegment() ) 831 { 832 String aParentURL 833 = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE ); 834 835 // ensure all parent folders exist. 836 createFolder( aParentURL ); 837 838 // create the new file... 839 String aTitle 840 = aURL.getName( INetURLObject::LAST_SEGMENT, 841 true, 842 INetURLObject::DECODE_WITH_CHARSET ); 843 if ( createNewFile( aParentURL, aTitle, data ) ) 844 { 845 // success 846 return; 847 } 848 } 849 } 850 851 throw; 852 } 853 } 854 855 sal_Bool OFileAccess::isHidden( const ::rtl::OUString& FileURL ) 856 throw(CommandAbortedException, Exception, RuntimeException) 857 { 858 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 859 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 860 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ) ); 861 sal_Bool bRet = sal_False; 862 aRetAny >>= bRet; 863 return bRet; 864 } 865 866 void OFileAccess::setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden ) 867 throw(CommandAbortedException, Exception, RuntimeException) 868 { 869 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 870 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 871 Any aAny; 872 aAny <<= bHidden; 873 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), aAny ); 874 } 875 876 //================================================================================================== 877 //================================================================================================== 878 //================================================================================================== 879 880 Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XMultiServiceFactory > & xSMgr ) 881 { 882 return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( xSMgr ) ); 883 } 884 885 886 Sequence< rtl::OUString > FileAccess_getSupportedServiceNames() 887 { 888 static Sequence < rtl::OUString > *pNames = 0; 889 if( ! pNames ) 890 { 891 osl::MutexGuard guard( osl::Mutex::getGlobalMutex() ); 892 if( !pNames ) 893 { 894 static Sequence< rtl::OUString > seqNames(1); 895 seqNames.getArray()[0] = rtl::OUString::createFromAscii( SERVICE_NAME ); 896 pNames = &seqNames; 897 } 898 } 899 return *pNames; 900 } 901 902 903 } 904 905 //================================================================================================== 906 // Component exports 907 908 extern "C" 909 { 910 //================================================================================================== 911 void SAL_CALL component_getImplementationEnvironment( 912 const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) 913 { 914 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 915 } 916 //================================================================================================== 917 void * SAL_CALL component_getFactory( 918 const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) 919 { 920 void * pRet = 0; 921 922 if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) 923 { 924 Reference< XSingleServiceFactory > xFactory( cppu::createSingleFactory( 925 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), 926 rtl::OUString::createFromAscii( pImplName ), 927 io_FileAccess::FileAccess_CreateInstance, 928 io_FileAccess::FileAccess_getSupportedServiceNames() ) ); 929 930 if (xFactory.is()) 931 { 932 xFactory->acquire(); 933 pRet = xFactory.get(); 934 } 935 } 936 937 return pRet; 938 } 939 } 940 941 942