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 #include <cppuhelper/implementationentry.hxx> 34 35 #include <tools/ref.hxx> 36 #include <tools/urlobj.hxx> 37 #include <ucbhelper/content.hxx> 38 #include <unotools/streamwrap.hxx> 39 #include <tools/stream.hxx> 40 41 #include <com/sun/star/beans/Property.hpp> 42 #include <com/sun/star/beans/XPropertySet.hpp> 43 #include <com/sun/star/container/XChild.hpp> 44 #include <com/sun/star/io/XActiveDataSink.hpp> 45 #include <com/sun/star/io/XActiveDataSource.hpp> 46 #include <com/sun/star/io/XActiveDataStreamer.hpp> 47 #include <com/sun/star/sdbc/XResultSet.hpp> 48 #include <com/sun/star/ucb/CommandFailedException.hpp> 49 #include <com/sun/star/ucb/ContentInfo.hpp> 50 #include <com/sun/star/ucb/ContentInfoAttribute.hpp> 51 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 52 #include <com/sun/star/ucb/InteractiveIOException.hpp> 53 #include <com/sun/star/ucb/NameClash.hpp> 54 #include <com/sun/star/ucb/NameClashException.hpp> 55 #include <com/sun/star/ucb/OpenCommandArgument2.hpp> 56 #include <com/sun/star/ucb/OpenMode.hpp> 57 #include <com/sun/star/ucb/XCommandEnvironment.hpp> 58 #include <com/sun/star/ucb/XContent.hpp> 59 #include <com/sun/star/ucb/XContentAccess.hpp> 60 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp> 61 #include <com/sun/star/util/XMacroExpander.hpp> 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< XComponentContext > mxCtx; 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< XComponentContext > & xCtx ) 99 : mxCtx( xCtx ), 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 hierarchical 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< XMacroExpander > xExpander; 324 325 mxCtx->getValueByName( 326 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 327 "/singletons/com.sun.star.util.theMacroExpander" ) ) ) 328 >>= xExpander; 329 330 OSL_ENSURE( xExpander.is(), 331 "Unable to obtain macro expander singleton!" ); 332 333 aDestURL = xExpander->expandMacros( 334 aDestObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) ); 335 } 336 catch ( Exception const & ) 337 { 338 throw RuntimeException( 339 rtl::OUString( 340 RTL_CONSTASCII_USTRINGPARAM( 341 "OFileAccess::transferrImpl - Unable to obtain " 342 "destination folder URL!" ) ), 343 static_cast< cppu::OWeakObject * >( this ) ); 344 } 345 346 transferImpl( rSource, aDestURL, bMoveData ); 347 return; 348 } 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 #endif 357 } 358 359 ucbhelper::Content aDestPath( aDestURL, mxEnvironment ); 360 ucbhelper::Content aSrc ( aSourceURL, mxEnvironment ); 361 362 try 363 { 364 aDestPath.transferContent( aSrc, 365 bMoveData 366 ? ucbhelper::InsertOperation_MOVE 367 : ucbhelper::InsertOperation_COPY, 368 aName, 369 ::com::sun::star::ucb::NameClash::OVERWRITE ); 370 } 371 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 372 { 373 // Interaction Handler already handled the error that has occurred... 374 } 375 } 376 377 void OFileAccess::copy( const rtl::OUString& SourceURL, const rtl::OUString& DestURL ) 378 throw(CommandAbortedException, Exception, RuntimeException) 379 { 380 transferImpl( SourceURL, DestURL, sal_False ); 381 } 382 383 void OFileAccess::move( const rtl::OUString& SourceURL, const rtl::OUString& DestURL ) 384 throw(CommandAbortedException, Exception, RuntimeException) 385 { 386 transferImpl( SourceURL, DestURL, sal_True ); 387 } 388 389 void OFileAccess::kill( const rtl::OUString& FileURL ) 390 throw(CommandAbortedException, Exception, RuntimeException) 391 { 392 // SfxContentHelper::Kill 393 INetURLObject aDeleteObj( FileURL, INET_PROT_FILE ); 394 ucbhelper::Content aCnt( aDeleteObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 395 try 396 { 397 aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); 398 } 399 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 400 { 401 // Interaction Handler already handled the error that has occurred... 402 } 403 } 404 405 sal_Bool OFileAccess::isFolder( const rtl::OUString& FileURL ) 406 throw(CommandAbortedException, Exception, RuntimeException) 407 { 408 sal_Bool bRet = sal_False; 409 try 410 { 411 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 412 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 413 bRet = aCnt.isFolder(); 414 } 415 catch (Exception &) {} 416 return bRet; 417 } 418 419 sal_Bool OFileAccess::isReadOnly( const rtl::OUString& FileURL ) 420 throw(CommandAbortedException, Exception, RuntimeException) 421 { 422 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 423 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 424 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ) ); 425 sal_Bool bRet = sal_False; 426 aRetAny >>= bRet; 427 return bRet; 428 } 429 430 void OFileAccess::setReadOnly( const rtl::OUString& FileURL, sal_Bool bReadOnly ) 431 throw(CommandAbortedException, Exception, RuntimeException) 432 { 433 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 434 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 435 Any aAny; 436 aAny <<= bReadOnly; 437 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), aAny ); 438 } 439 440 void OFileAccess::createFolder( const rtl::OUString& NewFolderURL ) 441 throw(CommandAbortedException, Exception, RuntimeException) 442 { 443 // Does the folder already exist? 444 if( !NewFolderURL.getLength() || isFolder( NewFolderURL ) ) 445 return; 446 447 // SfxContentHelper::MakeFolder 448 INetURLObject aURL( NewFolderURL, INET_PROT_FILE ); 449 String aNewFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE ); 450 String aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); 451 if ( aTitle.Len() ) 452 { 453 aURL.removeSegment(); 454 455 // Does the base folder exist? Otherwise create it first 456 String aBaseFolderURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE ); 457 if( !isFolder( aBaseFolderURLStr ) ) 458 { 459 createFolder( aBaseFolderURLStr ); 460 } 461 } 462 463 ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 464 465 Sequence< ContentInfo > aInfo = aCnt.queryCreatableContentsInfo(); 466 sal_Int32 nCount = aInfo.getLength(); 467 if ( nCount == 0 ) 468 return; 469 470 for ( sal_Int32 i = 0; i < nCount; ++i ) 471 { 472 // Simply look for the first KIND_FOLDER... 473 const ContentInfo & rCurr = aInfo[i]; 474 if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER ) 475 { 476 // Make sure the only required bootstrap property is "Title", 477 const Sequence< Property > & rProps = rCurr.Properties; 478 if ( rProps.getLength() != 1 ) 479 continue; 480 481 if ( !rProps[ 0 ].Name.equalsAsciiL( 482 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 483 continue; 484 485 Sequence<rtl::OUString> aNames(1); 486 rtl::OUString* pNames = aNames.getArray(); 487 pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 488 Sequence< Any > aValues(1); 489 Any* pValues = aValues.getArray(); 490 pValues[0] = makeAny( rtl::OUString( aTitle ) ); 491 492 ucbhelper::Content aNew; 493 try 494 { 495 if ( !aCnt.insertNewContent( rCurr.Type, aNames, aValues, aNew ) ) 496 continue; 497 498 // Success. We're done. 499 return; 500 } 501 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 502 { 503 // Interaction Handler already handled the error that has occurred... 504 continue; 505 } 506 } 507 } 508 } 509 510 sal_Int32 OFileAccess::getSize( const rtl::OUString& FileURL ) 511 throw(CommandAbortedException, Exception, RuntimeException) 512 { 513 // SfxContentHelper::GetSize 514 sal_Int32 nSize = 0; 515 sal_Int64 nTemp = 0; 516 INetURLObject aObj( FileURL, INET_PROT_FILE ); 517 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 518 aCnt.getPropertyValue( rtl::OUString::createFromAscii( "Size" ) ) >>= nTemp; 519 nSize = (sal_Int32)nTemp; 520 return nSize; 521 } 522 523 rtl::OUString OFileAccess::getContentType( const rtl::OUString& FileURL ) 524 throw(CommandAbortedException, Exception, RuntimeException) 525 { 526 INetURLObject aObj( FileURL, INET_PROT_FILE ); 527 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 528 529 Reference< XContent > xContent = aCnt.get(); 530 rtl::OUString aTypeStr = xContent->getContentType(); 531 return aTypeStr; 532 } 533 534 DateTime OFileAccess::getDateTimeModified( const rtl::OUString& FileURL ) 535 throw(CommandAbortedException, Exception, RuntimeException) 536 { 537 INetURLObject aFileObj( FileURL, INET_PROT_FILE ); 538 DateTime aDateTime; 539 540 Reference< XCommandEnvironment > aCmdEnv; 541 ucbhelper::Content aYoung( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); 542 aYoung.getPropertyValue( rtl::OUString::createFromAscii( "DateModified" ) ) >>= aDateTime; 543 return aDateTime; 544 } 545 546 547 DECLARE_LIST( StringList_Impl, rtl::OUString* ) 548 549 Sequence< rtl::OUString > OFileAccess::getFolderContents( const rtl::OUString& FolderURL, sal_Bool bIncludeFolders ) 550 throw(CommandAbortedException, Exception, RuntimeException) 551 { 552 // SfxContentHelper::GetFolderContents 553 554 StringList_Impl* pFiles = NULL; 555 INetURLObject aFolderObj( FolderURL, INET_PROT_FILE ); 556 557 ucbhelper::Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 558 Reference< XResultSet > xResultSet; 559 Sequence< rtl::OUString > aProps(0); 560 //Sequence< rtl::OUString > aProps(1); 561 //rtl::OUString* pProps = aProps.getArray(); 562 //pProps[0] == rtl::OUString::createFromAscii( "Url" ); 563 564 ucbhelper::ResultSetInclude eInclude = bIncludeFolders ? ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS : ucbhelper::INCLUDE_DOCUMENTS_ONLY; 565 566 try 567 { 568 xResultSet = aCnt.createCursor( aProps, eInclude ); 569 } 570 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 571 { 572 // Interaction Handler already handled the error that has occurred... 573 } 574 575 if ( xResultSet.is() ) 576 { 577 pFiles = new StringList_Impl; 578 Reference< com::sun::star::ucb::XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); 579 580 while ( xResultSet->next() ) 581 { 582 rtl::OUString aId = xContentAccess->queryContentIdentifierString(); 583 INetURLObject aURL( aId, INET_PROT_FILE ); 584 rtl::OUString* pFile = new rtl::OUString( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); 585 pFiles->Insert( pFile, LIST_APPEND ); 586 } 587 } 588 589 if ( pFiles ) 590 { 591 sal_uIntPtr nCount = pFiles->Count(); 592 Sequence < rtl::OUString > aRet( nCount ); 593 rtl::OUString* pRet = aRet.getArray(); 594 for ( sal_uInt16 i = 0; i < nCount; ++i ) 595 { 596 rtl::OUString* pFile = pFiles->GetObject(i); 597 pRet[i] = *( pFile ); 598 delete pFile; 599 } 600 delete pFiles; 601 return aRet; 602 } 603 else 604 return Sequence < rtl::OUString > (); 605 } 606 607 sal_Bool OFileAccess::exists( const rtl::OUString& FileURL ) 608 throw(CommandAbortedException, Exception, RuntimeException) 609 { 610 sal_Bool bRet = sal_False; 611 try 612 { 613 bRet = isFolder( FileURL ); 614 if( !bRet ) 615 { 616 Reference< XInputStream > xStream = openFileRead( FileURL ); 617 bRet = xStream.is(); 618 if( bRet ) 619 xStream->closeInput(); 620 } 621 } 622 catch (Exception &) {} 623 return bRet; 624 } 625 626 Reference< XInputStream > OFileAccess::openFileRead( const rtl::OUString& FileURL ) 627 throw(CommandAbortedException, Exception, RuntimeException) 628 { 629 Reference< XInputStream > xRet; 630 INetURLObject aObj( FileURL, INET_PROT_FILE ); 631 ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 632 633 Reference< XActiveDataSink > xSink = (XActiveDataSink*)(new OActiveDataSink()); 634 635 try 636 { 637 sal_Bool bRet = aCnt.openStream( xSink ); 638 if( bRet ) 639 xRet = xSink->getInputStream(); 640 } 641 catch ( ::com::sun::star::ucb::CommandFailedException const & ) 642 { 643 // Interaction Handler already handled the error that has occurred... 644 } 645 646 return xRet; 647 } 648 649 Reference< XOutputStream > OFileAccess::openFileWrite( const rtl::OUString& FileURL ) 650 throw(CommandAbortedException, Exception, RuntimeException) 651 { 652 Reference< XOutputStream > xRet; 653 Reference< XStream > xStream = OFileAccess::openFileReadWrite( FileURL ); 654 if( xStream.is() ) 655 xRet = xStream->getOutputStream(); 656 return xRet; 657 } 658 659 Reference< XStream > OFileAccess::openFileReadWrite( const rtl::OUString& FileURL ) 660 throw(CommandAbortedException, Exception, RuntimeException) 661 { 662 Reference< XActiveDataStreamer > xSink = (XActiveDataStreamer*)new OActiveDataStreamer(); 663 Reference< XInterface > xSinkIface = Reference< XInterface >::query( xSink ); 664 665 OpenCommandArgument2 aArg; 666 aArg.Mode = OpenMode::DOCUMENT; 667 aArg.Priority = 0; // unused 668 aArg.Sink = xSink; 669 aArg.Properties = Sequence< Property >( 0 ); // unused 670 671 Any aCmdArg; 672 aCmdArg <<= aArg; 673 674 INetURLObject aFileObj( FileURL, INET_PROT_FILE ); 675 ucbhelper::Content aCnt( aFileObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 676 677 // Be silent... 678 Reference< XInteractionHandler > xIH; 679 if ( mpEnvironment ) 680 { 681 xIH = mpEnvironment->getInteractionHandler(); 682 mpEnvironment->setHandler( 0 ); 683 } 684 685 try 686 { 687 aCnt.executeCommand( rtl::OUString::createFromAscii( "open" ), aCmdArg ); 688 } 689 catch ( InteractiveIOException const & e ) 690 { 691 if ( xIH.is() ) 692 mpEnvironment->setHandler( xIH ); 693 694 if ( e.Code == IOErrorCode_NOT_EXISTING ) 695 { 696 // Create file... 697 SvMemoryStream aStream(0,0); 698 ::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream ); 699 Reference< XInputStream > xInput( pInput ); 700 InsertCommandArgument aInsertArg; 701 aInsertArg.Data = xInput; 702 aInsertArg.ReplaceExisting = sal_False; 703 704 aCmdArg <<= aInsertArg; 705 aCnt.executeCommand( rtl::OUString::createFromAscii( "insert" ), aCmdArg ); 706 707 // Retry... 708 return openFileReadWrite( FileURL ); 709 } 710 711 throw; 712 } 713 714 if ( xIH.is() ) 715 mpEnvironment->setHandler( xIH ); 716 717 Reference< XStream > xRet = xSink->getStream(); 718 return xRet; 719 } 720 721 void OFileAccess::setInteractionHandler( const Reference< XInteractionHandler >& Handler ) 722 throw(RuntimeException) 723 { 724 if( !mpEnvironment ) 725 { 726 mpEnvironment = new OCommandEnvironment(); 727 mxEnvironment = (XCommandEnvironment*)mpEnvironment; 728 } 729 mpEnvironment->setHandler( Handler ); 730 } 731 732 bool OFileAccess::createNewFile( const rtl::OUString & rParentURL, 733 const rtl::OUString & rTitle, 734 const Reference< XInputStream >& data ) 735 throw ( Exception ) 736 { 737 ucbhelper::Content aParentCnt( rParentURL, mxEnvironment ); 738 739 Sequence< ContentInfo > aInfo = aParentCnt.queryCreatableContentsInfo(); 740 sal_Int32 nCount = aInfo.getLength(); 741 if ( nCount == 0 ) 742 return false; 743 744 for ( sal_Int32 i = 0; i < nCount; ++i ) 745 { 746 const ContentInfo & rCurr = aInfo[i]; 747 if ( ( rCurr.Attributes 748 & ContentInfoAttribute::KIND_DOCUMENT ) && 749 ( rCurr.Attributes 750 & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM ) ) 751 { 752 // Make sure the only required bootstrap property is 753 // "Title", 754 const Sequence< Property > & rProps = rCurr.Properties; 755 if ( rProps.getLength() != 1 ) 756 continue; 757 758 if ( !rProps[ 0 ].Name.equalsAsciiL( 759 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 760 continue; 761 762 Sequence<rtl::OUString> aNames(1); 763 rtl::OUString* pNames = aNames.getArray(); 764 pNames[0] = rtl::OUString( 765 RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 766 Sequence< Any > aValues(1); 767 Any* pValues = aValues.getArray(); 768 pValues[0] = makeAny( rtl::OUString( rTitle ) ); 769 770 try 771 { 772 ucbhelper::Content aNew; 773 if ( aParentCnt.insertNewContent( 774 rCurr.Type, aNames, aValues, data, aNew ) ) 775 return true; // success. 776 else 777 continue; 778 } 779 catch ( CommandFailedException const & ) 780 { 781 // Interaction Handler already handled the 782 // error that has occurred... 783 continue; 784 } 785 } 786 } 787 788 return false; 789 } 790 791 void SAL_CALL OFileAccess::writeFile( const rtl::OUString& FileURL, 792 const Reference< XInputStream >& data ) 793 throw ( Exception, RuntimeException ) 794 { 795 INetURLObject aURL( FileURL, INET_PROT_FILE ); 796 try 797 { 798 ucbhelper::Content aCnt( 799 aURL.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 800 801 try 802 { 803 aCnt.writeStream( data, sal_True /* bReplaceExisting */ ); 804 } 805 catch ( CommandFailedException const & ) 806 { 807 // Interaction Handler already handled the error that has occurred... 808 } 809 } 810 catch ( ContentCreationException const & e ) 811 { 812 // Most probably file does not exist. Try to create. 813 if ( e.eError == ContentCreationError_CONTENT_CREATION_FAILED ) 814 { 815 INetURLObject aParentURLObj( aURL ); 816 if ( aParentURLObj.removeSegment() ) 817 { 818 String aParentURL 819 = aParentURLObj.GetMainURL( INetURLObject::NO_DECODE ); 820 821 // ensure all parent folders exist. 822 createFolder( aParentURL ); 823 824 // create the new file... 825 String aTitle 826 = aURL.getName( INetURLObject::LAST_SEGMENT, 827 true, 828 INetURLObject::DECODE_WITH_CHARSET ); 829 if ( createNewFile( aParentURL, aTitle, data ) ) 830 { 831 // success 832 return; 833 } 834 } 835 } 836 837 throw; 838 } 839 } 840 841 sal_Bool OFileAccess::isHidden( const ::rtl::OUString& FileURL ) 842 throw(CommandAbortedException, Exception, RuntimeException) 843 { 844 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 845 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 846 Any aRetAny = aCnt.getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ) ); 847 sal_Bool bRet = sal_False; 848 aRetAny >>= bRet; 849 return bRet; 850 } 851 852 void OFileAccess::setHidden( const ::rtl::OUString& FileURL, sal_Bool bHidden ) 853 throw(CommandAbortedException, Exception, RuntimeException) 854 { 855 INetURLObject aURLObj( FileURL, INET_PROT_FILE ); 856 ucbhelper::Content aCnt( aURLObj.GetMainURL( INetURLObject::NO_DECODE ), mxEnvironment ); 857 Any aAny; 858 aAny <<= bHidden; 859 aCnt.setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), aAny ); 860 } 861 862 //================================================================================================== 863 //================================================================================================== 864 //================================================================================================== 865 866 Reference< XInterface > SAL_CALL FileAccess_CreateInstance( const Reference< XComponentContext > & xCtx ) 867 { 868 return Reference < XInterface >( ( cppu::OWeakObject * ) new OFileAccess( xCtx ) ); 869 } 870 871 rtl::OUString FileAccess_getImplementationName() 872 { 873 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ucb.SimpleFileAccess" ) ); 874 } 875 876 Sequence< rtl::OUString > FileAccess_getSupportedServiceNames() 877 { 878 static Sequence < rtl::OUString > *pNames = 0; 879 if( ! pNames ) 880 { 881 osl::MutexGuard guard( osl::Mutex::getGlobalMutex() ); 882 if( !pNames ) 883 { 884 static Sequence< rtl::OUString > seqNames(1); 885 seqNames.getArray()[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ); 886 pNames = &seqNames; 887 } 888 } 889 return *pNames; 890 } 891 892 struct ::cppu::ImplementationEntry g_component_entries [] = 893 { 894 { 895 FileAccess_CreateInstance, 896 FileAccess_getImplementationName, 897 FileAccess_getSupportedServiceNames, 898 ::cppu::createSingleComponentFactory, 899 0, 900 0 901 }, 902 { 0, 0, 0, 0, 0, 0 } 903 }; 904 905 } 906 907 //================================================================================================== 908 // Component exports 909 910 extern "C" 911 { 912 //================================================================================================== 913 FILEACCESS_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( 914 const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) 915 { 916 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 917 } 918 //================================================================================================== 919 FILEACCESS_DLLPUBLIC void * SAL_CALL component_getFactory( 920 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) 921 { 922 return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, ::io_FileAccess::g_component_entries ); 923 } 924 } 925