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_cppuhelper.hxx" 30 #include <osl/diagnose.h> 31 #include <osl/mutex.hxx> 32 #include <cppuhelper/weak.hxx> 33 #include <cppuhelper/component.hxx> 34 #include <cppuhelper/factory.hxx> 35 #ifndef _CPPUHELPER_IMPLBASE3_HXX 36 #include <cppuhelper/implbase3.hxx> 37 #endif 38 #include <cppuhelper/typeprovider.hxx> 39 #include <rtl/unload.h> 40 41 #include "cppuhelper/propshlp.hxx" 42 43 #include <com/sun/star/lang/XServiceInfo.hpp> 44 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 45 #include <com/sun/star/lang/XSingleComponentFactory.hpp> 46 #include <com/sun/star/lang/XInitialization.hpp> 47 #include <com/sun/star/loader/XImplementationLoader.hpp> 48 #include <com/sun/star/lang/XComponent.hpp> 49 #include <com/sun/star/lang/IllegalArgumentException.hpp> 50 #include <com/sun/star/uno/XUnloadingPreference.hpp> 51 #include "com/sun/star/beans/PropertyAttribute.hpp" 52 53 #include <memory> 54 55 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 56 57 58 using namespace osl; 59 using namespace rtl; 60 using namespace com::sun::star; 61 using namespace com::sun::star::uno; 62 using namespace com::sun::star::lang; 63 using namespace com::sun::star::loader; 64 using namespace com::sun::star::registry; 65 66 namespace cppu 67 { 68 69 //----------------------------------------------------------------------------- 70 //----------------------------------------------------------------------------- 71 //----------------------------------------------------------------------------- 72 class OSingleFactoryHelper 73 : public XServiceInfo 74 , public XSingleServiceFactory 75 , public lang::XSingleComponentFactory 76 , public XUnloadingPreference 77 { 78 public: 79 OSingleFactoryHelper( 80 const Reference<XMultiServiceFactory > & rServiceManager, 81 const OUString & rImplementationName_, 82 ComponentInstantiation pCreateFunction_, 83 ComponentFactoryFunc fptr, 84 const Sequence< OUString > * pServiceNames_ ) 85 SAL_THROW( () ) 86 : xSMgr( rServiceManager ) 87 , pCreateFunction( pCreateFunction_ ) 88 , m_fptr( fptr ) 89 , aImplementationName( rImplementationName_ ) 90 { 91 if( pServiceNames_ ) 92 aServiceNames = *pServiceNames_; 93 } 94 95 // old function, only for backward compatibility 96 OSingleFactoryHelper( 97 const Reference<XMultiServiceFactory > & rServiceManager, 98 const OUString & rImplementationName_ ) 99 SAL_THROW( () ) 100 : xSMgr( rServiceManager ) 101 , pCreateFunction( NULL ) 102 , m_fptr( 0 ) 103 , aImplementationName( rImplementationName_ ) 104 {} 105 106 virtual ~OSingleFactoryHelper(); 107 108 // XInterface 109 Any SAL_CALL queryInterface( const Type & rType ) 110 throw(::com::sun::star::uno::RuntimeException); 111 112 // XSingleServiceFactory 113 Reference<XInterface > SAL_CALL createInstance() 114 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 115 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) 116 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 117 // XSingleComponentFactory 118 virtual Reference< XInterface > SAL_CALL createInstanceWithContext( 119 Reference< XComponentContext > const & xContext ) 120 throw (Exception, RuntimeException); 121 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( 122 Sequence< Any > const & rArguments, 123 Reference< XComponentContext > const & xContext ) 124 throw (Exception, RuntimeException); 125 126 // XServiceInfo 127 OUString SAL_CALL getImplementationName() 128 throw(::com::sun::star::uno::RuntimeException); 129 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 130 throw(::com::sun::star::uno::RuntimeException); 131 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) 132 throw(::com::sun::star::uno::RuntimeException); 133 134 protected: 135 /** 136 * Create an instance specified by the factory. The one instance logic is implemented 137 * in the createInstance and createInstanceWithArguments methods. 138 * @return the newly created instance. Do not return a previous (one instance) instance. 139 */ 140 virtual Reference<XInterface > createInstanceEveryTime( 141 Reference< XComponentContext > const & xContext ) 142 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 143 144 Reference<XMultiServiceFactory > xSMgr; 145 ComponentInstantiation pCreateFunction; 146 ComponentFactoryFunc m_fptr; 147 Sequence< OUString > aServiceNames; 148 OUString aImplementationName; 149 }; 150 OSingleFactoryHelper::~OSingleFactoryHelper() 151 { 152 } 153 154 155 //----------------------------------------------------------------------------- 156 Any OSingleFactoryHelper::queryInterface( const Type & rType ) 157 throw(::com::sun::star::uno::RuntimeException) 158 { 159 return ::cppu::queryInterface( 160 rType, 161 static_cast< XSingleComponentFactory * >( this ), 162 static_cast< XSingleServiceFactory * >( this ), 163 static_cast< XServiceInfo * >( this ) , 164 static_cast< XUnloadingPreference * >( this )); 165 } 166 167 // OSingleFactoryHelper 168 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime( 169 Reference< XComponentContext > const & xContext ) 170 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 171 { 172 if (m_fptr) 173 { 174 return (*m_fptr)( xContext ); 175 } 176 else if( pCreateFunction ) 177 { 178 if (xContext.is()) 179 { 180 Reference< lang::XMultiServiceFactory > xContextMgr( 181 xContext->getServiceManager(), UNO_QUERY ); 182 if (xContextMgr.is()) 183 return (*pCreateFunction)( xContextMgr ); 184 } 185 return (*pCreateFunction)( xSMgr ); 186 } 187 else 188 { 189 return Reference< XInterface >(); 190 } 191 } 192 193 // XSingleServiceFactory 194 Reference<XInterface > OSingleFactoryHelper::createInstance() 195 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 196 { 197 return createInstanceWithContext( Reference< XComponentContext >() ); 198 } 199 200 // XSingleServiceFactory 201 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments( 202 const Sequence<Any>& Arguments ) 203 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 204 { 205 return createInstanceWithArgumentsAndContext( 206 Arguments, Reference< XComponentContext >() ); 207 } 208 209 // XSingleComponentFactory 210 //__________________________________________________________________________________________________ 211 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext( 212 Reference< XComponentContext > const & xContext ) 213 throw (Exception, RuntimeException) 214 { 215 return createInstanceEveryTime( xContext ); 216 } 217 //__________________________________________________________________________________________________ 218 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext( 219 Sequence< Any > const & rArguments, 220 Reference< XComponentContext > const & xContext ) 221 throw (Exception, RuntimeException) 222 { 223 Reference< XInterface > xRet( createInstanceWithContext( xContext ) ); 224 225 Reference< lang::XInitialization > xInit( xRet, UNO_QUERY ); 226 // always call initialize, even if there are no arguments. 227 // #i63511# / 2006-03-27 / frank.schoenheit@sun.com 228 if (xInit.is()) 229 { 230 xInit->initialize( rArguments ); 231 } 232 else 233 { 234 if ( rArguments.getLength() ) 235 { 236 // dispose the here created UNO object before throwing out exception 237 // to avoid risk of memory leaks #i113722# 238 Reference<XComponent> xComp( xRet, UNO_QUERY ); 239 if (xComp.is()) 240 xComp->dispose(); 241 242 throw lang::IllegalArgumentException( 243 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot pass arguments to component => no XInitialization implemented!") ), 244 Reference< XInterface >(), 0 ); 245 } 246 } 247 248 return xRet; 249 } 250 251 // XServiceInfo 252 OUString OSingleFactoryHelper::getImplementationName() 253 throw(::com::sun::star::uno::RuntimeException) 254 { 255 return aImplementationName; 256 } 257 258 // XServiceInfo 259 sal_Bool OSingleFactoryHelper::supportsService( 260 const OUString& ServiceName ) 261 throw(::com::sun::star::uno::RuntimeException) 262 { 263 Sequence< OUString > seqServices = getSupportedServiceNames(); 264 const OUString * pServices = seqServices.getConstArray(); 265 for( sal_Int32 i = 0; i < seqServices.getLength(); i++ ) 266 if( pServices[i] == ServiceName ) 267 return sal_True; 268 269 return sal_False; 270 } 271 272 // XServiceInfo 273 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void) 274 throw(::com::sun::star::uno::RuntimeException) 275 { 276 return aServiceNames; 277 } 278 279 280 //---------------------------------------------------------------------- 281 //---------------------------------------------------------------------- 282 //---------------------------------------------------------------------- 283 struct OFactoryComponentHelper_Mutex 284 { 285 Mutex aMutex; 286 }; 287 288 class OFactoryComponentHelper 289 : public OFactoryComponentHelper_Mutex 290 , public OComponentHelper 291 , public OSingleFactoryHelper 292 { 293 public: 294 OFactoryComponentHelper( 295 const Reference<XMultiServiceFactory > & rServiceManager, 296 const OUString & rImplementationName_, 297 ComponentInstantiation pCreateFunction_, 298 ComponentFactoryFunc fptr, 299 const Sequence< OUString > * pServiceNames_, 300 sal_Bool bOneInstance_ = sal_False ) 301 SAL_THROW( () ) 302 : OComponentHelper( aMutex ) 303 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ ) 304 , bOneInstance( bOneInstance_ ) 305 , pModuleCount(0) 306 { 307 } 308 309 // Used by the createXXXFactory functions. The argument pModCount is used to prevent the unloading of the module 310 // which contains pCreateFunction_ 311 OFactoryComponentHelper( 312 const Reference<XMultiServiceFactory > & rServiceManager, 313 const OUString & rImplementationName_, 314 ComponentInstantiation pCreateFunction_, 315 ComponentFactoryFunc fptr, 316 const Sequence< OUString > * pServiceNames_, 317 rtl_ModuleCount * pModCount, 318 sal_Bool bOneInstance_ = sal_False ) 319 SAL_THROW( () ) 320 : OComponentHelper( aMutex ) 321 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ ) 322 , bOneInstance( bOneInstance_ ) 323 , pModuleCount(pModCount) 324 { 325 if(pModuleCount) 326 pModuleCount->acquire( pModuleCount); 327 } 328 329 // old function, only for backward compatibility 330 OFactoryComponentHelper( 331 const Reference<XMultiServiceFactory > & rServiceManager, 332 const OUString & rImplementationName_, 333 sal_Bool bOneInstance_ = sal_False ) 334 SAL_THROW( () ) 335 : OComponentHelper( aMutex ) 336 , OSingleFactoryHelper( rServiceManager, rImplementationName_ ) 337 , bOneInstance( bOneInstance_ ) 338 , pModuleCount(0) 339 { 340 } 341 342 ~OFactoryComponentHelper() 343 { 344 if(pModuleCount) 345 pModuleCount->release( pModuleCount); 346 } 347 348 // XInterface 349 Any SAL_CALL queryInterface( const Type & rType ) 350 throw(::com::sun::star::uno::RuntimeException); 351 void SAL_CALL acquire() throw() 352 { OComponentHelper::acquire(); } 353 void SAL_CALL release() throw() 354 { OComponentHelper::release(); } 355 356 // XSingleServiceFactory 357 Reference<XInterface > SAL_CALL createInstance() 358 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 359 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments ) 360 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 361 // XSingleComponentFactory 362 virtual Reference< XInterface > SAL_CALL createInstanceWithContext( 363 Reference< XComponentContext > const & xContext ) 364 throw (Exception, RuntimeException); 365 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( 366 Sequence< Any > const & rArguments, 367 Reference< XComponentContext > const & xContext ) 368 throw (Exception, RuntimeException); 369 370 // XTypeProvider 371 virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); 372 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); 373 374 // XAggregation 375 Any SAL_CALL queryAggregation( const Type & rType ) 376 throw(::com::sun::star::uno::RuntimeException); 377 378 // XUnloadingPreference 379 virtual sal_Bool SAL_CALL releaseOnNotification() 380 throw(::com::sun::star::uno::RuntimeException); 381 382 // OComponentHelper 383 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); 384 385 private: 386 Reference<XInterface > xTheInstance; 387 sal_Bool bOneInstance; 388 rtl_ModuleCount * pModuleCount; 389 protected: 390 // needed for implementing XUnloadingPreference in inheriting classes 391 sal_Bool isOneInstance() {return bOneInstance;} 392 sal_Bool isInstance() {return xTheInstance.is();} 393 }; 394 395 396 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType ) 397 throw(::com::sun::star::uno::RuntimeException) 398 { 399 if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0)) 400 { 401 return makeAny( 402 Reference< XUnloadingPreference >( 403 static_cast< XUnloadingPreference * >(this) ) ); 404 } 405 return OComponentHelper::queryInterface( rType ); 406 } 407 408 // XAggregation 409 Any OFactoryComponentHelper::queryAggregation( const Type & rType ) 410 throw(::com::sun::star::uno::RuntimeException) 411 { 412 Any aRet( OComponentHelper::queryAggregation( rType ) ); 413 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType )); 414 } 415 416 // XTypeProvider 417 Sequence< Type > OFactoryComponentHelper::getTypes() 418 throw (::com::sun::star::uno::RuntimeException) 419 { 420 Type ar[ 4 ]; 421 ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ); 422 ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 ); 423 ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 ); 424 425 if (m_fptr) 426 ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 ); 427 428 return Sequence< Type >( ar, m_fptr ? 4 : 3 ); 429 } 430 431 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId() 432 throw (::com::sun::star::uno::RuntimeException) 433 { 434 static OImplementationId * pId = 0; 435 if (! pId) 436 { 437 MutexGuard aGuard( Mutex::getGlobalMutex() ); 438 if (! pId) 439 { 440 static OImplementationId aId; 441 pId = &aId; 442 } 443 } 444 return pId->getImplementationId(); 445 } 446 447 // XSingleServiceFactory 448 Reference<XInterface > OFactoryComponentHelper::createInstance() 449 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 450 { 451 if( bOneInstance ) 452 { 453 if( !xTheInstance.is() ) 454 { 455 MutexGuard aGuard( aMutex ); 456 if( !xTheInstance.is() ) 457 xTheInstance = OSingleFactoryHelper::createInstance(); 458 } 459 return xTheInstance; 460 } 461 return OSingleFactoryHelper::createInstance(); 462 } 463 464 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments( 465 const Sequence<Any>& Arguments ) 466 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 467 { 468 if( bOneInstance ) 469 { 470 if( !xTheInstance.is() ) 471 { 472 MutexGuard aGuard( aMutex ); 473 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" ); 474 if( !xTheInstance.is() ) 475 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments ); 476 } 477 return xTheInstance; 478 } 479 return OSingleFactoryHelper::createInstanceWithArguments( Arguments ); 480 } 481 482 // XSingleComponentFactory 483 //__________________________________________________________________________________________________ 484 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext( 485 Reference< XComponentContext > const & xContext ) 486 throw (Exception, RuntimeException) 487 { 488 if( bOneInstance ) 489 { 490 if( !xTheInstance.is() ) 491 { 492 MutexGuard aGuard( aMutex ); 493 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" ); 494 if( !xTheInstance.is() ) 495 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext ); 496 } 497 return xTheInstance; 498 } 499 return OSingleFactoryHelper::createInstanceWithContext( xContext ); 500 } 501 //__________________________________________________________________________________________________ 502 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext( 503 Sequence< Any > const & rArguments, 504 Reference< XComponentContext > const & xContext ) 505 throw (Exception, RuntimeException) 506 { 507 if( bOneInstance ) 508 { 509 if( !xTheInstance.is() ) 510 { 511 MutexGuard aGuard( aMutex ); 512 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" ); 513 if( !xTheInstance.is() ) 514 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext ); 515 } 516 return xTheInstance; 517 } 518 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext ); 519 } 520 521 522 // OComponentHelper 523 void OFactoryComponentHelper::dispose() 524 throw(::com::sun::star::uno::RuntimeException) 525 { 526 OComponentHelper::dispose(); 527 528 Reference<XInterface > x; 529 { 530 // do not delete in the guard section 531 MutexGuard aGuard( aMutex ); 532 x = xTheInstance; 533 xTheInstance = Reference<XInterface >(); 534 } 535 // if it is a component call dispose at the component 536 Reference<XComponent > xComp( x, UNO_QUERY ); 537 if( xComp.is() ) 538 xComp->dispose(); 539 } 540 541 // XUnloadingPreference 542 // This class is used for single factories, component factories and 543 // one-instance factories. Depending on the usage this function has 544 // to return different values. 545 // one-instance factory: sal_False 546 // single factory: sal_True 547 // component factory: sal_True 548 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException) 549 { 550 if( bOneInstance) 551 return sal_False; 552 return sal_True; 553 } 554 555 556 //----------------------------------------------------------------------------- 557 //----------------------------------------------------------------------------- 558 //----------------------------------------------------------------------------- 559 class ORegistryFactoryHelper : public OFactoryComponentHelper, 560 public OPropertySetHelper 561 562 { 563 public: 564 ORegistryFactoryHelper( 565 const Reference<XMultiServiceFactory > & rServiceManager, 566 const OUString & rImplementationName_, 567 const Reference<XRegistryKey > & xImplementationKey_, 568 sal_Bool bOneInstance_ = sal_False ) SAL_THROW( () ) 569 : OFactoryComponentHelper( 570 rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ), 571 OPropertySetHelper( OComponentHelper::rBHelper ), 572 xImplementationKey( xImplementationKey_ ) 573 {} 574 575 // XInterface 576 virtual Any SAL_CALL queryInterface( Type const & type ) 577 throw (RuntimeException); 578 virtual void SAL_CALL acquire() throw (); 579 virtual void SAL_CALL release() throw (); 580 // XTypeProvider 581 virtual Sequence< Type > SAL_CALL getTypes() 582 throw (RuntimeException); 583 // XPropertySet 584 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() 585 throw (RuntimeException); 586 587 // OPropertySetHelper 588 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper(); 589 virtual sal_Bool SAL_CALL convertFastPropertyValue( 590 Any & rConvertedValue, Any & rOldValue, 591 sal_Int32 nHandle, Any const & rValue ) 592 throw (lang::IllegalArgumentException); 593 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( 594 sal_Int32 nHandle, Any const & rValue ) 595 throw (Exception); 596 using OPropertySetHelper::getFastPropertyValue; 597 virtual void SAL_CALL getFastPropertyValue( 598 Any & rValue, sal_Int32 nHandle ) const; 599 600 // OSingleFactoryHelper 601 Reference<XInterface > createInstanceEveryTime( 602 Reference< XComponentContext > const & xContext ) 603 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 604 605 // XSingleServiceFactory 606 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) 607 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 608 // XSingleComponentFactory 609 Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( 610 Sequence< Any > const & rArguments, 611 Reference< XComponentContext > const & xContext ) 612 throw (Exception, RuntimeException); 613 614 // XServiceInfo 615 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) 616 throw(::com::sun::star::uno::RuntimeException); 617 // XUnloadingPreference 618 sal_Bool SAL_CALL releaseOnNotification() 619 throw( RuntimeException); 620 621 622 private: 623 Reference< XInterface > createModuleFactory() 624 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 625 626 /** The registry key of the implementation section */ 627 Reference<XRegistryKey > xImplementationKey; 628 /** The factory created with the loader. */ 629 Reference<XSingleComponentFactory > xModuleFactory; 630 Reference<XSingleServiceFactory > xModuleFactoryDepr; 631 Reference< beans::XPropertySetInfo > m_xInfo; 632 ::std::auto_ptr< IPropertyArrayHelper > m_property_array_helper; 633 protected: 634 using OPropertySetHelper::getTypes; 635 }; 636 637 // XInterface 638 //______________________________________________________________________________ 639 Any SAL_CALL ORegistryFactoryHelper::queryInterface( 640 Type const & type ) throw (RuntimeException) 641 { 642 Any ret( OFactoryComponentHelper::queryInterface( type ) ); 643 if (ret.hasValue()) 644 return ret; 645 else 646 return OPropertySetHelper::queryInterface( type ); 647 } 648 649 //______________________________________________________________________________ 650 void ORegistryFactoryHelper::acquire() throw () 651 { 652 OFactoryComponentHelper::acquire(); 653 } 654 655 //______________________________________________________________________________ 656 void ORegistryFactoryHelper::release() throw () 657 { 658 OFactoryComponentHelper::release(); 659 } 660 661 // XTypeProvider 662 //______________________________________________________________________________ 663 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException) 664 { 665 Sequence< Type > types( OFactoryComponentHelper::getTypes() ); 666 sal_Int32 pos = types.getLength(); 667 types.realloc( pos + 3 ); 668 Type * p = types.getArray(); 669 p[ pos++ ] = ::getCppuType( 670 reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) ); 671 p[ pos++ ] = ::getCppuType( 672 reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) ); 673 p[ pos++ ] = ::getCppuType( 674 reinterpret_cast< Reference< beans::XPropertySet > const * >(0) ); 675 return types; 676 } 677 678 // XPropertySet 679 //______________________________________________________________________________ 680 Reference< beans::XPropertySetInfo > 681 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException) 682 { 683 ::osl::MutexGuard guard( aMutex ); 684 if (! m_xInfo.is()) 685 m_xInfo = createPropertySetInfo( getInfoHelper() ); 686 return m_xInfo; 687 } 688 689 // OPropertySetHelper 690 //______________________________________________________________________________ 691 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper() 692 { 693 ::osl::MutexGuard guard( aMutex ); 694 if (m_property_array_helper.get() == 0) 695 { 696 beans::Property prop( 697 OUSTR("ImplementationKey") /* name */, 698 0 /* handle */, 699 ::getCppuType( &xImplementationKey ), 700 beans::PropertyAttribute::READONLY | 701 beans::PropertyAttribute::OPTIONAL ); 702 m_property_array_helper.reset( 703 new ::cppu::OPropertyArrayHelper( &prop, 1 ) ); 704 } 705 return *m_property_array_helper.get(); 706 } 707 708 //______________________________________________________________________________ 709 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue( 710 Any &, Any &, sal_Int32, Any const & ) 711 throw (lang::IllegalArgumentException) 712 { 713 OSL_ENSURE( 0, "unexpected!" ); 714 return false; 715 } 716 717 //______________________________________________________________________________ 718 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast( 719 sal_Int32, Any const & ) 720 throw (Exception) 721 { 722 throw beans::PropertyVetoException( 723 OUSTR("unexpected: only readonly properties!"), 724 static_cast< OWeakObject * >(this) ); 725 } 726 727 //______________________________________________________________________________ 728 void ORegistryFactoryHelper::getFastPropertyValue( 729 Any & rValue, sal_Int32 nHandle ) const 730 { 731 if (nHandle == 0) 732 { 733 rValue <<= xImplementationKey; 734 } 735 else 736 { 737 rValue.clear(); 738 throw beans::UnknownPropertyException( 739 OUSTR("unknown property!"), static_cast< OWeakObject * >( 740 const_cast< ORegistryFactoryHelper * >(this) ) ); 741 } 742 } 743 744 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime( 745 Reference< XComponentContext > const & xContext ) 746 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 747 { 748 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) 749 { 750 Reference< XInterface > x( createModuleFactory() ); 751 if (x.is()) 752 { 753 MutexGuard aGuard( aMutex ); 754 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) 755 { 756 xModuleFactory.set( x, UNO_QUERY ); 757 xModuleFactoryDepr.set( x, UNO_QUERY ); 758 } 759 } 760 } 761 if( xModuleFactory.is() ) 762 { 763 return xModuleFactory->createInstanceWithContext( xContext ); 764 } 765 else if( xModuleFactoryDepr.is() ) 766 { 767 return xModuleFactoryDepr->createInstance(); 768 } 769 770 return Reference<XInterface >(); 771 } 772 773 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments( 774 const Sequence<Any>& Arguments ) 775 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 776 { 777 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) 778 { 779 Reference< XInterface > x( createModuleFactory() ); 780 if (x.is()) 781 { 782 MutexGuard aGuard( aMutex ); 783 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) 784 { 785 xModuleFactory.set( x, UNO_QUERY ); 786 xModuleFactoryDepr.set( x, UNO_QUERY ); 787 } 788 } 789 } 790 if( xModuleFactoryDepr.is() ) 791 { 792 return xModuleFactoryDepr->createInstanceWithArguments( Arguments ); 793 } 794 else if( xModuleFactory.is() ) 795 { 796 #if OSL_DEBUG_LEVEL > 1 797 OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" ); 798 #endif 799 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() ); 800 } 801 802 return Reference<XInterface >(); 803 } 804 805 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext( 806 Sequence< Any > const & rArguments, 807 Reference< XComponentContext > const & xContext ) 808 throw (Exception, RuntimeException) 809 { 810 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) 811 { 812 Reference< XInterface > x( createModuleFactory() ); 813 if (x.is()) 814 { 815 MutexGuard aGuard( aMutex ); 816 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() ) 817 { 818 xModuleFactory.set( x, UNO_QUERY ); 819 xModuleFactoryDepr.set( x, UNO_QUERY ); 820 } 821 } 822 } 823 if( xModuleFactory.is() ) 824 { 825 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext ); 826 } 827 else if( xModuleFactoryDepr.is() ) 828 { 829 #if OSL_DEBUG_LEVEL > 1 830 if (xContext.is()) 831 { 832 OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" ); 833 } 834 #endif 835 return xModuleFactoryDepr->createInstanceWithArguments( rArguments ); 836 } 837 838 return Reference<XInterface >(); 839 } 840 841 842 // OSingleFactoryHelper 843 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory() 844 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 845 { 846 OUString aActivatorUrl; 847 OUString aActivatorName; 848 OUString aLocation; 849 850 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey( 851 OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) ); 852 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII ) 853 { 854 aActivatorUrl = xActivatorKey->getAsciiValue(); 855 856 OUString tmpActivator(aActivatorUrl.getStr()); 857 sal_Int32 nIndex = 0; 858 aActivatorName = tmpActivator.getToken(0, ':', nIndex ); 859 860 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey( 861 OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) ); 862 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII ) 863 aLocation = xLocationKey->getAsciiValue(); 864 } 865 else 866 { 867 // old style"url" 868 // the location of the program code of the implementation 869 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey( 870 OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/URL") ) ); 871 // is the the key of the right type ? 872 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII ) 873 { 874 // one implementation found -> try to activate 875 aLocation = xLocationKey->getAsciiValue(); 876 877 // search protocol delemitter 878 sal_Int32 nPos = aLocation.indexOf( 879 OUString( RTL_CONSTASCII_USTRINGPARAM("://") ) ); 880 if( nPos != -1 ) 881 { 882 aActivatorName = aLocation.copy( 0, nPos ); 883 if( aActivatorName.compareToAscii( "java" ) == 0 ) 884 aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ); 885 else if( aActivatorName.compareToAscii( "module" ) == 0 ) 886 aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ); 887 aLocation = aLocation.copy( nPos + 3 ); 888 } 889 } 890 } 891 892 Reference< XInterface > xFactory; 893 if( aActivatorName.getLength() != 0 ) 894 { 895 Reference<XInterface > x = xSMgr->createInstance( aActivatorName ); 896 Reference<XImplementationLoader > xLoader( x, UNO_QUERY ); 897 Reference<XInterface > xMF; 898 if (xLoader.is()) 899 { 900 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey ); 901 } 902 } 903 return xFactory; 904 } 905 906 // XServiceInfo 907 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void) 908 throw(::com::sun::star::uno::RuntimeException) 909 { 910 MutexGuard aGuard( aMutex ); 911 if( aServiceNames.getLength() == 0 ) 912 { 913 // not yet loaded 914 try 915 { 916 Reference<XRegistryKey > xKey = xImplementationKey->openKey( 917 OUString( RTL_CONSTASCII_USTRINGPARAM("UNO/SERVICES") ) ); 918 919 if (xKey.is()) 920 { 921 // length of prefix. +1 for the '/' at the end 922 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1; 923 924 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..." 925 Sequence<OUString> seqKeys = xKey->getKeyNames(); 926 OUString* pKeys = seqKeys.getArray(); 927 for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ ) 928 pKeys[i] = pKeys[i].copy(nPrefixLen); 929 930 aServiceNames = seqKeys; 931 } 932 } 933 catch (InvalidRegistryException &) 934 { 935 } 936 } 937 return aServiceNames; 938 } 939 940 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException) 941 { 942 sal_Bool retVal= sal_True; 943 if( isOneInstance() && isInstance()) 944 { 945 retVal= sal_False; 946 } 947 else if( ! isOneInstance()) 948 { 949 // try to delegate 950 if( xModuleFactory.is()) 951 { 952 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY); 953 if( xunloading.is()) 954 retVal= xunloading->releaseOnNotification(); 955 } 956 else if( xModuleFactoryDepr.is()) 957 { 958 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY); 959 if( xunloading.is()) 960 retVal= xunloading->releaseOnNotification(); 961 } 962 } 963 return retVal; 964 } 965 966 //----------------------------------------------------------------------------- 967 //----------------------------------------------------------------------------- 968 //----------------------------------------------------------------------------- 969 970 class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory, 971 XUnloadingPreference > 972 { 973 Reference<XSingleServiceFactory > xFactory; 974 975 public: 976 977 OFactoryProxyHelper( 978 const Reference<XMultiServiceFactory > & /*rServiceManager*/, 979 const Reference<XSingleServiceFactory > & rFactory ) 980 SAL_THROW( () ) 981 : xFactory( rFactory ) 982 {} 983 984 // XSingleServiceFactory 985 Reference<XInterface > SAL_CALL createInstance() 986 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 987 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) 988 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 989 990 // XServiceInfo 991 OUString SAL_CALL getImplementationName() 992 throw(::com::sun::star::uno::RuntimeException); 993 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) 994 throw(::com::sun::star::uno::RuntimeException); 995 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) 996 throw(::com::sun::star::uno::RuntimeException); 997 //XUnloadingPreference 998 sal_Bool SAL_CALL releaseOnNotification() 999 throw(::com::sun::star::uno::RuntimeException); 1000 1001 }; 1002 1003 // XSingleServiceFactory 1004 Reference<XInterface > OFactoryProxyHelper::createInstance() 1005 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1006 { 1007 return xFactory->createInstance(); 1008 } 1009 1010 // XSingleServiceFactory 1011 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments 1012 ( 1013 const Sequence<Any>& Arguments 1014 ) 1015 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1016 { 1017 return xFactory->createInstanceWithArguments( Arguments ); 1018 } 1019 1020 // XServiceInfo 1021 OUString OFactoryProxyHelper::getImplementationName() 1022 throw(::com::sun::star::uno::RuntimeException) 1023 { 1024 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); 1025 if( xInfo.is() ) 1026 return xInfo->getImplementationName(); 1027 return OUString(); 1028 } 1029 1030 // XServiceInfo 1031 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName) 1032 throw(::com::sun::star::uno::RuntimeException) 1033 { 1034 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); 1035 if( xInfo.is() ) 1036 return xInfo->supportsService( ServiceName ); 1037 return sal_False; 1038 } 1039 1040 // XServiceInfo 1041 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void) 1042 throw(::com::sun::star::uno::RuntimeException) 1043 { 1044 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY ); 1045 if( xInfo.is() ) 1046 return xInfo->getSupportedServiceNames(); 1047 return Sequence< OUString >(); 1048 } 1049 1050 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException) 1051 { 1052 1053 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY); 1054 if( pref.is()) 1055 return pref->releaseOnNotification(); 1056 return sal_True; 1057 } 1058 1059 1060 //----------------------------------------------------------------------------- 1061 //----------------------------------------------------------------------------- 1062 //----------------------------------------------------------------------------- 1063 // global function 1064 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory( 1065 const Reference<XMultiServiceFactory > & rServiceManager, 1066 const OUString & rImplementationName, 1067 ComponentInstantiation pCreateFunction, 1068 const Sequence< OUString > & rServiceNames, 1069 rtl_ModuleCount *pModCount ) 1070 SAL_THROW( () ) 1071 { 1072 return new OFactoryComponentHelper( 1073 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_False ); 1074 } 1075 1076 // global function 1077 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy( 1078 const Reference<XMultiServiceFactory > & rServiceManager, 1079 const Reference<XSingleServiceFactory > & rFactory ) 1080 SAL_THROW( () ) 1081 { 1082 return new OFactoryProxyHelper( 1083 rServiceManager, rFactory ); 1084 } 1085 1086 // global function 1087 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory( 1088 const Reference<XMultiServiceFactory > & rServiceManager, 1089 const OUString & rImplementationName, 1090 ComponentInstantiation pCreateFunction, 1091 const Sequence< OUString > & rServiceNames, 1092 rtl_ModuleCount *pModCount ) 1093 SAL_THROW( () ) 1094 { 1095 return new OFactoryComponentHelper( 1096 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True ); 1097 // return new OFactoryUnloadableComponentHelper( 1098 // rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True ); 1099 } 1100 1101 // global function 1102 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory( 1103 const Reference<XMultiServiceFactory > & rServiceManager, 1104 const OUString & rImplementationName, 1105 const Reference<XRegistryKey > & rImplementationKey ) 1106 SAL_THROW( () ) 1107 { 1108 return new ORegistryFactoryHelper( 1109 rServiceManager, rImplementationName, rImplementationKey, sal_False ); 1110 } 1111 1112 // global function 1113 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory( 1114 const Reference<XMultiServiceFactory > & rServiceManager, 1115 const OUString & rImplementationName, 1116 const Reference<XRegistryKey > & rImplementationKey ) 1117 SAL_THROW( () ) 1118 { 1119 return new ORegistryFactoryHelper( 1120 rServiceManager, rImplementationName, rImplementationKey, sal_True ); 1121 } 1122 1123 //################################################################################################## 1124 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory( 1125 ComponentFactoryFunc fptr, 1126 OUString const & rImplementationName, 1127 Sequence< OUString > const & rServiceNames, 1128 rtl_ModuleCount * pModCount) 1129 SAL_THROW( () ) 1130 { 1131 return new OFactoryComponentHelper( 1132 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_False ); 1133 } 1134 1135 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory( 1136 ComponentFactoryFunc fptr, 1137 OUString const & rImplementationName, 1138 Sequence< OUString > const & rServiceNames, 1139 rtl_ModuleCount * pModCount) 1140 SAL_THROW( () ) 1141 { 1142 return new OFactoryComponentHelper( 1143 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_True ); 1144 } 1145 1146 } 1147 1148 1149