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 Note: Configuration Management classes do not support XAggregation. 32 So I have to wrap the interesting interfaces manually. 33 34 *************************************************************************/ 35 #include "hierarchydatasource.hxx" 36 #include <osl/diagnose.h> 37 38 #include "osl/doublecheckedlocking.h" 39 #include <cppuhelper/interfacecontainer.hxx> 40 #include <com/sun/star/beans/PropertyValue.hpp> 41 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 42 #include <com/sun/star/container/XNameContainer.hpp> 43 #include <com/sun/star/util/XChangesBatch.hpp> 44 #include <com/sun/star/util/XChangesNotifier.hpp> 45 46 using namespace com::sun::star; 47 using namespace hierarchy_ucp; 48 49 //========================================================================= 50 51 // describe path of cfg entry 52 #define CFGPROPERTY_NODEPATH "nodepath" 53 // true->async. update; false->sync. update 54 #define CFGPROPERTY_LAZYWRITE "lazywrite" 55 56 #define READ_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadAccess" 57 #define READWRITE_SERVICE_NAME "com.sun.star.ucb.HierarchyDataReadWriteAccess" 58 59 #define CONFIG_PROVIDER_SERVICE_NAME \ 60 "com.sun.star.configuration.ConfigurationProvider" 61 #define CONFIG_READ_SERVICE_NAME \ 62 "com.sun.star.configuration.ConfigurationAccess" 63 #define CONFIG_READWRITE_SERVICE_NAME \ 64 "com.sun.star.configuration.ConfigurationUpdateAccess" 65 #define CONFIG_DATA_ROOT_KEY \ 66 "/org.openoffice.ucb.Hierarchy/Root" 67 68 //========================================================================= 69 70 namespace hcp_impl 71 { 72 73 //========================================================================= 74 // 75 // HierarchyDataReadAccess Implementation. 76 // 77 //========================================================================= 78 79 class HierarchyDataAccess : public cppu::OWeakObject, 80 public lang::XServiceInfo, 81 public lang::XTypeProvider, 82 public lang::XComponent, 83 public lang::XSingleServiceFactory, 84 public container::XHierarchicalNameAccess, 85 public container::XNameContainer, 86 public util::XChangesNotifier, 87 public util::XChangesBatch 88 { 89 osl::Mutex m_aMutex; 90 uno::Reference< uno::XInterface > m_xConfigAccess; 91 uno::Reference< lang::XComponent > m_xCfgC; 92 uno::Reference< lang::XSingleServiceFactory > m_xCfgSSF; 93 uno::Reference< container::XHierarchicalNameAccess > m_xCfgHNA; 94 uno::Reference< container::XNameContainer > m_xCfgNC; 95 uno::Reference< container::XNameReplace > m_xCfgNR; 96 uno::Reference< container::XNameAccess > m_xCfgNA; 97 uno::Reference< container::XElementAccess > m_xCfgEA; 98 uno::Reference< util::XChangesNotifier > m_xCfgCN; 99 uno::Reference< util::XChangesBatch > m_xCfgCB; 100 bool m_bReadOnly; 101 102 public: 103 HierarchyDataAccess( const uno::Reference< 104 uno::XInterface > & xConfigAccess, 105 bool bReadOnly ); 106 virtual ~HierarchyDataAccess(); 107 108 // XInterface 109 XINTERFACE_DECL() 110 111 // XServiceInfo 112 XSERVICEINFO_DECL() 113 114 // XTypeProvider 115 XTYPEPROVIDER_DECL() 116 117 // XComponent 118 virtual void SAL_CALL 119 dispose() 120 throw ( uno::RuntimeException ); 121 virtual void SAL_CALL 122 addEventListener( const uno::Reference< lang::XEventListener > & xListener ) 123 throw ( uno::RuntimeException ); 124 virtual void SAL_CALL 125 removeEventListener( const uno::Reference< 126 lang::XEventListener > & aListener ) 127 throw ( uno::RuntimeException ); 128 129 // XSingleServiceFactory 130 virtual uno::Reference< uno::XInterface > SAL_CALL 131 createInstance() 132 throw ( uno::Exception, uno::RuntimeException ); 133 virtual uno::Reference< uno::XInterface > SAL_CALL 134 createInstanceWithArguments( const uno::Sequence< uno::Any > & aArguments ) 135 throw ( uno::Exception, uno::RuntimeException ); 136 137 // XHierarchicalNameAccess 138 virtual uno::Any SAL_CALL 139 getByHierarchicalName( const rtl::OUString & aName ) 140 throw ( container::NoSuchElementException, uno::RuntimeException ); 141 virtual sal_Bool SAL_CALL 142 hasByHierarchicalName( const rtl::OUString & aName ) 143 throw ( uno::RuntimeException ); 144 145 // XNameContainer 146 virtual void SAL_CALL 147 insertByName( const rtl::OUString & aName, const uno::Any & aElement ) 148 throw ( lang::IllegalArgumentException, 149 container::ElementExistException, 150 lang::WrappedTargetException, 151 uno::RuntimeException ); 152 virtual void SAL_CALL 153 removeByName( const rtl::OUString & Name ) 154 throw ( container::NoSuchElementException, 155 lang::WrappedTargetException, 156 uno::RuntimeException ); 157 158 // XNameReplace ( base of XNameContainer ) 159 virtual void SAL_CALL 160 replaceByName( const rtl::OUString & aName, const uno::Any & aElement ) 161 throw ( lang::IllegalArgumentException, 162 container::NoSuchElementException, 163 lang::WrappedTargetException, 164 uno::RuntimeException ); 165 166 // XNameAccess ( base of XNameReplace ) 167 virtual uno::Any SAL_CALL 168 getByName( const rtl::OUString & aName ) 169 throw ( container::NoSuchElementException, 170 lang::WrappedTargetException, 171 uno::RuntimeException ); 172 virtual uno::Sequence< rtl::OUString > SAL_CALL 173 getElementNames() 174 throw ( uno::RuntimeException ); 175 virtual sal_Bool SAL_CALL 176 hasByName( const rtl::OUString & aName ) 177 throw ( uno::RuntimeException ); 178 179 // XElementAccess ( base of XNameAccess ) 180 virtual uno::Type SAL_CALL 181 getElementType() 182 throw ( uno::RuntimeException ); 183 virtual sal_Bool SAL_CALL 184 hasElements() 185 throw ( uno::RuntimeException ); 186 187 // XChangesNotifier 188 virtual void SAL_CALL 189 addChangesListener( const uno::Reference< 190 util::XChangesListener > & aListener ) 191 throw ( uno::RuntimeException ); 192 virtual void SAL_CALL 193 removeChangesListener( const uno::Reference< 194 util::XChangesListener > & aListener ) 195 throw ( uno::RuntimeException ); 196 197 // XChangesBatch 198 virtual void SAL_CALL 199 commitChanges() 200 throw ( lang::WrappedTargetException, uno::RuntimeException ); 201 virtual sal_Bool SAL_CALL 202 hasPendingChanges() 203 throw ( uno::RuntimeException ); 204 virtual uno::Sequence< util::ElementChange > SAL_CALL 205 getPendingChanges() 206 throw ( uno::RuntimeException ); 207 }; 208 209 } // namespace hcp_impl 210 211 using namespace hcp_impl; 212 213 //========================================================================= 214 //========================================================================= 215 // 216 // HierarchyDataSource Implementation. 217 // 218 //========================================================================= 219 //========================================================================= 220 221 HierarchyDataSource::HierarchyDataSource( 222 const uno::Reference< lang::XMultiServiceFactory > & rxServiceMgr ) 223 : m_xSMgr( rxServiceMgr ), 224 m_pDisposeEventListeners( 0 ) 225 { 226 } 227 228 //========================================================================= 229 // virtual 230 HierarchyDataSource::~HierarchyDataSource() 231 { 232 delete m_pDisposeEventListeners; 233 } 234 235 //========================================================================= 236 // 237 // XInterface methods. 238 // 239 //========================================================================= 240 241 XINTERFACE_IMPL_4( HierarchyDataSource, 242 lang::XTypeProvider, 243 lang::XServiceInfo, 244 lang::XComponent, 245 lang::XMultiServiceFactory ); 246 247 //========================================================================= 248 // 249 // XTypeProvider methods. 250 // 251 //========================================================================= 252 253 XTYPEPROVIDER_IMPL_4( HierarchyDataSource, 254 lang::XTypeProvider, 255 lang::XServiceInfo, 256 lang::XComponent, 257 lang::XMultiServiceFactory ); 258 259 //========================================================================= 260 // 261 // XServiceInfo methods. 262 // 263 //========================================================================= 264 265 XSERVICEINFO_IMPL_0( HierarchyDataSource, 266 rtl::OUString::createFromAscii( 267 "com.sun.star.comp.ucb.HierarchyDataSource" ) ) 268 { 269 uno::Sequence< rtl::OUString > aSNS( 2 ); 270 aSNS[ 0 ] = rtl::OUString::createFromAscii( 271 "com.sun.star.ucb.DefaultHierarchyDataSource" ); 272 aSNS[ 1 ] = rtl::OUString::createFromAscii( 273 "com.sun.star.ucb.HierarchyDataSource" ); 274 return aSNS; 275 } 276 277 ONE_INSTANCE_SERVICE_FACTORY_IMPL( HierarchyDataSource ); 278 279 //========================================================================= 280 // 281 // XComponent methods. 282 // 283 //========================================================================= 284 285 // virtual 286 void SAL_CALL HierarchyDataSource::dispose() 287 throw( uno::RuntimeException ) 288 { 289 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 290 291 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) 292 { 293 lang::EventObject aEvt; 294 aEvt.Source = static_cast< lang::XComponent * >( this ); 295 m_pDisposeEventListeners->disposeAndClear( aEvt ); 296 } 297 } 298 299 //========================================================================= 300 // virtual 301 void SAL_CALL HierarchyDataSource::addEventListener( 302 const uno::Reference< lang::XEventListener > & Listener ) 303 throw( uno::RuntimeException ) 304 { 305 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 306 307 if ( !m_pDisposeEventListeners ) 308 m_pDisposeEventListeners 309 = new cppu::OInterfaceContainerHelper( m_aMutex ); 310 311 m_pDisposeEventListeners->addInterface( Listener ); 312 } 313 314 //========================================================================= 315 // virtual 316 void SAL_CALL HierarchyDataSource::removeEventListener( 317 const uno::Reference< lang::XEventListener > & Listener ) 318 throw( uno::RuntimeException ) 319 { 320 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 321 322 if ( m_pDisposeEventListeners ) 323 m_pDisposeEventListeners->removeInterface( Listener ); 324 } 325 326 //========================================================================= 327 // 328 // XMultiServiceFactory methods. 329 // 330 //========================================================================= 331 332 // virtual 333 uno::Reference< uno::XInterface > SAL_CALL 334 HierarchyDataSource::createInstance( const rtl::OUString & aServiceSpecifier ) 335 throw ( uno::Exception, uno::RuntimeException ) 336 { 337 // Create view to root node. 338 339 beans::PropertyValue aProp; 340 aProp.Name = rtl::OUString( 341 RTL_CONSTASCII_USTRINGPARAM( CFGPROPERTY_NODEPATH ) ); 342 aProp.Value <<= 343 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) ); 344 345 uno::Sequence< uno::Any > aArguments( 1 ); 346 aArguments[ 0 ] <<= aProp; 347 348 return createInstanceWithArguments( aServiceSpecifier, aArguments, false ); 349 } 350 351 //========================================================================= 352 // virtual 353 uno::Reference< uno::XInterface > SAL_CALL 354 HierarchyDataSource::createInstanceWithArguments( 355 const rtl::OUString & ServiceSpecifier, 356 const uno::Sequence< uno::Any > & Arguments ) 357 throw ( uno::Exception, uno::RuntimeException ) 358 { 359 return createInstanceWithArguments( ServiceSpecifier, Arguments, true ); 360 } 361 362 //========================================================================= 363 // virtual 364 uno::Sequence< rtl::OUString > SAL_CALL 365 HierarchyDataSource::getAvailableServiceNames() 366 throw ( uno::RuntimeException ) 367 { 368 uno::Sequence< rtl::OUString > aNames( 2 ); 369 aNames[ 0 ] = rtl::OUString( 370 RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) ); 371 aNames[ 1 ] = rtl::OUString( 372 RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) ); 373 return aNames; 374 } 375 376 //========================================================================= 377 // 378 // Non-interface methods 379 // 380 //========================================================================= 381 382 uno::Reference< uno::XInterface > SAL_CALL 383 HierarchyDataSource::createInstanceWithArguments( 384 const rtl::OUString & ServiceSpecifier, 385 const uno::Sequence< uno::Any > & Arguments, 386 bool bCheckArgs ) 387 throw ( uno::Exception, uno::RuntimeException ) 388 { 389 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 390 391 // Check service specifier. 392 bool bReadOnly = !!ServiceSpecifier.equalsAsciiL( 393 RTL_CONSTASCII_STRINGPARAM( READ_SERVICE_NAME ) ); 394 bool bReadWrite = !bReadOnly && 395 ServiceSpecifier.equalsAsciiL( 396 RTL_CONSTASCII_STRINGPARAM( READWRITE_SERVICE_NAME ) ); 397 398 if ( !bReadOnly && !bReadWrite ) 399 { 400 OSL_ENSURE( false, 401 "HierarchyDataSource::createInstanceWithArguments - " 402 "Unsupported service specifier!" ); 403 return uno::Reference< uno::XInterface >(); 404 } 405 406 uno::Sequence< uno::Any > aNewArgs( Arguments ); 407 408 bool bHasLazyWriteProp = bReadOnly; // property must be added only if 409 // a writable view is requested. 410 if ( bCheckArgs ) 411 { 412 // Check arguments. 413 bool bHasNodePath = false; 414 sal_Int32 nCount = Arguments.getLength(); 415 for ( sal_Int32 n = 0; n < nCount; ++n ) 416 { 417 beans::PropertyValue aProp; 418 if ( Arguments[ n ] >>= aProp ) 419 { 420 if ( aProp.Name.equalsAsciiL( 421 RTL_CONSTASCII_STRINGPARAM( CFGPROPERTY_NODEPATH ) ) ) 422 { 423 rtl::OUString aPath; 424 if ( aProp.Value >>= aPath ) 425 { 426 bHasNodePath = true; 427 428 // Create path to data inside the configuration. 429 rtl::OUString aConfigPath; 430 if ( !createConfigPath( aPath, aConfigPath ) ) 431 { 432 OSL_ENSURE( false, 433 "HierarchyDataSource::" 434 "createInstanceWithArguments - " 435 "Invalid node path!" ); 436 return uno::Reference< uno::XInterface >(); 437 } 438 439 aProp.Value <<= aConfigPath; 440 441 // Set new path in arguments. 442 aNewArgs[ n ] <<= aProp; 443 444 if ( bHasLazyWriteProp ) 445 break; 446 } 447 else 448 { 449 OSL_ENSURE( false, 450 "HierarchyDataSource::createInstanceWithArguments - " 451 "Invalid type for property 'nodepath'!" ); 452 return uno::Reference< uno::XInterface >(); 453 } 454 } 455 else if ( aProp.Name.equalsAsciiL( 456 RTL_CONSTASCII_STRINGPARAM( 457 CFGPROPERTY_LAZYWRITE ) ) ) 458 { 459 if ( aProp.Value.getValueType() == getCppuBooleanType() ) 460 { 461 bHasLazyWriteProp = true; 462 463 if ( bHasNodePath ) 464 break; 465 } 466 else 467 { 468 OSL_ENSURE( false, 469 "HierarchyDataSource::createInstanceWithArguments - " 470 "Invalid type for property 'lazywrite'!" ); 471 return uno::Reference< uno::XInterface >(); 472 } 473 } 474 } 475 } 476 477 if ( !bHasNodePath ) 478 { 479 OSL_ENSURE( false, 480 "HierarchyDataSource::createInstanceWithArguments - " 481 "No 'nodepath' property!" ); 482 return uno::Reference< uno::XInterface >(); 483 } 484 } 485 486 // Create Configuration Provider. 487 uno::Reference< lang::XMultiServiceFactory > xProv = getConfigProvider(); 488 if ( !xProv.is() ) 489 return uno::Reference< uno::XInterface >(); 490 491 uno::Reference< uno::XInterface > xConfigAccess; 492 try 493 { 494 if ( bReadOnly ) 495 { 496 // Create configuration read-only access object. 497 xConfigAccess = xProv->createInstanceWithArguments( 498 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 499 CONFIG_READ_SERVICE_NAME ) ), 500 aNewArgs ); 501 } 502 else 503 { 504 // Append 'lazywrite' property value, if not already present. 505 if ( !bHasLazyWriteProp ) 506 { 507 sal_Int32 nLen = aNewArgs.getLength(); 508 aNewArgs.realloc( nLen + 1 ); 509 510 beans::PropertyValue aProp; 511 aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 512 CFGPROPERTY_LAZYWRITE ) ); 513 aProp.Value <<= sal_True; 514 aNewArgs[ nLen ] <<= aProp; 515 } 516 517 // Create configuration read-write access object. 518 xConfigAccess = xProv->createInstanceWithArguments( 519 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 520 CONFIG_READWRITE_SERVICE_NAME ) ), 521 aNewArgs ); 522 } 523 } 524 catch ( uno::Exception const & ) 525 { 526 OSL_ENSURE( false, 527 "HierarchyDataSource::createInstanceWithArguments - " 528 "Cannot instanciate configuration access!" ); 529 throw; 530 } 531 532 if ( !xConfigAccess.is() ) 533 { 534 OSL_ENSURE( false, 535 "HierarchyDataSource::createInstanceWithArguments - " 536 "Cannot instanciate configuration access!" ); 537 return xConfigAccess; 538 } 539 540 return uno::Reference< uno::XInterface >( 541 static_cast< cppu::OWeakObject * >( 542 new HierarchyDataAccess( xConfigAccess, bReadOnly ) ) ); 543 } 544 545 //========================================================================= 546 uno::Reference< lang::XMultiServiceFactory > 547 HierarchyDataSource::getConfigProvider() 548 { 549 if ( !m_xConfigProvider.is() ) 550 { 551 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 552 if ( !m_xConfigProvider.is() ) 553 { 554 try 555 { 556 m_xConfigProvider 557 = uno::Reference< lang::XMultiServiceFactory >( 558 m_xSMgr->createInstance( 559 rtl::OUString( 560 RTL_CONSTASCII_USTRINGPARAM( 561 CONFIG_PROVIDER_SERVICE_NAME ) ) ), 562 uno::UNO_QUERY ); 563 564 OSL_ENSURE( m_xConfigProvider.is(), 565 "HierarchyDataSource::getConfigProvider - " 566 "No configuration provider!" ); 567 } 568 catch ( uno::Exception const & ) 569 { 570 OSL_ENSURE( false, 571 "HierarchyDataSource::getConfigProvider - " 572 "caught exception!" ); 573 } 574 } 575 } 576 577 return m_xConfigProvider; 578 } 579 580 //========================================================================= 581 bool HierarchyDataSource::createConfigPath( 582 const rtl::OUString & rInPath, rtl::OUString & rOutPath ) 583 { 584 if ( rInPath.getLength() ) 585 { 586 if ( rInPath.indexOf( '/' ) == 0 ) 587 { 588 OSL_ENSURE( false, 589 "HierarchyDataSource::createConfigPath - " 590 "Leading slash in node path!" ); 591 return false; 592 } 593 594 if ( rInPath.lastIndexOf( '/' ) == rInPath.getLength() - 1 ) 595 { 596 OSL_ENSURE( false, 597 "HierarchyDataSource::createConfigPath - " 598 "Trailing slash in node path!" ); 599 return false; 600 } 601 602 rtl::OUString aOutPath( 603 RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY "/" ) ); 604 aOutPath += rInPath; 605 rOutPath = aOutPath; 606 } 607 else 608 { 609 rOutPath = rtl::OUString( 610 RTL_CONSTASCII_USTRINGPARAM( CONFIG_DATA_ROOT_KEY ) ); 611 } 612 613 return true; 614 } 615 616 //========================================================================= 617 //========================================================================= 618 // 619 // HierarchyDataAccess Implementation. 620 // 621 //========================================================================= 622 //========================================================================= 623 624 #define ENSURE_ORIG_INTERFACE( interface_name, member_name ) \ 625 m_xCfg##member_name; \ 626 if ( !m_xCfg##member_name.is() ) \ 627 { \ 628 osl::Guard< osl::Mutex > aGuard( m_aMutex ); \ 629 if ( !m_xCfg##member_name.is() ) \ 630 m_xCfg##member_name \ 631 = uno::Reference< interface_name >( \ 632 m_xConfigAccess, uno::UNO_QUERY ); \ 633 xOrig = m_xCfg##member_name; \ 634 } 635 636 //========================================================================= 637 HierarchyDataAccess::HierarchyDataAccess( const uno::Reference< 638 uno::XInterface > & xConfigAccess, 639 bool bReadOnly ) 640 : m_xConfigAccess( xConfigAccess ), 641 m_bReadOnly( bReadOnly ) 642 { 643 } 644 645 //========================================================================= 646 // virtual 647 HierarchyDataAccess::~HierarchyDataAccess() 648 { 649 } 650 651 //========================================================================= 652 // 653 // XInterface methods. 654 // 655 //========================================================================= 656 657 XINTERFACE_COMMON_IMPL( HierarchyDataAccess ); 658 659 //========================================================================= 660 // virtual 661 uno::Any SAL_CALL HierarchyDataAccess::queryInterface( const uno::Type & aType ) 662 throw ( uno::RuntimeException ) 663 { 664 // Interfaces supported in read-only and read-write mode. 665 uno::Any aRet = cppu::queryInterface( aType, 666 static_cast< lang::XTypeProvider * >( this ), 667 static_cast< lang::XServiceInfo * >( this ), 668 static_cast< lang::XComponent * >( this ), 669 static_cast< container::XHierarchicalNameAccess * >( this ), 670 static_cast< container::XNameAccess * >( this ), 671 static_cast< container::XElementAccess * >( this ), 672 static_cast< util::XChangesNotifier * >( this ) ); 673 674 // Interfaces supported only in read-write mode. 675 if ( !aRet.hasValue() && !m_bReadOnly ) 676 { 677 aRet = cppu::queryInterface( aType, 678 static_cast< lang::XSingleServiceFactory * >( this ), 679 static_cast< container::XNameContainer * >( this ), 680 static_cast< container::XNameReplace * >( this ), 681 static_cast< util::XChangesBatch * >( this ) ); 682 } 683 684 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( aType ); 685 } 686 687 //========================================================================= 688 // 689 // XTypeProvider methods. 690 // 691 //========================================================================= 692 693 XTYPEPROVIDER_COMMON_IMPL( HierarchyDataAccess ); 694 695 //========================================================================= 696 // virtual 697 uno::Sequence< uno::Type > SAL_CALL HierarchyDataAccess::getTypes() 698 throw( uno::RuntimeException ) 699 { 700 cppu::OTypeCollection * pCollection = 0; 701 702 if ( m_bReadOnly ) 703 { 704 static cppu::OTypeCollection* pReadOnlyTypes = 0; 705 706 pCollection = pReadOnlyTypes; 707 if ( !pCollection ) 708 { 709 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 710 711 pCollection = pReadOnlyTypes; 712 if ( !pCollection ) 713 { 714 static cppu::OTypeCollection aCollection( 715 CPPU_TYPE_REF( lang::XTypeProvider ), 716 CPPU_TYPE_REF( lang::XServiceInfo ), 717 CPPU_TYPE_REF( lang::XComponent ), 718 CPPU_TYPE_REF( container::XHierarchicalNameAccess ), 719 CPPU_TYPE_REF( container::XNameAccess ), 720 CPPU_TYPE_REF( util::XChangesNotifier ) ); 721 pCollection = &aCollection; 722 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 723 pReadOnlyTypes = pCollection; 724 } 725 } 726 else { 727 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 728 } 729 } 730 else 731 { 732 static cppu::OTypeCollection* pReadWriteTypes = 0; 733 734 pCollection = pReadWriteTypes; 735 if ( !pCollection ) 736 { 737 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 738 739 pCollection = pReadWriteTypes; 740 if ( !pCollection ) 741 { 742 static cppu::OTypeCollection aCollection( 743 CPPU_TYPE_REF( lang::XTypeProvider ), 744 CPPU_TYPE_REF( lang::XServiceInfo ), 745 CPPU_TYPE_REF( lang::XComponent ), 746 CPPU_TYPE_REF( lang::XSingleServiceFactory ), 747 CPPU_TYPE_REF( container::XHierarchicalNameAccess ), 748 CPPU_TYPE_REF( container::XNameContainer ), 749 CPPU_TYPE_REF( util::XChangesBatch ), 750 CPPU_TYPE_REF( util::XChangesNotifier ) ); 751 pCollection = &aCollection; 752 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 753 pReadWriteTypes = pCollection; 754 } 755 } 756 else { 757 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 758 } 759 } 760 761 return (*pCollection).getTypes(); 762 } 763 764 //========================================================================= 765 // 766 // XServiceInfo methods. 767 // 768 //========================================================================= 769 770 XSERVICEINFO_NOFACTORY_IMPL_0( 771 HierarchyDataAccess, 772 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 773 "com.sun.star.comp.ucb.HierarchyDataAccess" ) ) ) 774 { 775 uno::Sequence< rtl::OUString > aSNS( 2 ); 776 aSNS[ 0 ] = rtl::OUString( 777 RTL_CONSTASCII_USTRINGPARAM( READ_SERVICE_NAME ) ); 778 aSNS[ 1 ] = rtl::OUString( 779 RTL_CONSTASCII_USTRINGPARAM( READWRITE_SERVICE_NAME ) ); 780 return aSNS; 781 } 782 783 //========================================================================= 784 // 785 // XComponent methods. 786 // 787 //========================================================================= 788 789 // virtual 790 void SAL_CALL HierarchyDataAccess::dispose() 791 throw ( uno::RuntimeException ) 792 { 793 uno::Reference< lang::XComponent > xOrig 794 = ENSURE_ORIG_INTERFACE( lang::XComponent, C ); 795 796 OSL_ENSURE( xOrig.is(), 797 "HierarchyDataAccess : Data source is not an XComponent!" ); 798 xOrig->dispose(); 799 } 800 801 //========================================================================= 802 // virtual 803 void SAL_CALL HierarchyDataAccess::addEventListener( 804 const uno::Reference< lang::XEventListener > & xListener ) 805 throw ( uno::RuntimeException ) 806 { 807 uno::Reference< lang::XComponent > xOrig 808 = ENSURE_ORIG_INTERFACE( lang::XComponent, C ); 809 810 OSL_ENSURE( xOrig.is(), 811 "HierarchyDataAccess : Data source is not an XComponent!" ); 812 xOrig->addEventListener( xListener ); 813 } 814 815 //========================================================================= 816 // virtual 817 void SAL_CALL HierarchyDataAccess::removeEventListener( 818 const uno::Reference< lang::XEventListener > & aListener ) 819 throw ( uno::RuntimeException ) 820 { 821 uno::Reference< lang::XComponent > xOrig 822 = ENSURE_ORIG_INTERFACE( lang::XComponent, C ); 823 824 OSL_ENSURE( xOrig.is(), 825 "HierarchyDataAccess : Data source is not an XComponent!" ); 826 xOrig->removeEventListener( aListener ); 827 } 828 829 //========================================================================= 830 // 831 // XHierarchicalNameAccess methods. 832 // 833 //========================================================================= 834 835 // virtual 836 uno::Any SAL_CALL HierarchyDataAccess::getByHierarchicalName( 837 const rtl::OUString & aName ) 838 throw ( container::NoSuchElementException, uno::RuntimeException ) 839 { 840 uno::Reference< container::XHierarchicalNameAccess > xOrig 841 = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA ); 842 843 OSL_ENSURE( xOrig.is(), 844 "HierarchyDataAccess : " 845 "Data source is not an XHierarchicalNameAccess!" ); 846 return xOrig->getByHierarchicalName( aName ); 847 } 848 849 //========================================================================= 850 // virtual 851 sal_Bool SAL_CALL HierarchyDataAccess::hasByHierarchicalName( 852 const rtl::OUString & aName ) 853 throw ( uno::RuntimeException ) 854 { 855 uno::Reference< container::XHierarchicalNameAccess > xOrig 856 = ENSURE_ORIG_INTERFACE( container::XHierarchicalNameAccess, HNA ); 857 858 OSL_ENSURE( xOrig.is(), 859 "HierarchyDataAccess : " 860 "Data source is not an XHierarchicalNameAccess!" ); 861 return xOrig->hasByHierarchicalName( aName ); 862 } 863 864 //========================================================================= 865 // 866 // XNameAccess methods. 867 // 868 //========================================================================= 869 870 // virtual 871 uno::Any SAL_CALL HierarchyDataAccess::getByName( const rtl::OUString & aName ) 872 throw ( container::NoSuchElementException, 873 lang::WrappedTargetException, 874 uno::RuntimeException ) 875 { 876 uno::Reference< container::XNameAccess > xOrig 877 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA ); 878 879 OSL_ENSURE( xOrig.is(), 880 "HierarchyDataAccess : Data source is not an XNameAccess!" ); 881 return xOrig->getByName( aName ); 882 } 883 884 //========================================================================= 885 // virtual 886 uno::Sequence< rtl::OUString > SAL_CALL HierarchyDataAccess::getElementNames() 887 throw ( uno::RuntimeException ) 888 { 889 uno::Reference< container::XNameAccess > xOrig 890 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA ); 891 892 OSL_ENSURE( xOrig.is(), 893 "HierarchyDataAccess : Data source is not an XNameAccess!" ); 894 return xOrig->getElementNames(); 895 } 896 897 //========================================================================= 898 // virtual 899 sal_Bool SAL_CALL HierarchyDataAccess::hasByName( const rtl::OUString & aName ) 900 throw ( uno::RuntimeException ) 901 { 902 uno::Reference< container::XNameAccess > xOrig 903 = ENSURE_ORIG_INTERFACE( container::XNameAccess, NA ); 904 905 OSL_ENSURE( xOrig.is(), 906 "HierarchyDataAccess : Data source is not an XNameAccess!" ); 907 return xOrig->hasByName( aName ); 908 } 909 910 //========================================================================= 911 // 912 // XElementAccess methods. 913 // 914 //========================================================================= 915 916 // virtual 917 uno::Type SAL_CALL HierarchyDataAccess::getElementType() 918 throw ( uno::RuntimeException ) 919 { 920 uno::Reference< container::XElementAccess > xOrig 921 = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA ); 922 923 OSL_ENSURE( xOrig.is(), 924 "HierarchyDataAccess : Data source is not an XElementAccess!" ); 925 return xOrig->getElementType(); 926 } 927 928 //========================================================================= 929 // virtual 930 sal_Bool SAL_CALL HierarchyDataAccess::hasElements() 931 throw ( uno::RuntimeException ) 932 { 933 uno::Reference< container::XElementAccess > xOrig 934 = ENSURE_ORIG_INTERFACE( container::XElementAccess, EA ); 935 936 OSL_ENSURE( xOrig.is(), 937 "HierarchyDataAccess : Data source is not an XElementAccess!" ); 938 return xOrig->hasElements(); 939 } 940 941 //========================================================================= 942 // 943 // XChangesNotifier methods. 944 // 945 //========================================================================= 946 947 // virtual 948 void SAL_CALL HierarchyDataAccess::addChangesListener( 949 const uno::Reference< util::XChangesListener > & aListener ) 950 throw ( uno::RuntimeException ) 951 { 952 uno::Reference< util::XChangesNotifier > xOrig 953 = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN ); 954 955 OSL_ENSURE( xOrig.is(), 956 "HierarchyDataAccess : Data source is not an XChangesNotifier!" ); 957 xOrig->addChangesListener( aListener ); 958 } 959 960 //========================================================================= 961 // virtual 962 void SAL_CALL HierarchyDataAccess::removeChangesListener( 963 const uno::Reference< util::XChangesListener > & aListener ) 964 throw ( uno::RuntimeException ) 965 { 966 uno::Reference< util::XChangesNotifier > xOrig 967 = ENSURE_ORIG_INTERFACE( util::XChangesNotifier, CN ); 968 969 OSL_ENSURE( xOrig.is(), 970 "HierarchyDataAccess : Data source is not an XChangesNotifier!" ); 971 xOrig->removeChangesListener( aListener ); 972 } 973 974 //========================================================================= 975 // 976 // XSingleServiceFactory methods. 977 // 978 //========================================================================= 979 980 // virtual 981 uno::Reference< uno::XInterface > SAL_CALL HierarchyDataAccess::createInstance() 982 throw ( uno::Exception, uno::RuntimeException ) 983 { 984 uno::Reference< lang::XSingleServiceFactory > xOrig 985 = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF ); 986 987 OSL_ENSURE( xOrig.is(), 988 "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" ); 989 return xOrig->createInstance(); 990 } 991 992 //========================================================================= 993 // virtual 994 uno::Reference< uno::XInterface > SAL_CALL 995 HierarchyDataAccess::createInstanceWithArguments( 996 const uno::Sequence< uno::Any > & aArguments ) 997 throw ( uno::Exception, uno::RuntimeException ) 998 { 999 uno::Reference< lang::XSingleServiceFactory > xOrig 1000 = ENSURE_ORIG_INTERFACE( lang::XSingleServiceFactory, SSF ); 1001 1002 OSL_ENSURE( xOrig.is(), 1003 "HierarchyDataAccess : Data source is not an XSingleServiceFactory!" ); 1004 return xOrig->createInstanceWithArguments( aArguments ); 1005 } 1006 1007 //========================================================================= 1008 // 1009 // XNameContainer methods. 1010 // 1011 //========================================================================= 1012 1013 // virtual 1014 void SAL_CALL 1015 HierarchyDataAccess::insertByName( const rtl::OUString & aName, 1016 const uno::Any & aElement ) 1017 throw ( lang::IllegalArgumentException, 1018 container::ElementExistException, 1019 lang::WrappedTargetException, 1020 uno::RuntimeException ) 1021 { 1022 uno::Reference< container::XNameContainer > xOrig 1023 = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC ); 1024 1025 OSL_ENSURE( xOrig.is(), 1026 "HierarchyDataAccess : Data source is not an XNameContainer!" ); 1027 xOrig->insertByName( aName, aElement ); 1028 } 1029 1030 //========================================================================= 1031 // virtual 1032 void SAL_CALL 1033 HierarchyDataAccess::removeByName( const rtl::OUString & Name ) 1034 throw ( container::NoSuchElementException, 1035 lang::WrappedTargetException, 1036 uno::RuntimeException ) 1037 { 1038 uno::Reference< container::XNameContainer > xOrig 1039 = ENSURE_ORIG_INTERFACE( container::XNameContainer, NC ); 1040 1041 OSL_ENSURE( xOrig.is(), 1042 "HierarchyDataAccess : Data source is not an XNameContainer!" ); 1043 xOrig->removeByName( Name ); 1044 } 1045 1046 //========================================================================= 1047 // 1048 // XNameReplace methods. 1049 // 1050 //========================================================================= 1051 1052 // virtual 1053 void SAL_CALL HierarchyDataAccess::replaceByName( const rtl::OUString & aName, 1054 const uno::Any & aElement ) 1055 throw ( lang::IllegalArgumentException, 1056 container::NoSuchElementException, 1057 lang::WrappedTargetException, 1058 uno::RuntimeException ) 1059 { 1060 uno::Reference< container::XNameReplace > xOrig 1061 = ENSURE_ORIG_INTERFACE( container::XNameReplace, NR ); 1062 1063 OSL_ENSURE( xOrig.is(), 1064 "HierarchyDataAccess : Data source is not an XNameReplace!" ); 1065 xOrig->replaceByName( aName, aElement ); 1066 } 1067 1068 //========================================================================= 1069 // 1070 // XChangesBatch methods. 1071 // 1072 //========================================================================= 1073 1074 // virtual 1075 void SAL_CALL HierarchyDataAccess::commitChanges() 1076 throw ( lang::WrappedTargetException, uno::RuntimeException ) 1077 { 1078 uno::Reference< util::XChangesBatch > xOrig 1079 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB ); 1080 1081 OSL_ENSURE( xOrig.is(), 1082 "HierarchyDataAccess : Data source is not an XChangesBatch!" ); 1083 xOrig->commitChanges(); 1084 } 1085 1086 //========================================================================= 1087 // virtual 1088 sal_Bool SAL_CALL HierarchyDataAccess::hasPendingChanges() 1089 throw ( uno::RuntimeException ) 1090 { 1091 uno::Reference< util::XChangesBatch > xOrig 1092 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB ); 1093 1094 OSL_ENSURE( xOrig.is(), 1095 "HierarchyDataAccess : Data source is not an XChangesBatch!" ); 1096 return xOrig->hasPendingChanges(); 1097 } 1098 1099 //========================================================================= 1100 // virtual 1101 uno::Sequence< util::ElementChange > SAL_CALL 1102 HierarchyDataAccess::getPendingChanges() 1103 throw ( uno::RuntimeException ) 1104 { 1105 uno::Reference< util::XChangesBatch > xOrig 1106 = ENSURE_ORIG_INTERFACE( util::XChangesBatch, CB ); 1107 1108 OSL_ENSURE( xOrig.is(), 1109 "HierarchyDataAccess : Data source is not an XChangesBatch!" ); 1110 return xOrig->getPendingChanges(); 1111 } 1112 1113