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