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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_pkg.hxx" 26 27 /************************************************************************** 28 TODO 29 ************************************************************************** 30 *************************************************************************/ 31 #include <osl/diagnose.h> 32 33 #include "osl/doublecheckedlocking.h" 34 #include <rtl/ustring.h> 35 #include <rtl/ustring.hxx> 36 #include <com/sun/star/beans/PropertyAttribute.hpp> 37 #include <com/sun/star/beans/PropertyState.hpp> 38 #include <com/sun/star/beans/PropertyValue.hpp> 39 #include <com/sun/star/beans/XPropertyAccess.hpp> 40 #include <com/sun/star/container/XEnumerationAccess.hpp> 41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 42 #include <com/sun/star/container/XNameContainer.hpp> 43 #include <com/sun/star/container/XNamed.hpp> 44 #include <com/sun/star/io/XActiveDataSink.hpp> 45 #include <com/sun/star/io/XInputStream.hpp> 46 #include <com/sun/star/io/XOutputStream.hpp> 47 #include <com/sun/star/lang/IllegalAccessException.hpp> 48 #include <com/sun/star/sdbc/XRow.hpp> 49 #include <com/sun/star/ucb/ContentInfoAttribute.hpp> 50 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 51 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> 52 #include <com/sun/star/ucb/MissingInputStreamException.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/TransferInfo.hpp> 58 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> 59 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp> 60 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp> 61 #include <com/sun/star/ucb/XCommandInfo.hpp> 62 #include <com/sun/star/ucb/XPersistentPropertySet.hpp> 63 #include <com/sun/star/util/XChangesBatch.hpp> 64 #include <com/sun/star/uno/Any.hxx> 65 #include <com/sun/star/uno/Sequence.hxx> 66 #include <ucbhelper/contentidentifier.hxx> 67 #include <ucbhelper/propertyvalueset.hxx> 68 #include <ucbhelper/cancelcommandexecution.hxx> 69 #include "pkgcontent.hxx" 70 #include "pkgprovider.hxx" 71 #include "pkgresultset.hxx" 72 73 #include "../inc/urihelper.hxx" 74 75 using namespace com::sun::star; 76 using namespace package_ucp; 77 78 #define NONE_MODIFIED sal_uInt32( 0x00 ) 79 #define MEDIATYPE_MODIFIED sal_uInt32( 0x01 ) 80 #define COMPRESSED_MODIFIED sal_uInt32( 0x02 ) 81 #define ENCRYPTED_MODIFIED sal_uInt32( 0x04 ) 82 #define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 ) 83 84 //========================================================================= 85 //========================================================================= 86 // 87 // ContentProperties Implementation. 88 // 89 //========================================================================= 90 //========================================================================= 91 92 ContentProperties::ContentProperties( const rtl::OUString& rContentType ) 93 : aContentType( rContentType ), 94 nSize( 0 ), 95 bCompressed( sal_True ), 96 bEncrypted( sal_False ), 97 bHasEncryptedEntries( sal_False ) 98 { 99 bIsFolder = rContentType.equalsAsciiL( 100 RTL_CONSTASCII_STRINGPARAM( PACKAGE_FOLDER_CONTENT_TYPE ) ) 101 || rContentType.equalsAsciiL( 102 RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_FOLDER_CONTENT_TYPE ) ); 103 bIsDocument = !bIsFolder; 104 105 OSL_ENSURE( bIsFolder || 106 rContentType.equalsAsciiL( 107 RTL_CONSTASCII_STRINGPARAM( PACKAGE_STREAM_CONTENT_TYPE ) ) 108 || rContentType.equalsAsciiL( 109 RTL_CONSTASCII_STRINGPARAM( PACKAGE_ZIP_STREAM_CONTENT_TYPE ) ), 110 "ContentProperties::ContentProperties - Unknown type!" ); 111 } 112 113 //========================================================================= 114 115 uno::Sequence< ucb::ContentInfo > 116 ContentProperties::getCreatableContentsInfo( PackageUri const & rUri ) const 117 { 118 if ( bIsFolder ) 119 { 120 uno::Sequence< beans::Property > aProps( 1 ); 121 aProps.getArray()[ 0 ] = beans::Property( 122 rtl::OUString::createFromAscii( "Title" ), 123 -1, 124 getCppuType( static_cast< const rtl::OUString * >( 0 ) ), 125 beans::PropertyAttribute::BOUND ); 126 127 uno::Sequence< ucb::ContentInfo > aSeq( 2 ); 128 129 // Folder. 130 aSeq.getArray()[ 0 ].Type 131 = Content::getContentType( rUri.getScheme(), sal_True ); 132 aSeq.getArray()[ 0 ].Attributes 133 = ucb::ContentInfoAttribute::KIND_FOLDER; 134 aSeq.getArray()[ 0 ].Properties = aProps; 135 136 // Stream. 137 aSeq.getArray()[ 1 ].Type 138 = Content::getContentType( rUri.getScheme(), sal_False ); 139 aSeq.getArray()[ 1 ].Attributes 140 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM 141 | ucb::ContentInfoAttribute::KIND_DOCUMENT; 142 aSeq.getArray()[ 1 ].Properties = aProps; 143 144 return aSeq; 145 } 146 else 147 { 148 return uno::Sequence< ucb::ContentInfo >( 0 ); 149 } 150 } 151 152 //========================================================================= 153 //========================================================================= 154 // 155 // Content Implementation. 156 // 157 //========================================================================= 158 //========================================================================= 159 160 // static ( "virtual" ctor ) 161 Content* Content::create( 162 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 163 ContentProvider* pProvider, 164 const uno::Reference< ucb::XContentIdentifier >& Identifier ) 165 { 166 rtl::OUString aURL = Identifier->getContentIdentifier(); 167 PackageUri aURI( aURL ); 168 ContentProperties aProps; 169 uno::Reference< container::XHierarchicalNameAccess > xPackage; 170 171 if ( loadData( pProvider, aURI, aProps, xPackage ) ) 172 { 173 // resource exists 174 175 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' ); 176 if ( ( nLastSlash + 1 ) == aURL.getLength() ) 177 { 178 // Client explicitly requested a folder! 179 if ( !aProps.bIsFolder ) 180 return 0; 181 } 182 183 uno::Reference< ucb::XContentIdentifier > xId 184 = new ::ucbhelper::ContentIdentifier( rxSMgr, aURI.getUri() ); 185 return new Content( rxSMgr, pProvider, xId, xPackage, aURI, aProps ); 186 } 187 else 188 { 189 // resource doesn't exist 190 191 sal_Bool bFolder = sal_False; 192 193 // Guess type according to URI. 194 sal_Int32 nLastSlash = aURL.lastIndexOf( '/' ); 195 if ( ( nLastSlash + 1 ) == aURL.getLength() ) 196 bFolder = sal_True; 197 198 uno::Reference< ucb::XContentIdentifier > xId 199 = new ::ucbhelper::ContentIdentifier( rxSMgr, aURI.getUri() ); 200 201 ucb::ContentInfo aInfo; 202 if ( bFolder || aURI.isRootFolder() ) 203 aInfo.Type = getContentType( aURI.getScheme(), sal_True ); 204 else 205 aInfo.Type = getContentType( aURI.getScheme(), sal_False ); 206 207 return new Content( rxSMgr, pProvider, xId, xPackage, aURI, aInfo ); 208 } 209 } 210 211 //========================================================================= 212 // static ( "virtual" ctor ) 213 Content* Content::create( 214 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 215 ContentProvider* pProvider, 216 const uno::Reference< ucb::XContentIdentifier >& Identifier, 217 const ucb::ContentInfo& Info ) 218 { 219 if ( !Info.Type.getLength() ) 220 return 0; 221 222 PackageUri aURI( Identifier->getContentIdentifier() ); 223 224 if ( !Info.Type.equalsIgnoreAsciiCase( 225 getContentType( aURI.getScheme(), sal_True ) ) && 226 !Info.Type.equalsIgnoreAsciiCase( 227 getContentType( aURI.getScheme(), sal_False ) ) ) 228 return 0; 229 230 uno::Reference< container::XHierarchicalNameAccess > xPackage; 231 232 #if 0 233 // Fail, if content does exist. 234 if ( hasData( pProvider, aURI, xPackage ) ) 235 return 0; 236 #else 237 xPackage = pProvider->createPackage( aURI.getPackage(), aURI.getParam() ); 238 #endif 239 240 uno::Reference< ucb::XContentIdentifier > xId 241 = new ::ucbhelper::ContentIdentifier( rxSMgr, aURI.getUri() ); 242 return new Content( rxSMgr, pProvider, xId, xPackage, aURI, Info ); 243 } 244 245 //========================================================================= 246 // static 247 ::rtl::OUString Content::getContentType( 248 const ::rtl::OUString& aScheme, sal_Bool bFolder ) 249 { 250 return ( rtl::OUString::createFromAscii( "application/" ) 251 + aScheme 252 + ( bFolder 253 ? rtl::OUString::createFromAscii( "-folder" ) 254 : rtl::OUString::createFromAscii( "-stream" ) ) ); 255 } 256 257 //========================================================================= 258 Content::Content( 259 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 260 ContentProvider* pProvider, 261 const uno::Reference< ucb::XContentIdentifier >& Identifier, 262 const uno::Reference< container::XHierarchicalNameAccess > & Package, 263 const PackageUri& rUri, 264 const ContentProperties& rProps ) 265 : ContentImplHelper( rxSMgr, pProvider, Identifier ), 266 m_aUri( rUri ), 267 m_aProps( rProps ), 268 m_eState( PERSISTENT ), 269 m_xPackage( Package ), 270 m_pProvider( pProvider ), 271 m_nModifiedProps( NONE_MODIFIED ) 272 { 273 } 274 275 //========================================================================= 276 Content::Content( 277 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 278 ContentProvider* pProvider, 279 const uno::Reference< ucb::XContentIdentifier >& Identifier, 280 const uno::Reference< container::XHierarchicalNameAccess > & Package, 281 const PackageUri& rUri, 282 const ucb::ContentInfo& Info ) 283 : ContentImplHelper( rxSMgr, pProvider, Identifier ), 284 m_aUri( rUri ), 285 m_aProps( Info.Type ), 286 m_eState( TRANSIENT ), 287 m_xPackage( Package ), 288 m_pProvider( pProvider ), 289 m_nModifiedProps( NONE_MODIFIED ) 290 { 291 } 292 293 //========================================================================= 294 // virtual 295 Content::~Content() 296 { 297 } 298 299 //========================================================================= 300 // 301 // XInterface methods. 302 // 303 //========================================================================= 304 305 // virtual 306 void SAL_CALL Content::acquire() 307 throw( ) 308 { 309 ContentImplHelper::acquire(); 310 } 311 312 //========================================================================= 313 // virtual 314 void SAL_CALL Content::release() 315 throw( ) 316 { 317 ContentImplHelper::release(); 318 } 319 320 //========================================================================= 321 // virtual 322 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) 323 { 324 uno::Any aRet; 325 326 if ( isFolder() ) 327 aRet = cppu::queryInterface( 328 rType, static_cast< ucb::XContentCreator * >( this ) ); 329 330 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); 331 } 332 333 //========================================================================= 334 // 335 // XTypeProvider methods. 336 // 337 //========================================================================= 338 339 XTYPEPROVIDER_COMMON_IMPL( Content ); 340 341 //========================================================================= 342 // virtual 343 uno::Sequence< uno::Type > SAL_CALL Content::getTypes() 344 { 345 cppu::OTypeCollection * pCollection = 0; 346 347 if ( isFolder() ) 348 { 349 static cppu::OTypeCollection* pFolderTypes = 0; 350 351 pCollection = pFolderTypes; 352 if ( !pCollection ) 353 { 354 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 355 356 pCollection = pFolderTypes; 357 if ( !pCollection ) 358 { 359 static cppu::OTypeCollection aCollection( 360 CPPU_TYPE_REF( lang::XTypeProvider ), 361 CPPU_TYPE_REF( lang::XServiceInfo ), 362 CPPU_TYPE_REF( lang::XComponent ), 363 CPPU_TYPE_REF( ucb::XContent ), 364 CPPU_TYPE_REF( ucb::XCommandProcessor ), 365 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), 366 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), 367 CPPU_TYPE_REF( beans::XPropertyContainer ), 368 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), 369 CPPU_TYPE_REF( container::XChild ), 370 CPPU_TYPE_REF( ucb::XContentCreator ) ); // !! 371 pCollection = &aCollection; 372 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 373 pFolderTypes = pCollection; 374 } 375 } 376 else { 377 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 378 } 379 } 380 else 381 { 382 static cppu::OTypeCollection* pDocumentTypes = 0; 383 384 pCollection = pDocumentTypes; 385 if ( !pCollection ) 386 { 387 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 388 389 pCollection = pDocumentTypes; 390 if ( !pCollection ) 391 { 392 static cppu::OTypeCollection aCollection( 393 CPPU_TYPE_REF( lang::XTypeProvider ), 394 CPPU_TYPE_REF( lang::XServiceInfo ), 395 CPPU_TYPE_REF( lang::XComponent ), 396 CPPU_TYPE_REF( ucb::XContent ), 397 CPPU_TYPE_REF( ucb::XCommandProcessor ), 398 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), 399 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), 400 CPPU_TYPE_REF( beans::XPropertyContainer ), 401 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), 402 CPPU_TYPE_REF( container::XChild ) ); 403 pCollection = &aCollection; 404 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 405 pDocumentTypes = pCollection; 406 } 407 } 408 else { 409 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 410 } 411 } 412 413 return (*pCollection).getTypes(); 414 } 415 416 //========================================================================= 417 // 418 // XServiceInfo methods. 419 // 420 //========================================================================= 421 422 // virtual 423 rtl::OUString SAL_CALL Content::getImplementationName() 424 { 425 return rtl::OUString::createFromAscii( 426 "com.sun.star.comp.ucb.PackageContent" ); 427 } 428 429 //========================================================================= 430 // virtual 431 uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() 432 { 433 uno::Sequence< rtl::OUString > aSNS( 1 ); 434 if ( isFolder() ) 435 aSNS.getArray()[ 0 ] 436 = rtl::OUString::createFromAscii( 437 PACKAGE_FOLDER_CONTENT_SERVICE_NAME ); 438 else 439 aSNS.getArray()[ 0 ] 440 = rtl::OUString::createFromAscii( 441 PACKAGE_STREAM_CONTENT_SERVICE_NAME ); 442 443 return aSNS; 444 } 445 446 //========================================================================= 447 // 448 // XContent methods. 449 // 450 //========================================================================= 451 452 // virtual 453 rtl::OUString SAL_CALL Content::getContentType() 454 { 455 return m_aProps.aContentType; 456 } 457 458 //========================================================================= 459 // 460 // XCommandProcessor methods. 461 // 462 //========================================================================= 463 464 // virtual 465 uno::Any SAL_CALL Content::execute( 466 const ucb::Command& aCommand, 467 sal_Int32 /*CommandId*/, 468 const uno::Reference< ucb::XCommandEnvironment >& Environment ) 469 { 470 uno::Any aRet; 471 472 if ( aCommand.Name.equalsAsciiL( 473 RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) ) 474 { 475 ////////////////////////////////////////////////////////////////// 476 // getPropertyValues 477 ////////////////////////////////////////////////////////////////// 478 479 uno::Sequence< beans::Property > Properties; 480 if ( !( aCommand.Argument >>= Properties ) ) 481 { 482 ucbhelper::cancelCommandExecution( 483 uno::makeAny( lang::IllegalArgumentException( 484 rtl::OUString::createFromAscii( 485 "Wrong argument type!" ), 486 static_cast< cppu::OWeakObject * >( this ), 487 -1 ) ), 488 Environment ); 489 // Unreachable 490 } 491 492 aRet <<= getPropertyValues( Properties ); 493 } 494 else if ( aCommand.Name.equalsAsciiL( 495 RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) ) 496 { 497 ////////////////////////////////////////////////////////////////// 498 // setPropertyValues 499 ////////////////////////////////////////////////////////////////// 500 501 uno::Sequence< beans::PropertyValue > aProperties; 502 if ( !( aCommand.Argument >>= aProperties ) ) 503 { 504 ucbhelper::cancelCommandExecution( 505 uno::makeAny( lang::IllegalArgumentException( 506 rtl::OUString::createFromAscii( 507 "Wrong argument type!" ), 508 static_cast< cppu::OWeakObject * >( this ), 509 -1 ) ), 510 Environment ); 511 // Unreachable 512 } 513 514 if ( !aProperties.getLength() ) 515 { 516 ucbhelper::cancelCommandExecution( 517 uno::makeAny( lang::IllegalArgumentException( 518 rtl::OUString::createFromAscii( 519 "No properties!" ), 520 static_cast< cppu::OWeakObject * >( this ), 521 -1 ) ), 522 Environment ); 523 // Unreachable 524 } 525 526 aRet <<= setPropertyValues( aProperties, Environment ); 527 } 528 else if ( aCommand.Name.equalsAsciiL( 529 RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) ) 530 { 531 ////////////////////////////////////////////////////////////////// 532 // getPropertySetInfo 533 ////////////////////////////////////////////////////////////////// 534 535 // Note: Implemented by base class. 536 aRet <<= getPropertySetInfo( Environment ); 537 } 538 else if ( aCommand.Name.equalsAsciiL( 539 RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) ) 540 { 541 ////////////////////////////////////////////////////////////////// 542 // getCommandInfo 543 ////////////////////////////////////////////////////////////////// 544 545 // Note: Implemented by base class. 546 aRet <<= getCommandInfo( Environment ); 547 } 548 else if ( aCommand.Name.equalsAsciiL( 549 RTL_CONSTASCII_STRINGPARAM( "open" ) ) ) 550 { 551 ////////////////////////////////////////////////////////////////// 552 // open 553 ////////////////////////////////////////////////////////////////// 554 555 ucb::OpenCommandArgument2 aOpenCommand; 556 if ( !( aCommand.Argument >>= aOpenCommand ) ) 557 { 558 ucbhelper::cancelCommandExecution( 559 uno::makeAny( lang::IllegalArgumentException( 560 rtl::OUString::createFromAscii( 561 "Wrong argument type!" ), 562 static_cast< cppu::OWeakObject * >( this ), 563 -1 ) ), 564 Environment ); 565 // Unreachable 566 } 567 568 aRet = open( aOpenCommand, Environment ); 569 } 570 else if ( !m_aUri.isRootFolder() 571 && aCommand.Name.equalsAsciiL( 572 RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) 573 { 574 ////////////////////////////////////////////////////////////////// 575 // insert 576 ////////////////////////////////////////////////////////////////// 577 578 ucb::InsertCommandArgument aArg; 579 if ( !( aCommand.Argument >>= aArg ) ) 580 { 581 ucbhelper::cancelCommandExecution( 582 uno::makeAny( lang::IllegalArgumentException( 583 rtl::OUString::createFromAscii( 584 "Wrong argument type!" ), 585 static_cast< cppu::OWeakObject * >( this ), 586 -1 ) ), 587 Environment ); 588 // Unreachable 589 } 590 591 sal_Int32 nNameClash = aArg.ReplaceExisting 592 ? ucb::NameClash::OVERWRITE 593 : ucb::NameClash::ERROR; 594 insert( aArg.Data, nNameClash, Environment ); 595 } 596 else if ( !m_aUri.isRootFolder() 597 && aCommand.Name.equalsAsciiL( 598 RTL_CONSTASCII_STRINGPARAM( "delete" ) ) ) 599 { 600 ////////////////////////////////////////////////////////////////// 601 // delete 602 ////////////////////////////////////////////////////////////////// 603 604 sal_Bool bDeletePhysical = sal_False; 605 aCommand.Argument >>= bDeletePhysical; 606 destroy( bDeletePhysical, Environment ); 607 608 // Remove own and all children's persistent data. 609 if ( !removeData() ) 610 { 611 uno::Any aProps 612 = uno::makeAny( 613 beans::PropertyValue( 614 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 615 "Uri")), 616 -1, 617 uno::makeAny(m_xIdentifier-> 618 getContentIdentifier()), 619 beans::PropertyState_DIRECT_VALUE)); 620 ucbhelper::cancelCommandExecution( 621 ucb::IOErrorCode_CANT_WRITE, 622 uno::Sequence< uno::Any >(&aProps, 1), 623 Environment, 624 rtl::OUString::createFromAscii( 625 "Cannot remove persistent data!" ), 626 this ); 627 // Unreachable 628 } 629 630 // Remove own and all children's Additional Core Properties. 631 removeAdditionalPropertySet( sal_True ); 632 } 633 else if ( aCommand.Name.equalsAsciiL( 634 RTL_CONSTASCII_STRINGPARAM( "transfer" ) ) ) 635 { 636 ////////////////////////////////////////////////////////////////// 637 // transfer 638 // ( Not available at stream objects ) 639 ////////////////////////////////////////////////////////////////// 640 641 ucb::TransferInfo aInfo; 642 if ( !( aCommand.Argument >>= aInfo ) ) 643 { 644 ucbhelper::cancelCommandExecution( 645 uno::makeAny( lang::IllegalArgumentException( 646 rtl::OUString::createFromAscii( 647 "Wrong argument type!" ), 648 static_cast< cppu::OWeakObject * >( this ), 649 -1 ) ), 650 Environment ); 651 // Unreachable 652 } 653 654 transfer( aInfo, Environment ); 655 } 656 else if ( aCommand.Name.equalsAsciiL( 657 RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) ) && 658 isFolder() ) 659 { 660 ////////////////////////////////////////////////////////////////// 661 // createNewContent 662 // ( Not available at stream objects ) 663 ////////////////////////////////////////////////////////////////// 664 665 ucb::ContentInfo aInfo; 666 if ( !( aCommand.Argument >>= aInfo ) ) 667 { 668 OSL_ENSURE( sal_False, "Wrong argument type!" ); 669 ucbhelper::cancelCommandExecution( 670 uno::makeAny( lang::IllegalArgumentException( 671 rtl::OUString::createFromAscii( 672 "Wrong argument type!" ), 673 static_cast< cppu::OWeakObject * >( this ), 674 -1 ) ), 675 Environment ); 676 // Unreachable 677 } 678 679 aRet <<= createNewContent( aInfo ); 680 } 681 else if ( aCommand.Name.equalsAsciiL( 682 RTL_CONSTASCII_STRINGPARAM( "flush" ) ) ) 683 { 684 ////////////////////////////////////////////////////////////////// 685 // flush 686 // ( Not available at stream objects ) 687 ////////////////////////////////////////////////////////////////// 688 689 if( !flushData() ) 690 { 691 uno::Any aProps 692 = uno::makeAny( 693 beans::PropertyValue( 694 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 695 "Uri")), 696 -1, 697 uno::makeAny(m_xIdentifier-> 698 getContentIdentifier()), 699 beans::PropertyState_DIRECT_VALUE)); 700 ucbhelper::cancelCommandExecution( 701 ucb::IOErrorCode_CANT_WRITE, 702 uno::Sequence< uno::Any >(&aProps, 1), 703 Environment, 704 rtl::OUString::createFromAscii( 705 "Cannot write file to disk!" ), 706 this ); 707 // Unreachable 708 } 709 } 710 else 711 { 712 ////////////////////////////////////////////////////////////////// 713 // Unsupported command 714 ////////////////////////////////////////////////////////////////// 715 716 ucbhelper::cancelCommandExecution( 717 uno::makeAny( ucb::UnsupportedCommandException( 718 rtl::OUString(), 719 static_cast< cppu::OWeakObject * >( this ) ) ), 720 Environment ); 721 // Unreachable 722 } 723 724 return aRet; 725 } 726 727 //========================================================================= 728 // virtual 729 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) 730 { 731 // @@@ Implement logic to abort running commands, if this makes 732 // sense for your content. 733 } 734 735 //========================================================================= 736 // 737 // XContentCreator methods. 738 // 739 //========================================================================= 740 741 // virtual 742 uno::Sequence< ucb::ContentInfo > SAL_CALL 743 Content::queryCreatableContentsInfo() 744 { 745 return m_aProps.getCreatableContentsInfo( m_aUri ); 746 } 747 748 //========================================================================= 749 // virtual 750 uno::Reference< ucb::XContent > SAL_CALL 751 Content::createNewContent( const ucb::ContentInfo& Info ) 752 { 753 if ( isFolder() ) 754 { 755 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 756 757 if ( !Info.Type.getLength() ) 758 return uno::Reference< ucb::XContent >(); 759 760 if ( !Info.Type.equalsIgnoreAsciiCase( 761 getContentType( m_aUri.getScheme(), sal_True ) ) && 762 !Info.Type.equalsIgnoreAsciiCase( 763 getContentType( m_aUri.getScheme(), sal_False ) ) ) 764 return uno::Reference< ucb::XContent >(); 765 766 rtl::OUString aURL = m_aUri.getUri(); 767 aURL += rtl::OUString::createFromAscii( "/" ); 768 769 if ( Info.Type.equalsIgnoreAsciiCase( 770 getContentType( m_aUri.getScheme(), sal_True ) ) ) 771 aURL += rtl::OUString::createFromAscii( "New_Folder" ); 772 else 773 aURL += rtl::OUString::createFromAscii( "New_Stream" ); 774 775 uno::Reference< ucb::XContentIdentifier > xId( 776 new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ) ); 777 778 return create( m_xSMgr, m_pProvider, xId, Info ); 779 } 780 else 781 { 782 OSL_ENSURE( sal_False, 783 "createNewContent called on non-folder object!" ); 784 return uno::Reference< ucb::XContent >(); 785 } 786 } 787 788 //========================================================================= 789 // 790 // Non-interface methods. 791 // 792 //========================================================================= 793 794 // virtual 795 rtl::OUString Content::getParentURL() 796 { 797 return m_aUri.getParentUri(); 798 } 799 800 //========================================================================= 801 // static 802 uno::Reference< sdbc::XRow > Content::getPropertyValues( 803 const uno::Reference< lang::XMultiServiceFactory >& rSMgr, 804 const uno::Sequence< beans::Property >& rProperties, 805 ContentProvider* pProvider, 806 const rtl::OUString& rContentId ) 807 { 808 ContentProperties aData; 809 uno::Reference< container::XHierarchicalNameAccess > xPackage; 810 if ( loadData( pProvider, PackageUri( rContentId ), aData, xPackage ) ) 811 { 812 return getPropertyValues( rSMgr, 813 rProperties, 814 aData, 815 rtl::Reference< 816 ::ucbhelper::ContentProviderImplHelper >( 817 pProvider ), 818 rContentId ); 819 } 820 else 821 { 822 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow 823 = new ::ucbhelper::PropertyValueSet( rSMgr ); 824 825 sal_Int32 nCount = rProperties.getLength(); 826 if ( nCount ) 827 { 828 const beans::Property* pProps = rProperties.getConstArray(); 829 for ( sal_Int32 n = 0; n < nCount; ++n ) 830 xRow->appendVoid( pProps[ n ] ); 831 } 832 833 return uno::Reference< sdbc::XRow >( xRow.get() ); 834 } 835 } 836 837 //========================================================================= 838 // static 839 uno::Reference< sdbc::XRow > Content::getPropertyValues( 840 const uno::Reference< lang::XMultiServiceFactory >& rSMgr, 841 const uno::Sequence< beans::Property >& rProperties, 842 const ContentProperties& rData, 843 const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& 844 rProvider, 845 const rtl::OUString& rContentId ) 846 { 847 // Note: Empty sequence means "get values of all supported properties". 848 849 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow 850 = new ::ucbhelper::PropertyValueSet( rSMgr ); 851 852 sal_Int32 nCount = rProperties.getLength(); 853 if ( nCount ) 854 { 855 uno::Reference< beans::XPropertySet > xAdditionalPropSet; 856 sal_Bool bTriedToGetAdditonalPropSet = sal_False; 857 858 const beans::Property* pProps = rProperties.getConstArray(); 859 for ( sal_Int32 n = 0; n < nCount; ++n ) 860 { 861 const beans::Property& rProp = pProps[ n ]; 862 863 // Process Core properties. 864 865 if ( rProp.Name.equalsAsciiL( 866 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) 867 { 868 xRow->appendString ( rProp, rData.aContentType ); 869 } 870 else if ( rProp.Name.equalsAsciiL( 871 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 872 { 873 xRow->appendString ( rProp, rData.aTitle ); 874 } 875 else if ( rProp.Name.equalsAsciiL( 876 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) 877 { 878 xRow->appendBoolean( rProp, rData.bIsDocument ); 879 } 880 else if ( rProp.Name.equalsAsciiL( 881 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) 882 { 883 xRow->appendBoolean( rProp, rData.bIsFolder ); 884 } 885 else if ( rProp.Name.equalsAsciiL( 886 RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) 887 { 888 xRow->appendObject( 889 rProp, uno::makeAny( 890 rData.getCreatableContentsInfo( 891 PackageUri( rContentId ) ) ) ); 892 } 893 else if ( rProp.Name.equalsAsciiL( 894 RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) 895 { 896 xRow->appendString ( rProp, rData.aMediaType ); 897 } 898 else if ( rProp.Name.equalsAsciiL( 899 RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) 900 { 901 // Property only available for streams. 902 if ( rData.bIsDocument ) 903 xRow->appendLong( rProp, rData.nSize ); 904 else 905 xRow->appendVoid( rProp ); 906 } 907 else if ( rProp.Name.equalsAsciiL( 908 RTL_CONSTASCII_STRINGPARAM( "Compressed" ) ) ) 909 { 910 // Property only available for streams. 911 if ( rData.bIsDocument ) 912 xRow->appendBoolean( rProp, rData.bCompressed ); 913 else 914 xRow->appendVoid( rProp ); 915 } 916 else if ( rProp.Name.equalsAsciiL( 917 RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) ) 918 { 919 // Property only available for streams. 920 if ( rData.bIsDocument ) 921 xRow->appendBoolean( rProp, rData.bEncrypted ); 922 else 923 xRow->appendVoid( rProp ); 924 } 925 else if ( rProp.Name.equalsAsciiL( 926 RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) ) ) 927 { 928 // Property only available for root folder. 929 PackageUri aURI( rContentId ); 930 if ( aURI.isRootFolder() ) 931 xRow->appendBoolean( rProp, rData.bHasEncryptedEntries ); 932 else 933 xRow->appendVoid( rProp ); 934 } 935 else 936 { 937 // Not a Core Property! Maybe it's an Additional Core Property?! 938 939 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) 940 { 941 xAdditionalPropSet 942 = uno::Reference< beans::XPropertySet >( 943 rProvider->getAdditionalPropertySet( rContentId, 944 sal_False ), 945 uno::UNO_QUERY ); 946 bTriedToGetAdditonalPropSet = sal_True; 947 } 948 949 if ( xAdditionalPropSet.is() ) 950 { 951 if ( !xRow->appendPropertySetValue( 952 xAdditionalPropSet, 953 rProp ) ) 954 { 955 // Append empty entry. 956 xRow->appendVoid( rProp ); 957 } 958 } 959 else 960 { 961 // Append empty entry. 962 xRow->appendVoid( rProp ); 963 } 964 } 965 } 966 } 967 else 968 { 969 // Append all Core Properties. 970 xRow->appendString ( 971 beans::Property( 972 rtl::OUString::createFromAscii( "ContentType" ), 973 -1, 974 getCppuType( static_cast< const rtl::OUString * >( 0 ) ), 975 beans::PropertyAttribute::BOUND 976 | beans::PropertyAttribute::READONLY ), 977 rData.aContentType ); 978 xRow->appendString( 979 beans::Property( 980 rtl::OUString::createFromAscii( "Title" ), 981 -1, 982 getCppuType( static_cast< const rtl::OUString * >( 0 ) ), 983 beans::PropertyAttribute::BOUND ), 984 rData.aTitle ); 985 xRow->appendBoolean( 986 beans::Property( 987 rtl::OUString::createFromAscii( "IsDocument" ), 988 -1, 989 getCppuBooleanType(), 990 beans::PropertyAttribute::BOUND 991 | beans::PropertyAttribute::READONLY ), 992 rData.bIsDocument ); 993 xRow->appendBoolean( 994 beans::Property( 995 rtl::OUString::createFromAscii( "IsFolder" ), 996 -1, 997 getCppuBooleanType(), 998 beans::PropertyAttribute::BOUND 999 | beans::PropertyAttribute::READONLY ), 1000 rData.bIsFolder ); 1001 xRow->appendObject( 1002 beans::Property( 1003 rtl::OUString::createFromAscii( "CreatableContentsInfo" ), 1004 -1, 1005 getCppuType( static_cast< 1006 const uno::Sequence< ucb::ContentInfo > * >( 0 ) ), 1007 beans::PropertyAttribute::BOUND 1008 | beans::PropertyAttribute::READONLY ), 1009 uno::makeAny( 1010 rData.getCreatableContentsInfo( PackageUri( rContentId ) ) ) ); 1011 xRow->appendString( 1012 beans::Property( 1013 rtl::OUString::createFromAscii( "MediaType" ), 1014 -1, 1015 getCppuType( static_cast< const rtl::OUString * >( 0 ) ), 1016 beans::PropertyAttribute::BOUND ), 1017 rData.aMediaType ); 1018 1019 // Properties only available for streams. 1020 if ( rData.bIsDocument ) 1021 { 1022 xRow->appendLong( 1023 beans::Property( 1024 rtl::OUString::createFromAscii( "Size" ), 1025 -1, 1026 getCppuType( static_cast< const sal_Int64 * >( 0 ) ), 1027 beans::PropertyAttribute::BOUND 1028 | beans::PropertyAttribute::READONLY ), 1029 rData.nSize ); 1030 1031 xRow->appendBoolean( 1032 beans::Property( 1033 rtl::OUString::createFromAscii( "Compressed" ), 1034 -1, 1035 getCppuBooleanType(), 1036 beans::PropertyAttribute::BOUND ), 1037 rData.bCompressed ); 1038 1039 xRow->appendBoolean( 1040 beans::Property( 1041 rtl::OUString::createFromAscii( "Encrypted" ), 1042 -1, 1043 getCppuBooleanType(), 1044 beans::PropertyAttribute::BOUND ), 1045 rData.bEncrypted ); 1046 } 1047 1048 // Properties only available for root folder. 1049 PackageUri aURI( rContentId ); 1050 if ( aURI.isRootFolder() ) 1051 { 1052 xRow->appendBoolean( 1053 beans::Property( 1054 rtl::OUString::createFromAscii( "HasEncryptedEntries" ), 1055 -1, 1056 getCppuBooleanType(), 1057 beans::PropertyAttribute::BOUND 1058 | beans::PropertyAttribute::READONLY ), 1059 rData.bHasEncryptedEntries ); 1060 } 1061 1062 // Append all Additional Core Properties. 1063 1064 uno::Reference< beans::XPropertySet > xSet( 1065 rProvider->getAdditionalPropertySet( rContentId, sal_False ), 1066 uno::UNO_QUERY ); 1067 xRow->appendPropertySet( xSet ); 1068 } 1069 1070 return uno::Reference< sdbc::XRow >( xRow.get() ); 1071 } 1072 1073 //========================================================================= 1074 uno::Reference< sdbc::XRow > Content::getPropertyValues( 1075 const uno::Sequence< beans::Property >& rProperties ) 1076 { 1077 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1078 return getPropertyValues( m_xSMgr, 1079 rProperties, 1080 m_aProps, 1081 rtl::Reference< 1082 ::ucbhelper::ContentProviderImplHelper >( 1083 m_xProvider.get() ), 1084 m_xIdentifier->getContentIdentifier() ); 1085 } 1086 1087 //========================================================================= 1088 uno::Sequence< uno::Any > Content::setPropertyValues( 1089 const uno::Sequence< beans::PropertyValue >& rValues, 1090 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 1091 { 1092 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 1093 1094 uno::Sequence< uno::Any > aRet( rValues.getLength() ); 1095 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() ); 1096 sal_Int32 nChanged = 0; 1097 1098 beans::PropertyChangeEvent aEvent; 1099 aEvent.Source = static_cast< cppu::OWeakObject * >( this ); 1100 aEvent.Further = sal_False; 1101 // aEvent.PropertyName = 1102 aEvent.PropertyHandle = -1; 1103 // aEvent.OldValue = 1104 // aEvent.NewValue = 1105 1106 const beans::PropertyValue* pValues = rValues.getConstArray(); 1107 sal_Int32 nCount = rValues.getLength(); 1108 1109 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet; 1110 sal_Bool bTriedToGetAdditonalPropSet = sal_False; 1111 sal_Bool bExchange = sal_False; 1112 sal_Bool bStore = sal_False; 1113 rtl::OUString aNewTitle; 1114 sal_Int32 nTitlePos = -1; 1115 1116 for ( sal_Int32 n = 0; n < nCount; ++n ) 1117 { 1118 const beans::PropertyValue& rValue = pValues[ n ]; 1119 1120 if ( rValue.Name.equalsAsciiL( 1121 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) 1122 { 1123 // Read-only property! 1124 aRet[ n ] <<= lang::IllegalAccessException( 1125 rtl::OUString::createFromAscii( 1126 "Property is read-only!" ), 1127 static_cast< cppu::OWeakObject * >( this ) ); 1128 } 1129 else if ( rValue.Name.equalsAsciiL( 1130 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) 1131 { 1132 // Read-only property! 1133 aRet[ n ] <<= lang::IllegalAccessException( 1134 rtl::OUString::createFromAscii( 1135 "Property is read-only!" ), 1136 static_cast< cppu::OWeakObject * >( this ) ); 1137 } 1138 else if ( rValue.Name.equalsAsciiL( 1139 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) 1140 { 1141 // Read-only property! 1142 aRet[ n ] <<= lang::IllegalAccessException( 1143 rtl::OUString::createFromAscii( 1144 "Property is read-only!" ), 1145 static_cast< cppu::OWeakObject * >( this ) ); 1146 } 1147 else if ( rValue.Name.equalsAsciiL( 1148 RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) 1149 { 1150 // Read-only property! 1151 aRet[ n ] <<= lang::IllegalAccessException( 1152 rtl::OUString::createFromAscii( 1153 "Property is read-only!" ), 1154 static_cast< cppu::OWeakObject * >( this ) ); 1155 } 1156 else if ( rValue.Name.equalsAsciiL( 1157 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 1158 { 1159 if ( m_aUri.isRootFolder() ) 1160 { 1161 // Read-only property! 1162 aRet[ n ] <<= lang::IllegalAccessException( 1163 rtl::OUString::createFromAscii( 1164 "Property is read-only!" ), 1165 static_cast< cppu::OWeakObject * >( this ) ); 1166 } 1167 else 1168 { 1169 rtl::OUString aNewValue; 1170 if ( rValue.Value >>= aNewValue ) 1171 { 1172 // No empty titles! 1173 if ( aNewValue.getLength() > 0 ) 1174 { 1175 if ( aNewValue != m_aProps.aTitle ) 1176 { 1177 // modified title -> modified URL -> exchange ! 1178 if ( m_eState == PERSISTENT ) 1179 bExchange = sal_True; 1180 1181 // new value will be set later... 1182 aNewTitle = aNewValue; 1183 1184 // remember position within sequence of values 1185 // (for error handling). 1186 nTitlePos = n; 1187 } 1188 } 1189 else 1190 { 1191 aRet[ n ] <<= 1192 lang::IllegalArgumentException( 1193 rtl::OUString::createFromAscii( 1194 "Empty title not allowed!" ), 1195 static_cast< cppu::OWeakObject * >( this ), 1196 -1 ); 1197 } 1198 } 1199 else 1200 { 1201 aRet[ n ] <<= 1202 beans::IllegalTypeException( 1203 rtl::OUString::createFromAscii( 1204 "Property value has wrong type!" ), 1205 static_cast< cppu::OWeakObject * >( this ) ); 1206 } 1207 } 1208 } 1209 else if ( rValue.Name.equalsAsciiL( 1210 RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) 1211 { 1212 rtl::OUString aNewValue; 1213 if ( rValue.Value >>= aNewValue ) 1214 { 1215 if ( aNewValue != m_aProps.aMediaType ) 1216 { 1217 aEvent.PropertyName = rValue.Name; 1218 aEvent.OldValue = uno::makeAny( m_aProps.aMediaType ); 1219 aEvent.NewValue = uno::makeAny( aNewValue ); 1220 1221 m_aProps.aMediaType = aNewValue; 1222 nChanged++; 1223 bStore = sal_True; 1224 m_nModifiedProps |= MEDIATYPE_MODIFIED; 1225 } 1226 } 1227 else 1228 { 1229 aRet[ n ] <<= beans::IllegalTypeException( 1230 rtl::OUString::createFromAscii( 1231 "Property value has wrong type!" ), 1232 static_cast< cppu::OWeakObject * >( this ) ); 1233 } 1234 } 1235 else if ( rValue.Name.equalsAsciiL( 1236 RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ) 1237 { 1238 // Read-only property! 1239 aRet[ n ] <<= lang::IllegalAccessException( 1240 rtl::OUString::createFromAscii( 1241 "Property is read-only!" ), 1242 static_cast< cppu::OWeakObject * >( this ) ); 1243 } 1244 else if ( rValue.Name.equalsAsciiL( 1245 RTL_CONSTASCII_STRINGPARAM( "Compressed" ) ) ) 1246 { 1247 // Property only available for streams. 1248 if ( m_aProps.bIsDocument ) 1249 { 1250 sal_Bool bNewValue; 1251 if ( rValue.Value >>= bNewValue ) 1252 { 1253 if ( bNewValue != m_aProps.bCompressed ) 1254 { 1255 aEvent.PropertyName = rValue.Name; 1256 aEvent.OldValue = uno::makeAny( m_aProps.bCompressed ); 1257 aEvent.NewValue = uno::makeAny( bNewValue ); 1258 1259 m_aProps.bCompressed = bNewValue; 1260 nChanged++; 1261 bStore = sal_True; 1262 m_nModifiedProps |= COMPRESSED_MODIFIED; 1263 } 1264 } 1265 else 1266 { 1267 aRet[ n ] <<= beans::IllegalTypeException( 1268 rtl::OUString::createFromAscii( 1269 "Property value has wrong type!" ), 1270 static_cast< cppu::OWeakObject * >( this ) ); 1271 } 1272 } 1273 else 1274 { 1275 aRet[ n ] <<= beans::UnknownPropertyException( 1276 rtl::OUString::createFromAscii( 1277 "Compressed only supported by streams!" ), 1278 static_cast< cppu::OWeakObject * >( this ) ); 1279 } 1280 } 1281 else if ( rValue.Name.equalsAsciiL( 1282 RTL_CONSTASCII_STRINGPARAM( "Encrypted" ) ) ) 1283 { 1284 // Property only available for streams. 1285 if ( m_aProps.bIsDocument ) 1286 { 1287 sal_Bool bNewValue; 1288 if ( rValue.Value >>= bNewValue ) 1289 { 1290 if ( bNewValue != m_aProps.bEncrypted ) 1291 { 1292 aEvent.PropertyName = rValue.Name; 1293 aEvent.OldValue = uno::makeAny( m_aProps.bEncrypted ); 1294 aEvent.NewValue = uno::makeAny( bNewValue ); 1295 1296 m_aProps.bEncrypted = bNewValue; 1297 nChanged++; 1298 bStore = sal_True; 1299 m_nModifiedProps |= ENCRYPTED_MODIFIED; 1300 } 1301 } 1302 else 1303 { 1304 aRet[ n ] <<= beans::IllegalTypeException( 1305 rtl::OUString::createFromAscii( 1306 "Property value has wrong type!" ), 1307 static_cast< cppu::OWeakObject * >( this ) ); 1308 } 1309 } 1310 else 1311 { 1312 aRet[ n ] <<= beans::UnknownPropertyException( 1313 rtl::OUString::createFromAscii( 1314 "Encrypted only supported by streams!" ), 1315 static_cast< cppu::OWeakObject * >( this ) ); 1316 } 1317 } 1318 else if ( rValue.Name.equalsAsciiL( 1319 RTL_CONSTASCII_STRINGPARAM( "HasEncryptedEntries" ) ) ) 1320 { 1321 // Read-only property! 1322 aRet[ n ] <<= lang::IllegalAccessException( 1323 rtl::OUString::createFromAscii( 1324 "Property is read-only!" ), 1325 static_cast< cppu::OWeakObject * >( this ) ); 1326 } 1327 else if ( rValue.Name.equalsAsciiL( 1328 RTL_CONSTASCII_STRINGPARAM( "EncryptionKey" ) ) ) 1329 { 1330 // @@@ This is a temporary solution. In the future submitting 1331 // the key should be done using an interaction handler! 1332 1333 // Write-Only property. Only supported by root folder and streams 1334 // (all non-root folders of a package have the same encryption key). 1335 if ( m_aUri.isRootFolder() || m_aProps.bIsDocument ) 1336 { 1337 uno::Sequence < sal_Int8 > aNewValue; 1338 if ( rValue.Value >>= aNewValue ) 1339 { 1340 if ( aNewValue != m_aProps.aEncryptionKey ) 1341 { 1342 aEvent.PropertyName = rValue.Name; 1343 aEvent.OldValue = uno::makeAny( 1344 m_aProps.aEncryptionKey ); 1345 aEvent.NewValue = uno::makeAny( aNewValue ); 1346 1347 m_aProps.aEncryptionKey = aNewValue; 1348 nChanged++; 1349 bStore = sal_True; 1350 m_nModifiedProps |= ENCRYPTIONKEY_MODIFIED; 1351 } 1352 } 1353 else 1354 { 1355 aRet[ n ] <<= beans::IllegalTypeException( 1356 rtl::OUString::createFromAscii( 1357 "Property value has wrong type!" ), 1358 static_cast< cppu::OWeakObject * >( this ) ); 1359 } 1360 } 1361 else 1362 { 1363 aRet[ n ] <<= beans::UnknownPropertyException( 1364 rtl::OUString::createFromAscii( 1365 "EncryptionKey not supported by non-root folder!" ), 1366 static_cast< cppu::OWeakObject * >( this ) ); 1367 } 1368 } 1369 else 1370 { 1371 // Not a Core Property! Maybe it's an Additional Core Property?! 1372 1373 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) 1374 { 1375 xAdditionalPropSet = getAdditionalPropertySet( sal_False ); 1376 bTriedToGetAdditonalPropSet = sal_True; 1377 } 1378 1379 if ( xAdditionalPropSet.is() ) 1380 { 1381 try 1382 { 1383 uno::Any aOldValue 1384 = xAdditionalPropSet->getPropertyValue( rValue.Name ); 1385 if ( aOldValue != rValue.Value ) 1386 { 1387 xAdditionalPropSet->setPropertyValue( 1388 rValue.Name, rValue.Value ); 1389 1390 aEvent.PropertyName = rValue.Name; 1391 aEvent.OldValue = aOldValue; 1392 aEvent.NewValue = rValue.Value; 1393 1394 aChanges.getArray()[ nChanged ] = aEvent; 1395 nChanged++; 1396 } 1397 } 1398 catch ( beans::UnknownPropertyException const & e ) 1399 { 1400 aRet[ n ] <<= e; 1401 } 1402 catch ( lang::WrappedTargetException const & e ) 1403 { 1404 aRet[ n ] <<= e; 1405 } 1406 catch ( beans::PropertyVetoException const & e ) 1407 { 1408 aRet[ n ] <<= e; 1409 } 1410 catch ( lang::IllegalArgumentException const & e ) 1411 { 1412 aRet[ n ] <<= e; 1413 } 1414 } 1415 else 1416 { 1417 aRet[ n ] <<= uno::Exception( 1418 rtl::OUString::createFromAscii( 1419 "No property set for storing the value!" ), 1420 static_cast< cppu::OWeakObject * >( this ) ); 1421 } 1422 } 1423 } 1424 1425 if ( bExchange ) 1426 { 1427 uno::Reference< ucb::XContentIdentifier > xOldId = m_xIdentifier; 1428 1429 // Assemble new content identifier... 1430 rtl::OUString aNewURL = m_aUri.getParentUri(); 1431 aNewURL += rtl::OUString::createFromAscii( "/" ); 1432 aNewURL += ::ucb_impl::urihelper::encodeSegment( aNewTitle ); 1433 uno::Reference< ucb::XContentIdentifier > xNewId 1434 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL ); 1435 1436 aGuard.clear(); 1437 if ( exchangeIdentity( xNewId ) ) 1438 { 1439 // Adapt persistent data. 1440 renameData( xOldId, xNewId ); 1441 1442 // Adapt Additional Core Properties. 1443 renameAdditionalPropertySet( xOldId->getContentIdentifier(), 1444 xNewId->getContentIdentifier(), 1445 sal_True ); 1446 } 1447 else 1448 { 1449 // Do not set new title! 1450 aNewTitle = rtl::OUString(); 1451 1452 // Set error . 1453 aRet[ nTitlePos ] <<= uno::Exception( 1454 rtl::OUString::createFromAscii( "Exchange failed!" ), 1455 static_cast< cppu::OWeakObject * >( this ) ); 1456 } 1457 } 1458 1459 if ( aNewTitle.getLength() ) 1460 { 1461 aEvent.PropertyName = rtl::OUString::createFromAscii( "Title" ); 1462 aEvent.OldValue = uno::makeAny( m_aProps.aTitle ); 1463 aEvent.NewValue = uno::makeAny( aNewTitle ); 1464 1465 m_aProps.aTitle = aNewTitle; 1466 1467 aChanges.getArray()[ nChanged ] = aEvent; 1468 nChanged++; 1469 } 1470 1471 if ( nChanged > 0 ) 1472 { 1473 // Save changes, if content was already made persistent. 1474 if ( ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) || 1475 ( bStore && ( m_eState == PERSISTENT ) ) ) 1476 { 1477 if ( !storeData( uno::Reference< io::XInputStream >() ) ) 1478 { 1479 uno::Any aProps 1480 = uno::makeAny( 1481 beans::PropertyValue( 1482 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1483 "Uri")), 1484 -1, 1485 uno::makeAny(m_xIdentifier-> 1486 getContentIdentifier()), 1487 beans::PropertyState_DIRECT_VALUE)); 1488 ucbhelper::cancelCommandExecution( 1489 ucb::IOErrorCode_CANT_WRITE, 1490 uno::Sequence< uno::Any >(&aProps, 1), 1491 xEnv, 1492 rtl::OUString::createFromAscii( 1493 "Cannot store persistent data!" ), 1494 this ); 1495 // Unreachable 1496 } 1497 } 1498 1499 aGuard.clear(); 1500 aChanges.realloc( nChanged ); 1501 notifyPropertiesChange( aChanges ); 1502 } 1503 1504 return aRet; 1505 } 1506 1507 //========================================================================= 1508 uno::Any Content::open( 1509 const ucb::OpenCommandArgument2& rArg, 1510 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 1511 { 1512 if ( rArg.Mode == ucb::OpenMode::ALL || 1513 rArg.Mode == ucb::OpenMode::FOLDERS || 1514 rArg.Mode == ucb::OpenMode::DOCUMENTS ) 1515 { 1516 ////////////////////////////////////////////////////////////////// 1517 // open command for a folder content 1518 ////////////////////////////////////////////////////////////////// 1519 1520 uno::Reference< ucb::XDynamicResultSet > xSet 1521 = new DynamicResultSet( m_xSMgr, this, rArg, xEnv ); 1522 return uno::makeAny( xSet ); 1523 } 1524 else 1525 { 1526 ////////////////////////////////////////////////////////////////// 1527 // open command for a document content 1528 ////////////////////////////////////////////////////////////////// 1529 1530 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || 1531 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) 1532 { 1533 // Currently(?) unsupported. 1534 ucbhelper::cancelCommandExecution( 1535 uno::makeAny( ucb::UnsupportedOpenModeException( 1536 rtl::OUString(), 1537 static_cast< cppu::OWeakObject * >( this ), 1538 sal_Int16( rArg.Mode ) ) ), 1539 xEnv ); 1540 // Unreachable 1541 } 1542 1543 rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); 1544 uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY ); 1545 if ( xOut.is() ) 1546 { 1547 // PUSH: write data into xOut 1548 1549 uno::Reference< io::XInputStream > xIn = getInputStream(); 1550 if ( !xIn.is() ) 1551 { 1552 // No interaction if we are not persistent! 1553 uno::Any aProps 1554 = uno::makeAny( 1555 beans::PropertyValue( 1556 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1557 "Uri")), 1558 -1, 1559 uno::makeAny(m_xIdentifier-> 1560 getContentIdentifier()), 1561 beans::PropertyState_DIRECT_VALUE)); 1562 ucbhelper::cancelCommandExecution( 1563 ucb::IOErrorCode_CANT_READ, 1564 uno::Sequence< uno::Any >(&aProps, 1), 1565 m_eState == PERSISTENT 1566 ? xEnv 1567 : uno::Reference< ucb::XCommandEnvironment >(), 1568 rtl::OUString::createFromAscii( "Got no data stream!" ), 1569 this ); 1570 // Unreachable 1571 } 1572 1573 try 1574 { 1575 uno::Sequence< sal_Int8 > aBuffer; 1576 sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 ); 1577 1578 while ( nRead > 0 ) 1579 { 1580 aBuffer.realloc( nRead ); 1581 xOut->writeBytes( aBuffer ); 1582 aBuffer.realloc( 0 ); 1583 nRead = xIn->readSomeBytes( aBuffer, 65536 ); 1584 } 1585 1586 xOut->closeOutput(); 1587 } 1588 catch ( io::NotConnectedException const & ) 1589 { 1590 // closeOutput, readSomeBytes, writeBytes 1591 } 1592 catch ( io::BufferSizeExceededException const & ) 1593 { 1594 // closeOutput, readSomeBytes, writeBytes 1595 } 1596 catch ( io::IOException const & ) 1597 { 1598 // closeOutput, readSomeBytes, writeBytes 1599 } 1600 } 1601 else 1602 { 1603 uno::Reference< io::XActiveDataSink > xDataSink( 1604 rArg.Sink, uno::UNO_QUERY ); 1605 if ( xDataSink.is() ) 1606 { 1607 // PULL: wait for client read 1608 1609 uno::Reference< io::XInputStream > xIn = getInputStream(); 1610 if ( !xIn.is() ) 1611 { 1612 // No interaction if we are not persistent! 1613 uno::Any aProps 1614 = uno::makeAny( 1615 beans::PropertyValue( 1616 rtl::OUString( 1617 RTL_CONSTASCII_USTRINGPARAM("Uri")), 1618 -1, 1619 uno::makeAny(m_xIdentifier-> 1620 getContentIdentifier()), 1621 beans::PropertyState_DIRECT_VALUE)); 1622 ucbhelper::cancelCommandExecution( 1623 ucb::IOErrorCode_CANT_READ, 1624 uno::Sequence< uno::Any >(&aProps, 1), 1625 m_eState == PERSISTENT 1626 ? xEnv 1627 : uno::Reference< 1628 ucb::XCommandEnvironment >(), 1629 rtl::OUString::createFromAscii( 1630 "Got no data stream!" ), 1631 this ); 1632 // Unreachable 1633 } 1634 1635 // Done. 1636 xDataSink->setInputStream( xIn ); 1637 } 1638 else 1639 { 1640 // Note: aOpenCommand.Sink may contain an XStream 1641 // implementation. Support for this type of 1642 // sink is optional... 1643 ucbhelper::cancelCommandExecution( 1644 uno::makeAny( 1645 ucb::UnsupportedDataSinkException( 1646 rtl::OUString(), 1647 static_cast< cppu::OWeakObject * >( this ), 1648 rArg.Sink ) ), 1649 xEnv ); 1650 // Unreachable 1651 } 1652 } 1653 } 1654 1655 return uno::Any(); 1656 } 1657 1658 //========================================================================= 1659 void Content::insert( 1660 const uno::Reference< io::XInputStream >& xStream, 1661 sal_Int32 nNameClashResolve, 1662 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 1663 { 1664 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 1665 1666 // Check, if all required properties were set. 1667 if ( isFolder() ) 1668 { 1669 // Required: Title 1670 1671 if ( !m_aProps.aTitle.getLength() ) 1672 m_aProps.aTitle = m_aUri.getName(); 1673 } 1674 else 1675 { 1676 // Required: rArg.Data 1677 1678 if ( !xStream.is() ) 1679 { 1680 ucbhelper::cancelCommandExecution( 1681 uno::makeAny( ucb::MissingInputStreamException( 1682 rtl::OUString(), 1683 static_cast< cppu::OWeakObject * >( this ) ) ), 1684 xEnv ); 1685 // Unreachable 1686 } 1687 1688 // Required: Title 1689 1690 if ( !m_aProps.aTitle.getLength() ) 1691 m_aProps.aTitle = m_aUri.getName(); 1692 } 1693 1694 rtl::OUString aNewURL = m_aUri.getParentUri(); 1695 if (1 + aNewURL.lastIndexOf('/') != aNewURL.getLength()) 1696 aNewURL += rtl::OUString::createFromAscii( "/" ); 1697 aNewURL += ::ucb_impl::urihelper::encodeSegment( m_aProps.aTitle ); 1698 PackageUri aNewUri( aNewURL ); 1699 1700 // Handle possible name clash... 1701 switch ( nNameClashResolve ) 1702 { 1703 // fail. 1704 case ucb::NameClash::ERROR: 1705 if ( hasData( aNewUri ) ) 1706 { 1707 ucbhelper::cancelCommandExecution( 1708 uno::makeAny( ucb::NameClashException( 1709 rtl::OUString(), 1710 static_cast< cppu::OWeakObject * >( this ), 1711 task::InteractionClassification_ERROR, 1712 m_aProps.aTitle ) ), 1713 xEnv ); 1714 // Unreachable 1715 } 1716 break; 1717 1718 // replace (possibly) existing object. 1719 case ucb::NameClash::OVERWRITE: 1720 break; 1721 1722 // "invent" a new valid title. 1723 case ucb::NameClash::RENAME: 1724 if ( hasData( aNewUri ) ) 1725 { 1726 sal_Int32 nTry = 0; 1727 1728 do 1729 { 1730 rtl::OUString aNew = aNewUri.getUri(); 1731 aNew += rtl::OUString::createFromAscii( "_" ); 1732 aNew += rtl::OUString::valueOf( ++nTry ); 1733 aNewUri.setUri( aNew ); 1734 } 1735 while ( hasData( aNewUri ) && ( nTry < 1000 ) ); 1736 1737 if ( nTry == 1000 ) 1738 { 1739 ucbhelper::cancelCommandExecution( 1740 uno::makeAny( 1741 ucb::UnsupportedNameClashException( 1742 rtl::OUString::createFromAscii( 1743 "Unable to resolve name clash!" ), 1744 static_cast< cppu::OWeakObject * >( this ), 1745 nNameClashResolve ) ), 1746 xEnv ); 1747 // Unreachable 1748 } 1749 else 1750 { 1751 m_aProps.aTitle += rtl::OUString::createFromAscii( "_" ); 1752 m_aProps.aTitle += rtl::OUString::valueOf( nTry ); 1753 } 1754 } 1755 break; 1756 1757 case ucb::NameClash::KEEP: // deprecated 1758 case ucb::NameClash::ASK: 1759 default: 1760 if ( hasData( aNewUri ) ) 1761 { 1762 ucbhelper::cancelCommandExecution( 1763 uno::makeAny( 1764 ucb::UnsupportedNameClashException( 1765 rtl::OUString(), 1766 static_cast< cppu::OWeakObject * >( this ), 1767 nNameClashResolve ) ), 1768 xEnv ); 1769 // Unreachable 1770 } 1771 break; 1772 } 1773 1774 // Identifier changed? 1775 sal_Bool bNewId = ( m_aUri.getUri() != aNewUri.getUri() ); 1776 1777 if ( bNewId ) 1778 { 1779 m_xIdentifier = new ::ucbhelper::ContentIdentifier( m_xSMgr, aNewURL ); 1780 m_aUri = aNewUri; 1781 } 1782 1783 if ( !storeData( xStream ) ) 1784 { 1785 uno::Any aProps 1786 = uno::makeAny(beans::PropertyValue( 1787 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1788 "Uri")), 1789 -1, 1790 uno::makeAny(m_xIdentifier-> 1791 getContentIdentifier()), 1792 beans::PropertyState_DIRECT_VALUE)); 1793 ucbhelper::cancelCommandExecution( 1794 ucb::IOErrorCode_CANT_WRITE, 1795 uno::Sequence< uno::Any >(&aProps, 1), 1796 xEnv, 1797 rtl::OUString::createFromAscii( "Cannot store persistent data!" ), 1798 this ); 1799 // Unreachable 1800 } 1801 1802 m_eState = PERSISTENT; 1803 1804 if ( bNewId ) 1805 { 1806 // Take over correct default values from underlying packager... 1807 uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess; 1808 loadData( m_pProvider, 1809 m_aUri, 1810 m_aProps, 1811 xXHierarchicalNameAccess ); 1812 1813 aGuard.clear(); 1814 inserted(); 1815 } 1816 } 1817 1818 //========================================================================= 1819 void Content::destroy( 1820 sal_Bool bDeletePhysical, 1821 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 1822 { 1823 // @@@ take care about bDeletePhysical -> trashcan support 1824 1825 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 1826 1827 uno::Reference< ucb::XContent > xThis = this; 1828 1829 // Persistent? 1830 if ( m_eState != PERSISTENT ) 1831 { 1832 ucbhelper::cancelCommandExecution( 1833 uno::makeAny( ucb::UnsupportedCommandException( 1834 rtl::OUString::createFromAscii( 1835 "Not persistent!" ), 1836 static_cast< cppu::OWeakObject * >( this ) ) ), 1837 xEnv ); 1838 // Unreachable 1839 } 1840 1841 m_eState = DEAD; 1842 1843 aGuard.clear(); 1844 deleted(); 1845 1846 if ( isFolder() ) 1847 { 1848 // Process instantiated children... 1849 1850 ContentRefList aChildren; 1851 queryChildren( aChildren ); 1852 1853 ContentRefList::const_iterator it = aChildren.begin(); 1854 ContentRefList::const_iterator end = aChildren.end(); 1855 1856 while ( it != end ) 1857 { 1858 (*it)->destroy( bDeletePhysical, xEnv ); 1859 ++it; 1860 } 1861 } 1862 } 1863 1864 //========================================================================= 1865 void Content::transfer( 1866 const ucb::TransferInfo& rInfo, 1867 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 1868 { 1869 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 1870 1871 // Persistent? 1872 if ( m_eState != PERSISTENT ) 1873 { 1874 ucbhelper::cancelCommandExecution( 1875 uno::makeAny( ucb::UnsupportedCommandException( 1876 rtl::OUString::createFromAscii( 1877 "Not persistent!" ), 1878 static_cast< cppu::OWeakObject * >( this ) ) ), 1879 xEnv ); 1880 // Unreachable 1881 } 1882 1883 // Is source a package content? 1884 if ( ( rInfo.SourceURL.getLength() == 0 ) || 1885 ( rInfo.SourceURL.compareTo( 1886 m_aUri.getUri(), PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 ) ) 1887 { 1888 ucbhelper::cancelCommandExecution( 1889 uno::makeAny( ucb::InteractiveBadTransferURLException( 1890 rtl::OUString(), 1891 static_cast< cppu::OWeakObject * >( this ) ) ), 1892 xEnv ); 1893 // Unreachable 1894 } 1895 1896 // Is source not a parent of me / not me? 1897 rtl::OUString aId = m_aUri.getParentUri(); 1898 aId += rtl::OUString::createFromAscii( "/" ); 1899 1900 if ( rInfo.SourceURL.getLength() <= aId.getLength() ) 1901 { 1902 if ( aId.compareTo( 1903 rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 ) 1904 { 1905 uno::Any aProps 1906 = uno::makeAny(beans::PropertyValue( 1907 rtl::OUString( 1908 RTL_CONSTASCII_USTRINGPARAM("Uri")), 1909 -1, 1910 uno::makeAny(rInfo.SourceURL), 1911 beans::PropertyState_DIRECT_VALUE)); 1912 ucbhelper::cancelCommandExecution( 1913 ucb::IOErrorCode_RECURSIVE, 1914 uno::Sequence< uno::Any >(&aProps, 1), 1915 xEnv, 1916 rtl::OUString::createFromAscii( 1917 "Target is equal to or is a child of source!" ), 1918 this ); 1919 // Unreachable 1920 } 1921 } 1922 1923 ////////////////////////////////////////////////////////////////////// 1924 // 0) Obtain content object for source. 1925 ////////////////////////////////////////////////////////////////////// 1926 1927 uno::Reference< ucb::XContentIdentifier > xId 1928 = new ::ucbhelper::ContentIdentifier( m_xSMgr, rInfo.SourceURL ); 1929 1930 // Note: The static cast is okay here, because its sure that 1931 // m_xProvider is always the PackageContentProvider. 1932 rtl::Reference< Content > xSource; 1933 1934 try 1935 { 1936 xSource = static_cast< Content * >( 1937 m_xProvider->queryContent( xId ).get() ); 1938 } 1939 catch ( ucb::IllegalIdentifierException const & ) 1940 { 1941 // queryContent 1942 } 1943 1944 if ( !xSource.is() ) 1945 { 1946 uno::Any aProps 1947 = uno::makeAny(beans::PropertyValue( 1948 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1949 "Uri")), 1950 -1, 1951 uno::makeAny(xId->getContentIdentifier()), 1952 beans::PropertyState_DIRECT_VALUE)); 1953 ucbhelper::cancelCommandExecution( 1954 ucb::IOErrorCode_CANT_READ, 1955 uno::Sequence< uno::Any >(&aProps, 1), 1956 xEnv, 1957 rtl::OUString::createFromAscii( 1958 "Cannot instantiate source object!" ), 1959 this ); 1960 // Unreachable 1961 } 1962 1963 ////////////////////////////////////////////////////////////////////// 1964 // 1) Create new child content. 1965 ////////////////////////////////////////////////////////////////////// 1966 1967 rtl::OUString aType = xSource->isFolder() 1968 ? getContentType( m_aUri.getScheme(), sal_True ) 1969 : getContentType( m_aUri.getScheme(), sal_False ); 1970 ucb::ContentInfo aContentInfo; 1971 aContentInfo.Type = aType; 1972 aContentInfo.Attributes = 0; 1973 1974 // Note: The static cast is okay here, because its sure that 1975 // createNewContent always creates a Content. 1976 rtl::Reference< Content > xTarget 1977 = static_cast< Content * >( createNewContent( aContentInfo ).get() ); 1978 if ( !xTarget.is() ) 1979 { 1980 uno::Any aProps 1981 = uno::makeAny(beans::PropertyValue( 1982 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1983 "Folder")), 1984 -1, 1985 uno::makeAny(aId), 1986 beans::PropertyState_DIRECT_VALUE)); 1987 ucbhelper::cancelCommandExecution( 1988 ucb::IOErrorCode_CANT_CREATE, 1989 uno::Sequence< uno::Any >(&aProps, 1), 1990 xEnv, 1991 rtl::OUString::createFromAscii( 1992 "XContentCreator::createNewContent failed!" ), 1993 this ); 1994 // Unreachable 1995 } 1996 1997 ////////////////////////////////////////////////////////////////////// 1998 // 2) Copy data from source content to child content. 1999 ////////////////////////////////////////////////////////////////////// 2000 2001 uno::Sequence< beans::Property > aSourceProps 2002 = xSource->getPropertySetInfo( xEnv )->getProperties(); 2003 sal_Int32 nCount = aSourceProps.getLength(); 2004 2005 if ( nCount ) 2006 { 2007 sal_Bool bHadTitle = ( rInfo.NewTitle.getLength() == 0 ); 2008 2009 // Get all source values. 2010 uno::Reference< sdbc::XRow > xRow 2011 = xSource->getPropertyValues( aSourceProps ); 2012 2013 uno::Sequence< beans::PropertyValue > aValues( nCount ); 2014 beans::PropertyValue* pValues = aValues.getArray(); 2015 2016 const beans::Property* pProps = aSourceProps.getConstArray(); 2017 for ( sal_Int32 n = 0; n < nCount; ++n ) 2018 { 2019 const beans::Property& rProp = pProps[ n ]; 2020 beans::PropertyValue& rValue = pValues[ n ]; 2021 2022 rValue.Name = rProp.Name; 2023 rValue.Handle = rProp.Handle; 2024 2025 if ( !bHadTitle && rProp.Name.equalsAsciiL( 2026 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 2027 { 2028 // Set new title instead of original. 2029 bHadTitle = sal_True; 2030 rValue.Value <<= rInfo.NewTitle; 2031 } 2032 else 2033 rValue.Value 2034 = xRow->getObject( n + 1, 2035 uno::Reference< 2036 container::XNameAccess >() ); 2037 2038 rValue.State = beans::PropertyState_DIRECT_VALUE; 2039 2040 if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE ) 2041 { 2042 // Add Additional Core Property. 2043 try 2044 { 2045 xTarget->addProperty( rProp.Name, 2046 rProp.Attributes, 2047 rValue.Value ); 2048 } 2049 catch ( beans::PropertyExistException const & ) 2050 { 2051 } 2052 catch ( beans::IllegalTypeException const & ) 2053 { 2054 } 2055 catch ( lang::IllegalArgumentException const & ) 2056 { 2057 } 2058 } 2059 } 2060 2061 // Set target values. 2062 xTarget->setPropertyValues( aValues, xEnv ); 2063 } 2064 2065 ////////////////////////////////////////////////////////////////////// 2066 // 3) Commit (insert) child. 2067 ////////////////////////////////////////////////////////////////////// 2068 2069 xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv ); 2070 2071 ////////////////////////////////////////////////////////////////////// 2072 // 4) Transfer (copy) children of source. 2073 ////////////////////////////////////////////////////////////////////// 2074 2075 if ( xSource->isFolder() ) 2076 { 2077 uno::Reference< container::XEnumeration > xIter 2078 = xSource->getIterator(); 2079 if ( xIter.is() ) 2080 { 2081 while ( xIter->hasMoreElements() ) 2082 { 2083 try 2084 { 2085 uno::Reference< container::XNamed > xNamed; 2086 xIter->nextElement() >>= xNamed; 2087 2088 if ( !xNamed.is() ) 2089 { 2090 OSL_ENSURE( sal_False, 2091 "Content::transfer - Got no XNamed!" ); 2092 break; 2093 } 2094 2095 rtl::OUString aName = xNamed->getName(); 2096 2097 if ( !aName.getLength() ) 2098 { 2099 OSL_ENSURE( sal_False, 2100 "Content::transfer - Empty name!" ); 2101 break; 2102 } 2103 2104 rtl::OUString aChildId = xId->getContentIdentifier(); 2105 if ( ( aChildId.lastIndexOf( '/' ) + 1 ) 2106 != aChildId.getLength() ) 2107 aChildId += rtl::OUString::createFromAscii( "/" ); 2108 2109 aChildId += ::ucb_impl::urihelper::encodeSegment( aName ); 2110 2111 ucb::TransferInfo aInfo; 2112 aInfo.MoveData = sal_False; 2113 aInfo.NewTitle = rtl::OUString(); 2114 aInfo.SourceURL = aChildId; 2115 aInfo.NameClash = rInfo.NameClash; 2116 2117 // Transfer child to target. 2118 xTarget->transfer( aInfo, xEnv ); 2119 } 2120 catch ( container::NoSuchElementException const & ) 2121 { 2122 } 2123 catch ( lang::WrappedTargetException const & ) 2124 { 2125 } 2126 } 2127 } 2128 } 2129 2130 ////////////////////////////////////////////////////////////////////// 2131 // 5) Destroy source ( when moving only ) . 2132 ////////////////////////////////////////////////////////////////////// 2133 2134 if ( rInfo.MoveData ) 2135 { 2136 xSource->destroy( sal_True, xEnv ); 2137 2138 // Remove all persistent data of source and its children. 2139 if ( !xSource->removeData() ) 2140 { 2141 uno::Any aProps 2142 = uno::makeAny( 2143 beans::PropertyValue( 2144 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 2145 "Uri")), 2146 -1, 2147 uno::makeAny( 2148 xSource->m_xIdentifier-> 2149 getContentIdentifier()), 2150 beans::PropertyState_DIRECT_VALUE)); 2151 ucbhelper::cancelCommandExecution( 2152 ucb::IOErrorCode_CANT_WRITE, 2153 uno::Sequence< uno::Any >(&aProps, 1), 2154 xEnv, 2155 rtl::OUString::createFromAscii( 2156 "Cannot remove persistent data of source object!" ), 2157 this ); 2158 // Unreachable 2159 } 2160 2161 // Remove own and all children's Additional Core Properties. 2162 xSource->removeAdditionalPropertySet( sal_True ); 2163 } 2164 } 2165 2166 //========================================================================= 2167 sal_Bool Content::exchangeIdentity( 2168 const uno::Reference< ucb::XContentIdentifier >& xNewId ) 2169 { 2170 if ( !xNewId.is() ) 2171 return sal_False; 2172 2173 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 2174 2175 uno::Reference< ucb::XContent > xThis = this; 2176 2177 // Already persistent? 2178 if ( m_eState != PERSISTENT ) 2179 { 2180 OSL_ENSURE( sal_False, 2181 "Content::exchangeIdentity - Not persistent!" ); 2182 return sal_False; 2183 } 2184 2185 // Exchange own identitity. 2186 2187 // Fail, if a content with given id already exists. 2188 PackageUri aNewUri( xNewId->getContentIdentifier() ); 2189 if ( !hasData( aNewUri ) ) 2190 { 2191 rtl::OUString aOldURL = m_xIdentifier->getContentIdentifier(); 2192 2193 aGuard.clear(); 2194 if ( exchange( xNewId ) ) 2195 { 2196 m_aUri = aNewUri; 2197 if ( isFolder() ) 2198 { 2199 // Process instantiated children... 2200 2201 ContentRefList aChildren; 2202 queryChildren( aChildren ); 2203 2204 ContentRefList::const_iterator it = aChildren.begin(); 2205 ContentRefList::const_iterator end = aChildren.end(); 2206 2207 while ( it != end ) 2208 { 2209 ContentRef xChild = (*it); 2210 2211 // Create new content identifier for the child... 2212 uno::Reference< ucb::XContentIdentifier > xOldChildId 2213 = xChild->getIdentifier(); 2214 rtl::OUString aOldChildURL 2215 = xOldChildId->getContentIdentifier(); 2216 rtl::OUString aNewChildURL 2217 = aOldChildURL.replaceAt( 2218 0, 2219 aOldURL.getLength(), 2220 xNewId->getContentIdentifier() ); 2221 uno::Reference< ucb::XContentIdentifier > xNewChildId 2222 = new ::ucbhelper::ContentIdentifier( 2223 m_xSMgr, aNewChildURL ); 2224 2225 if ( !xChild->exchangeIdentity( xNewChildId ) ) 2226 return sal_False; 2227 2228 ++it; 2229 } 2230 } 2231 return sal_True; 2232 } 2233 } 2234 2235 OSL_ENSURE( sal_False, 2236 "Content::exchangeIdentity - Panic! Cannot exchange identity!" ); 2237 return sal_False; 2238 } 2239 2240 //========================================================================= 2241 void Content::queryChildren( ContentRefList& rChildren ) 2242 { 2243 // Obtain a list with a snapshot of all currently instantiated contents 2244 // from provider and extract the contents which are direct children 2245 // of this content. 2246 2247 ::ucbhelper::ContentRefList aAllContents; 2248 m_xProvider->queryExistingContents( aAllContents ); 2249 2250 rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); 2251 2252 OSL_ENSURE( aURL.lastIndexOf( '/' ) != ( aURL.getLength() - 1 ), 2253 "Content::queryChildren - Invalid URL!" ); 2254 2255 aURL += rtl::OUString::createFromAscii( "/" ); 2256 2257 sal_Int32 nLen = aURL.getLength(); 2258 2259 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin(); 2260 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end(); 2261 2262 while ( it != end ) 2263 { 2264 ::ucbhelper::ContentImplHelperRef xChild = (*it); 2265 rtl::OUString aChildURL 2266 = xChild->getIdentifier()->getContentIdentifier(); 2267 2268 // Is aURL a prefix of aChildURL? 2269 if ( ( aChildURL.getLength() > nLen ) && 2270 ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) 2271 { 2272 if ( aChildURL.indexOf( '/', nLen ) == -1 ) 2273 { 2274 // No further slashes. It's a child! 2275 rChildren.push_back( 2276 ContentRef( 2277 static_cast< Content * >( xChild.get() ) ) ); 2278 } 2279 } 2280 ++it; 2281 } 2282 } 2283 2284 //========================================================================= 2285 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage( 2286 const PackageUri& rURI ) 2287 { 2288 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2289 2290 uno::Reference< container::XHierarchicalNameAccess > xPackage; 2291 if ( rURI.getPackage() == m_aUri.getPackage() ) 2292 { 2293 if ( !m_xPackage.is() ) 2294 m_xPackage = m_pProvider->createPackage( m_aUri.getPackage(), m_aUri.getParam() ); 2295 2296 return m_xPackage; 2297 } 2298 2299 return m_pProvider->createPackage( rURI.getPackage(), rURI.getParam() ); 2300 } 2301 2302 //========================================================================= 2303 uno::Reference< container::XHierarchicalNameAccess > Content::getPackage() 2304 { 2305 return getPackage( m_aUri ); 2306 } 2307 2308 //========================================================================= 2309 // static 2310 sal_Bool Content::hasData( 2311 ContentProvider* pProvider, 2312 const PackageUri& rURI, 2313 uno::Reference< container::XHierarchicalNameAccess > & rxPackage ) 2314 { 2315 rxPackage = pProvider->createPackage( rURI.getPackage(), rURI.getParam() ); 2316 if ( !rxPackage.is() ) 2317 return sal_False; 2318 2319 return rxPackage->hasByHierarchicalName( rURI.getPath() ); 2320 } 2321 2322 //========================================================================= 2323 sal_Bool Content::hasData( const PackageUri& rURI ) 2324 { 2325 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2326 2327 uno::Reference< container::XHierarchicalNameAccess > xPackage; 2328 if ( rURI.getPackage() == m_aUri.getPackage() ) 2329 { 2330 xPackage = getPackage(); 2331 if ( !xPackage.is() ) 2332 return sal_False; 2333 2334 return xPackage->hasByHierarchicalName( rURI.getPath() ); 2335 } 2336 2337 return hasData( m_pProvider, rURI, xPackage ); 2338 } 2339 2340 //========================================================================= 2341 //static 2342 sal_Bool Content::loadData( 2343 ContentProvider* pProvider, 2344 const PackageUri& rURI, 2345 ContentProperties& rProps, 2346 uno::Reference< container::XHierarchicalNameAccess > & rxPackage ) 2347 { 2348 rxPackage = pProvider->createPackage( rURI.getPackage(), rURI.getParam() ); 2349 if ( !rxPackage.is() ) 2350 return sal_False; 2351 2352 if ( rURI.isRootFolder() ) 2353 { 2354 // Properties available only from package 2355 uno::Reference< beans::XPropertySet > xPackagePropSet( 2356 rxPackage, uno::UNO_QUERY ); 2357 2358 OSL_ENSURE( xPackagePropSet.is(), 2359 "Content::loadData - " 2360 "Got no XPropertySet interface from package!" ); 2361 2362 if ( xPackagePropSet.is() ) 2363 { 2364 // HasEncryptedEntries ( only available at root folder ) 2365 try 2366 { 2367 uno::Any aHasEncryptedEntries 2368 = xPackagePropSet->getPropertyValue( 2369 rtl::OUString::createFromAscii( 2370 "HasEncryptedEntries" ) ); 2371 if ( !( aHasEncryptedEntries >>= rProps.bHasEncryptedEntries ) ) 2372 { 2373 OSL_ENSURE( sal_False, 2374 "Content::loadData - " 2375 "Got no HasEncryptedEntries value!" ); 2376 return sal_False; 2377 } 2378 } 2379 catch ( beans::UnknownPropertyException const & ) 2380 { 2381 OSL_ENSURE( sal_False, 2382 "Content::loadData - " 2383 "Got no HasEncryptedEntries value!" ); 2384 return sal_False; 2385 } 2386 catch ( lang::WrappedTargetException const & ) 2387 { 2388 OSL_ENSURE( sal_False, 2389 "Content::loadData - " 2390 "Got no HasEncryptedEntries value!" ); 2391 return sal_False; 2392 } 2393 } 2394 } 2395 2396 if ( !rxPackage->hasByHierarchicalName( rURI.getPath() ) ) 2397 return sal_False; 2398 2399 try 2400 { 2401 uno::Any aEntry = rxPackage->getByHierarchicalName( rURI.getPath() ); 2402 if ( aEntry.hasValue() ) 2403 { 2404 uno::Reference< beans::XPropertySet > xPropSet; 2405 aEntry >>= xPropSet; 2406 2407 if ( !xPropSet.is() ) 2408 { 2409 OSL_ENSURE( sal_False, 2410 "Content::loadData - Got no XPropertySet interface!" ); 2411 return sal_False; 2412 } 2413 2414 // Title 2415 rProps.aTitle = rURI.getName(); 2416 2417 // MediaType 2418 try 2419 { 2420 uno::Any aMediaType 2421 = xPropSet->getPropertyValue( 2422 rtl::OUString::createFromAscii( "MediaType" ) ); 2423 if ( !( aMediaType >>= rProps.aMediaType ) ) 2424 { 2425 OSL_ENSURE( sal_False, 2426 "Content::loadData - Got no MediaType value!" ); 2427 return sal_False; 2428 } 2429 } 2430 catch ( beans::UnknownPropertyException const & ) 2431 { 2432 OSL_ENSURE( sal_False, 2433 "Content::loadData - Got no MediaType value!" ); 2434 return sal_False; 2435 } 2436 catch ( lang::WrappedTargetException const & ) 2437 { 2438 OSL_ENSURE( sal_False, 2439 "Content::loadData - Got no MediaType value!" ); 2440 return sal_False; 2441 } 2442 2443 uno::Reference< container::XEnumerationAccess > xEnumAccess; 2444 aEntry >>= xEnumAccess; 2445 2446 // ContentType / IsFolder / IsDocument 2447 if ( xEnumAccess.is() ) 2448 { 2449 // folder 2450 rProps.aContentType = getContentType( rURI.getScheme(), sal_True ); 2451 rProps.bIsDocument = sal_False; 2452 rProps.bIsFolder = sal_True; 2453 } 2454 else 2455 { 2456 // stream 2457 rProps.aContentType = getContentType( rURI.getScheme(), sal_False ); 2458 rProps.bIsDocument = sal_True; 2459 rProps.bIsFolder = sal_False; 2460 } 2461 2462 if ( rProps.bIsDocument ) 2463 { 2464 // Size ( only available for streams ) 2465 try 2466 { 2467 uno::Any aSize 2468 = xPropSet->getPropertyValue( 2469 rtl::OUString::createFromAscii( "Size" ) ); 2470 if ( !( aSize >>= rProps.nSize ) ) 2471 { 2472 OSL_ENSURE( sal_False, 2473 "Content::loadData - Got no Size value!" ); 2474 return sal_False; 2475 } 2476 } 2477 catch ( beans::UnknownPropertyException const & ) 2478 { 2479 OSL_ENSURE( sal_False, 2480 "Content::loadData - Got no Size value!" ); 2481 return sal_False; 2482 } 2483 catch ( lang::WrappedTargetException const & ) 2484 { 2485 OSL_ENSURE( sal_False, 2486 "Content::loadData - Got no Size value!" ); 2487 return sal_False; 2488 } 2489 2490 // Compressed ( only available for streams ) 2491 try 2492 { 2493 uno::Any aCompressed 2494 = xPropSet->getPropertyValue( 2495 rtl::OUString::createFromAscii( "Compressed" ) ); 2496 if ( !( aCompressed >>= rProps.bCompressed ) ) 2497 { 2498 OSL_ENSURE( sal_False, 2499 "Content::loadData - Got no Compressed value!" ); 2500 return sal_False; 2501 } 2502 } 2503 catch ( beans::UnknownPropertyException const & ) 2504 { 2505 OSL_ENSURE( sal_False, 2506 "Content::loadData - Got no Compressed value!" ); 2507 return sal_False; 2508 } 2509 catch ( lang::WrappedTargetException const & ) 2510 { 2511 OSL_ENSURE( sal_False, 2512 "Content::loadData - Got no Compressed value!" ); 2513 return sal_False; 2514 } 2515 2516 // Encrypted ( only available for streams ) 2517 try 2518 { 2519 uno::Any aEncrypted 2520 = xPropSet->getPropertyValue( 2521 rtl::OUString::createFromAscii( "Encrypted" ) ); 2522 if ( !( aEncrypted >>= rProps.bEncrypted ) ) 2523 { 2524 OSL_ENSURE( sal_False, 2525 "Content::loadData - Got no Encrypted value!" ); 2526 return sal_False; 2527 } 2528 } 2529 catch ( beans::UnknownPropertyException const & ) 2530 { 2531 OSL_ENSURE( sal_False, 2532 "Content::loadData - Got no Encrypted value!" ); 2533 return sal_False; 2534 } 2535 catch ( lang::WrappedTargetException const & ) 2536 { 2537 OSL_ENSURE( sal_False, 2538 "Content::loadData - Got no Encrypted value!" ); 2539 return sal_False; 2540 } 2541 } 2542 return sal_True; 2543 } 2544 } 2545 catch ( container::NoSuchElementException const & ) 2546 { 2547 // getByHierarchicalName 2548 } 2549 2550 return sal_False; 2551 } 2552 2553 //========================================================================= 2554 sal_Bool Content::renameData( 2555 const uno::Reference< ucb::XContentIdentifier >& xOldId, 2556 const uno::Reference< ucb::XContentIdentifier >& xNewId ) 2557 { 2558 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2559 2560 PackageUri aURI( xOldId->getContentIdentifier() ); 2561 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage( 2562 aURI ); 2563 if ( !xNA.is() ) 2564 return sal_False; 2565 2566 if ( !xNA->hasByHierarchicalName( aURI.getPath() ) ) 2567 return sal_False; 2568 2569 try 2570 { 2571 uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() ); 2572 uno::Reference< container::XNamed > xNamed; 2573 aEntry >>= xNamed; 2574 2575 if ( !xNamed.is() ) 2576 { 2577 OSL_ENSURE( sal_False, 2578 "Content::renameData - Got no XNamed interface!" ); 2579 return sal_False; 2580 } 2581 2582 PackageUri aNewURI( xNewId->getContentIdentifier() ); 2583 2584 // No success indicator!? No return value / exceptions specified. 2585 xNamed->setName( aNewURI.getName() ); 2586 2587 return sal_True; 2588 } 2589 catch ( container::NoSuchElementException const & ) 2590 { 2591 // getByHierarchicalName 2592 } 2593 2594 return sal_False; 2595 } 2596 2597 //========================================================================= 2598 sal_Bool Content::storeData( const uno::Reference< io::XInputStream >& xStream ) 2599 { 2600 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2601 2602 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(); 2603 if ( !xNA.is() ) 2604 return sal_False; 2605 2606 uno::Reference< beans::XPropertySet > xPackagePropSet( 2607 xNA, uno::UNO_QUERY ); 2608 OSL_ENSURE( xPackagePropSet.is(), 2609 "Content::storeData - " 2610 "Got no XPropertySet interface from package!" ); 2611 2612 if ( !xPackagePropSet.is() ) 2613 return sal_False; 2614 2615 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) 2616 { 2617 if ( m_aUri.isRootFolder() ) 2618 { 2619 // Property available only from package and from streams (see below) 2620 try 2621 { 2622 xPackagePropSet->setPropertyValue( 2623 rtl::OUString::createFromAscii( "EncryptionKey" ), 2624 uno::makeAny( m_aProps.aEncryptionKey ) ); 2625 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED; 2626 } 2627 catch ( beans::UnknownPropertyException const & ) 2628 { 2629 // setPropertyValue 2630 } 2631 catch ( beans::PropertyVetoException const & ) 2632 { 2633 // setPropertyValue 2634 } 2635 catch ( lang::IllegalArgumentException const & ) 2636 { 2637 // setPropertyValue 2638 } 2639 catch ( lang::WrappedTargetException const & ) 2640 { 2641 // setPropertyValue 2642 } 2643 } 2644 } 2645 2646 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) ) 2647 { 2648 // if ( !bCreate ) 2649 // return sal_True; 2650 2651 try 2652 { 2653 // Create new resource... 2654 uno::Reference< lang::XSingleServiceFactory > xFac( 2655 xNA, uno::UNO_QUERY ); 2656 if ( !xFac.is() ) 2657 { 2658 OSL_ENSURE( sal_False, 2659 "Content::storeData - " 2660 "Got no XSingleServiceFactory interface!" ); 2661 return sal_False; 2662 } 2663 2664 uno::Sequence< uno::Any > aArgs( 1 ); 2665 aArgs[ 0 ] <<= isFolder(); 2666 2667 uno::Reference< uno::XInterface > xNew 2668 = xFac->createInstanceWithArguments( aArgs ); 2669 2670 if ( !xNew.is() ) 2671 { 2672 OSL_ENSURE( sal_False, 2673 "Content::storeData - createInstance failed!" ); 2674 return sal_False; 2675 } 2676 2677 PackageUri aParentUri( getParentURL() ); 2678 uno::Any aEntry 2679 = xNA->getByHierarchicalName( aParentUri.getPath() ); 2680 uno::Reference< container::XNameContainer > xParentContainer; 2681 aEntry >>= xParentContainer; 2682 2683 if ( !xParentContainer.is() ) 2684 { 2685 OSL_ENSURE( sal_False, 2686 "Content::storeData - " 2687 "Got no XNameContainer interface!" ); 2688 return sal_False; 2689 } 2690 2691 xParentContainer->insertByName( m_aProps.aTitle, 2692 uno::makeAny( xNew ) ); 2693 } 2694 catch ( uno::RuntimeException const & ) 2695 { 2696 throw; 2697 } 2698 catch ( lang::IllegalArgumentException const & ) 2699 { 2700 // insertByName 2701 OSL_ENSURE( sal_False, 2702 "Content::storeData - insertByName failed!" ); 2703 return sal_False; 2704 } 2705 catch ( container::ElementExistException const & ) 2706 { 2707 // insertByName 2708 OSL_ENSURE( sal_False, 2709 "Content::storeData - insertByName failed!" ); 2710 return sal_False; 2711 } 2712 catch ( lang::WrappedTargetException const & ) 2713 { 2714 // insertByName 2715 OSL_ENSURE( sal_False, 2716 "Content::storeData - insertByName failed!" ); 2717 return sal_False; 2718 } 2719 catch ( container::NoSuchElementException const & ) 2720 { 2721 // getByHierarchicalName 2722 OSL_ENSURE( sal_False, 2723 "Content::storeData - getByHierarchicalName failed!" ); 2724 return sal_False; 2725 } 2726 catch ( uno::Exception const & ) 2727 { 2728 // createInstanceWithArguments 2729 OSL_ENSURE( sal_False, "Content::storeData - Error!" ); 2730 return sal_False; 2731 } 2732 } 2733 2734 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) ) 2735 return sal_False; 2736 2737 try 2738 { 2739 uno::Reference< beans::XPropertySet > xPropSet; 2740 xNA->getByHierarchicalName( m_aUri.getPath() ) >>= xPropSet; 2741 2742 if ( !xPropSet.is() ) 2743 { 2744 OSL_ENSURE( sal_False, 2745 "Content::storeData - Got no XPropertySet interface!" ); 2746 return sal_False; 2747 } 2748 2749 ////////////////////////////////////////////////////////////////// 2750 // Store property values... 2751 ////////////////////////////////////////////////////////////////// 2752 2753 if ( m_nModifiedProps & MEDIATYPE_MODIFIED ) 2754 { 2755 xPropSet->setPropertyValue( 2756 rtl::OUString::createFromAscii( "MediaType" ), 2757 uno::makeAny( m_aProps.aMediaType ) ); 2758 m_nModifiedProps &= ~MEDIATYPE_MODIFIED; 2759 } 2760 2761 if ( m_nModifiedProps & COMPRESSED_MODIFIED ) 2762 { 2763 if ( !isFolder() ) 2764 xPropSet->setPropertyValue( 2765 rtl::OUString::createFromAscii( "Compressed" ), 2766 uno::makeAny( m_aProps.bCompressed ) ); 2767 2768 m_nModifiedProps &= ~COMPRESSED_MODIFIED; 2769 } 2770 2771 if ( m_nModifiedProps & ENCRYPTED_MODIFIED ) 2772 { 2773 if ( !isFolder() ) 2774 xPropSet->setPropertyValue( 2775 rtl::OUString::createFromAscii( "Encrypted" ), 2776 uno::makeAny( m_aProps.bEncrypted ) ); 2777 2778 m_nModifiedProps &= ~ENCRYPTED_MODIFIED; 2779 } 2780 2781 if ( m_nModifiedProps & ENCRYPTIONKEY_MODIFIED ) 2782 { 2783 if ( !isFolder() ) 2784 xPropSet->setPropertyValue( 2785 rtl::OUString::createFromAscii( "EncryptionKey" ), 2786 uno::makeAny( m_aProps.aEncryptionKey ) ); 2787 2788 m_nModifiedProps &= ~ENCRYPTIONKEY_MODIFIED; 2789 } 2790 2791 ////////////////////////////////////////////////////////////////// 2792 // Store data stream... 2793 ////////////////////////////////////////////////////////////////// 2794 2795 if ( xStream.is() && !isFolder() ) 2796 { 2797 uno::Reference< io::XActiveDataSink > xSink( 2798 xPropSet, uno::UNO_QUERY ); 2799 2800 if ( !xSink.is() ) 2801 { 2802 OSL_ENSURE( sal_False, 2803 "Content::storeData - " 2804 "Got no XActiveDataSink interface!" ); 2805 return sal_False; 2806 } 2807 2808 xSink->setInputStream( xStream ); 2809 } 2810 2811 return sal_True; 2812 } 2813 catch ( container::NoSuchElementException const & ) 2814 { 2815 // getByHierarchicalName 2816 } 2817 catch ( beans::UnknownPropertyException const & ) 2818 { 2819 // setPropertyValue 2820 } 2821 catch ( beans::PropertyVetoException const & ) 2822 { 2823 // setPropertyValue 2824 } 2825 catch ( lang::IllegalArgumentException const & ) 2826 { 2827 // setPropertyValue 2828 } 2829 catch ( lang::WrappedTargetException const & ) 2830 { 2831 // setPropertyValue 2832 } 2833 2834 OSL_ENSURE( sal_False, "Content::storeData - Error!" ); 2835 return sal_False; 2836 } 2837 2838 //========================================================================= 2839 sal_Bool Content::removeData() 2840 { 2841 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2842 2843 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(); 2844 if ( !xNA.is() ) 2845 return sal_False; 2846 2847 PackageUri aParentUri( getParentURL() ); 2848 if ( !xNA->hasByHierarchicalName( aParentUri.getPath() ) ) 2849 return sal_False; 2850 2851 try 2852 { 2853 uno::Any aEntry = xNA->getByHierarchicalName( aParentUri.getPath() ); 2854 uno::Reference< container::XNameContainer > xContainer; 2855 aEntry >>= xContainer; 2856 2857 if ( !xContainer.is() ) 2858 { 2859 OSL_ENSURE( sal_False, 2860 "Content::removeData - " 2861 "Got no XNameContainer interface!" ); 2862 return sal_False; 2863 } 2864 2865 xContainer->removeByName( m_aUri.getName() ); 2866 return sal_True; 2867 } 2868 catch ( container::NoSuchElementException const & ) 2869 { 2870 // getByHierarchicalName, removeByName 2871 } 2872 catch ( lang::WrappedTargetException const & ) 2873 { 2874 // removeByName 2875 } 2876 2877 OSL_ENSURE( sal_False, "Content::removeData - Error!" ); 2878 return sal_False; 2879 } 2880 2881 //========================================================================= 2882 sal_Bool Content::flushData() 2883 { 2884 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2885 2886 // Note: XChangesBatch is only implemented by the package itself, not 2887 // by the single entries. Maybe this has to change... 2888 2889 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(); 2890 if ( !xNA.is() ) 2891 return sal_False; 2892 2893 uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY ); 2894 if ( !xBatch.is() ) 2895 { 2896 OSL_ENSURE( sal_False, 2897 "Content::flushData - Got no XChangesBatch interface!" ); 2898 return sal_False; 2899 } 2900 2901 try 2902 { 2903 xBatch->commitChanges(); 2904 return sal_True; 2905 } 2906 catch ( lang::WrappedTargetException const & ) 2907 { 2908 } 2909 2910 OSL_ENSURE( sal_False, "Content::flushData - Error!" ); 2911 return sal_False; 2912 } 2913 2914 //========================================================================= 2915 uno::Reference< io::XInputStream > Content::getInputStream() 2916 { 2917 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2918 2919 uno::Reference< io::XInputStream > xStream; 2920 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(); 2921 if ( !xNA.is() ) 2922 return xStream; 2923 2924 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) ) 2925 return xStream; 2926 2927 try 2928 { 2929 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() ); 2930 uno::Reference< io::XActiveDataSink > xSink; 2931 aEntry >>= xSink; 2932 2933 if ( !xSink.is() ) 2934 { 2935 OSL_ENSURE( sal_False, 2936 "Content::getInputStream - " 2937 "Got no XActiveDataSink interface!" ); 2938 return xStream; 2939 } 2940 2941 xStream = xSink->getInputStream(); 2942 2943 OSL_ENSURE( xStream.is(), 2944 "Content::getInputStream - Got no stream!" ); 2945 } 2946 catch ( container::NoSuchElementException const & ) 2947 { 2948 // getByHierarchicalName 2949 } 2950 2951 return xStream; 2952 } 2953 2954 //========================================================================= 2955 uno::Reference< container::XEnumeration > Content::getIterator() 2956 { 2957 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 2958 2959 uno::Reference< container::XEnumeration > xIter; 2960 uno::Reference< container::XHierarchicalNameAccess > xNA = getPackage(); 2961 if ( !xNA.is() ) 2962 return xIter; 2963 2964 if ( !xNA->hasByHierarchicalName( m_aUri.getPath() ) ) 2965 return xIter; 2966 2967 try 2968 { 2969 uno::Any aEntry = xNA->getByHierarchicalName( m_aUri.getPath() ); 2970 uno::Reference< container::XEnumerationAccess > xIterFac; 2971 aEntry >>= xIterFac; 2972 2973 if ( !xIterFac.is() ) 2974 { 2975 OSL_ENSURE( sal_False, 2976 "Content::getIterator - " 2977 "Got no XEnumerationAccess interface!" ); 2978 return xIter; 2979 } 2980 2981 xIter = xIterFac->createEnumeration(); 2982 2983 OSL_ENSURE( xIter.is(), 2984 "Content::getIterator - Got no iterator!" ); 2985 } 2986 catch ( container::NoSuchElementException const & ) 2987 { 2988 // getByHierarchicalName 2989 } 2990 2991 return xIter; 2992 } 2993