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