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