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