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