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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_ucb.hxx" 24 25 /************************************************************************** 26 TODO 27 ************************************************************************** 28 29 *************************************************************************/ 30 31 #include <list> 32 #include <hash_map> 33 #include <osl/diagnose.h> 34 #include <rtl/ustrbuf.hxx> 35 #include <cppuhelper/interfacecontainer.hxx> 36 #include <com/sun/star/beans/PropertyAttribute.hpp> 37 #include <com/sun/star/beans/PropertySetInfoChange.hpp> 38 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 39 #include <com/sun/star/container/XNameContainer.hpp> 40 #include <com/sun/star/container/XNameReplace.hpp> 41 #include <com/sun/star/util/XChangesBatch.hpp> 42 #include "ucbstore.hxx" 43 44 using namespace com::sun::star::beans; 45 using namespace com::sun::star::container; 46 using namespace com::sun::star::lang; 47 using namespace com::sun::star::ucb; 48 using namespace com::sun::star::uno; 49 using namespace com::sun::star::util; 50 using namespace cppu; 51 using namespace rtl; 52 53 //========================================================================= 54 rtl::OUString makeHierarchalNameSegment( const rtl::OUString & rIn ) 55 { 56 rtl::OUStringBuffer aBuffer; 57 aBuffer.appendAscii( "['" ); 58 59 sal_Int32 nCount = rIn.getLength(); 60 for ( sal_Int32 n = 0; n < nCount; ++n ) 61 { 62 const sal_Unicode c = rIn.getStr()[ n ]; 63 switch ( c ) 64 { 65 case '&': 66 aBuffer.appendAscii( "&" ); 67 break; 68 69 case '"': 70 aBuffer.appendAscii( """ ); 71 break; 72 73 case '\'': 74 aBuffer.appendAscii( "'" ); 75 break; 76 77 case '<': 78 aBuffer.appendAscii( "<" ); 79 break; 80 81 case '>': 82 aBuffer.appendAscii( ">" ); 83 break; 84 85 default: 86 aBuffer.append( c ); 87 break; 88 } 89 } 90 91 aBuffer.appendAscii( "']" ); 92 return rtl::OUString( aBuffer.makeStringAndClear() ); 93 } 94 95 //========================================================================= 96 97 #define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties" 98 99 // describe path of cfg entry 100 #define CFGPROPERTY_NODEPATH "nodepath" 101 // true->async. update; false->sync. update 102 #define CFGPROPERTY_LAZYWRITE "lazywrite" 103 104 //========================================================================= 105 106 struct equalString_Impl 107 { 108 bool operator()( const OUString& s1, const OUString& s2 ) const 109 { 110 return !!( s1 == s2 ); 111 } 112 }; 113 114 struct hashString_Impl 115 { 116 size_t operator()( const OUString & rName ) const 117 { 118 return rName.hashCode(); 119 } 120 }; 121 122 //========================================================================= 123 // 124 // PropertySetMap_Impl. 125 // 126 //========================================================================= 127 128 typedef std::hash_map 129 < 130 OUString, 131 PersistentPropertySet*, 132 hashString_Impl, 133 equalString_Impl 134 > 135 PropertySetMap_Impl; 136 137 //========================================================================= 138 // 139 // class PropertySetInfo_Impl 140 // 141 //========================================================================= 142 143 class PropertySetInfo_Impl : 144 public OWeakObject, public XTypeProvider, public XPropertySetInfo 145 { 146 Reference< XMultiServiceFactory > m_xSMgr; 147 Sequence< Property >* m_pProps; 148 PersistentPropertySet* m_pOwner; 149 150 public: 151 PropertySetInfo_Impl( const Reference< XMultiServiceFactory >& rxSMgr, 152 PersistentPropertySet* pOwner ); 153 virtual ~PropertySetInfo_Impl(); 154 155 // XInterface 156 XINTERFACE_DECL() 157 158 // XTypeProvider 159 XTYPEPROVIDER_DECL() 160 161 // XPropertySetInfo 162 virtual Sequence< Property > SAL_CALL getProperties() 163 throw( RuntimeException ); 164 virtual Property SAL_CALL getPropertyByName( const OUString& aName ) 165 throw( UnknownPropertyException, RuntimeException ); 166 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) 167 throw( RuntimeException ); 168 169 // Non-interface methods. 170 void reset() { delete m_pProps; m_pProps = 0; } 171 }; 172 173 //========================================================================= 174 // 175 // UcbStore_Impl. 176 // 177 //========================================================================= 178 179 struct UcbStore_Impl 180 { 181 osl::Mutex m_aMutex; 182 Sequence< Any > m_aInitArgs; 183 Reference< XPropertySetRegistry > m_xTheRegistry; 184 }; 185 186 //========================================================================= 187 //========================================================================= 188 //========================================================================= 189 // 190 // UcbStore Implementation. 191 // 192 //========================================================================= 193 //========================================================================= 194 //========================================================================= 195 196 UcbStore::UcbStore( const Reference< XMultiServiceFactory >& rXSMgr ) 197 : m_xSMgr( rXSMgr ), 198 m_pImpl( new UcbStore_Impl() ) 199 { 200 } 201 202 //========================================================================= 203 // virtual 204 UcbStore::~UcbStore() 205 { 206 delete m_pImpl; 207 } 208 209 //========================================================================= 210 // 211 // XInterface methods. 212 // 213 //========================================================================= 214 215 XINTERFACE_IMPL_4( UcbStore, 216 XTypeProvider, 217 XServiceInfo, 218 XPropertySetRegistryFactory, 219 XInitialization ); 220 221 //========================================================================= 222 // 223 // XTypeProvider methods. 224 // 225 //========================================================================= 226 227 XTYPEPROVIDER_IMPL_4( UcbStore, 228 XTypeProvider, 229 XServiceInfo, 230 XPropertySetRegistryFactory, 231 XInitialization ); 232 233 //========================================================================= 234 // 235 // XServiceInfo methods. 236 // 237 //========================================================================= 238 239 XSERVICEINFO_IMPL_1( UcbStore, 240 OUString::createFromAscii( 241 "com.sun.star.comp.ucb.UcbStore" ), 242 OUString::createFromAscii( 243 STORE_SERVICE_NAME ) ); 244 245 //========================================================================= 246 // 247 // Service factory implementation. 248 // 249 //========================================================================= 250 251 ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore ); 252 253 //========================================================================= 254 // 255 // XPropertySetRegistryFactory methods. 256 // 257 //========================================================================= 258 259 // virtual 260 Reference< XPropertySetRegistry > SAL_CALL 261 UcbStore::createPropertySetRegistry( const OUString& ) 262 throw( RuntimeException ) 263 { 264 // The URL parameter is ignored by this interface implementation. It always 265 // uses the configuration server as storage medium. 266 267 if ( !m_pImpl->m_xTheRegistry.is() ) 268 { 269 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 270 if ( !m_pImpl->m_xTheRegistry.is() ) 271 m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xSMgr, getInitArgs() ); 272 } 273 274 return m_pImpl->m_xTheRegistry; 275 } 276 277 //========================================================================= 278 // 279 // XInitialization methods. 280 // 281 //========================================================================= 282 283 // virtual 284 void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments ) 285 throw( Exception, RuntimeException ) 286 { 287 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 288 m_pImpl->m_aInitArgs = aArguments; 289 } 290 291 //========================================================================= 292 const Sequence< Any >& UcbStore::getInitArgs() const 293 { 294 return m_pImpl->m_aInitArgs; 295 } 296 297 //========================================================================= 298 // 299 // PropertySetRegistry_Impl. 300 // 301 //========================================================================= 302 303 struct PropertySetRegistry_Impl 304 { 305 const Sequence< Any > m_aInitArgs; 306 PropertySetMap_Impl m_aPropSets; 307 Reference< XMultiServiceFactory > m_xConfigProvider; 308 Reference< XInterface > m_xRootReadAccess; 309 Reference< XInterface > m_xRootWriteAccess; 310 osl::Mutex m_aMutex; 311 sal_Bool m_bTriedToGetRootReadAccess; // #82494# 312 sal_Bool m_bTriedToGetRootWriteAccess; // #82494# 313 314 PropertySetRegistry_Impl( const Sequence< Any > &rInitArgs ) 315 : m_aInitArgs( rInitArgs ), 316 m_bTriedToGetRootReadAccess( sal_False ), 317 m_bTriedToGetRootWriteAccess( sal_False ) 318 { 319 } 320 }; 321 322 //========================================================================= 323 //========================================================================= 324 //========================================================================= 325 // 326 // PropertySetRegistry Implementation. 327 // 328 //========================================================================= 329 //========================================================================= 330 //========================================================================= 331 332 PropertySetRegistry::PropertySetRegistry( 333 const Reference< XMultiServiceFactory >& rXSMgr, 334 const Sequence< Any > &rInitArgs ) 335 : m_xSMgr( rXSMgr ), 336 m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) ) 337 { 338 } 339 340 //========================================================================= 341 // virtual 342 PropertySetRegistry::~PropertySetRegistry() 343 { 344 delete m_pImpl; 345 } 346 347 //========================================================================= 348 // 349 // XInterface methods. 350 // 351 //========================================================================= 352 353 XINTERFACE_IMPL_5( PropertySetRegistry, 354 XTypeProvider, 355 XServiceInfo, 356 XPropertySetRegistry, 357 XElementAccess, /* base of XNameAccess */ 358 XNameAccess ); 359 360 //========================================================================= 361 // 362 // XTypeProvider methods. 363 // 364 //========================================================================= 365 366 XTYPEPROVIDER_IMPL_4( PropertySetRegistry, 367 XTypeProvider, 368 XServiceInfo, 369 XPropertySetRegistry, 370 XNameAccess ); 371 372 //========================================================================= 373 // 374 // XServiceInfo methods. 375 // 376 //========================================================================= 377 378 XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry, 379 OUString::createFromAscii( 380 "com.sun.star.comp.ucb.PropertySetRegistry" ), 381 OUString::createFromAscii( 382 PROPSET_REG_SERVICE_NAME ) ); 383 384 //========================================================================= 385 // 386 // XPropertySetRegistry methods. 387 // 388 //========================================================================= 389 390 // virtual 391 Reference< XPersistentPropertySet > SAL_CALL 392 PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create ) 393 throw( RuntimeException ) 394 { 395 if ( key.getLength() ) 396 { 397 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 398 399 PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets; 400 401 PropertySetMap_Impl::const_iterator it = rSets.find( key ); 402 if ( it != rSets.end() ) 403 { 404 // Already instantiated. 405 return Reference< XPersistentPropertySet >( (*it).second ); 406 } 407 else 408 { 409 // Create new instance. 410 Reference< XNameAccess > xRootNameAccess( 411 getRootConfigReadAccess(), UNO_QUERY ); 412 if ( xRootNameAccess.is() ) 413 { 414 // Propertyset in registry? 415 if ( xRootNameAccess->hasByName( key ) ) 416 { 417 // Yep! 418 return Reference< XPersistentPropertySet >( 419 new PersistentPropertySet( 420 m_xSMgr, *this, key ) ); 421 } 422 else if ( create ) 423 { 424 // No. Create entry for propertyset. 425 426 Reference< XSingleServiceFactory > xFac( 427 getConfigWriteAccess( OUString() ), UNO_QUERY ); 428 Reference< XChangesBatch > xBatch( xFac, UNO_QUERY ); 429 Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); 430 431 OSL_ENSURE( xFac.is(), 432 "PropertySetRegistry::openPropertySet - " 433 "No factory!" ); 434 435 OSL_ENSURE( xBatch.is(), 436 "PropertySetRegistry::openPropertySet - " 437 "No batch!" ); 438 439 OSL_ENSURE( xContainer.is(), 440 "PropertySetRegistry::openPropertySet - " 441 "No container!" ); 442 443 if ( xFac.is() && xBatch.is() && xContainer.is() ) 444 { 445 try 446 { 447 // Create new "Properties" config item. 448 Reference< XNameReplace > xNameReplace( 449 xFac->createInstance(), UNO_QUERY ); 450 451 if ( xNameReplace.is() ) 452 { 453 // Fill new item... 454 455 // // Set Values 456 // xNameReplace->replaceByName( 457 // OUString::createFromAscii( "Values" ), 458 // makeAny( ... ) ); 459 460 // Insert new item. 461 xContainer->insertByName( 462 key, makeAny( xNameReplace ) ); 463 // Commit changes. 464 xBatch->commitChanges(); 465 466 return Reference< XPersistentPropertySet >( 467 new PersistentPropertySet( 468 m_xSMgr, *this, key ) ); 469 } 470 } 471 catch ( IllegalArgumentException& ) 472 { 473 // insertByName 474 475 OSL_ENSURE( sal_False, 476 "PropertySetRegistry::openPropertySet - " 477 "caught IllegalArgumentException!" ); 478 } 479 catch ( ElementExistException& ) 480 { 481 // insertByName 482 483 OSL_ENSURE( sal_False, 484 "PropertySetRegistry::openPropertySet - " 485 "caught ElementExistException!" ); 486 } 487 catch ( WrappedTargetException& ) 488 { 489 // insertByName, commitChanges 490 491 OSL_ENSURE( sal_False, 492 "PropertySetRegistry::openPropertySet - " 493 "caught WrappedTargetException!" ); 494 } 495 catch ( RuntimeException& ) 496 { 497 OSL_ENSURE( sal_False, 498 "PropertySetRegistry::openPropertySet - " 499 "caught RuntimeException!" ); 500 } 501 catch ( Exception& ) 502 { 503 // createInstance 504 505 OSL_ENSURE( sal_False, 506 "PropertySetRegistry::openPropertySet - " 507 "caught Exception!" ); 508 } 509 } 510 } 511 else 512 { 513 // No entry. Fail, but no error. 514 return Reference< XPersistentPropertySet >(); 515 } 516 } 517 518 OSL_ENSURE( sal_False, 519 "PropertySetRegistry::openPropertySet - Error!" ); 520 } 521 } 522 523 return Reference< XPersistentPropertySet >(); 524 } 525 526 //========================================================================= 527 // virtual 528 void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key ) 529 throw( RuntimeException ) 530 { 531 if ( !key.getLength() ) 532 return; 533 534 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 535 536 Reference< XNameAccess > xRootNameAccess( 537 getRootConfigReadAccess(), UNO_QUERY ); 538 if ( xRootNameAccess.is() ) 539 { 540 // Propertyset in registry? 541 if ( !xRootNameAccess->hasByName( key ) ) 542 return; 543 Reference< XChangesBatch > xBatch( 544 getConfigWriteAccess( OUString() ), UNO_QUERY ); 545 Reference< XNameContainer > xContainer( xBatch, UNO_QUERY ); 546 547 OSL_ENSURE( xBatch.is(), 548 "PropertySetRegistry::removePropertySet - " 549 "No batch!" ); 550 551 OSL_ENSURE( xContainer.is(), 552 "PropertySetRegistry::removePropertySet - " 553 "No container!" ); 554 555 if ( xBatch.is() && xContainer.is() ) 556 { 557 try 558 { 559 // Remove item. 560 xContainer->removeByName( key ); 561 // Commit changes. 562 xBatch->commitChanges(); 563 564 // Success. 565 return; 566 } 567 catch ( NoSuchElementException& ) 568 { 569 // removeByName 570 571 OSL_ENSURE( sal_False, 572 "PropertySetRegistry::removePropertySet - " 573 "caught NoSuchElementException!" ); 574 return; 575 } 576 catch ( WrappedTargetException& ) 577 { 578 // commitChanges 579 580 OSL_ENSURE( sal_False, 581 "PropertySetRegistry::removePropertySet - " 582 "caught WrappedTargetException!" ); 583 return; 584 } 585 } 586 587 return; 588 } 589 590 OSL_ENSURE( sal_False, "PropertySetRegistry::removePropertySet - Error!" ); 591 } 592 593 //========================================================================= 594 // 595 // XElementAccess methods. 596 // 597 //========================================================================= 598 599 // virtual 600 com::sun::star::uno::Type SAL_CALL PropertySetRegistry::getElementType() 601 throw( RuntimeException ) 602 { 603 return getCppuType( ( Reference< XPersistentPropertySet > * ) 0 ); 604 } 605 606 //========================================================================= 607 // virtual 608 sal_Bool SAL_CALL PropertySetRegistry::hasElements() 609 throw( RuntimeException ) 610 { 611 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 612 613 Reference< XElementAccess > xElemAccess( 614 getRootConfigReadAccess(), UNO_QUERY ); 615 if ( xElemAccess.is() ) 616 return xElemAccess->hasElements(); 617 618 return sal_False; 619 } 620 621 //========================================================================= 622 // 623 // XNameAccess methods. 624 // 625 //========================================================================= 626 627 // virtual 628 Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName ) 629 throw( NoSuchElementException, WrappedTargetException, RuntimeException ) 630 { 631 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 632 633 Reference< XNameAccess > xNameAccess( 634 getRootConfigReadAccess(), UNO_QUERY ); 635 if ( xNameAccess.is() ) 636 { 637 638 try 639 { 640 return xNameAccess->getByName( aName ); 641 } 642 catch ( NoSuchElementException& ) 643 { 644 // getByName 645 } 646 catch ( WrappedTargetException& ) 647 { 648 // getByName 649 } 650 } 651 652 return Any(); 653 } 654 655 //========================================================================= 656 // virtual 657 Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames() 658 throw( RuntimeException ) 659 { 660 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 661 662 Reference< XNameAccess > xNameAccess( 663 getRootConfigReadAccess(), UNO_QUERY ); 664 if ( xNameAccess.is() ) 665 { 666 return xNameAccess->getElementNames(); 667 } 668 return Sequence< OUString >( 0 ); 669 } 670 671 //========================================================================= 672 // virtual 673 sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName ) 674 throw( RuntimeException ) 675 { 676 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 677 678 Reference< XNameAccess > xNameAccess( 679 getRootConfigReadAccess(), UNO_QUERY ); 680 if ( xNameAccess.is() ) 681 { 682 return xNameAccess->hasByName( aName ); 683 } 684 685 return sal_False; 686 } 687 688 //========================================================================= 689 void PropertySetRegistry::add( PersistentPropertySet* pSet ) 690 { 691 OUString key( pSet->getKey() ); 692 693 if ( key.getLength() ) 694 { 695 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 696 m_pImpl->m_aPropSets[ key ] = pSet; 697 } 698 } 699 700 //========================================================================= 701 void PropertySetRegistry::remove( PersistentPropertySet* pSet ) 702 { 703 OUString key( pSet->getKey() ); 704 705 if ( key.getLength() ) 706 { 707 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 708 709 PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets; 710 711 PropertySetMap_Impl::iterator it = rSets.find( key ); 712 if ( it != rSets.end() ) 713 { 714 // Found. 715 rSets.erase( it ); 716 } 717 } 718 } 719 720 //========================================================================= 721 void PropertySetRegistry::renamePropertySet( const OUString& rOldKey, 722 const OUString& rNewKey ) 723 { 724 if ( rOldKey == rNewKey ) 725 return; 726 727 Reference< XNameAccess > xRootNameAccess( 728 getConfigWriteAccess( OUString() ), UNO_QUERY ); 729 if ( xRootNameAccess.is() ) 730 { 731 // Old key present? 732 if ( xRootNameAccess->hasByName( rOldKey ) ) 733 { 734 // New key not present? 735 if ( xRootNameAccess->hasByName( rNewKey ) ) 736 { 737 OSL_ENSURE( sal_False, 738 "PropertySetRegistry::renamePropertySet - " 739 "New key exists!" ); 740 return; 741 } 742 Reference< XSingleServiceFactory > xFac( 743 xRootNameAccess, UNO_QUERY ); 744 Reference< XChangesBatch > xBatch( xFac, UNO_QUERY ); 745 Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); 746 747 OSL_ENSURE( xFac.is(), 748 "PropertySetRegistry::renamePropertySet - " 749 "No factory!" ); 750 751 OSL_ENSURE( xBatch.is(), 752 "PropertySetRegistry::renamePropertySet - " 753 "No batch!" ); 754 755 OSL_ENSURE( xContainer.is(), 756 "PropertySetRegistry::renamePropertySet - " 757 "No container!" ); 758 759 if ( xFac.is() && xBatch.is() && xContainer.is() ) 760 { 761 ////////////////////////////////////////////////////// 762 // Create new "Properties" config item. 763 ////////////////////////////////////////////////////// 764 765 try 766 { 767 Reference< XNameReplace > xNameReplace( 768 xFac->createInstance(), UNO_QUERY ); 769 770 if ( xNameReplace.is() ) 771 { 772 // Insert new item. 773 xContainer->insertByName( 774 rNewKey, makeAny( xNameReplace ) ); 775 // Commit changes. 776 xBatch->commitChanges(); 777 } 778 } 779 catch ( IllegalArgumentException& ) 780 { 781 // insertByName 782 783 OSL_ENSURE( sal_False, 784 "PropertySetRegistry::renamePropertySet - " 785 "caught IllegalArgumentException!" ); 786 return; 787 } 788 catch ( ElementExistException& ) 789 { 790 // insertByName 791 792 OSL_ENSURE( sal_False, 793 "PropertySetRegistry::renamePropertySet - " 794 "caught ElementExistException!" ); 795 return; 796 } 797 catch ( WrappedTargetException& ) 798 { 799 // insertByName, commitChanges 800 801 OSL_ENSURE( sal_False, 802 "PropertySetRegistry::renamePropertySet - " 803 "caught WrappedTargetException!" ); 804 return; 805 } 806 catch ( RuntimeException& ) 807 { 808 OSL_ENSURE( sal_False, 809 "PropertySetRegistry::renamePropertySet - " 810 "caught RuntimeException!" ); 811 return; 812 } 813 catch ( Exception& ) 814 { 815 // createInstance 816 817 OSL_ENSURE( sal_False, 818 "PropertySetRegistry::renamePropertySet - " 819 "caught Exception!" ); 820 return; 821 } 822 823 ////////////////////////////////////////////////////// 824 // Copy data... 825 ////////////////////////////////////////////////////// 826 827 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 828 xRootNameAccess, UNO_QUERY ); 829 if ( !xRootHierNameAccess.is() ) 830 { 831 OSL_ENSURE( sal_False, 832 "PropertySetRegistry::renamePropertySet - " 833 "No hierarchical name access!" ); 834 return; 835 } 836 837 try 838 { 839 rtl::OUString aOldValuesKey 840 = makeHierarchalNameSegment( rOldKey ); 841 aOldValuesKey += OUString::createFromAscii( "/Values" ); 842 843 Reference< XNameAccess > xOldNameAccess; 844 xRootHierNameAccess->getByHierarchicalName( 845 aOldValuesKey ) 846 >>= xOldNameAccess; 847 if ( !xOldNameAccess.is() ) 848 { 849 OSL_ENSURE( sal_False, 850 "PersistentPropertySet::renamePropertySet - " 851 "No old name access!" ); 852 return; 853 } 854 855 // Obtain property names. 856 Sequence< OUString > aElems 857 = xOldNameAccess->getElementNames(); 858 sal_Int32 nCount = aElems.getLength(); 859 if ( nCount ) 860 { 861 rtl::OUString aNewValuesKey 862 = makeHierarchalNameSegment( rNewKey ); 863 aNewValuesKey += OUString::createFromAscii( "/Values" ); 864 865 Reference< XSingleServiceFactory > xNewFac; 866 xRootHierNameAccess->getByHierarchicalName( 867 aNewValuesKey ) 868 >>= xNewFac; 869 if ( !xNewFac.is() ) 870 { 871 OSL_ENSURE( sal_False, 872 "PersistentPropertySet::renamePropertySet - " 873 "No new factory!" ); 874 return; 875 } 876 877 Reference< XNameContainer > xNewContainer( 878 xNewFac, UNO_QUERY ); 879 if ( !xNewContainer.is() ) 880 { 881 OSL_ENSURE( sal_False, 882 "PersistentPropertySet::renamePropertySet - " 883 "No new container!" ); 884 return; 885 } 886 887 aOldValuesKey += OUString::createFromAscii( "/" ); 888 889 OUString aHandleKey 890 = OUString::createFromAscii( "/Handle" ); 891 OUString aValueKey 892 = OUString::createFromAscii( "/Value" ); 893 OUString aStateKey 894 = OUString::createFromAscii( "/State" ); 895 OUString aAttrKey 896 = OUString::createFromAscii( "/Attributes" ); 897 898 for ( sal_Int32 n = 0; n < nCount; ++n ) 899 { 900 const OUString& rPropName = aElems[ n ]; 901 902 // Create new item. 903 Reference< XNameReplace > xNewPropNameReplace( 904 xNewFac->createInstance(), UNO_QUERY ); 905 906 if ( !xNewPropNameReplace.is() ) 907 { 908 OSL_ENSURE( sal_False, 909 "PersistentPropertySet::renamePropertySet - " 910 "No new prop name replace!" ); 911 return; 912 } 913 914 // Fill new item... 915 916 // Set Values 917 OUString aKey = aOldValuesKey; 918 aKey += makeHierarchalNameSegment( rPropName ); 919 920 // ... handle 921 OUString aNewKey1 = aKey; 922 aNewKey1 += aHandleKey; 923 Any aAny = 924 xRootHierNameAccess->getByHierarchicalName( 925 aNewKey1 ); 926 xNewPropNameReplace->replaceByName( 927 OUString::createFromAscii( "Handle" ), 928 aAny ); 929 930 // ... value 931 aNewKey1 = aKey; 932 aNewKey1 += aValueKey; 933 aAny = 934 xRootHierNameAccess->getByHierarchicalName( 935 aNewKey1 ); 936 xNewPropNameReplace->replaceByName( 937 OUString::createFromAscii( "Value" ), 938 aAny ); 939 940 // ... state 941 aNewKey1 = aKey; 942 aNewKey1 += aStateKey; 943 aAny = 944 xRootHierNameAccess->getByHierarchicalName( 945 aNewKey1 ); 946 xNewPropNameReplace->replaceByName( 947 OUString::createFromAscii( "State" ), 948 aAny ); 949 950 // ... attributes 951 aNewKey1 = aKey; 952 aNewKey1 += aAttrKey; 953 aAny = 954 xRootHierNameAccess->getByHierarchicalName( 955 aNewKey1 ); 956 xNewPropNameReplace->replaceByName( 957 OUString::createFromAscii( "Attributes" ), 958 aAny ); 959 960 // Insert new item. 961 xNewContainer->insertByName( 962 rPropName, makeAny( xNewPropNameReplace ) ); 963 964 // Commit changes. 965 xBatch->commitChanges(); 966 } 967 } 968 } 969 catch ( IllegalArgumentException& ) 970 { 971 // insertByName, replaceByName 972 973 OSL_ENSURE( sal_False, 974 "PropertySetRegistry::renamePropertySet - " 975 "caught IllegalArgumentException!" ); 976 return; 977 } 978 catch ( ElementExistException& ) 979 { 980 // insertByName 981 982 OSL_ENSURE( sal_False, 983 "PropertySetRegistry::renamePropertySet - " 984 "caught ElementExistException!" ); 985 return; 986 } 987 catch ( WrappedTargetException& ) 988 { 989 // insertByName, replaceByName, commitChanges 990 991 OSL_ENSURE( sal_False, 992 "PropertySetRegistry::renamePropertySet - " 993 "caught WrappedTargetException!" ); 994 return; 995 } 996 catch ( NoSuchElementException& ) 997 { 998 // getByHierarchicalName, replaceByName 999 1000 OSL_ENSURE( sal_False, 1001 "PropertySetRegistry::renamePropertySet - " 1002 "caught NoSuchElementException!" ); 1003 return; 1004 } 1005 catch ( RuntimeException& ) 1006 { 1007 OSL_ENSURE( sal_False, 1008 "PropertySetRegistry::renamePropertySet - " 1009 "caught RuntimeException!" ); 1010 return; 1011 } 1012 catch ( Exception& ) 1013 { 1014 // createInstance 1015 1016 OSL_ENSURE( sal_False, 1017 "PropertySetRegistry::renamePropertySet - " 1018 "caught Exception!" ); 1019 return; 1020 } 1021 1022 ////////////////////////////////////////////////////// 1023 // Remove old entry... 1024 ////////////////////////////////////////////////////// 1025 1026 try 1027 { 1028 // Remove item. 1029 xContainer->removeByName( rOldKey ); 1030 // Commit changes. 1031 xBatch->commitChanges(); 1032 1033 // Success. 1034 return; 1035 } 1036 catch ( NoSuchElementException& ) 1037 { 1038 // removeByName 1039 1040 OSL_ENSURE( sal_False, 1041 "PropertySetRegistry::renamePropertySet - " 1042 "caught NoSuchElementException!" ); 1043 return; 1044 } 1045 catch ( WrappedTargetException& ) 1046 { 1047 // commitChanges 1048 1049 OSL_ENSURE( sal_False, 1050 "PropertySetRegistry::renamePropertySet - " 1051 "caught WrappedTargetException!" ); 1052 return; 1053 } 1054 } 1055 } 1056 } 1057 1058 OSL_ENSURE( sal_False, "PropertySetRegistry::renamePropertySet - Error!" ); 1059 } 1060 1061 //========================================================================= 1062 Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider() 1063 { 1064 if ( !m_pImpl->m_xConfigProvider.is() ) 1065 { 1066 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1067 if ( !m_pImpl->m_xConfigProvider.is() ) 1068 { 1069 const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs; 1070 1071 if ( rInitArgs.getLength() > 0 ) 1072 { 1073 // Extract config provider from service init args. 1074 rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider; 1075 1076 OSL_ENSURE( m_pImpl->m_xConfigProvider.is(), 1077 "PropertySetRegistry::getConfigProvider - " 1078 "No config provider!" ); 1079 } 1080 else 1081 { 1082 try 1083 { 1084 m_pImpl->m_xConfigProvider 1085 = Reference< XMultiServiceFactory >( 1086 m_xSMgr->createInstance( 1087 OUString::createFromAscii( 1088 "com.sun.star.configuration." 1089 "ConfigurationProvider" ) ), 1090 UNO_QUERY ); 1091 1092 OSL_ENSURE( m_pImpl->m_xConfigProvider.is(), 1093 "PropertySetRegistry::getConfigProvider - " 1094 "No config provider!" ); 1095 1096 } 1097 catch ( Exception& ) 1098 { 1099 OSL_ENSURE( sal_False, 1100 "PropertySetRegistry::getConfigProvider - " 1101 "caught exception!" ); 1102 } 1103 } 1104 } 1105 } 1106 1107 return m_pImpl->m_xConfigProvider; 1108 } 1109 1110 //========================================================================= 1111 Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess() 1112 { 1113 try 1114 { 1115 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1116 1117 if ( !m_pImpl->m_xRootReadAccess.is() ) 1118 { 1119 if ( m_pImpl->m_bTriedToGetRootReadAccess ) // #82494# 1120 { 1121 OSL_ENSURE( sal_False, 1122 "PropertySetRegistry::getRootConfigReadAccess - " 1123 "Unable to read any config data! -> #82494#" ); 1124 return Reference< XInterface >(); 1125 } 1126 1127 getConfigProvider(); 1128 1129 if ( m_pImpl->m_xConfigProvider.is() ) 1130 { 1131 Sequence< Any > aArguments( 1 ); 1132 PropertyValue aProperty; 1133 aProperty.Name 1134 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 1135 CFGPROPERTY_NODEPATH ) ); 1136 aProperty.Value 1137 <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 1138 STORE_CONTENTPROPERTIES_KEY ) ); 1139 aArguments[ 0 ] <<= aProperty; 1140 1141 m_pImpl->m_bTriedToGetRootReadAccess = sal_True; 1142 1143 m_pImpl->m_xRootReadAccess = 1144 m_pImpl->m_xConfigProvider->createInstanceWithArguments( 1145 OUString::createFromAscii( 1146 "com.sun.star.configuration.ConfigurationAccess" ), 1147 aArguments ); 1148 1149 if ( m_pImpl->m_xRootReadAccess.is() ) 1150 return m_pImpl->m_xRootReadAccess; 1151 } 1152 } 1153 else 1154 return m_pImpl->m_xRootReadAccess; 1155 } 1156 catch ( RuntimeException& ) 1157 { 1158 throw; 1159 } 1160 catch ( Exception& ) 1161 { 1162 // createInstance, createInstanceWithArguments 1163 1164 OSL_ENSURE( sal_False, 1165 "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" ); 1166 return Reference< XInterface >(); 1167 } 1168 1169 OSL_ENSURE( sal_False, 1170 "PropertySetRegistry::getRootConfigReadAccess - Error!" ); 1171 return Reference< XInterface >(); 1172 } 1173 1174 //========================================================================= 1175 Reference< XInterface > PropertySetRegistry::getConfigWriteAccess( 1176 const OUString& rPath ) 1177 { 1178 try 1179 { 1180 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1181 1182 if ( !m_pImpl->m_xRootWriteAccess.is() ) 1183 { 1184 if ( m_pImpl->m_bTriedToGetRootWriteAccess ) // #82494# 1185 { 1186 OSL_ENSURE( sal_False, 1187 "PropertySetRegistry::getConfigWriteAccess - " 1188 "Unable to write any config data! -> #82494#" ); 1189 return Reference< XInterface >(); 1190 } 1191 1192 getConfigProvider(); 1193 1194 if ( m_pImpl->m_xConfigProvider.is() ) 1195 { 1196 Sequence< Any > aArguments( 2 ); 1197 PropertyValue aProperty; 1198 1199 aProperty.Name 1200 = OUString( RTL_CONSTASCII_USTRINGPARAM( 1201 CFGPROPERTY_NODEPATH ) ); 1202 aProperty.Value 1203 <<= OUString( RTL_CONSTASCII_USTRINGPARAM( 1204 STORE_CONTENTPROPERTIES_KEY ) ); 1205 aArguments[ 0 ] <<= aProperty; 1206 1207 aProperty.Name 1208 = OUString( RTL_CONSTASCII_USTRINGPARAM( 1209 CFGPROPERTY_LAZYWRITE ) ); 1210 aProperty.Value <<= sal_True; 1211 aArguments[ 1 ] <<= aProperty; 1212 1213 m_pImpl->m_bTriedToGetRootWriteAccess = sal_True; 1214 1215 m_pImpl->m_xRootWriteAccess = 1216 m_pImpl->m_xConfigProvider->createInstanceWithArguments( 1217 OUString::createFromAscii( 1218 "com.sun.star.configuration.ConfigurationUpdateAccess" ), 1219 aArguments ); 1220 1221 OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(), 1222 "PropertySetRegistry::getConfigWriteAccess - " 1223 "No config update access!" ); 1224 } 1225 } 1226 1227 if ( m_pImpl->m_xRootWriteAccess.is() ) 1228 { 1229 if ( rPath.getLength() ) 1230 { 1231 Reference< XHierarchicalNameAccess > xNA( 1232 m_pImpl->m_xRootWriteAccess, UNO_QUERY ); 1233 if ( xNA.is() ) 1234 { 1235 Reference< XInterface > xInterface; 1236 xNA->getByHierarchicalName( rPath ) >>= xInterface; 1237 1238 if ( xInterface.is() ) 1239 return xInterface; 1240 } 1241 } 1242 else 1243 return m_pImpl->m_xRootWriteAccess; 1244 } 1245 } 1246 catch ( RuntimeException& ) 1247 { 1248 throw; 1249 } 1250 catch ( NoSuchElementException& ) 1251 { 1252 // getByHierarchicalName 1253 1254 OSL_ENSURE( sal_False, 1255 "PropertySetRegistry::getConfigWriteAccess - " 1256 "caught NoSuchElementException!" ); 1257 return Reference< XInterface >(); 1258 } 1259 catch ( Exception& ) 1260 { 1261 // createInstance, createInstanceWithArguments 1262 1263 OSL_ENSURE( sal_False, 1264 "PropertySetRegistry::getConfigWriteAccess - " 1265 "caught Exception!" ); 1266 return Reference< XInterface >(); 1267 } 1268 1269 OSL_ENSURE( sal_False, 1270 "PropertySetRegistry::getConfigWriteAccess - Error!" ); 1271 return Reference< XInterface >(); 1272 } 1273 1274 //========================================================================= 1275 // 1276 // PropertyListeners_Impl. 1277 // 1278 //========================================================================= 1279 1280 typedef OMultiTypeInterfaceContainerHelperVar 1281 < 1282 OUString, 1283 hashString_Impl, 1284 equalString_Impl 1285 > PropertyListeners_Impl; 1286 1287 //========================================================================= 1288 // 1289 // PersistentPropertySet_Impl. 1290 // 1291 //========================================================================= 1292 1293 struct PersistentPropertySet_Impl 1294 { 1295 PropertySetRegistry* m_pCreator; 1296 PropertySetInfo_Impl* m_pInfo; 1297 OUString m_aKey; 1298 OUString m_aFullKey; 1299 osl::Mutex m_aMutex; 1300 OInterfaceContainerHelper* m_pDisposeEventListeners; 1301 OInterfaceContainerHelper* m_pPropSetChangeListeners; 1302 PropertyListeners_Impl* m_pPropertyChangeListeners; 1303 1304 PersistentPropertySet_Impl( PropertySetRegistry& rCreator, 1305 const OUString& rKey ) 1306 : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ), 1307 m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ), 1308 m_pPropertyChangeListeners( NULL ) 1309 { 1310 m_pCreator->acquire(); 1311 } 1312 1313 ~PersistentPropertySet_Impl() 1314 { 1315 m_pCreator->release(); 1316 1317 if ( m_pInfo ) 1318 m_pInfo->release(); 1319 1320 delete m_pDisposeEventListeners; 1321 delete m_pPropSetChangeListeners; 1322 delete m_pPropertyChangeListeners; 1323 } 1324 }; 1325 1326 //========================================================================= 1327 //========================================================================= 1328 //========================================================================= 1329 // 1330 // PersistentPropertySet Implementation. 1331 // 1332 //========================================================================= 1333 //========================================================================= 1334 //========================================================================= 1335 1336 PersistentPropertySet::PersistentPropertySet( 1337 const Reference< XMultiServiceFactory >& rXSMgr, 1338 PropertySetRegistry& rCreator, 1339 const OUString& rKey ) 1340 : m_xSMgr( rXSMgr ), 1341 m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) ) 1342 { 1343 // register at creator. 1344 rCreator.add( this ); 1345 } 1346 1347 //========================================================================= 1348 // virtual 1349 PersistentPropertySet::~PersistentPropertySet() 1350 { 1351 // deregister at creator. 1352 m_pImpl->m_pCreator->remove( this ); 1353 1354 delete m_pImpl; 1355 } 1356 1357 //========================================================================= 1358 // 1359 // XInterface methods. 1360 // 1361 //========================================================================= 1362 1363 XINTERFACE_IMPL_9( PersistentPropertySet, 1364 XTypeProvider, 1365 XServiceInfo, 1366 XComponent, 1367 XPropertySet, /* base of XPersistentPropertySet */ 1368 XNamed, 1369 XPersistentPropertySet, 1370 XPropertyContainer, 1371 XPropertySetInfoChangeNotifier, 1372 XPropertyAccess ); 1373 1374 //========================================================================= 1375 // 1376 // XTypeProvider methods. 1377 // 1378 //========================================================================= 1379 1380 XTYPEPROVIDER_IMPL_8( PersistentPropertySet, 1381 XTypeProvider, 1382 XServiceInfo, 1383 XComponent, 1384 XPersistentPropertySet, 1385 XNamed, 1386 XPropertyContainer, 1387 XPropertySetInfoChangeNotifier, 1388 XPropertyAccess ); 1389 1390 //========================================================================= 1391 // 1392 // XServiceInfo methods. 1393 // 1394 //========================================================================= 1395 1396 XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet, 1397 OUString::createFromAscii( 1398 "com.sun.star.comp.ucb.PersistentPropertySet" ), 1399 OUString::createFromAscii( 1400 PERS_PROPSET_SERVICE_NAME ) ); 1401 1402 //========================================================================= 1403 // 1404 // XComponent methods. 1405 // 1406 //========================================================================= 1407 1408 // virtual 1409 void SAL_CALL PersistentPropertySet::dispose() 1410 throw( RuntimeException ) 1411 { 1412 if ( m_pImpl->m_pDisposeEventListeners && 1413 m_pImpl->m_pDisposeEventListeners->getLength() ) 1414 { 1415 EventObject aEvt; 1416 aEvt.Source = static_cast< XComponent * >( this ); 1417 m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt ); 1418 } 1419 1420 if ( m_pImpl->m_pPropSetChangeListeners && 1421 m_pImpl->m_pPropSetChangeListeners->getLength() ) 1422 { 1423 EventObject aEvt; 1424 aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this ); 1425 m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt ); 1426 } 1427 1428 if ( m_pImpl->m_pPropertyChangeListeners ) 1429 { 1430 EventObject aEvt; 1431 aEvt.Source = static_cast< XPropertySet * >( this ); 1432 m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt ); 1433 } 1434 } 1435 1436 //========================================================================= 1437 // virtual 1438 void SAL_CALL PersistentPropertySet::addEventListener( 1439 const Reference< XEventListener >& Listener ) 1440 throw( RuntimeException ) 1441 { 1442 if ( !m_pImpl->m_pDisposeEventListeners ) 1443 m_pImpl->m_pDisposeEventListeners = 1444 new OInterfaceContainerHelper( m_pImpl->m_aMutex ); 1445 1446 m_pImpl->m_pDisposeEventListeners->addInterface( Listener ); 1447 } 1448 1449 //========================================================================= 1450 // virtual 1451 void SAL_CALL PersistentPropertySet::removeEventListener( 1452 const Reference< XEventListener >& Listener ) 1453 throw( RuntimeException ) 1454 { 1455 if ( m_pImpl->m_pDisposeEventListeners ) 1456 m_pImpl->m_pDisposeEventListeners->removeInterface( Listener ); 1457 1458 // Note: Don't want to delete empty container here -> performance. 1459 } 1460 1461 //========================================================================= 1462 // 1463 // XPropertySet methods. 1464 // 1465 //========================================================================= 1466 1467 // virtual 1468 Reference< XPropertySetInfo > SAL_CALL 1469 PersistentPropertySet::getPropertySetInfo() 1470 throw( RuntimeException ) 1471 { 1472 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1473 1474 PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo; 1475 if ( !rpInfo ) 1476 { 1477 rpInfo = new PropertySetInfo_Impl( m_xSMgr, this ); 1478 rpInfo->acquire(); 1479 } 1480 return Reference< XPropertySetInfo >( rpInfo ); 1481 } 1482 1483 //========================================================================= 1484 // virtual 1485 void SAL_CALL PersistentPropertySet::setPropertyValue( 1486 const OUString& aPropertyName, const Any& aValue ) 1487 throw( UnknownPropertyException, 1488 PropertyVetoException, 1489 IllegalArgumentException, 1490 WrappedTargetException, 1491 RuntimeException ) 1492 { 1493 if ( !aPropertyName.getLength() ) 1494 throw UnknownPropertyException(); 1495 1496 osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex ); 1497 1498 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 1499 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); 1500 if ( xRootHierNameAccess.is() ) 1501 { 1502 OUString aFullPropName( getFullKey() ); 1503 aFullPropName += OUString::createFromAscii( "/" ); 1504 aFullPropName += makeHierarchalNameSegment( aPropertyName ); 1505 1506 // Does property exist? 1507 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) 1508 { 1509 Reference< XNameReplace > xNameReplace( 1510 m_pImpl->m_pCreator->getConfigWriteAccess( 1511 aFullPropName ), UNO_QUERY ); 1512 Reference< XChangesBatch > xBatch( 1513 m_pImpl->m_pCreator->getConfigWriteAccess( 1514 OUString() ), UNO_QUERY ); 1515 1516 if ( xNameReplace.is() && xBatch.is() ) 1517 { 1518 try 1519 { 1520 // Obtain old value 1521 OUString aValueName = aFullPropName; 1522 aValueName += OUString::createFromAscii( "/Value" ); 1523 Any aOldValue 1524 = xRootHierNameAccess->getByHierarchicalName( 1525 aValueName ); 1526 // Check value type. 1527 if ( aOldValue.getValueType() != aValue.getValueType() ) 1528 { 1529 aCGuard.clear(); 1530 throw IllegalArgumentException(); 1531 } 1532 1533 // Write value 1534 xNameReplace->replaceByName( 1535 OUString::createFromAscii( "Value" ), 1536 aValue ); 1537 1538 // Write state ( Now it is a directly set value ) 1539 xNameReplace->replaceByName( 1540 OUString::createFromAscii( "State" ), 1541 makeAny( 1542 sal_Int32( 1543 PropertyState_DIRECT_VALUE ) ) ); 1544 1545 // Commit changes. 1546 xBatch->commitChanges(); 1547 1548 PropertyChangeEvent aEvt; 1549 if ( m_pImpl->m_pPropertyChangeListeners ) 1550 { 1551 // Obtain handle 1552 aValueName = aFullPropName; 1553 aValueName += OUString::createFromAscii( "/Handle" ); 1554 sal_Int32 nHandle = -1; 1555 xRootHierNameAccess->getByHierarchicalName( aValueName ) 1556 >>= nHandle; 1557 1558 aEvt.Source = (OWeakObject*)this; 1559 aEvt.PropertyName = aPropertyName; 1560 aEvt.PropertyHandle = nHandle; 1561 aEvt.Further = sal_False; 1562 aEvt.OldValue = aOldValue; 1563 aEvt.NewValue = aValue; 1564 1565 // Callback follows! 1566 aCGuard.clear(); 1567 1568 notifyPropertyChangeEvent( aEvt ); 1569 } 1570 return; 1571 } 1572 catch ( IllegalArgumentException& ) 1573 { 1574 // replaceByName 1575 } 1576 catch ( NoSuchElementException& ) 1577 { 1578 // getByHierarchicalName, replaceByName 1579 } 1580 catch ( WrappedTargetException& ) 1581 { 1582 // replaceByName, commitChanges 1583 } 1584 } 1585 } 1586 } 1587 1588 throw UnknownPropertyException(); 1589 } 1590 1591 //========================================================================= 1592 // virtual 1593 Any SAL_CALL PersistentPropertySet::getPropertyValue( 1594 const OUString& PropertyName ) 1595 throw( UnknownPropertyException, 1596 WrappedTargetException, 1597 RuntimeException ) 1598 { 1599 if ( !PropertyName.getLength() ) 1600 throw UnknownPropertyException(); 1601 1602 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1603 1604 Reference< XHierarchicalNameAccess > xNameAccess( 1605 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); 1606 if ( xNameAccess.is() ) 1607 { 1608 OUString aFullPropName( getFullKey() ); 1609 aFullPropName += OUString::createFromAscii( "/" ); 1610 aFullPropName += makeHierarchalNameSegment( PropertyName ); 1611 aFullPropName += OUString::createFromAscii( "/Value" ); 1612 try 1613 { 1614 return xNameAccess->getByHierarchicalName( aFullPropName ); 1615 } 1616 catch ( NoSuchElementException& ) 1617 { 1618 throw UnknownPropertyException(); 1619 } 1620 } 1621 1622 throw UnknownPropertyException(); 1623 } 1624 1625 //========================================================================= 1626 // virtual 1627 void SAL_CALL PersistentPropertySet::addPropertyChangeListener( 1628 const OUString& aPropertyName, 1629 const Reference< XPropertyChangeListener >& xListener ) 1630 throw( UnknownPropertyException, 1631 WrappedTargetException, 1632 RuntimeException ) 1633 { 1634 // load(); 1635 1636 if ( !m_pImpl->m_pPropertyChangeListeners ) 1637 m_pImpl->m_pPropertyChangeListeners = 1638 new PropertyListeners_Impl( m_pImpl->m_aMutex ); 1639 1640 m_pImpl->m_pPropertyChangeListeners->addInterface( 1641 aPropertyName, xListener ); 1642 } 1643 1644 //========================================================================= 1645 // virtual 1646 void SAL_CALL PersistentPropertySet::removePropertyChangeListener( 1647 const OUString& aPropertyName, 1648 const Reference< XPropertyChangeListener >& aListener ) 1649 throw( UnknownPropertyException, 1650 WrappedTargetException, 1651 RuntimeException ) 1652 { 1653 // load(); 1654 1655 if ( m_pImpl->m_pPropertyChangeListeners ) 1656 m_pImpl->m_pPropertyChangeListeners->removeInterface( 1657 aPropertyName, aListener ); 1658 1659 // Note: Don't want to delete empty container here -> performance. 1660 } 1661 1662 //========================================================================= 1663 // virtual 1664 void SAL_CALL PersistentPropertySet::addVetoableChangeListener( 1665 const OUString&, 1666 const Reference< XVetoableChangeListener >& ) 1667 throw( UnknownPropertyException, 1668 WrappedTargetException, 1669 RuntimeException ) 1670 { 1671 // load(); 1672 // OSL_ENSURE( sal_False, 1673 // "PersistentPropertySet::addVetoableChangeListener - N.Y.I." ); 1674 } 1675 1676 //========================================================================= 1677 // virtual 1678 void SAL_CALL PersistentPropertySet::removeVetoableChangeListener( 1679 const OUString&, 1680 const Reference< XVetoableChangeListener >& ) 1681 throw( UnknownPropertyException, 1682 WrappedTargetException, 1683 RuntimeException ) 1684 { 1685 // load(); 1686 // OSL_ENSURE( sal_False, 1687 // "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." ); 1688 } 1689 1690 //========================================================================= 1691 // 1692 // XPersistentPropertySet methods. 1693 // 1694 //========================================================================= 1695 1696 // virtual 1697 Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry() 1698 throw( RuntimeException ) 1699 { 1700 return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator ); 1701 } 1702 1703 //========================================================================= 1704 // virtual 1705 OUString SAL_CALL PersistentPropertySet::getKey() 1706 throw( RuntimeException ) 1707 { 1708 return m_pImpl->m_aKey; 1709 } 1710 1711 //========================================================================= 1712 // 1713 // XNamed methods. 1714 // 1715 //========================================================================= 1716 1717 // virtual 1718 rtl::OUString SAL_CALL PersistentPropertySet::getName() 1719 throw( RuntimeException ) 1720 { 1721 // same as getKey() 1722 return m_pImpl->m_aKey; 1723 } 1724 1725 //========================================================================= 1726 // virtual 1727 void SAL_CALL PersistentPropertySet::setName( const OUString& aName ) 1728 throw( RuntimeException ) 1729 { 1730 if ( aName != m_pImpl->m_aKey ) 1731 m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName ); 1732 } 1733 1734 //========================================================================= 1735 // 1736 // XPropertyContainer methods. 1737 // 1738 //========================================================================= 1739 1740 // virtual 1741 void SAL_CALL PersistentPropertySet::addProperty( 1742 const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue ) 1743 throw( PropertyExistException, 1744 IllegalTypeException, 1745 IllegalArgumentException, 1746 RuntimeException ) 1747 { 1748 if ( !Name.getLength() ) 1749 throw IllegalArgumentException(); 1750 1751 // @@@ What other types can't be written to config server? 1752 1753 // Check type class ( Not all types can be written to storage ) 1754 TypeClass eTypeClass = DefaultValue.getValueTypeClass(); 1755 if ( eTypeClass == TypeClass_INTERFACE ) 1756 throw IllegalTypeException(); 1757 1758 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1759 1760 // Property already in set? 1761 1762 OUString aFullValuesName; 1763 1764 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 1765 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); 1766 if ( xRootHierNameAccess.is() ) 1767 { 1768 aFullValuesName = getFullKey(); 1769 OUString aFullPropName = aFullValuesName; 1770 aFullPropName += OUString::createFromAscii( "/" ); 1771 aFullPropName += makeHierarchalNameSegment( Name ); 1772 1773 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) 1774 { 1775 // Already in set. 1776 throw PropertyExistException(); 1777 } 1778 } 1779 1780 // Property is always removeable. 1781 Attributes |= PropertyAttribute::REMOVEABLE; 1782 1783 // Add property. 1784 1785 Reference< XSingleServiceFactory > xFac( 1786 m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ), 1787 UNO_QUERY ); 1788 Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); 1789 Reference< XChangesBatch > xBatch( 1790 m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ), 1791 UNO_QUERY ); 1792 1793 OSL_ENSURE( xFac.is(), 1794 "PersistentPropertySet::addProperty - No factory!" ); 1795 1796 OSL_ENSURE( xBatch.is(), 1797 "PersistentPropertySet::addProperty - No batch!" ); 1798 1799 OSL_ENSURE( xContainer.is(), 1800 "PersistentPropertySet::addProperty - No container!" ); 1801 1802 if ( xFac.is() && xBatch.is() && xContainer.is() ) 1803 { 1804 try 1805 { 1806 // Create new "PropertyValue" config item. 1807 Reference< XNameReplace > xNameReplace( 1808 xFac->createInstance(), UNO_QUERY ); 1809 1810 if ( xNameReplace.is() ) 1811 { 1812 // Fill new item... 1813 1814 // Set handle 1815 xNameReplace->replaceByName( 1816 OUString::createFromAscii( "Handle" ), 1817 makeAny( sal_Int32( -1 ) ) ); 1818 1819 // Set default value 1820 xNameReplace->replaceByName( 1821 OUString::createFromAscii( "Value" ), 1822 DefaultValue ); 1823 1824 // Set state ( always "default" ) 1825 xNameReplace->replaceByName( 1826 OUString::createFromAscii( "State" ), 1827 makeAny( 1828 sal_Int32( 1829 PropertyState_DEFAULT_VALUE ) ) ); 1830 1831 // Set attributes 1832 xNameReplace->replaceByName( 1833 OUString::createFromAscii( "Attributes" ), 1834 makeAny( sal_Int32( Attributes ) ) ); 1835 1836 // Insert new item. 1837 xContainer->insertByName( Name, makeAny( xNameReplace ) ); 1838 1839 // Commit changes. 1840 xBatch->commitChanges(); 1841 1842 // Property set info is invalid. 1843 if ( m_pImpl->m_pInfo ) 1844 m_pImpl->m_pInfo->reset(); 1845 1846 // Notify propertyset info change listeners. 1847 if ( m_pImpl->m_pPropSetChangeListeners && 1848 m_pImpl->m_pPropSetChangeListeners->getLength() ) 1849 { 1850 PropertySetInfoChangeEvent evt( 1851 static_cast< OWeakObject * >( this ), 1852 Name, 1853 -1, 1854 PropertySetInfoChange::PROPERTY_INSERTED ); 1855 notifyPropertySetInfoChange( evt ); 1856 } 1857 1858 // Success. 1859 return; 1860 } 1861 } 1862 catch ( IllegalArgumentException& ) 1863 { 1864 // insertByName 1865 1866 OSL_ENSURE( sal_False, 1867 "PersistentPropertySet::addProperty - " 1868 "caught IllegalArgumentException!" ); 1869 return; 1870 } 1871 catch ( ElementExistException& ) 1872 { 1873 // insertByName 1874 1875 OSL_ENSURE( sal_False, 1876 "PersistentPropertySet::addProperty - " 1877 "caught ElementExistException!" ); 1878 return; 1879 } 1880 catch ( WrappedTargetException& ) 1881 { 1882 // replaceByName, insertByName, commitChanges 1883 1884 OSL_ENSURE( sal_False, 1885 "PersistentPropertySet::addProperty - " 1886 "caught WrappedTargetException!" ); 1887 return; 1888 } 1889 catch ( RuntimeException& ) 1890 { 1891 throw; 1892 } 1893 catch ( Exception& ) 1894 { 1895 // createInstance 1896 1897 OSL_ENSURE( sal_False, 1898 "PersistentPropertySet::addProperty - " 1899 "caught Exception!" ); 1900 return; 1901 } 1902 } 1903 1904 OSL_ENSURE( sal_False, 1905 "PersistentPropertySet::addProperty - Error!" ); 1906 } 1907 1908 //========================================================================= 1909 // virtual 1910 void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name ) 1911 throw( UnknownPropertyException, 1912 NotRemoveableException, 1913 RuntimeException ) 1914 { 1915 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 1916 1917 OUString aFullValuesName; 1918 OUString aFullPropName; 1919 1920 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 1921 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); 1922 if ( xRootHierNameAccess.is() ) 1923 { 1924 aFullValuesName = getFullKey(); 1925 aFullPropName = aFullValuesName; 1926 aFullPropName += OUString::createFromAscii( "/" ); 1927 aFullPropName += makeHierarchalNameSegment( Name ); 1928 1929 // Property in set? 1930 if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) 1931 throw UnknownPropertyException(); 1932 1933 // Property removeable? 1934 try 1935 { 1936 OUString aFullAttrName = aFullPropName; 1937 aFullAttrName += OUString::createFromAscii( "/Attributes" ); 1938 1939 sal_Int32 nAttribs = 0; 1940 if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName ) 1941 >>= nAttribs ) 1942 { 1943 if ( !( nAttribs & PropertyAttribute::REMOVEABLE ) ) 1944 { 1945 // Not removeable! 1946 throw NotRemoveableException(); 1947 } 1948 } 1949 else 1950 { 1951 OSL_ENSURE( sal_False, 1952 "PersistentPropertySet::removeProperty - " 1953 "No attributes!" ); 1954 return; 1955 } 1956 } 1957 catch ( NoSuchElementException& ) 1958 { 1959 // getByHierarchicalName 1960 1961 OSL_ENSURE( sal_False, 1962 "PersistentPropertySet::removeProperty - " 1963 "caught NoSuchElementException!" ); 1964 } 1965 1966 // Remove property... 1967 1968 Reference< XNameContainer > xContainer( 1969 m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ), 1970 UNO_QUERY ); 1971 Reference< XChangesBatch > xBatch( 1972 m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ), 1973 UNO_QUERY ); 1974 1975 OSL_ENSURE( xBatch.is(), 1976 "PersistentPropertySet::removeProperty - No batch!" ); 1977 1978 OSL_ENSURE( xContainer.is(), 1979 "PersistentPropertySet::removeProperty - No container!" ); 1980 1981 if ( xBatch.is() && xContainer.is() ) 1982 { 1983 try 1984 { 1985 sal_Int32 nHandle = -1; 1986 1987 if ( m_pImpl->m_pPropSetChangeListeners && 1988 m_pImpl->m_pPropSetChangeListeners->getLength() ) 1989 { 1990 // Obtain property handle ( needed for propertysetinfo 1991 // change event )... 1992 1993 try 1994 { 1995 OUString aFullHandleName = aFullPropName; 1996 aFullHandleName 1997 += OUString::createFromAscii( "/Handle" ); 1998 1999 if ( ! ( xRootHierNameAccess->getByHierarchicalName( 2000 aFullHandleName ) >>= nHandle ) ) 2001 nHandle = -1; 2002 2003 } 2004 catch ( NoSuchElementException& ) 2005 { 2006 // getByHierarchicalName 2007 2008 OSL_ENSURE( sal_False, 2009 "PersistentPropertySet::removeProperty - " 2010 "caught NoSuchElementException!" ); 2011 nHandle = -1; 2012 } 2013 } 2014 2015 xContainer->removeByName( Name ); 2016 xBatch->commitChanges(); 2017 2018 // Property set info is invalid. 2019 if ( m_pImpl->m_pInfo ) 2020 m_pImpl->m_pInfo->reset(); 2021 2022 // Notify propertyset info change listeners. 2023 if ( m_pImpl->m_pPropSetChangeListeners && 2024 m_pImpl->m_pPropSetChangeListeners->getLength() ) 2025 { 2026 PropertySetInfoChangeEvent evt( 2027 static_cast< OWeakObject * >( this ), 2028 Name, 2029 nHandle, 2030 PropertySetInfoChange::PROPERTY_REMOVED ); 2031 notifyPropertySetInfoChange( evt ); 2032 } 2033 2034 // Success. 2035 return; 2036 } 2037 catch ( NoSuchElementException& ) 2038 { 2039 // removeByName 2040 2041 OSL_ENSURE( sal_False, 2042 "PersistentPropertySet::removeProperty - " 2043 "caught NoSuchElementException!" ); 2044 return; 2045 } 2046 catch ( WrappedTargetException& ) 2047 { 2048 // commitChanges 2049 2050 OSL_ENSURE( sal_False, 2051 "PersistentPropertySet::removeProperty - " 2052 "caught WrappedTargetException!" ); 2053 return; 2054 } 2055 } 2056 } 2057 2058 OSL_ENSURE( sal_False, 2059 "PersistentPropertySet::removeProperty - Error!" ); 2060 } 2061 2062 //========================================================================= 2063 // 2064 // XPropertySetInfoChangeNotifier methods. 2065 // 2066 //========================================================================= 2067 2068 // virtual 2069 void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener( 2070 const Reference< XPropertySetInfoChangeListener >& Listener ) 2071 throw( RuntimeException ) 2072 { 2073 if ( !m_pImpl->m_pPropSetChangeListeners ) 2074 m_pImpl->m_pPropSetChangeListeners = 2075 new OInterfaceContainerHelper( m_pImpl->m_aMutex ); 2076 2077 m_pImpl->m_pPropSetChangeListeners->addInterface( Listener ); 2078 } 2079 2080 //========================================================================= 2081 // virtual 2082 void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener( 2083 const Reference< XPropertySetInfoChangeListener >& Listener ) 2084 throw( RuntimeException ) 2085 { 2086 if ( m_pImpl->m_pPropSetChangeListeners ) 2087 m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener ); 2088 } 2089 2090 //========================================================================= 2091 // 2092 // XPropertyAccess methods. 2093 // 2094 //========================================================================= 2095 2096 // virtual 2097 Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues() 2098 throw( RuntimeException ) 2099 { 2100 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 2101 2102 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 2103 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); 2104 if ( xRootHierNameAccess.is() ) 2105 { 2106 try 2107 { 2108 Reference< XNameAccess > xNameAccess; 2109 xRootHierNameAccess->getByHierarchicalName(getFullKey()) 2110 >>= xNameAccess; 2111 if ( xNameAccess.is() ) 2112 { 2113 // Obtain property names. 2114 2115 Sequence< OUString > aElems = xNameAccess->getElementNames(); 2116 2117 sal_Int32 nCount = aElems.getLength(); 2118 if ( nCount ) 2119 { 2120 Reference< XHierarchicalNameAccess > xHierNameAccess( 2121 xNameAccess, UNO_QUERY ); 2122 2123 OSL_ENSURE( xHierNameAccess.is(), 2124 "PersistentPropertySet::getPropertyValues - " 2125 "No hierarchical name access!" ); 2126 2127 if ( xHierNameAccess.is() ) 2128 { 2129 Sequence< PropertyValue > aValues( nCount ); 2130 2131 const OUString aHandleName 2132 = OUString::createFromAscii( "/Handle" ); 2133 const OUString aValueName 2134 = OUString::createFromAscii( "/Value" ); 2135 const OUString aStateName 2136 = OUString::createFromAscii( "/State" ); 2137 2138 for ( sal_Int32 n = 0; n < nCount; ++n ) 2139 { 2140 PropertyValue& rValue = aValues[ n ]; 2141 OUString rName = aElems[ n ]; 2142 OUString aXMLName 2143 = makeHierarchalNameSegment( rName ); 2144 2145 // Set property name. 2146 2147 rValue.Name = rName; 2148 2149 try 2150 { 2151 // Obtain and set property handle 2152 OUString aHierName = aXMLName; 2153 aHierName += aHandleName; 2154 Any aKeyValue 2155 = xHierNameAccess->getByHierarchicalName( 2156 aHierName ); 2157 2158 if ( !( aKeyValue >>= rValue.Handle ) ) 2159 OSL_ENSURE( sal_False, 2160 "PersistentPropertySet::getPropertyValues - " 2161 "Error getting property handle!" ); 2162 } 2163 catch ( NoSuchElementException& ) 2164 { 2165 // getByHierarchicalName 2166 2167 OSL_ENSURE( sal_False, 2168 "PersistentPropertySet::getPropertyValues - " 2169 "NoSuchElementException!" ); 2170 } 2171 2172 try 2173 { 2174 // Obtain and set property value 2175 OUString aHierName = aXMLName; 2176 aHierName += aValueName; 2177 rValue.Value 2178 = xHierNameAccess->getByHierarchicalName( 2179 aHierName ); 2180 2181 // Note: The value may be void if addProperty 2182 // was called with a default value 2183 // of type void. 2184 } 2185 catch ( NoSuchElementException& ) 2186 { 2187 // getByHierarchicalName 2188 2189 OSL_ENSURE( sal_False, 2190 "PersistentPropertySet::getPropertyValues - " 2191 "NoSuchElementException!" ); 2192 } 2193 2194 try 2195 { 2196 // Obtain and set property state 2197 OUString aHierName = aXMLName; 2198 aHierName += aStateName; 2199 Any aKeyValue 2200 = xHierNameAccess->getByHierarchicalName( 2201 aHierName ); 2202 2203 sal_Int32 nState = 0; 2204 if ( !( aKeyValue >>= nState ) ) 2205 OSL_ENSURE( sal_False, 2206 "PersistentPropertySet::getPropertyValues - " 2207 "Error getting property state!" ); 2208 else 2209 rValue.State = PropertyState( nState ); 2210 } 2211 catch ( NoSuchElementException& ) 2212 { 2213 // getByHierarchicalName 2214 2215 OSL_ENSURE( sal_False, 2216 "PersistentPropertySet::getPropertyValues - " 2217 "NoSuchElementException!" ); 2218 } 2219 } 2220 2221 return aValues; 2222 } 2223 } 2224 } 2225 } 2226 catch ( NoSuchElementException& ) 2227 { 2228 // getByHierarchicalName 2229 } 2230 } 2231 2232 return Sequence< PropertyValue >( 0 ); 2233 } 2234 2235 //========================================================================= 2236 // virtual 2237 void SAL_CALL PersistentPropertySet::setPropertyValues( 2238 const Sequence< PropertyValue >& aProps ) 2239 throw( UnknownPropertyException, 2240 PropertyVetoException, 2241 IllegalArgumentException, 2242 WrappedTargetException, 2243 RuntimeException ) 2244 { 2245 sal_Int32 nCount = aProps.getLength(); 2246 if ( !nCount ) 2247 return; 2248 2249 osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex ); 2250 2251 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 2252 m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); 2253 if ( xRootHierNameAccess.is() ) 2254 { 2255 const PropertyValue* pNewValues = aProps.getConstArray(); 2256 2257 typedef std::list< PropertyChangeEvent > Events; 2258 Events aEvents; 2259 2260 OUString aFullPropNamePrefix( getFullKey() ); 2261 aFullPropNamePrefix += OUString::createFromAscii( "/" ); 2262 2263 // Iterate over given property value sequence. 2264 for ( sal_Int32 n = 0; n < nCount; ++n ) 2265 { 2266 const PropertyValue& rNewValue = pNewValues[ n ]; 2267 const OUString& rName = rNewValue.Name; 2268 2269 OUString aFullPropName = aFullPropNamePrefix; 2270 aFullPropName += makeHierarchalNameSegment( rName ); 2271 2272 // Does property exist? 2273 if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) 2274 { 2275 Reference< XNameReplace > xNameReplace( 2276 m_pImpl->m_pCreator->getConfigWriteAccess( 2277 aFullPropName ), UNO_QUERY ); 2278 Reference< XChangesBatch > xBatch( 2279 m_pImpl->m_pCreator->getConfigWriteAccess( 2280 OUString() ), UNO_QUERY ); 2281 2282 if ( xNameReplace.is() && xBatch.is() ) 2283 { 2284 try 2285 { 2286 // Write handle 2287 xNameReplace->replaceByName( 2288 OUString::createFromAscii( "Handle" ), 2289 makeAny( rNewValue.Handle ) ); 2290 2291 // Save old value 2292 OUString aValueName = aFullPropName; 2293 aValueName += OUString::createFromAscii( "/Value" ); 2294 Any aOldValue 2295 = xRootHierNameAccess->getByHierarchicalName( 2296 aValueName ); 2297 // Write value 2298 xNameReplace->replaceByName( 2299 OUString::createFromAscii( "Value" ), 2300 rNewValue.Value ); 2301 2302 // Write state ( Now it is a directly set value ) 2303 xNameReplace->replaceByName( 2304 OUString::createFromAscii( "State" ), 2305 makeAny( 2306 sal_Int32( 2307 PropertyState_DIRECT_VALUE ) ) ); 2308 2309 // Commit changes. 2310 xBatch->commitChanges(); 2311 2312 if ( m_pImpl->m_pPropertyChangeListeners ) 2313 { 2314 PropertyChangeEvent aEvt; 2315 aEvt.Source = (OWeakObject*)this; 2316 aEvt.PropertyName = rNewValue.Name; 2317 aEvt.PropertyHandle = rNewValue.Handle; 2318 aEvt.Further = sal_False; 2319 aEvt.OldValue = aOldValue; 2320 aEvt.NewValue = rNewValue.Value; 2321 2322 aEvents.push_back( aEvt ); 2323 } 2324 } 2325 catch ( IllegalArgumentException& ) 2326 { 2327 // replaceByName 2328 } 2329 catch ( NoSuchElementException& ) 2330 { 2331 // getByHierarchicalName, replaceByName 2332 } 2333 catch ( WrappedTargetException& ) 2334 { 2335 // replaceByName, commitChanges 2336 } 2337 } 2338 } 2339 } 2340 2341 // Callback follows! 2342 aCGuard.clear(); 2343 2344 if ( m_pImpl->m_pPropertyChangeListeners ) 2345 { 2346 // Notify property changes. 2347 Events::const_iterator it = aEvents.begin(); 2348 Events::const_iterator end = aEvents.end(); 2349 2350 while ( it != end ) 2351 { 2352 notifyPropertyChangeEvent( (*it) ); 2353 it++; 2354 } 2355 } 2356 2357 return; 2358 } 2359 2360 OSL_ENSURE( sal_False, 2361 "PersistentPropertySet::setPropertyValues - Nothing set!" ); 2362 } 2363 2364 //========================================================================= 2365 // 2366 // Non-interface methods 2367 // 2368 //========================================================================= 2369 2370 void PersistentPropertySet::notifyPropertyChangeEvent( 2371 const PropertyChangeEvent& rEvent ) const 2372 { 2373 // Get "normal" listeners for the property. 2374 OInterfaceContainerHelper* pContainer = 2375 m_pImpl->m_pPropertyChangeListeners->getContainer( 2376 rEvent.PropertyName ); 2377 if ( pContainer && pContainer->getLength() ) 2378 { 2379 OInterfaceIteratorHelper aIter( *pContainer ); 2380 while ( aIter.hasMoreElements() ) 2381 { 2382 // Propagate event. 2383 Reference< XPropertyChangeListener > xListener( 2384 aIter.next(), UNO_QUERY ); 2385 if ( xListener.is() ) 2386 xListener->propertyChange( rEvent ); 2387 } 2388 } 2389 2390 // Get "normal" listeners for all properties. 2391 OInterfaceContainerHelper* pNoNameContainer = 2392 m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() ); 2393 if ( pNoNameContainer && pNoNameContainer->getLength() ) 2394 { 2395 OInterfaceIteratorHelper aIter( *pNoNameContainer ); 2396 while ( aIter.hasMoreElements() ) 2397 { 2398 // Propagate event. 2399 Reference< XPropertyChangeListener > xListener( 2400 aIter.next(), UNO_QUERY ); 2401 if ( xListener.is() ) 2402 xListener->propertyChange( rEvent ); 2403 } 2404 } 2405 } 2406 2407 //========================================================================= 2408 void PersistentPropertySet::notifyPropertySetInfoChange( 2409 const PropertySetInfoChangeEvent& evt ) const 2410 { 2411 if ( !m_pImpl->m_pPropSetChangeListeners ) 2412 return; 2413 2414 // Notify event listeners. 2415 OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) ); 2416 while ( aIter.hasMoreElements() ) 2417 { 2418 // Propagate event. 2419 Reference< XPropertySetInfoChangeListener > 2420 xListener( aIter.next(), UNO_QUERY ); 2421 if ( xListener.is() ) 2422 xListener->propertySetInfoChange( evt ); 2423 } 2424 } 2425 2426 //========================================================================= 2427 const OUString& PersistentPropertySet::getFullKey() 2428 { 2429 if ( !m_pImpl->m_aFullKey.getLength() ) 2430 { 2431 osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); 2432 if ( !m_pImpl->m_aFullKey.getLength() ) 2433 { 2434 m_pImpl->m_aFullKey 2435 = makeHierarchalNameSegment( m_pImpl->m_aKey ); 2436 m_pImpl->m_aFullKey 2437 += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Values" ) ); 2438 } 2439 } 2440 2441 return m_pImpl->m_aFullKey; 2442 } 2443 2444 //========================================================================= 2445 PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry() 2446 { 2447 return *m_pImpl->m_pCreator; 2448 } 2449 2450 //========================================================================= 2451 //========================================================================= 2452 // 2453 // PropertySetInfo_Impl Implementation. 2454 // 2455 //========================================================================= 2456 //========================================================================= 2457 2458 PropertySetInfo_Impl::PropertySetInfo_Impl( 2459 const Reference< XMultiServiceFactory >& rxSMgr, 2460 PersistentPropertySet* pOwner ) 2461 : m_xSMgr( rxSMgr ), 2462 m_pProps( NULL ), 2463 m_pOwner( pOwner ) 2464 { 2465 } 2466 2467 //========================================================================= 2468 // virtual 2469 PropertySetInfo_Impl::~PropertySetInfo_Impl() 2470 { 2471 delete m_pProps; 2472 2473 // !!! Do not delete m_pOwner !!! 2474 } 2475 2476 //========================================================================= 2477 // 2478 // XInterface methods. 2479 // 2480 //========================================================================= 2481 2482 XINTERFACE_IMPL_2( PropertySetInfo_Impl, 2483 XTypeProvider, 2484 XPropertySetInfo ); 2485 2486 //========================================================================= 2487 // 2488 // XTypeProvider methods. 2489 // 2490 //========================================================================= 2491 2492 XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl, 2493 XTypeProvider, 2494 XPropertySetInfo ); 2495 2496 //========================================================================= 2497 // 2498 // XPropertySetInfo methods. 2499 // 2500 //========================================================================= 2501 2502 // virtual 2503 Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties() 2504 throw( RuntimeException ) 2505 { 2506 if ( !m_pProps ) 2507 { 2508 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 2509 m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), 2510 UNO_QUERY ); 2511 if ( xRootHierNameAccess.is() ) 2512 { 2513 try 2514 { 2515 Reference< XNameAccess > xNameAccess; 2516 xRootHierNameAccess->getByHierarchicalName( 2517 m_pOwner->getFullKey() ) 2518 >>= xNameAccess; 2519 if ( xNameAccess.is() ) 2520 { 2521 // Obtain property names. 2522 2523 Sequence< OUString > aElems 2524 = xNameAccess->getElementNames(); 2525 2526 sal_uInt32 nCount = aElems.getLength(); 2527 Sequence< Property >* pPropSeq 2528 = new Sequence< Property >( nCount ); 2529 2530 if ( nCount ) 2531 { 2532 Reference< XHierarchicalNameAccess > xHierNameAccess( 2533 xNameAccess, UNO_QUERY ); 2534 2535 OSL_ENSURE( xHierNameAccess.is(), 2536 "PropertySetInfo_Impl::getProperties - " 2537 "No hierarchical name access!" ); 2538 2539 if ( xHierNameAccess.is() ) 2540 { 2541 const OUString aHandleName 2542 = OUString::createFromAscii( "/Handle" ); 2543 const OUString aValueName 2544 = OUString::createFromAscii( "/Value" ); 2545 const OUString aAttrName 2546 = OUString::createFromAscii( "/Attributes" ); 2547 2548 Property* pProps = pPropSeq->getArray(); 2549 2550 for ( sal_uInt32 n = 0; n < nCount; ++n ) 2551 { 2552 Property& rProp = pProps[ n ]; 2553 OUString rName = aElems[ n ]; 2554 OUString aXMLName 2555 = makeHierarchalNameSegment( rName ); 2556 2557 // Set property name. 2558 2559 rProp.Name = rName; 2560 2561 try 2562 { 2563 // Obtain and set property handle 2564 rtl::OUString aHierName = aXMLName; 2565 aHierName += aHandleName; 2566 Any aKeyValue 2567 = xHierNameAccess->getByHierarchicalName( 2568 aHierName ); 2569 2570 if ( !( aKeyValue >>= rProp.Handle ) ) 2571 OSL_ENSURE( sal_False, 2572 "PropertySetInfo_Impl::getProperties - " 2573 "Error getting property handle!" ); 2574 } 2575 catch ( NoSuchElementException& ) 2576 { 2577 // getByHierarchicalName 2578 2579 OSL_ENSURE( sal_False, 2580 "PropertySetInfo_Impl::getProperties - " 2581 "NoSuchElementException!" ); 2582 } 2583 2584 try 2585 { 2586 // Obtain and set property type 2587 rtl::OUString aHierName = aXMLName; 2588 aHierName += aValueName; 2589 Any aKeyValue 2590 = xHierNameAccess->getByHierarchicalName( 2591 aHierName ); 2592 2593 // Note: The type may be void if addProperty 2594 // was called with a default value 2595 // of type void. 2596 2597 rProp.Type = aKeyValue.getValueType(); 2598 } 2599 catch ( NoSuchElementException& ) 2600 { 2601 // getByHierarchicalName 2602 2603 OSL_ENSURE( sal_False, 2604 "PropertySetInfo_Impl::getProperties - " 2605 "NoSuchElementException!" ); 2606 } 2607 2608 try 2609 { 2610 // Obtain and set property attributes 2611 rtl::OUString aHierName = aXMLName; 2612 aHierName += aAttrName; 2613 Any aKeyValue 2614 = xHierNameAccess->getByHierarchicalName( 2615 aHierName ); 2616 2617 sal_Int32 nAttribs = 0; 2618 if ( aKeyValue >>= nAttribs ) 2619 rProp.Attributes 2620 = sal_Int16( nAttribs ); 2621 else 2622 OSL_ENSURE( sal_False, 2623 "PropertySetInfo_Impl::getProperties - " 2624 "Error getting property attributes!" ); 2625 } 2626 catch ( NoSuchElementException& ) 2627 { 2628 // getByHierarchicalName 2629 2630 OSL_ENSURE( sal_False, 2631 "PropertySetInfo_Impl::getProperties - " 2632 "NoSuchElementException!" ); 2633 } 2634 } 2635 } 2636 } 2637 2638 // Success. 2639 m_pProps = pPropSeq; 2640 return *m_pProps; 2641 } 2642 } 2643 catch ( NoSuchElementException& ) 2644 { 2645 // getByHierarchicalName 2646 } 2647 } 2648 2649 OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getProperties - Error!" ); 2650 m_pProps = new Sequence< Property >( 0 ); 2651 } 2652 2653 return *m_pProps; 2654 } 2655 2656 //========================================================================= 2657 // virtual 2658 Property SAL_CALL PropertySetInfo_Impl::getPropertyByName( 2659 const OUString& aName ) 2660 throw( UnknownPropertyException, RuntimeException ) 2661 { 2662 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 2663 m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), 2664 UNO_QUERY ); 2665 if ( xRootHierNameAccess.is() ) 2666 { 2667 OUString aFullPropName( m_pOwner->getFullKey() ); 2668 aFullPropName += OUString::createFromAscii( "/" ); 2669 aFullPropName += makeHierarchalNameSegment( aName ); 2670 2671 // Does property exist? 2672 if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) 2673 throw UnknownPropertyException(); 2674 2675 try 2676 { 2677 Property aProp; 2678 2679 // Obtain handle. 2680 OUString aKey = aFullPropName; 2681 aKey += OUString::createFromAscii( "/Handle" ); 2682 2683 if ( !( xRootHierNameAccess->getByHierarchicalName( aKey ) 2684 >>= aProp.Handle ) ) 2685 { 2686 OSL_ENSURE( sal_False, 2687 "PropertySetInfo_Impl::getPropertyByName - " 2688 "No handle!" ); 2689 return Property(); 2690 } 2691 2692 // Obtain Value and extract type. 2693 aKey = aFullPropName; 2694 aKey += OUString::createFromAscii( "/Value" ); 2695 2696 Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey ); 2697 if ( !aValue.hasValue() ) 2698 { 2699 OSL_ENSURE( sal_False, 2700 "PropertySetInfo_Impl::getPropertyByName - " 2701 "No Value!" ); 2702 return Property(); 2703 } 2704 2705 aProp.Type = aValue.getValueType(); 2706 2707 // Obtain Attributes. 2708 aKey = aFullPropName; 2709 aKey += OUString::createFromAscii( "/Attributes" ); 2710 2711 sal_Int32 nAttribs = 0; 2712 if ( xRootHierNameAccess->getByHierarchicalName( aKey ) 2713 >>= nAttribs ) 2714 aProp.Attributes = sal_Int16( nAttribs ); 2715 else 2716 { 2717 OSL_ENSURE( sal_False, 2718 "PropertySetInfo_Impl::getPropertyByName - " 2719 "No attributes!" ); 2720 return Property(); 2721 } 2722 2723 // set name. 2724 aProp.Name = aName; 2725 2726 // Success. 2727 return aProp; 2728 } 2729 catch ( NoSuchElementException& ) 2730 { 2731 // getByHierarchicalName 2732 2733 OSL_ENSURE( sal_False, 2734 "PropertySetInfo_Impl::getPropertyByName - " 2735 "caught NoSuchElementException!" ); 2736 } 2737 2738 } 2739 2740 OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getPropertyByName - Error!" ); 2741 return Property(); 2742 } 2743 2744 //========================================================================= 2745 // virtual 2746 sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName( 2747 const OUString& Name ) 2748 throw( RuntimeException ) 2749 { 2750 Reference< XHierarchicalNameAccess > xRootHierNameAccess( 2751 m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), 2752 UNO_QUERY ); 2753 if ( xRootHierNameAccess.is() ) 2754 { 2755 OUString aFullPropName( m_pOwner->getFullKey() ); 2756 aFullPropName += OUString::createFromAscii( "/" ); 2757 aFullPropName += makeHierarchalNameSegment( Name ); 2758 2759 return xRootHierNameAccess->hasByHierarchicalName( aFullPropName ); 2760 } 2761 2762 return sal_False; 2763 } 2764 2765 /* vim: set noet sw=4 ts=4: */ 2766