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