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