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