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