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_ucbhelper.hxx" 26 /************************************************************************** 27 TODO 28 ************************************************************************** 29 30 *************************************************************************/ 31 32 #include <hash_map> 33 #include <com/sun/star/ucb/ContentAction.hpp> 34 #include <com/sun/star/ucb/CommandInfoChange.hpp> 35 #include <com/sun/star/ucb/XPersistentPropertySet.hpp> 36 #include <com/sun/star/beans/PropertyAttribute.hpp> 37 #include <com/sun/star/beans/PropertySetInfoChange.hpp> 38 #include <cppuhelper/interfacecontainer.hxx> 39 40 #include "osl/diagnose.h" 41 #include "osl/mutex.hxx" 42 #include "rtl/ref.hxx" 43 #include <ucbhelper/contentidentifier.hxx> 44 #include <ucbhelper/contenthelper.hxx> 45 #include <ucbhelper/providerhelper.hxx> 46 #include <ucbhelper/contentinfo.hxx> 47 48 using namespace com::sun::star; 49 50 namespace ucbhelper_impl 51 { 52 53 //========================================================================= 54 // 55 // class PropertyEventSequence. 56 // 57 //========================================================================= 58 59 class PropertyEventSequence 60 { 61 uno::Sequence< beans::PropertyChangeEvent > m_aSeq; 62 sal_uInt32 m_nPos; 63 64 public: 65 PropertyEventSequence( sal_uInt32 nSize ) 66 : m_aSeq( nSize ), m_nPos( 0 ) {}; 67 68 void append( const beans::PropertyChangeEvent& rEvt ) 69 { m_aSeq.getArray()[ m_nPos ] = rEvt; ++m_nPos; } 70 71 const uno::Sequence< beans::PropertyChangeEvent >& getEvents() 72 { m_aSeq.realloc( m_nPos ); return m_aSeq; } 73 }; 74 75 //========================================================================= 76 // 77 // PropertiesEventListenerMap. 78 // 79 //========================================================================= 80 81 typedef void* XPropertiesChangeListenerPtr; // -> Compiler problems! 82 83 struct equalPtr 84 { 85 bool operator()( const XPropertiesChangeListenerPtr& rp1, 86 const XPropertiesChangeListenerPtr& rp2 ) const 87 { 88 return ( rp1 == rp2 ); 89 } 90 }; 91 92 struct hashPtr 93 { 94 size_t operator()( const XPropertiesChangeListenerPtr& rp ) const 95 { 96 return (size_t)rp; 97 } 98 }; 99 100 typedef std::hash_map 101 < 102 XPropertiesChangeListenerPtr, 103 PropertyEventSequence*, 104 hashPtr, 105 equalPtr 106 > 107 PropertiesEventListenerMap; 108 109 //========================================================================= 110 // 111 // PropertyChangeListenerContainer. 112 // 113 //========================================================================= 114 115 struct equalStr 116 { 117 bool operator()( const rtl::OUString& s1, const rtl::OUString& s2 ) const 118 { 119 return !!( s1 == s2 ); 120 } 121 }; 122 123 struct hashStr 124 { 125 size_t operator()( const rtl::OUString& rName ) const 126 { 127 return rName.hashCode(); 128 } 129 }; 130 131 typedef cppu::OMultiTypeInterfaceContainerHelperVar 132 < 133 rtl::OUString, 134 hashStr, 135 equalStr 136 > PropertyChangeListeners; 137 138 //========================================================================= 139 // 140 // struct ContentImplHelper_Impl 141 // 142 //========================================================================= 143 144 struct ContentImplHelper_Impl 145 { 146 rtl::Reference< ::ucbhelper::PropertySetInfo > m_xPropSetInfo; 147 rtl::Reference< ::ucbhelper::CommandProcessorInfo > m_xCommandsInfo; 148 cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; 149 cppu::OInterfaceContainerHelper* m_pContentEventListeners; 150 cppu::OInterfaceContainerHelper* m_pPropSetChangeListeners; 151 cppu::OInterfaceContainerHelper* m_pCommandChangeListeners; 152 PropertyChangeListeners* m_pPropertyChangeListeners; 153 154 ContentImplHelper_Impl() 155 : m_pDisposeEventListeners( 0 ), 156 m_pContentEventListeners( 0 ), 157 m_pPropSetChangeListeners( 0 ), 158 m_pCommandChangeListeners( 0 ), 159 m_pPropertyChangeListeners( 0 ) {} 160 161 ~ContentImplHelper_Impl() 162 { 163 delete m_pDisposeEventListeners; 164 delete m_pContentEventListeners; 165 delete m_pPropSetChangeListeners; 166 delete m_pCommandChangeListeners; 167 delete m_pPropertyChangeListeners; 168 } 169 }; 170 171 } // namespace ucbhelper_impl 172 173 using namespace ucbhelper_impl; 174 175 //========================================================================= 176 //========================================================================= 177 // 178 // ContentImplHelper Implementation. 179 // 180 //========================================================================= 181 //========================================================================= 182 183 namespace ucbhelper { 184 185 ContentImplHelper::ContentImplHelper( 186 const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 187 const rtl::Reference< ContentProviderImplHelper >& rxProvider, 188 const uno::Reference< 189 com::sun::star::ucb::XContentIdentifier >& Identifier ) 190 : m_pImpl( new ContentImplHelper_Impl ), 191 m_xSMgr( rxSMgr ), 192 m_xIdentifier( Identifier ), 193 m_xProvider( rxProvider ), 194 m_nCommandId( 0 ) 195 { 196 } 197 198 //========================================================================= 199 // virtual 200 ContentImplHelper::~ContentImplHelper() 201 { 202 delete m_pImpl; 203 } 204 205 //========================================================================= 206 // 207 // XInterface methods. 208 // 209 //========================================================================= 210 211 void SAL_CALL ContentImplHelper::acquire() 212 throw() 213 { 214 cppu::OWeakObject::acquire(); 215 } 216 217 void SAL_CALL ContentImplHelper::release() 218 throw() 219 { 220 // #144882# - Call to OWeakObject::release may destroy m_xProvider. 221 // Prevent this. 222 rtl::Reference< ContentProviderImplHelper > xKeepProviderAlive( 223 m_xProvider ); 224 225 { 226 osl::MutexGuard aGuard( m_xProvider->m_aMutex ); 227 OWeakObject::release(); 228 } 229 } 230 231 uno::Any SAL_CALL ContentImplHelper::queryInterface( const uno::Type & rType ) 232 throw( uno::RuntimeException ) 233 { 234 com::sun::star::uno::Any aRet = cppu::queryInterface( rType, 235 static_cast< lang::XTypeProvider * >(this), 236 static_cast< lang::XServiceInfo * >(this), 237 static_cast< lang::XComponent * >(this), 238 static_cast< com::sun::star::ucb::XContent * >(this), 239 static_cast< com::sun::star::ucb::XCommandProcessor * >(this), 240 static_cast< beans::XPropertiesChangeNotifier * >(this), 241 static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >(this), 242 static_cast< beans::XPropertyContainer * >(this), 243 static_cast< beans::XPropertySetInfoChangeNotifier * >(this), 244 static_cast< container::XChild * >(this)); 245 return aRet.hasValue() ? aRet : cppu::OWeakObject::queryInterface( rType ); 246 } 247 248 //========================================================================= 249 // 250 // XTypeProvider methods. 251 // 252 //========================================================================= 253 254 XTYPEPROVIDER_IMPL_10( ContentImplHelper, 255 lang::XTypeProvider, 256 lang::XServiceInfo, 257 lang::XComponent, 258 com::sun::star::ucb::XContent, 259 com::sun::star::ucb::XCommandProcessor, 260 beans::XPropertiesChangeNotifier, 261 com::sun::star::ucb::XCommandInfoChangeNotifier, 262 beans::XPropertyContainer, 263 beans::XPropertySetInfoChangeNotifier, 264 container::XChild ); 265 266 //========================================================================= 267 // 268 // XServiceInfo methods. 269 // 270 //========================================================================= 271 272 // virtual 273 sal_Bool SAL_CALL ContentImplHelper::supportsService( 274 const rtl::OUString& ServiceName ) 275 throw( uno::RuntimeException ) 276 { 277 uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames(); 278 const rtl::OUString* pArray = aSNL.getConstArray(); 279 for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 280 { 281 if ( pArray[ i ] == ServiceName ) 282 return sal_True; 283 } 284 285 return sal_False; 286 } 287 288 //========================================================================= 289 // 290 // XComponent methods. 291 // 292 //========================================================================= 293 294 // virtual 295 void SAL_CALL ContentImplHelper::dispose() 296 throw( uno::RuntimeException ) 297 { 298 osl::MutexGuard aGuard( m_aMutex ); 299 300 if ( m_pImpl->m_pDisposeEventListeners && 301 m_pImpl->m_pDisposeEventListeners->getLength() ) 302 { 303 lang::EventObject aEvt; 304 aEvt.Source = static_cast< lang::XComponent * >( this ); 305 m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt ); 306 } 307 308 if ( m_pImpl->m_pContentEventListeners && 309 m_pImpl->m_pContentEventListeners->getLength() ) 310 { 311 lang::EventObject aEvt; 312 aEvt.Source = static_cast< com::sun::star::ucb::XContent * >( this ); 313 m_pImpl->m_pContentEventListeners->disposeAndClear( aEvt ); 314 } 315 316 if ( m_pImpl->m_pPropSetChangeListeners && 317 m_pImpl->m_pPropSetChangeListeners->getLength() ) 318 { 319 lang::EventObject aEvt; 320 aEvt.Source 321 = static_cast< beans::XPropertySetInfoChangeNotifier * >( this ); 322 m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt ); 323 } 324 325 if ( m_pImpl->m_pCommandChangeListeners && 326 m_pImpl->m_pCommandChangeListeners->getLength() ) 327 { 328 lang::EventObject aEvt; 329 aEvt.Source = static_cast< com::sun::star::ucb::XCommandInfoChangeNotifier * >( this ); 330 m_pImpl->m_pCommandChangeListeners->disposeAndClear( aEvt ); 331 } 332 333 if ( m_pImpl->m_pPropertyChangeListeners ) 334 { 335 lang::EventObject aEvt; 336 aEvt.Source 337 = static_cast< beans::XPropertiesChangeNotifier * >( this ); 338 m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt ); 339 } 340 } 341 342 //========================================================================= 343 // virtual 344 void SAL_CALL ContentImplHelper::addEventListener( 345 const uno::Reference< lang::XEventListener >& Listener ) 346 throw( uno::RuntimeException ) 347 { 348 osl::MutexGuard aGuard( m_aMutex ); 349 350 if ( !m_pImpl->m_pDisposeEventListeners ) 351 m_pImpl->m_pDisposeEventListeners 352 = new cppu::OInterfaceContainerHelper( m_aMutex ); 353 354 m_pImpl->m_pDisposeEventListeners->addInterface( Listener ); 355 } 356 357 //========================================================================= 358 // virtual 359 void SAL_CALL ContentImplHelper::removeEventListener( 360 const uno::Reference< lang::XEventListener >& Listener ) 361 throw( uno::RuntimeException ) 362 { 363 osl::MutexGuard aGuard( m_aMutex ); 364 365 if ( m_pImpl->m_pDisposeEventListeners ) 366 m_pImpl->m_pDisposeEventListeners->removeInterface( Listener ); 367 } 368 369 //========================================================================= 370 // 371 // XContent methods. 372 // 373 //========================================================================= 374 375 // virtual 376 uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL 377 ContentImplHelper::getIdentifier() 378 throw( uno::RuntimeException ) 379 { 380 return m_xIdentifier; 381 } 382 383 //========================================================================= 384 // virtual 385 void SAL_CALL ContentImplHelper::addContentEventListener( 386 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener ) 387 throw( uno::RuntimeException ) 388 { 389 osl::MutexGuard aGuard( m_aMutex ); 390 391 if ( !m_pImpl->m_pContentEventListeners ) 392 m_pImpl->m_pContentEventListeners 393 = new cppu::OInterfaceContainerHelper( m_aMutex ); 394 395 m_pImpl->m_pContentEventListeners->addInterface( Listener ); 396 } 397 398 //========================================================================= 399 // virtual 400 void SAL_CALL ContentImplHelper::removeContentEventListener( 401 const uno::Reference< com::sun::star::ucb::XContentEventListener >& Listener ) 402 throw( uno::RuntimeException ) 403 { 404 osl::MutexGuard aGuard( m_aMutex ); 405 406 if ( m_pImpl->m_pContentEventListeners ) 407 m_pImpl->m_pContentEventListeners->removeInterface( Listener ); 408 } 409 410 //========================================================================= 411 // 412 // XCommandProcessor methods. 413 // 414 //========================================================================= 415 416 // virtual 417 sal_Int32 SAL_CALL ContentImplHelper::createCommandIdentifier() 418 throw( uno::RuntimeException ) 419 { 420 osl::MutexGuard aGuard( m_aMutex ); 421 422 // Just increase counter on every call to generate an identifier. 423 return ++m_nCommandId; 424 } 425 426 //========================================================================= 427 // 428 // XPropertiesChangeNotifier methods. 429 // 430 //========================================================================= 431 432 // virtual 433 void SAL_CALL ContentImplHelper::addPropertiesChangeListener( 434 const uno::Sequence< rtl::OUString >& PropertyNames, 435 const uno::Reference< beans::XPropertiesChangeListener >& Listener ) 436 throw( uno::RuntimeException ) 437 { 438 osl::MutexGuard aGuard( m_aMutex ); 439 440 if ( !m_pImpl->m_pPropertyChangeListeners ) 441 m_pImpl->m_pPropertyChangeListeners 442 = new PropertyChangeListeners( m_aMutex ); 443 444 sal_Int32 nCount = PropertyNames.getLength(); 445 if ( !nCount ) 446 { 447 // Note: An empty sequence means a listener for "all" properties. 448 m_pImpl->m_pPropertyChangeListeners->addInterface( 449 rtl::OUString(), Listener ); 450 } 451 else 452 { 453 const rtl::OUString* pSeq = PropertyNames.getConstArray(); 454 455 for ( sal_Int32 n = 0; n < nCount; ++n ) 456 { 457 const rtl::OUString& rName = pSeq[ n ]; 458 if ( rName.getLength() ) 459 m_pImpl->m_pPropertyChangeListeners->addInterface( 460 rName, Listener ); 461 } 462 } 463 } 464 465 //========================================================================= 466 // virtual 467 void SAL_CALL ContentImplHelper::removePropertiesChangeListener( 468 const uno::Sequence< rtl::OUString >& PropertyNames, 469 const uno::Reference< beans::XPropertiesChangeListener >& Listener ) 470 throw( uno::RuntimeException ) 471 { 472 osl::MutexGuard aGuard( m_aMutex ); 473 474 if ( !m_pImpl->m_pPropertyChangeListeners ) 475 return; 476 477 sal_Int32 nCount = PropertyNames.getLength(); 478 if ( !nCount ) 479 { 480 // Note: An empty sequence means a listener for "all" properties. 481 m_pImpl->m_pPropertyChangeListeners->removeInterface( 482 rtl::OUString(), Listener ); 483 } 484 else 485 { 486 const rtl::OUString* pSeq = PropertyNames.getConstArray(); 487 488 for ( sal_Int32 n = 0; n < nCount; ++n ) 489 { 490 const rtl::OUString& rName = pSeq[ n ]; 491 if ( rName.getLength() ) 492 m_pImpl->m_pPropertyChangeListeners->removeInterface( 493 rName, Listener ); 494 } 495 } 496 } 497 498 //========================================================================= 499 // 500 // XCommandInfoChangeNotifier methods. 501 // 502 //========================================================================= 503 504 // virtual 505 void SAL_CALL ContentImplHelper::addCommandInfoChangeListener( 506 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener ) 507 throw( uno::RuntimeException ) 508 { 509 osl::MutexGuard aGuard( m_aMutex ); 510 511 if ( !m_pImpl->m_pCommandChangeListeners ) 512 m_pImpl->m_pCommandChangeListeners 513 = new cppu::OInterfaceContainerHelper( m_aMutex ); 514 515 m_pImpl->m_pCommandChangeListeners->addInterface( Listener ); 516 } 517 518 //========================================================================= 519 // virtual 520 void SAL_CALL ContentImplHelper::removeCommandInfoChangeListener( 521 const uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener >& Listener ) 522 throw( uno::RuntimeException ) 523 { 524 osl::MutexGuard aGuard( m_aMutex ); 525 526 if ( m_pImpl->m_pCommandChangeListeners ) 527 m_pImpl->m_pCommandChangeListeners->removeInterface( Listener ); 528 } 529 530 //========================================================================= 531 // 532 // XPropertyContainer methods. 533 // 534 //========================================================================= 535 536 // virtual 537 void SAL_CALL ContentImplHelper::addProperty( 538 const rtl::OUString& Name, 539 sal_Int16 Attributes, 540 const uno::Any& DefaultValue ) 541 throw( beans::PropertyExistException, 542 beans::IllegalTypeException, 543 lang::IllegalArgumentException, 544 uno::RuntimeException ) 545 { 546 osl::MutexGuard aGuard( m_aMutex ); 547 548 ////////////////////////////////////////////////////////////////////// 549 // Make sure a property with the requested name does not already 550 // exist in dynamic and static(!) properties. 551 ////////////////////////////////////////////////////////////////////// 552 553 // @@@ Need real command environment here, but where to get it from? 554 // XPropertyContainer interface should be replaced by 555 // XCommandProcessor commands! 556 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv; 557 558 if ( getPropertySetInfo( xEnv )->hasPropertyByName( Name ) ) 559 { 560 // Property does already exist. 561 throw beans::PropertyExistException(); 562 } 563 564 ////////////////////////////////////////////////////////////////////// 565 // Add a new dynamic property. 566 ////////////////////////////////////////////////////////////////////// 567 568 // Open/create persistent property set. 569 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet( 570 getAdditionalPropertySet( sal_True ) ); 571 572 OSL_ENSURE( xSet.is(), 573 "ContentImplHelper::addProperty - No property set!" ); 574 575 if ( xSet.is() ) 576 { 577 uno::Reference< beans::XPropertyContainer > xContainer( 578 xSet, uno::UNO_QUERY ); 579 580 OSL_ENSURE( 581 xContainer.is(), 582 "ContentImplHelper::addProperty - No property container!" ); 583 584 if ( xContainer.is() ) 585 { 586 // Property is always removeable. 587 Attributes |= beans::PropertyAttribute::REMOVEABLE; 588 589 try 590 { 591 xContainer->addProperty( Name, Attributes, DefaultValue ); 592 } 593 catch ( beans::PropertyExistException const & ) 594 { 595 OSL_ENSURE( sal_False, 596 "ContentImplHelper::addProperty - Exists!" ); 597 throw; 598 } 599 catch ( beans::IllegalTypeException const & ) 600 { 601 OSL_ENSURE( sal_False, 602 "ContentImplHelper::addProperty - Wrong Type!" ); 603 throw; 604 } 605 catch ( lang::IllegalArgumentException const & ) 606 { 607 OSL_ENSURE( sal_False, 608 "ContentImplHelper::addProperty - Illegal Arg!" ); 609 throw; 610 } 611 612 // Success! 613 614 if ( m_pImpl->m_xPropSetInfo.is() ) 615 { 616 // Info cached in propertyset info is invalid now! 617 m_pImpl->m_xPropSetInfo->reset(); 618 } 619 620 // Notify propertyset info change listeners. 621 if ( m_pImpl->m_pPropSetChangeListeners && 622 m_pImpl->m_pPropSetChangeListeners->getLength() ) 623 { 624 beans::PropertySetInfoChangeEvent evt( 625 static_cast< cppu::OWeakObject * >( this ), 626 Name, 627 -1, // No handle available 628 beans::PropertySetInfoChange::PROPERTY_INSERTED ); 629 notifyPropertySetInfoChange( evt ); 630 } 631 } 632 } 633 } 634 635 //========================================================================= 636 // virtual 637 void SAL_CALL ContentImplHelper::removeProperty( const rtl::OUString& Name ) 638 throw( beans::UnknownPropertyException, 639 beans::NotRemoveableException, 640 uno::RuntimeException ) 641 { 642 osl::MutexGuard aGuard( m_aMutex ); 643 644 try 645 { 646 // @@@ Need real command environment here, but where to get it from? 647 // XPropertyContainer interface should be replaced by 648 // XCommandProcessor commands! 649 uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv; 650 651 beans::Property aProp 652 = getPropertySetInfo( xEnv )->getPropertyByName( Name ); 653 654 if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVEABLE ) ) 655 { 656 // Not removeable! 657 throw beans::NotRemoveableException(); 658 } 659 } 660 catch ( beans::UnknownPropertyException const & ) 661 { 662 OSL_ENSURE( sal_False, "ContentImplHelper::removeProperty - Unknown!" ); 663 throw; 664 } 665 666 ////////////////////////////////////////////////////////////////////// 667 // Try to remove property from dynamic property set. 668 ////////////////////////////////////////////////////////////////////// 669 670 // Open persistent property set, if exists. 671 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > xSet( 672 getAdditionalPropertySet( sal_False ) ); 673 if ( xSet.is() ) 674 { 675 uno::Reference< beans::XPropertyContainer > xContainer( 676 xSet, uno::UNO_QUERY ); 677 678 OSL_ENSURE( 679 xContainer.is(), 680 "ContentImplHelper::removeProperty - No property container!" ); 681 682 if ( xContainer.is() ) 683 { 684 try 685 { 686 xContainer->removeProperty( Name ); 687 } 688 catch ( beans::UnknownPropertyException const & ) 689 { 690 OSL_ENSURE( sal_False, 691 "ContentImplHelper::removeProperty - Unknown!" ); 692 throw; 693 } 694 catch ( beans::NotRemoveableException const & ) 695 { 696 OSL_ENSURE( 697 sal_False, 698 "ContentImplHelper::removeProperty - Unremoveable!" ); 699 throw; 700 } 701 702 xContainer = 0; 703 704 // Success! 705 706 if ( xSet->getPropertySetInfo()->getProperties().getLength() == 0 ) 707 { 708 // Remove empty propertyset from registry. 709 uno::Reference< com::sun::star::ucb::XPropertySetRegistry > 710 xReg = xSet->getRegistry(); 711 if ( xReg.is() ) 712 { 713 rtl::OUString aKey( xSet->getKey() ); 714 xSet = 0; 715 xReg->removePropertySet( aKey ); 716 } 717 } 718 719 if ( m_pImpl->m_xPropSetInfo.is() ) 720 { 721 // Info cached in propertyset info is invalid now! 722 m_pImpl->m_xPropSetInfo->reset(); 723 } 724 725 // Notify propertyset info change listeners. 726 if ( m_pImpl->m_pPropSetChangeListeners && 727 m_pImpl->m_pPropSetChangeListeners->getLength() ) 728 { 729 beans::PropertySetInfoChangeEvent evt( 730 static_cast< cppu::OWeakObject * >( this ), 731 Name, 732 -1, // No handle available 733 beans::PropertySetInfoChange::PROPERTY_REMOVED ); 734 notifyPropertySetInfoChange( evt ); 735 } 736 } 737 } 738 } 739 740 //========================================================================= 741 // 742 // XPropertySetInfoChangeNotifier methods. 743 // 744 //========================================================================= 745 746 // virtual 747 void SAL_CALL ContentImplHelper::addPropertySetInfoChangeListener( 748 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener ) 749 throw( uno::RuntimeException ) 750 { 751 osl::MutexGuard aGuard( m_aMutex ); 752 753 if ( !m_pImpl->m_pPropSetChangeListeners ) 754 m_pImpl->m_pPropSetChangeListeners 755 = new cppu::OInterfaceContainerHelper( m_aMutex ); 756 757 m_pImpl->m_pPropSetChangeListeners->addInterface( Listener ); 758 } 759 760 //========================================================================= 761 // virtual 762 void SAL_CALL ContentImplHelper::removePropertySetInfoChangeListener( 763 const uno::Reference< beans::XPropertySetInfoChangeListener >& Listener ) 764 throw( uno::RuntimeException ) 765 { 766 osl::MutexGuard aGuard( m_aMutex ); 767 768 if ( m_pImpl->m_pPropSetChangeListeners ) 769 m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener ); 770 } 771 772 //========================================================================= 773 // 774 // XChild methods. 775 // 776 //========================================================================= 777 778 // virtual 779 uno::Reference< uno::XInterface > SAL_CALL ContentImplHelper::getParent() 780 throw( uno::RuntimeException ) 781 { 782 uno::Reference< uno::XInterface > xParent; 783 rtl::OUString aURL = getParentURL(); 784 785 if ( aURL.getLength() ) 786 { 787 uno::Reference< com::sun::star::ucb::XContentIdentifier > xId( 788 new ContentIdentifier( m_xSMgr, aURL ) ); 789 try 790 { 791 xParent.set( m_xProvider->queryContent( xId ) ); 792 } 793 catch ( com::sun::star::ucb::IllegalIdentifierException const & ) 794 { 795 } 796 } 797 798 return xParent; 799 } 800 801 //========================================================================= 802 // virtual 803 void SAL_CALL ContentImplHelper::setParent( 804 const uno::Reference< uno::XInterface >& ) 805 throw( lang::NoSupportException, uno::RuntimeException ) 806 { 807 throw lang::NoSupportException(); 808 } 809 810 //========================================================================= 811 // 812 // Non-interface methods 813 // 814 //========================================================================= 815 816 uno::Reference< com::sun::star::ucb::XPersistentPropertySet > 817 ContentImplHelper::getAdditionalPropertySet( sal_Bool bCreate ) 818 { 819 // Get propertyset from provider. 820 return m_xProvider->getAdditionalPropertySet( 821 m_xIdentifier->getContentIdentifier(), bCreate ); 822 } 823 824 //========================================================================= 825 sal_Bool ContentImplHelper::renameAdditionalPropertySet( 826 const rtl::OUString& rOldKey, 827 const rtl::OUString& rNewKey, 828 sal_Bool bRecursive ) 829 { 830 return m_xProvider->renameAdditionalPropertySet( 831 rOldKey, rNewKey, bRecursive ); 832 } 833 834 //========================================================================= 835 sal_Bool ContentImplHelper::copyAdditionalPropertySet( 836 const rtl::OUString& rSourceKey, 837 const rtl::OUString& rTargetKey, 838 sal_Bool bRecursive ) 839 { 840 return m_xProvider->copyAdditionalPropertySet( 841 rSourceKey, rTargetKey, bRecursive ); 842 } 843 844 //========================================================================= 845 sal_Bool ContentImplHelper::removeAdditionalPropertySet( sal_Bool bRecursive ) 846 { 847 return m_xProvider->removeAdditionalPropertySet( 848 m_xIdentifier->getContentIdentifier(), bRecursive ); 849 } 850 851 //========================================================================= 852 void ContentImplHelper::notifyPropertiesChange( 853 const uno::Sequence< beans::PropertyChangeEvent >& evt ) const 854 { 855 if ( !m_pImpl->m_pPropertyChangeListeners ) 856 return; 857 858 sal_Int32 nCount = evt.getLength(); 859 if ( nCount ) 860 { 861 // First, notify listeners interested in changes of every property. 862 cppu::OInterfaceContainerHelper* pAllPropsContainer 863 = m_pImpl->m_pPropertyChangeListeners->getContainer( 864 rtl::OUString() ); 865 if ( pAllPropsContainer ) 866 { 867 cppu::OInterfaceIteratorHelper aIter( *pAllPropsContainer ); 868 while ( aIter.hasMoreElements() ) 869 { 870 // Propagate event. 871 uno::Reference< beans::XPropertiesChangeListener > xListener( 872 aIter.next(), uno::UNO_QUERY ); 873 if ( xListener.is() ) 874 xListener->propertiesChange( evt ); 875 } 876 } 877 878 PropertiesEventListenerMap aListeners; 879 880 const beans::PropertyChangeEvent* pEvents = evt.getConstArray(); 881 882 for ( sal_Int32 n = 0; n < nCount; ++n ) 883 { 884 const beans::PropertyChangeEvent& rEvent = pEvents[ n ]; 885 const rtl::OUString& rName = rEvent.PropertyName; 886 887 cppu::OInterfaceContainerHelper* pPropsContainer 888 = m_pImpl->m_pPropertyChangeListeners->getContainer( rName ); 889 if ( pPropsContainer ) 890 { 891 cppu::OInterfaceIteratorHelper aIter( *pPropsContainer ); 892 while ( aIter.hasMoreElements() ) 893 { 894 PropertyEventSequence* p = NULL; 895 896 beans::XPropertiesChangeListener* pListener = 897 static_cast< beans::XPropertiesChangeListener * >( 898 aIter.next() ); 899 PropertiesEventListenerMap::iterator it = 900 aListeners.find( pListener ); 901 if ( it == aListeners.end() ) 902 { 903 // Not in map - create and insert new entry. 904 p = new PropertyEventSequence( nCount ); 905 aListeners[ pListener ] = p; 906 } 907 else 908 p = (*it).second; 909 910 if ( p ) 911 p->append( rEvent ); 912 } 913 } 914 } 915 916 // Notify listeners. 917 PropertiesEventListenerMap::iterator it = aListeners.begin(); 918 while ( !aListeners.empty() ) 919 { 920 beans::XPropertiesChangeListener* pListener = 921 static_cast< beans::XPropertiesChangeListener * >( (*it).first ); 922 PropertyEventSequence* pSeq = (*it).second; 923 924 // Remove current element. 925 aListeners.erase( it ); 926 927 // Propagate event. 928 pListener->propertiesChange( pSeq->getEvents() ); 929 930 delete pSeq; 931 932 it = aListeners.begin(); 933 } 934 } 935 } 936 937 //========================================================================= 938 void ContentImplHelper::notifyPropertySetInfoChange( 939 const beans::PropertySetInfoChangeEvent& evt ) const 940 { 941 if ( !m_pImpl->m_pPropSetChangeListeners ) 942 return; 943 944 // Notify event listeners. 945 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pPropSetChangeListeners ); 946 while ( aIter.hasMoreElements() ) 947 { 948 // Propagate event. 949 uno::Reference< beans::XPropertySetInfoChangeListener > 950 xListener( aIter.next(), uno::UNO_QUERY ); 951 if ( xListener.is() ) 952 xListener->propertySetInfoChange( evt ); 953 } 954 } 955 956 //========================================================================= 957 void ContentImplHelper::notifyCommandInfoChange( 958 const com::sun::star::ucb::CommandInfoChangeEvent& evt ) const 959 { 960 if ( !m_pImpl->m_pCommandChangeListeners ) 961 return; 962 963 // Notify event listeners. 964 cppu::OInterfaceIteratorHelper aIter( 965 *m_pImpl->m_pCommandChangeListeners ); 966 while ( aIter.hasMoreElements() ) 967 { 968 // Propagate event. 969 uno::Reference< com::sun::star::ucb::XCommandInfoChangeListener > 970 xListener( aIter.next(), uno::UNO_QUERY ); 971 if ( xListener.is() ) 972 xListener->commandInfoChange( evt ); 973 } 974 } 975 976 //========================================================================= 977 void ContentImplHelper::notifyContentEvent( 978 const com::sun::star::ucb::ContentEvent& evt ) const 979 { 980 if ( !m_pImpl->m_pContentEventListeners ) 981 return; 982 983 // Notify event listeners. 984 cppu::OInterfaceIteratorHelper aIter( *m_pImpl->m_pContentEventListeners ); 985 while ( aIter.hasMoreElements() ) 986 { 987 // Propagate event. 988 uno::Reference< 989 com::sun::star::ucb::XContentEventListener > xListener( 990 aIter.next(), uno::UNO_QUERY ); 991 if ( xListener.is() ) 992 xListener->contentEvent( evt ); 993 } 994 } 995 996 //========================================================================= 997 void ContentImplHelper::inserted() 998 { 999 // Content is not yet registered at provider. 1000 m_xProvider->registerNewContent( this ); 1001 1002 // If the parent content is currently not instanciated, there can be 1003 // no listeners interested in changes ;-) 1004 1005 rtl::Reference< ContentImplHelper > xParent 1006 = m_xProvider->queryExistingContent( getParentURL() ); 1007 1008 if ( xParent.is() ) 1009 { 1010 com::sun::star::ucb::ContentEvent aEvt( 1011 static_cast< cppu::OWeakObject * >( xParent.get() ), // Source 1012 com::sun::star::ucb::ContentAction::INSERTED, // Action 1013 this, // Content 1014 xParent->getIdentifier() ); // Id 1015 xParent->notifyContentEvent( aEvt ); 1016 } 1017 } 1018 1019 //========================================================================= 1020 void ContentImplHelper::deleted() 1021 { 1022 uno::Reference< com::sun::star::ucb::XContent > xThis = this; 1023 1024 rtl::Reference< ContentImplHelper > xParent 1025 = m_xProvider->queryExistingContent( getParentURL() ); 1026 1027 if ( xParent.is() ) 1028 { 1029 // Let parent notify "REMOVED" event. 1030 com::sun::star::ucb::ContentEvent aEvt( 1031 static_cast< cppu::OWeakObject * >( xParent.get() ), 1032 com::sun::star::ucb::ContentAction::REMOVED, 1033 this, 1034 xParent->getIdentifier() ); 1035 xParent->notifyContentEvent( aEvt ); 1036 } 1037 1038 // Notify "DELETED" event. 1039 com::sun::star::ucb::ContentEvent aEvt1( 1040 static_cast< cppu::OWeakObject * >( this ), 1041 com::sun::star::ucb::ContentAction::DELETED, 1042 this, 1043 getIdentifier() ); 1044 notifyContentEvent( aEvt1 ); 1045 1046 m_xProvider->removeContent( this ); 1047 } 1048 1049 //========================================================================= 1050 sal_Bool ContentImplHelper::exchange( 1051 const uno::Reference< com::sun::star::ucb::XContentIdentifier >& rNewId ) 1052 { 1053 uno::Reference< com::sun::star::ucb::XContent > xThis = this; 1054 1055 osl::ClearableMutexGuard aGuard( m_aMutex ); 1056 1057 rtl::Reference< ContentImplHelper > xContent 1058 = m_xProvider->queryExistingContent( rNewId ); 1059 if ( xContent.is() ) 1060 { 1061 // @@@ 1062 // Big trouble. Another object with the new identity exists. 1063 // How shall I mutate to / merge with the other object? 1064 return sal_False; 1065 } 1066 1067 uno::Reference< com::sun::star::ucb::XContentIdentifier > xOldId 1068 = getIdentifier(); 1069 1070 // Re-insert at provider. 1071 m_xProvider->removeContent( this ); 1072 m_xIdentifier = rNewId; 1073 m_xProvider->registerNewContent( this ); 1074 1075 aGuard.clear(); 1076 1077 // Notify "EXCHANGED" event. 1078 com::sun::star::ucb::ContentEvent aEvt( 1079 static_cast< cppu::OWeakObject * >( this ), 1080 com::sun::star::ucb::ContentAction::EXCHANGED, 1081 this, 1082 xOldId ); 1083 notifyContentEvent( aEvt ); 1084 return sal_True; 1085 } 1086 1087 //========================================================================= 1088 uno::Reference< com::sun::star::ucb::XCommandInfo > 1089 ContentImplHelper::getCommandInfo( 1090 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv, 1091 sal_Bool bCache ) 1092 { 1093 osl::MutexGuard aGuard( m_aMutex ); 1094 1095 if ( !m_pImpl->m_xCommandsInfo.is() ) 1096 m_pImpl->m_xCommandsInfo 1097 = new CommandProcessorInfo( m_xSMgr, xEnv, this ); 1098 else if ( !bCache ) 1099 m_pImpl->m_xCommandsInfo->reset(); 1100 1101 return uno::Reference< com::sun::star::ucb::XCommandInfo >( 1102 m_pImpl->m_xCommandsInfo.get() ); 1103 } 1104 1105 //========================================================================= 1106 uno::Reference< beans::XPropertySetInfo > 1107 ContentImplHelper::getPropertySetInfo( 1108 const uno::Reference< com::sun::star::ucb::XCommandEnvironment > & xEnv, 1109 sal_Bool bCache ) 1110 { 1111 osl::MutexGuard aGuard( m_aMutex ); 1112 1113 if ( !m_pImpl->m_xPropSetInfo.is() ) 1114 m_pImpl->m_xPropSetInfo 1115 = new PropertySetInfo( m_xSMgr, xEnv, this ); 1116 else if ( !bCache ) 1117 m_pImpl->m_xPropSetInfo->reset(); 1118 1119 return uno::Reference< beans::XPropertySetInfo >( 1120 m_pImpl->m_xPropSetInfo.get() ); 1121 } 1122 1123 } // namespace ucbhelper 1124