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_stoc.hxx" 30 #include <osl/mutex.hxx> 31 #include <osl/diagnose.h> 32 #include <rtl/ustrbuf.hxx> 33 34 #include <hash_map> 35 #include <hash_set> 36 #include <list> 37 #include <uno/mapping.hxx> 38 #include <uno/dispatcher.h> 39 #include <cppuhelper/queryinterface.hxx> 40 #include <cppuhelper/weakref.hxx> 41 #include <cppuhelper/component.hxx> 42 #include <cppuhelper/factory.hxx> 43 #ifndef _CPPUHELPER_IMPLBASE1_HXX 44 #include <cppuhelper/implbase1.hxx> 45 #endif 46 #include <cppuhelper/typeprovider.hxx> 47 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_ 48 #include <cppuhelper/implementationentry.hxx> 49 #endif 50 #include <rtl/unload.h> 51 #include <cppuhelper/component_context.hxx> 52 #include <cppuhelper/bootstrap.hxx> 53 #include <cppuhelper/compbase8.hxx> 54 55 56 #include <com/sun/star/lang/XUnoTunnel.hpp> 57 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 58 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 59 #include <com/sun/star/lang/XServiceInfo.hpp> 60 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 61 #include <com/sun/star/lang/XInitialization.hpp> 62 #include <com/sun/star/lang/XEventListener.hpp> 63 #include <com/sun/star/lang/DisposedException.hpp> 64 #include <com/sun/star/beans/XPropertySet.hpp> 65 #include <com/sun/star/beans/PropertyAttribute.hpp> 66 #include <com/sun/star/registry/XRegistryKey.hpp> 67 #include <com/sun/star/registry/XSimpleRegistry.hpp> 68 #include <com/sun/star/container/XSet.hpp> 69 #include <com/sun/star/container/XElementAccess.hpp> 70 #include <com/sun/star/container/XEnumeration.hpp> 71 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 72 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 73 #include <com/sun/star/uno/XUnloadingPreference.hpp> 74 75 #include <bootstrapservices.hxx> 76 77 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 78 79 80 using namespace com::sun::star; 81 using namespace com::sun::star::uno; 82 using namespace com::sun::star::beans; 83 using namespace com::sun::star::registry; 84 using namespace com::sun::star::lang; 85 using namespace com::sun::star::container; 86 using namespace cppu; 87 using namespace osl; 88 using namespace rtl; 89 using namespace std; 90 91 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; 92 93 namespace stoc_bootstrap 94 { 95 Sequence< OUString > smgr_wrapper_getSupportedServiceNames() 96 { 97 static Sequence < OUString > *pNames = 0; 98 if( ! pNames ) 99 { 100 MutexGuard guard( Mutex::getGlobalMutex() ); 101 if( !pNames ) 102 { 103 static Sequence< OUString > seqNames(1); 104 seqNames.getArray()[0] = OUString( 105 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") ); 106 pNames = &seqNames; 107 } 108 } 109 return *pNames; 110 } 111 112 OUString smgr_wrapper_getImplementationName() 113 { 114 static OUString *pImplName = 0; 115 if( ! pImplName ) 116 { 117 MutexGuard guard( Mutex::getGlobalMutex() ); 118 if( ! pImplName ) 119 { 120 static OUString implName( 121 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManagerWrapper" ) ); 122 pImplName = &implName; 123 } 124 } 125 return *pImplName; 126 } 127 128 Sequence< OUString > smgr_getSupportedServiceNames() 129 { 130 static Sequence < OUString > *pNames = 0; 131 if( ! pNames ) 132 { 133 MutexGuard guard( Mutex::getGlobalMutex() ); 134 if( !pNames ) 135 { 136 static Sequence< OUString > seqNames(2); 137 seqNames.getArray()[0] = OUString( 138 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") ); 139 seqNames.getArray()[1] = OUString( 140 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.ServiceManager") ); 141 pNames = &seqNames; 142 } 143 } 144 return *pNames; 145 } 146 147 OUString smgr_getImplementationName() 148 { 149 static OUString *pImplName = 0; 150 if( ! pImplName ) 151 { 152 MutexGuard guard( Mutex::getGlobalMutex() ); 153 if( ! pImplName ) 154 { 155 static OUString implName( 156 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManager" ) ); 157 pImplName = &implName; 158 } 159 } 160 return *pImplName; 161 } 162 163 Sequence< OUString > regsmgr_getSupportedServiceNames() 164 { 165 static Sequence < OUString > *pNames = 0; 166 if( ! pNames ) 167 { 168 MutexGuard guard( Mutex::getGlobalMutex() ); 169 if( !pNames ) 170 { 171 static Sequence< OUString > seqNames(2); 172 seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory")); 173 seqNames.getArray()[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.RegistryServiceManager")); 174 pNames = &seqNames; 175 } 176 } 177 return *pNames; 178 } 179 180 OUString regsmgr_getImplementationName() 181 { 182 static OUString *pImplName = 0; 183 if( ! pImplName ) 184 { 185 MutexGuard guard( Mutex::getGlobalMutex() ); 186 if( ! pImplName ) 187 { 188 static OUString implName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.ORegistryServiceManager" ) ); 189 pImplName = &implName; 190 } 191 } 192 return *pImplName; 193 } 194 } 195 196 namespace stoc_smgr 197 { 198 static Sequence< sal_Int8 > smgr_getImplementationId() 199 { 200 static OImplementationId * s_pId = 0; 201 if (! s_pId) 202 { 203 MutexGuard aGuard( Mutex::getGlobalMutex() ); 204 if (! s_pId) 205 { 206 static OImplementationId s_aId; 207 s_pId = &s_aId; 208 } 209 } 210 return s_pId->getImplementationId(); 211 } 212 213 214 static Sequence< OUString > retrieveAsciiValueList( 215 const Reference< XSimpleRegistry > &xReg, const OUString &keyName ) 216 { 217 Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY ); 218 Sequence< OUString > seq; 219 if( xAccess.is() ) 220 { 221 Reference< XEnumeration > xEnum = xAccess->createEnumeration(); 222 while( xEnum.is() && xEnum->hasMoreElements() ) 223 { 224 Reference< XSimpleRegistry > xTempReg; 225 xEnum->nextElement() >>= xTempReg; 226 if( xTempReg.is() ) 227 { 228 Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName ); 229 230 if( seq2.getLength() ) 231 { 232 sal_Int32 n1Len = seq.getLength(); 233 sal_Int32 n2Len = seq2.getLength(); 234 235 seq.realloc( n1Len + n2Len ); 236 const OUString *pSource = seq2.getConstArray(); 237 OUString *pTarget = seq.getArray(); 238 for( int i = 0 ; i < n2Len ; i ++ ) 239 { 240 pTarget[i+n1Len] = pSource[i]; 241 } 242 } 243 } 244 } 245 } 246 else if( xReg.is () ) 247 { 248 try 249 { 250 Reference< XRegistryKey > rRootKey = xReg->getRootKey(); 251 if( rRootKey.is() ) 252 { 253 Reference<XRegistryKey > xKey = rRootKey->openKey(keyName); 254 if( xKey.is() ) 255 { 256 seq = xKey->getAsciiListValue(); 257 } 258 } 259 } 260 catch( InvalidRegistryException & ) 261 { 262 } 263 catch (InvalidValueException &) 264 { 265 } 266 } 267 return seq; 268 } 269 270 /***************************************************************************** 271 Enumeration by ServiceName 272 *****************************************************************************/ 273 struct hashRef_Impl 274 { 275 size_t operator()(const Reference<XInterface > & rName) const 276 { 277 // query to XInterface. The cast to XInterface* must be the same for the same object 278 Reference<XInterface > x( Reference<XInterface >::query( rName ) ); 279 return (size_t)x.get(); 280 } 281 }; 282 283 struct equaltoRef_Impl 284 { 285 size_t operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const 286 { return rName1 == rName2; } 287 }; 288 289 typedef hash_set 290 < 291 Reference<XInterface >, 292 hashRef_Impl, 293 equaltoRef_Impl 294 > HashSet_Ref; 295 296 297 class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration > 298 { 299 public: 300 ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories ) 301 : aFactories( rFactories ) 302 , nIt( 0 ) 303 { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); } 304 virtual ~ServiceEnumeration_Impl() 305 { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); } 306 307 // XEnumeration 308 sal_Bool SAL_CALL hasMoreElements() 309 throw(::com::sun::star::uno::RuntimeException); 310 Any SAL_CALL nextElement() 311 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 312 private: 313 Mutex aMutex; 314 Sequence< Reference<XInterface > > aFactories; 315 sal_Int32 nIt; 316 }; 317 318 // XEnumeration 319 sal_Bool ServiceEnumeration_Impl::hasMoreElements() throw(::com::sun::star::uno::RuntimeException) 320 { 321 MutexGuard aGuard( aMutex ); 322 return nIt != aFactories.getLength(); 323 } 324 325 // XEnumeration 326 Any ServiceEnumeration_Impl::nextElement() 327 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 328 { 329 MutexGuard aGuard( aMutex ); 330 if( nIt == aFactories.getLength() ) 331 throw NoSuchElementException(); 332 333 return Any( &aFactories.getConstArray()[nIt++], ::getCppuType( (const Reference<XInterface > *)0 ) ); 334 } 335 336 //================================================================================================== 337 class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo > 338 { 339 Sequence< beans::Property > m_properties; 340 341 public: 342 inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties ) SAL_THROW( () ) 343 : m_properties( properties ) 344 {} 345 346 // XPropertySetInfo impl 347 virtual Sequence< beans::Property > SAL_CALL getProperties() 348 throw (RuntimeException); 349 virtual beans::Property SAL_CALL getPropertyByName( OUString const & name ) 350 throw (beans::UnknownPropertyException, RuntimeException); 351 virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name ) 352 throw (RuntimeException); 353 }; 354 //__________________________________________________________________________________________________ 355 Sequence< beans::Property > PropertySetInfo_Impl::getProperties() 356 throw (RuntimeException) 357 { 358 return m_properties; 359 } 360 //__________________________________________________________________________________________________ 361 beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name ) 362 throw (beans::UnknownPropertyException, RuntimeException) 363 { 364 beans::Property const * p = m_properties.getConstArray(); 365 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; ) 366 { 367 if (p[ nPos ].Name.equals( name )) 368 return p[ nPos ]; 369 } 370 throw beans::UnknownPropertyException( 371 OUSTR("unknown property: ") + name, Reference< XInterface >() ); 372 } 373 //__________________________________________________________________________________________________ 374 sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name ) 375 throw (RuntimeException) 376 { 377 beans::Property const * p = m_properties.getConstArray(); 378 for ( sal_Int32 nPos = m_properties.getLength(); nPos--; ) 379 { 380 if (p[ nPos ].Name.equals( name )) 381 return sal_True; 382 } 383 return sal_False; 384 } 385 386 387 /***************************************************************************** 388 Enumeration by implementation 389 *****************************************************************************/ 390 class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration > 391 { 392 public: 393 ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap ) 394 : aImplementationMap( rImplementationMap ) 395 , aIt( aImplementationMap.begin() ) 396 { 397 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 398 } 399 virtual ~ImplementationEnumeration_Impl(); 400 401 // XEnumeration 402 virtual sal_Bool SAL_CALL hasMoreElements() 403 throw(::com::sun::star::uno::RuntimeException); 404 virtual Any SAL_CALL nextElement() 405 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 406 407 private: 408 Mutex aMutex; 409 HashSet_Ref aImplementationMap; 410 HashSet_Ref::iterator aIt; 411 sal_Int32 nNext; 412 Reference<XInterface > xNext; 413 }; 414 415 ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl() 416 { 417 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 418 } 419 420 // XEnumeration 421 sal_Bool ImplementationEnumeration_Impl::hasMoreElements() 422 throw(::com::sun::star::uno::RuntimeException) 423 { 424 MutexGuard aGuard( aMutex ); 425 return aIt != aImplementationMap.end(); 426 } 427 428 // XEnumeration 429 Any ImplementationEnumeration_Impl::nextElement() 430 throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 431 { 432 MutexGuard aGuard( aMutex ); 433 if( aIt == aImplementationMap.end() ) 434 throw NoSuchElementException(); 435 436 Any ret( &(*aIt), ::getCppuType( (const Reference<XInterface > *)0 ) ); 437 ++aIt; 438 return ret; 439 } 440 441 /***************************************************************************** 442 Hash tables 443 *****************************************************************************/ 444 struct equalOWString_Impl 445 { 446 sal_Bool operator()(const OUString & s1, const OUString & s2) const 447 { return s1 == s2; } 448 }; 449 450 struct hashOWString_Impl 451 { 452 size_t operator()(const OUString & rName) const 453 { return rName.hashCode(); } 454 }; 455 456 typedef hash_set 457 < 458 OUString, 459 hashOWString_Impl, 460 equalOWString_Impl 461 > HashSet_OWString; 462 463 typedef hash_multimap 464 < 465 OUString, 466 Reference<XInterface >, 467 hashOWString_Impl, 468 equalOWString_Impl 469 > HashMultimap_OWString_Interface; 470 471 typedef hash_map 472 < 473 OUString, 474 Reference<XInterface >, 475 hashOWString_Impl, 476 equalOWString_Impl 477 > HashMap_OWString_Interface; 478 479 /***************************************************************************** 480 class OServiceManager_Listener 481 *****************************************************************************/ 482 class OServiceManager_Listener : public WeakImplHelper1< XEventListener > 483 { 484 private: 485 WeakReference<XSet > xSMgr; 486 487 public: 488 OServiceManager_Listener( const Reference<XSet > & rSMgr ) 489 : xSMgr( rSMgr ) 490 {} 491 492 // XEventListener 493 virtual void SAL_CALL disposing(const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException); 494 }; 495 496 void OServiceManager_Listener::disposing(const EventObject & rEvt ) 497 throw(::com::sun::star::uno::RuntimeException) 498 { 499 Reference<XSet > x( xSMgr ); 500 if( x.is() ) 501 { 502 try 503 { 504 x->remove( Any( &rEvt.Source, ::getCppuType( (const Reference<XInterface > *)0 ) ) ); 505 } 506 catch( const IllegalArgumentException & ) 507 { 508 OSL_ENSURE( sal_False, "IllegalArgumentException catched" ); 509 } 510 catch( const NoSuchElementException & ) 511 { 512 OSL_ENSURE( sal_False, "NoSuchElementException catched" ); 513 } 514 } 515 } 516 517 518 /***************************************************************************** 519 class OServiceManager 520 *****************************************************************************/ 521 struct OServiceManagerMutex 522 { 523 Mutex m_mutex; 524 }; 525 526 extern "C" void SAL_CALL smgrUnloadingListener(void* id); 527 528 typedef WeakComponentImplHelper8< 529 lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo, 530 lang::XInitialization, lang::XUnoTunnel, 531 container::XSet, container::XContentEnumerationAccess, 532 beans::XPropertySet > t_OServiceManager_impl; 533 534 class OServiceManager 535 : public OServiceManagerMutex 536 , public t_OServiceManager_impl 537 { 538 public: 539 friend void SAL_CALL smgrUnloadingListener(void* id); 540 541 OServiceManager( Reference< XComponentContext > const & xContext ); 542 virtual ~OServiceManager(); 543 544 // XUnoTunnel 545 sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id ) 546 throw (RuntimeException); 547 548 // XInitialization 549 void SAL_CALL initialize( Sequence< Any > const & args ) 550 throw (Exception); 551 552 // XServiceInfo 553 virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); 554 static OUString getImplementationName_Static() throw(::com::sun::star::uno::RuntimeException) 555 { return stoc_bootstrap::smgr_getImplementationName(); } 556 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException); 557 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); 558 559 // XMultiComponentFactory 560 virtual Reference< XInterface > SAL_CALL createInstanceWithContext( 561 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext ) 562 throw (Exception, RuntimeException); 563 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( 564 OUString const & rServiceSpecifier, 565 Sequence< Any > const & rArguments, 566 Reference< XComponentContext > const & xContext ) 567 throw (Exception, RuntimeException); 568 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() 569 // throw (RuntimeException); 570 571 // XMultiServiceFactory 572 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException); 573 virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 574 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 575 576 // The same as the getAvailableServiceNames, but only uique names 577 Sequence< OUString > getUniqueAvailableServiceNames( 578 HashSet_OWString & aNameSet ); 579 580 // XElementAccess 581 virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException); 582 virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException); 583 584 // XEnumerationAccess 585 virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException); 586 587 // XSet 588 virtual sal_Bool SAL_CALL has( const Any & Element ) throw(::com::sun::star::uno::RuntimeException); 589 virtual void SAL_CALL insert( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); 590 virtual void SAL_CALL remove( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); 591 592 // XContentEnumerationAccess 593 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); 594 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException); 595 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration( 596 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) 597 throw(::com::sun::star::uno::RuntimeException); 598 599 // XComponent 600 virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); 601 602 // XPropertySet 603 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() 604 throw(::com::sun::star::uno::RuntimeException); 605 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) 606 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 607 Any SAL_CALL getPropertyValue(const OUString& PropertyName) 608 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 609 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) 610 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 611 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) 612 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 613 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) 614 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 615 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) 616 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 617 618 protected: 619 inline bool is_disposed() const SAL_THROW( (lang::DisposedException) ); 620 inline void check_undisposed() const SAL_THROW( (lang::DisposedException) ); 621 virtual void SAL_CALL disposing(); 622 623 sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName); 624 625 virtual Sequence< Reference< XInterface > > queryServiceFactories( 626 const OUString& aServiceName, Reference< XComponentContext > const & xContext ); 627 628 Reference< XComponentContext > m_xContext; 629 630 Reference< beans::XPropertySetInfo > m_xPropertyInfo; 631 632 sal_Int32 m_nUnloadingListenerId; 633 634 // Does clean up when the unloading mechanism has been set off. It is called from 635 // the listener function smgrUnloadingListener. 636 void onUnloadingNotify(); 637 // factories which have been loaded and not inserted( by XSet::insert) 638 // are remembered by this set. Those factories 639 // are not released on a call to onUnloadingNotify 640 HashSet_Ref m_SetLoadedFactories; 641 private: 642 643 Reference<XEventListener > getFactoryListener(); 644 645 646 HashMultimap_OWString_Interface m_ServiceMap; 647 HashSet_Ref m_ImplementationMap; 648 HashMap_OWString_Interface m_ImplementationNameMap; 649 Reference<XEventListener > xFactoryListener; 650 bool m_bInDisposing; 651 }; 652 653 654 //______________________________________________________________________________ 655 inline bool OServiceManager::is_disposed() const 656 SAL_THROW( (lang::DisposedException) ) 657 { 658 // ought to be guarded by m_mutex: 659 return (m_bInDisposing || rBHelper.bDisposed); 660 } 661 662 //______________________________________________________________________________ 663 inline void OServiceManager::check_undisposed() const 664 SAL_THROW( (lang::DisposedException) ) 665 { 666 if (is_disposed()) 667 { 668 throw lang::DisposedException( 669 OUSTR("service manager instance has already been disposed!"), 670 (OWeakObject *)this ); 671 } 672 } 673 674 //################################################################################################## 675 //################################################################################################## 676 //################################################################################################## 677 678 class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManager_impl 679 { 680 Reference< XComponentContext > m_xContext; 681 OServiceManager * m_root; 682 inline OServiceManager * getRoot() SAL_THROW( (RuntimeException) ) 683 { 684 if (! m_root) 685 { 686 throw lang::DisposedException( 687 OUSTR("service manager instance has already been disposed!"), 688 Reference< XInterface >() ); 689 } 690 return m_root; 691 } 692 693 protected: 694 virtual void SAL_CALL disposing(); 695 696 public: 697 OServiceManagerWrapper( 698 Reference< XComponentContext > const & xContext ) 699 SAL_THROW( (RuntimeException) ); 700 virtual ~OServiceManagerWrapper() SAL_THROW( () ); 701 702 // XUnoTunnel 703 sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id ) throw (RuntimeException) 704 { return getRoot()->getSomething( id ); } 705 706 // XInitialization 707 void SAL_CALL initialize( Sequence< Any > const & args ) throw (Exception) 708 { getRoot()->initialize( args ); } 709 710 // XServiceInfo 711 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException) 712 { return getRoot()->getImplementationName(); } 713 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException) 714 { return getRoot()->supportsService( ServiceName ); } 715 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException) 716 { return getRoot()->getSupportedServiceNames(); } 717 718 // XMultiComponentFactory 719 virtual Reference< XInterface > SAL_CALL createInstanceWithContext( 720 OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext ) 721 throw (Exception, RuntimeException) 722 { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); } 723 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( 724 OUString const & rServiceSpecifier, 725 Sequence< Any > const & rArguments, 726 Reference< XComponentContext > const & xContext ) 727 throw (Exception, RuntimeException) 728 { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); } 729 // virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() 730 // throw (RuntimeException); 731 732 // XMultiServiceFactory 733 virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException) 734 { return getRoot()->getAvailableServiceNames(); } 735 virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) throw (Exception) 736 { return getRoot()->createInstanceWithContext( name, m_xContext ); } 737 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments) throw (Exception) 738 { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); } 739 740 // XElementAccess 741 virtual Type SAL_CALL getElementType() throw (RuntimeException) 742 { return getRoot()->getElementType(); } 743 virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException) 744 { return getRoot()->hasElements(); } 745 746 // XEnumerationAccess 747 virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException) 748 { return getRoot()->createEnumeration(); } 749 750 // XSet 751 virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException) 752 { return getRoot()->has( Element ); } 753 virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException) 754 { getRoot()->insert( Element ); } 755 virtual void SAL_CALL remove( const Any & Element ) throw (lang::IllegalArgumentException, container::NoSuchElementException, RuntimeException) 756 { getRoot()->remove( Element ); } 757 758 // XContentEnumerationAccess 759 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); 760 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException) 761 { return getRoot()->createContentEnumeration( aServiceName, m_xContext ); } 762 763 // XPropertySet 764 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException) 765 { return getRoot()->getPropertySetInfo(); } 766 767 void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue) 768 throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException); 769 Any SAL_CALL getPropertyValue(const OUString& PropertyName) 770 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException); 771 772 void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) 773 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) 774 { getRoot()->addPropertyChangeListener( PropertyName, aListener ); } 775 void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener) 776 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) 777 { getRoot()->removePropertyChangeListener( PropertyName, aListener ); } 778 void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) 779 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) 780 { getRoot()->addVetoableChangeListener( PropertyName, aListener ); } 781 void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener) 782 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) 783 { getRoot()->removeVetoableChangeListener( PropertyName, aListener ); } 784 }; 785 //__________________________________________________________________________________________________ 786 void SAL_CALL OServiceManagerWrapper::setPropertyValue( 787 const OUString& PropertyName, const Any& aValue ) 788 throw (beans::UnknownPropertyException, beans::PropertyVetoException, 789 lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException) 790 { 791 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) 792 { 793 Reference< XComponentContext > xContext; 794 if (aValue >>= xContext) 795 { 796 MutexGuard aGuard( m_mutex ); 797 m_xContext = xContext; 798 } 799 else 800 { 801 throw IllegalArgumentException( 802 OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ), 803 (OWeakObject *)this, 1 ); 804 } 805 } 806 else 807 { 808 getRoot()->setPropertyValue( PropertyName, aValue ); 809 } 810 } 811 //__________________________________________________________________________________________________ 812 Any SAL_CALL OServiceManagerWrapper::getPropertyValue( 813 const OUString& PropertyName ) 814 throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException) 815 { 816 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) 817 { 818 MutexGuard aGuard( m_mutex ); 819 if( m_xContext.is() ) 820 return makeAny( m_xContext ); 821 else 822 return Any(); 823 } 824 else 825 { 826 return getRoot()->getPropertyValue( PropertyName ); 827 } 828 } 829 //__________________________________________________________________________________________________ 830 void OServiceManagerWrapper::disposing() 831 { 832 m_xContext.clear(); 833 834 if (m_root) 835 { 836 // no m_root->dispose(), because every context disposes its service manager... 837 m_root->release(); 838 m_root = 0; 839 } 840 } 841 //__________________________________________________________________________________________________ 842 OServiceManagerWrapper::~OServiceManagerWrapper() SAL_THROW( () ) 843 { 844 if (m_root) 845 { 846 m_root->release(); 847 m_root = 0; 848 } 849 850 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 851 } 852 //__________________________________________________________________________________________________ 853 OServiceManagerWrapper::OServiceManagerWrapper( 854 Reference< XComponentContext > const & xContext ) 855 SAL_THROW( (RuntimeException) ) 856 : t_OServiceManager_impl( m_mutex ) 857 , m_xContext( xContext ) 858 , m_root( 0 ) 859 { 860 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 861 862 Reference< XUnoTunnel > xTunnel( m_xContext->getServiceManager(), UNO_QUERY ); 863 OSL_ASSERT( xTunnel.is() ); 864 if (xTunnel.is()) 865 { 866 m_root = reinterpret_cast< OServiceManager * >( 867 xTunnel->getSomething( smgr_getImplementationId() ) ); 868 OSL_ASSERT( m_root ); 869 if (m_root) 870 { 871 m_root->acquire(); 872 } 873 } 874 875 if (! m_root) 876 { 877 throw RuntimeException( 878 OUString( RTL_CONSTASCII_USTRINGPARAM("can only wrap OServiceManager instances!") ), 879 Reference< XInterface >() ); 880 } 881 } 882 883 //################################################################################################## 884 //################################################################################################## 885 //################################################################################################## 886 887 // XUnoTunnel 888 sal_Int64 OServiceManager::getSomething( Sequence< sal_Int8 > const & id ) 889 throw (RuntimeException) 890 { 891 check_undisposed(); 892 if (id == smgr_getImplementationId()) 893 return reinterpret_cast< sal_Int64 >(this); 894 else 895 return 0; 896 } 897 898 /** 899 * Create a ServiceManager 900 */ 901 OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext ) 902 : t_OServiceManager_impl( m_mutex ) 903 , m_xContext( xContext ) 904 , m_bInDisposing( false ) 905 { 906 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 907 m_nUnloadingListenerId= rtl_addUnloadingListener( smgrUnloadingListener, this); 908 } 909 910 /** 911 * Destroy the ServiceManager 912 */ 913 OServiceManager::~OServiceManager() 914 { 915 if( m_nUnloadingListenerId != 0) 916 rtl_removeUnloadingListener( m_nUnloadingListenerId ); 917 918 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 919 } 920 921 // Removes entries in m_ServiceMap, m_ImplementationNameMap and m_ImplementationNameMap 922 // if those entries have not been inserted through XSet::insert. Therefore the entries 923 // are compared with the entries in m_SetLoadedFactories. 924 void OServiceManager::onUnloadingNotify() 925 { 926 MutexGuard aGuard( m_mutex); 927 928 typedef HashSet_Ref::const_iterator CIT_S; 929 typedef HashMultimap_OWString_Interface::iterator IT_MM; 930 931 CIT_S it_SetEnd= m_SetLoadedFactories.end(); 932 IT_MM it_end1= m_ServiceMap.end(); 933 list<IT_MM> listDeleteServiceMap; 934 typedef list<IT_MM>::const_iterator CIT_DMM; 935 // find occurences in m_ServiceMap 936 for(IT_MM it_i1= m_ServiceMap.begin(); it_i1 != it_end1; it_i1++) 937 { 938 if( m_SetLoadedFactories.find( it_i1->second) != it_SetEnd) 939 { 940 Reference<XUnloadingPreference> xunl( it_i1->second, UNO_QUERY); 941 if( xunl.is()) 942 { 943 if( xunl->releaseOnNotification()) 944 listDeleteServiceMap.push_front( it_i1); 945 } 946 else 947 listDeleteServiceMap.push_front( it_i1); 948 } 949 } 950 // delete elements from m_ServiceMap 951 CIT_DMM it_end2= listDeleteServiceMap.end(); 952 for( CIT_DMM it_i2= listDeleteServiceMap.begin(); it_i2 != it_end2; it_i2++) 953 m_ServiceMap.erase( *it_i2); 954 955 // find elements in m_ImplementationNameMap 956 typedef HashMap_OWString_Interface::iterator IT_M; 957 IT_M it_end3= m_ImplementationNameMap.end(); 958 list<IT_M> listDeleteImplementationNameMap; 959 typedef list<IT_M>::const_iterator CIT_DM; 960 for( IT_M it_i3= m_ImplementationNameMap.begin(); it_i3 != it_end3; it_i3++) 961 { 962 if( m_SetLoadedFactories.find( it_i3->second) != it_SetEnd) 963 { 964 Reference<XUnloadingPreference> xunl( it_i3->second, UNO_QUERY); 965 if( xunl.is()) 966 { 967 if( xunl->releaseOnNotification()) 968 listDeleteImplementationNameMap.push_front( it_i3); 969 } 970 else 971 listDeleteImplementationNameMap.push_front( it_i3); 972 } 973 } 974 // delete elements from m_ImplementationNameMap 975 CIT_DM it_end4= listDeleteImplementationNameMap.end(); 976 for( CIT_DM it_i4= listDeleteImplementationNameMap.begin(); it_i4 != it_end4; it_i4++) 977 m_ImplementationNameMap.erase( *it_i4); 978 979 // find elements in m_ImplementationMap 980 typedef HashSet_Ref::iterator IT_S; 981 IT_S it_end5= m_ImplementationMap.end(); 982 list<IT_S> listDeleteImplementationMap; 983 typedef list<IT_S>::const_iterator CIT_DS; 984 for( IT_S it_i5= m_ImplementationMap.begin(); it_i5 != it_end5; it_i5++) 985 { 986 if( m_SetLoadedFactories.find( *it_i5) != it_SetEnd) 987 { 988 Reference<XUnloadingPreference> xunl( *it_i5, UNO_QUERY); 989 if( xunl.is()) 990 { 991 if( xunl->releaseOnNotification()) 992 listDeleteImplementationMap.push_front( it_i5); 993 } 994 else 995 listDeleteImplementationMap.push_front( it_i5); 996 } 997 } 998 // delete elements from m_ImplementationMap 999 CIT_DS it_end6= listDeleteImplementationMap.end(); 1000 for( CIT_DS it_i6= listDeleteImplementationMap.begin(); it_i6 != it_end6; it_i6++) 1001 m_ImplementationMap.erase( *it_i6); 1002 1003 // remove Event listener before the factories are released. 1004 IT_S it_end7= m_SetLoadedFactories.end(); 1005 1006 Reference<XEventListener> xlistener= getFactoryListener(); 1007 for( IT_S it_i7= m_SetLoadedFactories.begin(); it_i7 != it_end7; it_i7++) 1008 { 1009 Reference<XComponent> xcomp( *it_i7, UNO_QUERY); 1010 if( xcomp.is()) 1011 xcomp->removeEventListener( xlistener); 1012 } 1013 // release the factories in m_SetLoadedFactories 1014 m_SetLoadedFactories.clear(); 1015 } 1016 1017 // XComponent 1018 void OServiceManager::dispose() 1019 throw(::com::sun::star::uno::RuntimeException) 1020 { 1021 if (rBHelper.bDisposed || rBHelper.bInDispose) 1022 return; 1023 t_OServiceManager_impl::dispose(); 1024 } 1025 1026 void OServiceManager::disposing() 1027 { 1028 // dispose all factories 1029 HashSet_Ref aImpls; 1030 { 1031 MutexGuard aGuard( m_mutex ); 1032 m_bInDisposing = true; 1033 aImpls = m_ImplementationMap; 1034 } 1035 HashSet_Ref::iterator aIt = aImpls.begin(); 1036 while( aIt != aImpls.end() ) 1037 { 1038 try 1039 { 1040 Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) ); 1041 if( xComp.is() ) 1042 xComp->dispose(); 1043 } 1044 catch (RuntimeException & exc) 1045 { 1046 #if OSL_DEBUG_LEVEL > 1 1047 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); 1048 OSL_TRACE( "### RuntimeException occured upon disposing factory: %s", str.getStr() ); 1049 #else 1050 (void) exc; // unused 1051 #endif 1052 } 1053 } 1054 1055 // dispose 1056 HashSet_Ref aImplMap; 1057 { 1058 MutexGuard aGuard( m_mutex ); 1059 // erase all members 1060 m_ServiceMap = HashMultimap_OWString_Interface(); 1061 aImplMap = m_ImplementationMap; 1062 m_ImplementationMap = HashSet_Ref(); 1063 m_ImplementationNameMap = HashMap_OWString_Interface(); 1064 m_SetLoadedFactories= HashSet_Ref(); 1065 } 1066 1067 m_xContext.clear(); 1068 1069 // not only the Event should hold the object 1070 OSL_ASSERT( m_refCount != 1 ); 1071 1072 // Revoke this service manager as unloading listener 1073 rtl_removeUnloadingListener( m_nUnloadingListenerId); 1074 m_nUnloadingListenerId=0; 1075 } 1076 1077 // XPropertySet 1078 Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo() 1079 throw(::com::sun::star::uno::RuntimeException) 1080 { 1081 check_undisposed(); 1082 if (! m_xPropertyInfo.is()) 1083 { 1084 Sequence< beans::Property > seq( 1 ); 1085 seq[ 0 ] = beans::Property( 1086 OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 ); 1087 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) ); 1088 1089 MutexGuard aGuard( m_mutex ); 1090 if (! m_xPropertyInfo.is()) 1091 { 1092 m_xPropertyInfo = xInfo; 1093 } 1094 } 1095 return m_xPropertyInfo; 1096 } 1097 1098 void OServiceManager::setPropertyValue( 1099 const OUString& PropertyName, const Any& aValue ) 1100 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1101 { 1102 check_undisposed(); 1103 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) 1104 { 1105 Reference< XComponentContext > xContext; 1106 if (aValue >>= xContext) 1107 { 1108 MutexGuard aGuard( m_mutex ); 1109 m_xContext = xContext; 1110 } 1111 else 1112 { 1113 throw IllegalArgumentException( 1114 OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ), 1115 (OWeakObject *)this, 1 ); 1116 } 1117 } 1118 else 1119 { 1120 throw UnknownPropertyException( 1121 OUString( RTL_CONSTASCII_USTRINGPARAM("unknown property ") ) + PropertyName, 1122 (OWeakObject *)this ); 1123 } 1124 } 1125 1126 Any OServiceManager::getPropertyValue(const OUString& PropertyName) 1127 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1128 { 1129 check_undisposed(); 1130 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") )) 1131 { 1132 MutexGuard aGuard( m_mutex ); 1133 if( m_xContext.is() ) 1134 return makeAny( m_xContext ); 1135 else 1136 return Any(); 1137 } 1138 else 1139 { 1140 UnknownPropertyException except; 1141 except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager : unknown property " ) ); 1142 except.Message += PropertyName; 1143 throw except; 1144 } 1145 } 1146 1147 void OServiceManager::addPropertyChangeListener( 1148 const OUString&, const Reference<XPropertyChangeListener >&) 1149 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1150 { 1151 check_undisposed(); 1152 throw UnknownPropertyException(); 1153 } 1154 1155 void OServiceManager::removePropertyChangeListener( 1156 const OUString&, const Reference<XPropertyChangeListener >&) 1157 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1158 { 1159 check_undisposed(); 1160 throw UnknownPropertyException(); 1161 } 1162 1163 void OServiceManager::addVetoableChangeListener( 1164 const OUString&, const Reference<XVetoableChangeListener >&) 1165 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1166 { 1167 check_undisposed(); 1168 throw UnknownPropertyException(); 1169 } 1170 1171 void OServiceManager::removeVetoableChangeListener( 1172 const OUString&, const Reference<XVetoableChangeListener >&) 1173 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1174 { 1175 check_undisposed(); 1176 throw UnknownPropertyException(); 1177 } 1178 1179 // OServiceManager 1180 Reference<XEventListener > OServiceManager::getFactoryListener() 1181 { 1182 check_undisposed(); 1183 MutexGuard aGuard( m_mutex ); 1184 if( !xFactoryListener.is() ) 1185 xFactoryListener = new OServiceManager_Listener( this ); 1186 return xFactoryListener; 1187 } 1188 1189 // XMultiServiceFactory, XContentEnumeration 1190 Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames( 1191 HashSet_OWString & aNameSet ) 1192 { 1193 check_undisposed(); 1194 MutexGuard aGuard( m_mutex ); 1195 HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin(); 1196 while( aSIt != m_ServiceMap.end() ) 1197 aNameSet.insert( (*aSIt++).first ); 1198 1199 /* do not return the implementation names 1200 HashMap_OWString_Interface m_ImplementationNameMap; 1201 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin(); 1202 while( aIt != m_ImplementationNameMap.end() ) 1203 aNameSet.insert( (*aIt++).first ); 1204 */ 1205 1206 Sequence< OUString > aNames( aNameSet.size() ); 1207 OUString * pArray = aNames.getArray(); 1208 sal_Int32 i = 0; 1209 HashSet_OWString::iterator next = aNameSet.begin(); 1210 while( next != aNameSet.end() ) 1211 pArray[i++] = (*next++); 1212 1213 return aNames; 1214 } 1215 1216 // XMultiComponentFactory 1217 Reference< XInterface > OServiceManager::createInstanceWithContext( 1218 OUString const & rServiceSpecifier, 1219 Reference< XComponentContext > const & xContext ) 1220 throw (Exception, RuntimeException) 1221 { 1222 check_undisposed(); 1223 #if OSL_DEBUG_LEVEL > 0 1224 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY ); 1225 OSL_ASSERT( xProps.is() ); 1226 if (xProps.is()) 1227 { 1228 Reference< XComponentContext > xDefContext; 1229 xProps->getPropertyValue( 1230 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext; 1231 OSL_ENSURE( 1232 xContext == xDefContext, 1233 "### default context of service manager singleton differs from context holding it!" ); 1234 } 1235 #endif 1236 1237 Sequence< Reference< XInterface > > factories( 1238 queryServiceFactories( rServiceSpecifier, xContext ) ); 1239 Reference< XInterface > const * p = factories.getConstArray(); 1240 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos ) 1241 { 1242 try 1243 { 1244 Reference< XInterface > const & xFactory = p[ nPos ]; 1245 if (xFactory.is()) 1246 { 1247 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY ); 1248 if (xFac.is()) 1249 { 1250 return xFac->createInstanceWithContext( xContext ); 1251 } 1252 else 1253 { 1254 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY ); 1255 if (xFac2.is()) 1256 { 1257 #if OSL_DEBUG_LEVEL > 1 1258 OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) ); 1259 OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() ); 1260 #endif 1261 return xFac2->createInstance(); 1262 } 1263 } 1264 } 1265 } 1266 catch (lang::DisposedException & exc) 1267 { 1268 #if OSL_DEBUG_LEVEL > 1 1269 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); 1270 OSL_TRACE( "### DisposedException occured: %s", str.getStr() ); 1271 #else 1272 (void) exc; // unused 1273 #endif 1274 } 1275 } 1276 1277 return Reference< XInterface >(); 1278 } 1279 // XMultiComponentFactory 1280 Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext( 1281 OUString const & rServiceSpecifier, 1282 Sequence< Any > const & rArguments, 1283 Reference< XComponentContext > const & xContext ) 1284 throw (Exception, RuntimeException) 1285 { 1286 check_undisposed(); 1287 #if OSL_DEBUG_LEVEL > 0 1288 Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY ); 1289 OSL_ASSERT( xProps.is() ); 1290 if (xProps.is()) 1291 { 1292 Reference< XComponentContext > xDefContext; 1293 xProps->getPropertyValue( 1294 OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext; 1295 OSL_ENSURE( 1296 xContext == xDefContext, 1297 "### default context of service manager singleton differs from context holding it!" ); 1298 } 1299 #endif 1300 1301 Sequence< Reference< XInterface > > factories( 1302 queryServiceFactories( rServiceSpecifier, xContext ) ); 1303 Reference< XInterface > const * p = factories.getConstArray(); 1304 for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos ) 1305 { 1306 try 1307 { 1308 Reference< XInterface > const & xFactory = p[ nPos ]; 1309 if (xFactory.is()) 1310 { 1311 Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY ); 1312 if (xFac.is()) 1313 { 1314 return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext ); 1315 } 1316 else 1317 { 1318 Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY ); 1319 if (xFac2.is()) 1320 { 1321 #if OSL_DEBUG_LEVEL > 1 1322 OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) ); 1323 OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() ); 1324 #endif 1325 return xFac2->createInstanceWithArguments( rArguments ); 1326 } 1327 } 1328 } 1329 } 1330 catch (lang::DisposedException & exc) 1331 { 1332 #if OSL_DEBUG_LEVEL > 1 1333 OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); 1334 OSL_TRACE( "### DisposedException occured: %s", str.getStr() ); 1335 #else 1336 (void) exc; // unused 1337 #endif 1338 } 1339 } 1340 1341 return Reference< XInterface >(); 1342 } 1343 1344 // XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration 1345 Sequence< OUString > OServiceManager::getAvailableServiceNames() 1346 throw(::com::sun::star::uno::RuntimeException) 1347 { 1348 check_undisposed(); 1349 // all names 1350 HashSet_OWString aNameSet; 1351 return getUniqueAvailableServiceNames( aNameSet ); 1352 } 1353 1354 // XMultibleServiceFactory 1355 Reference<XInterface > OServiceManager::createInstance( 1356 const OUString& rServiceSpecifier ) 1357 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1358 { 1359 return createInstanceWithContext( 1360 rServiceSpecifier, m_xContext ); 1361 } 1362 1363 // XMultibleServiceFactory 1364 Reference<XInterface > OServiceManager::createInstanceWithArguments( 1365 const OUString& rServiceSpecifier, 1366 const Sequence<Any >& rArguments ) 1367 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1368 { 1369 return createInstanceWithArgumentsAndContext( 1370 rServiceSpecifier, rArguments, m_xContext ); 1371 } 1372 1373 // XInitialization 1374 void OServiceManager::initialize( Sequence< Any > const & ) 1375 throw (Exception) 1376 { 1377 check_undisposed(); 1378 OSL_ENSURE( 0, "not impl!" ); 1379 } 1380 1381 // XServiceInfo 1382 OUString OServiceManager::getImplementationName() 1383 throw(::com::sun::star::uno::RuntimeException) 1384 { 1385 check_undisposed(); 1386 return getImplementationName_Static(); 1387 } 1388 1389 // XServiceInfo 1390 sal_Bool OServiceManager::supportsService(const OUString& ServiceName) 1391 throw(::com::sun::star::uno::RuntimeException) 1392 { 1393 check_undisposed(); 1394 Sequence< OUString > aSNL = getSupportedServiceNames(); 1395 const OUString * pArray = aSNL.getConstArray(); 1396 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 1397 if( pArray[i] == ServiceName ) 1398 return sal_True; 1399 return sal_False; 1400 } 1401 1402 // XServiceInfo 1403 Sequence< OUString > OServiceManager::getSupportedServiceNames() 1404 throw(::com::sun::star::uno::RuntimeException) 1405 { 1406 check_undisposed(); 1407 return stoc_bootstrap::smgr_getSupportedServiceNames(); 1408 } 1409 1410 1411 Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories( 1412 const OUString& aServiceName, Reference< XComponentContext > const & ) 1413 { 1414 Sequence< Reference< XInterface > > ret; 1415 1416 MutexGuard aGuard( m_mutex ); 1417 ::std::pair< 1418 HashMultimap_OWString_Interface::iterator, 1419 HashMultimap_OWString_Interface::iterator> p( 1420 m_ServiceMap.equal_range( aServiceName ) ); 1421 1422 if (p.first == p.second) // no factories 1423 { 1424 // no service found, look for an implementation 1425 HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName ); 1426 if( aIt != m_ImplementationNameMap.end() ) 1427 { 1428 Reference< XInterface > const & x = aIt->second; 1429 // an implementation found 1430 ret = Sequence< Reference< XInterface > >( &x, 1 ); 1431 } 1432 } 1433 else 1434 { 1435 ::std::vector< Reference< XInterface > > vec; 1436 vec.reserve( 4 ); 1437 while (p.first != p.second) 1438 { 1439 vec.push_back( p.first->second ); 1440 ++p.first; 1441 } 1442 ret = Sequence< Reference< XInterface > >( 1443 vec.empty() ? 0 : &vec[ 0 ], vec.size() ); 1444 } 1445 1446 return ret; 1447 } 1448 1449 // XContentEnumerationAccess 1450 Reference<XEnumeration > OServiceManager::createContentEnumeration( 1451 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) 1452 throw(::com::sun::star::uno::RuntimeException) 1453 { 1454 check_undisposed(); 1455 Sequence< Reference< XInterface > > factories( 1456 OServiceManager::queryServiceFactories( aServiceName, xContext ) ); 1457 if (factories.getLength()) 1458 return new ServiceEnumeration_Impl( factories ); 1459 else 1460 return Reference< XEnumeration >(); 1461 } 1462 Reference<XEnumeration > OServiceManager::createContentEnumeration( 1463 const OUString& aServiceName ) 1464 throw(::com::sun::star::uno::RuntimeException) 1465 { 1466 return createContentEnumeration( aServiceName, m_xContext ); 1467 } 1468 1469 // XEnumeration 1470 Reference<XEnumeration > OServiceManager::createEnumeration() throw(::com::sun::star::uno::RuntimeException) 1471 { 1472 check_undisposed(); 1473 MutexGuard aGuard( m_mutex ); 1474 return new ImplementationEnumeration_Impl( m_ImplementationMap ); 1475 } 1476 1477 // XElementAccess 1478 Type OServiceManager::getElementType() 1479 throw(::com::sun::star::uno::RuntimeException) 1480 { 1481 check_undisposed(); 1482 return ::getCppuType( (const Reference< XInterface > *)0 ); 1483 } 1484 1485 // XElementAccess 1486 sal_Bool OServiceManager::hasElements() 1487 throw(::com::sun::star::uno::RuntimeException) 1488 { 1489 check_undisposed(); 1490 MutexGuard aGuard( m_mutex ); 1491 return !m_ImplementationMap.empty(); 1492 } 1493 1494 // XSet 1495 sal_Bool OServiceManager::has( const Any & Element ) 1496 throw(::com::sun::star::uno::RuntimeException) 1497 { 1498 check_undisposed(); 1499 if( Element.getValueTypeClass() == TypeClass_INTERFACE ) 1500 { 1501 Reference<XInterface > xEle( Element, UNO_QUERY_THROW ); 1502 MutexGuard aGuard( m_mutex ); 1503 return m_ImplementationMap.find( xEle ) != 1504 m_ImplementationMap.end(); 1505 } 1506 else if (Element.getValueTypeClass() == TypeClass_STRING) 1507 { 1508 OUString const & implName = 1509 *reinterpret_cast< OUString const * >(Element.getValue()); 1510 MutexGuard aGuard( m_mutex ); 1511 return m_ImplementationNameMap.find( implName ) != 1512 m_ImplementationNameMap.end(); 1513 } 1514 return sal_False; 1515 } 1516 1517 // XSet 1518 void OServiceManager::insert( const Any & Element ) 1519 throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException) 1520 { 1521 check_undisposed(); 1522 if( Element.getValueTypeClass() != TypeClass_INTERFACE ) 1523 { 1524 throw IllegalArgumentException( 1525 OUString( RTL_CONSTASCII_USTRINGPARAM("no interface given!") ), 1526 Reference< XInterface >(), 0 ); 1527 } 1528 Reference<XInterface > xEle( Element, UNO_QUERY_THROW ); 1529 1530 { 1531 MutexGuard aGuard( m_mutex ); 1532 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle ); 1533 if( aIt != m_ImplementationMap.end() ) 1534 { 1535 throw ElementExistException( 1536 OUString( RTL_CONSTASCII_USTRINGPARAM("element already exists!") ), 1537 Reference< XInterface >() ); 1538 } 1539 1540 // put into the implementation hashmap 1541 m_ImplementationMap.insert( xEle ); 1542 1543 // put into the implementation name hashmap 1544 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) ); 1545 if( xInfo.is() ) 1546 { 1547 OUString aImplName = xInfo->getImplementationName(); 1548 if( aImplName.getLength() ) 1549 m_ImplementationNameMap[ aImplName ] = xEle; 1550 1551 //put into the service map 1552 Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames(); 1553 const OUString * pArray = aServiceNames.getConstArray(); 1554 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ ) 1555 { 1556 m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type( 1557 pArray[i], *(Reference<XInterface > *)Element.getValue() ) ); 1558 } 1559 } 1560 } 1561 // add the disposing listener to the factory 1562 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) ); 1563 if( xComp.is() ) 1564 xComp->addEventListener( getFactoryListener() ); 1565 } 1566 1567 // helper function 1568 sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName) 1569 { 1570 return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end()); 1571 } 1572 1573 // XSet 1574 void OServiceManager::remove( const Any & Element ) 1575 throw(::com::sun::star::lang::IllegalArgumentException, 1576 ::com::sun::star::container::NoSuchElementException, 1577 ::com::sun::star::uno::RuntimeException) 1578 { 1579 if (is_disposed()) 1580 return; 1581 1582 Reference<XInterface > xEle; 1583 if (Element.getValueTypeClass() == TypeClass_INTERFACE) 1584 { 1585 xEle.set( Element, UNO_QUERY_THROW ); 1586 } 1587 else if (Element.getValueTypeClass() == TypeClass_STRING) 1588 { 1589 OUString const & implName = 1590 *reinterpret_cast< OUString const * >(Element.getValue()); 1591 MutexGuard aGuard( m_mutex ); 1592 HashMap_OWString_Interface::const_iterator const iFind( 1593 m_ImplementationNameMap.find( implName ) ); 1594 if (iFind == m_ImplementationNameMap.end()) 1595 { 1596 throw NoSuchElementException( 1597 OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in: ") ) 1598 + implName, static_cast< OWeakObject * >(this) ); 1599 } 1600 xEle = iFind->second; 1601 } 1602 else 1603 { 1604 throw IllegalArgumentException( 1605 OUString( RTL_CONSTASCII_USTRINGPARAM( 1606 "neither interface nor string given!") ), 1607 Reference< XInterface >(), 0 ); 1608 } 1609 1610 // remove the disposing listener from the factory 1611 Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) ); 1612 if( xComp.is() ) 1613 xComp->removeEventListener( getFactoryListener() ); 1614 1615 MutexGuard aGuard( m_mutex ); 1616 HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle ); 1617 if( aIt == m_ImplementationMap.end() ) 1618 { 1619 throw NoSuchElementException( 1620 OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in!") ), 1621 static_cast< OWeakObject * >(this) ); 1622 } 1623 //First remove all factories which have been loaded by ORegistryServiceManager. 1624 m_SetLoadedFactories.erase( *aIt); 1625 //Remove from the implementation map. It contains all factories of m_SetLoadedFactories 1626 //which have been added directly through XSet, that is not via ORegistryServiceManager 1627 m_ImplementationMap.erase( aIt ); 1628 1629 // remove from the implementation name hashmap 1630 Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) ); 1631 if( xInfo.is() ) 1632 { 1633 OUString aImplName = xInfo->getImplementationName(); 1634 if( aImplName.getLength() ) 1635 m_ImplementationNameMap.erase( aImplName ); 1636 } 1637 1638 //remove from the service map 1639 Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) ); 1640 if( xSF.is() ) 1641 { 1642 Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames(); 1643 const OUString * pArray = aServiceNames.getConstArray(); 1644 for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ ) 1645 { 1646 pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p = 1647 m_ServiceMap.equal_range( pArray[i] ); 1648 1649 while( p.first != p.second ) 1650 { 1651 if( xEle == (*p.first).second ) 1652 { 1653 m_ServiceMap.erase( p.first ); 1654 break; 1655 } 1656 ++p.first; 1657 } 1658 } 1659 } 1660 } 1661 1662 /***************************************************************************** 1663 class ORegistryServiceManager 1664 *****************************************************************************/ 1665 class ORegistryServiceManager : public OServiceManager 1666 { 1667 public: 1668 ORegistryServiceManager( Reference< XComponentContext > const & xContext ); 1669 virtual ~ORegistryServiceManager(); 1670 1671 // XInitialization 1672 void SAL_CALL initialize(const Sequence< Any >& Arguments) 1673 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 1674 1675 // XServiceInfo 1676 OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException) 1677 { return stoc_bootstrap::regsmgr_getImplementationName(); } 1678 1679 Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); 1680 1681 // XMultiServiceFactory 1682 Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException); 1683 1684 // XContentEnumerationAccess 1685 //Sequence< OUString > getAvailableServiceNames() throw( (Exception) ); 1686 Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException); 1687 virtual Reference<XEnumeration > SAL_CALL createContentEnumeration( 1688 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) 1689 throw(::com::sun::star::uno::RuntimeException); 1690 1691 // XComponent 1692 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException); 1693 1694 // OServiceManager 1695 Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() 1696 throw(::com::sun::star::uno::RuntimeException); 1697 Any SAL_CALL getPropertyValue(const OUString& PropertyName) 1698 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 1699 1700 protected: 1701 //OServiceManager 1702 Sequence< Reference< XInterface > > queryServiceFactories( 1703 const OUString& aServiceName, Reference< XComponentContext > const & xContext ); 1704 private: 1705 Reference<XRegistryKey > getRootKey(); 1706 Reference<XInterface > loadWithImplementationName( 1707 const OUString & rImplName, Reference< XComponentContext > const & xContext ); 1708 Sequence<OUString> getFromServiceName(const OUString& serviceName); 1709 Reference<XInterface > loadWithServiceName( 1710 const OUString & rImplName, Reference< XComponentContext > const & xContext ); 1711 void fillAllNamesFromRegistry( HashSet_OWString & ); 1712 1713 sal_Bool m_searchedRegistry; 1714 Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry 1715 Reference<XRegistryKey > m_xRootKey; 1716 1717 #if OSL_DEBUG_LEVEL > 0 1718 bool m_init; 1719 #endif 1720 }; 1721 1722 /** 1723 * Create a ServiceManager 1724 */ 1725 ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext ) 1726 : OServiceManager( xContext ) 1727 , m_searchedRegistry(sal_False) 1728 #if OSL_DEBUG_LEVEL > 0 1729 , m_init( false ) 1730 #endif 1731 { 1732 } 1733 1734 /** 1735 * Destroy the ServiceManager 1736 */ 1737 ORegistryServiceManager::~ORegistryServiceManager() 1738 { 1739 } 1740 1741 // XComponent 1742 void ORegistryServiceManager::dispose() 1743 throw(::com::sun::star::uno::RuntimeException) 1744 { 1745 if (rBHelper.bDisposed || rBHelper.bInDispose) 1746 return; 1747 OServiceManager::dispose(); 1748 // dispose 1749 MutexGuard aGuard( m_mutex ); 1750 // erase all members 1751 m_xRegistry = Reference<XSimpleRegistry >(); 1752 m_xRootKey = Reference<XRegistryKey >(); 1753 } 1754 1755 /** 1756 * Return the root key of the registry. The Default registry service is ordered 1757 * if no registry is set. 1758 */ 1759 //Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider(); 1760 1761 Reference<XRegistryKey > ORegistryServiceManager::getRootKey() 1762 { 1763 if( !m_xRootKey.is() ) 1764 { 1765 MutexGuard aGuard( m_mutex ); 1766 // DefaultRegistry suchen !!!! 1767 if( !m_xRegistry.is() && !m_searchedRegistry ) 1768 { 1769 // merken, es wird nur einmal gesucht 1770 m_searchedRegistry = sal_True; 1771 1772 m_xRegistry.set( 1773 createInstanceWithContext( 1774 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.DefaultRegistry") ), 1775 m_xContext ), 1776 UNO_QUERY ); 1777 } 1778 if( m_xRegistry.is() && !m_xRootKey.is() ) 1779 m_xRootKey = m_xRegistry->getRootKey(); 1780 } 1781 1782 return m_xRootKey; 1783 } 1784 1785 /** 1786 * Create a service provider from the registry with an implementation name 1787 */ 1788 Reference<XInterface > ORegistryServiceManager::loadWithImplementationName( 1789 const OUString& name, Reference< XComponentContext > const & xContext ) 1790 { 1791 Reference<XInterface > ret; 1792 1793 Reference<XRegistryKey > xRootKey = getRootKey(); 1794 if( !xRootKey.is() ) 1795 return ret; 1796 1797 try 1798 { 1799 OUString implementationName = OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS/") ) + name; 1800 Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName); 1801 1802 if( xImpKey.is() ) 1803 { 1804 Reference< lang::XMultiServiceFactory > xMgr; 1805 if (xContext.is()) 1806 xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW ); 1807 else 1808 xMgr.set( this ); 1809 ret = createSingleRegistryFactory( xMgr, name, xImpKey ); 1810 insert( makeAny( ret ) ); 1811 // Remember this factory as loaded in contrast to inserted ( XSet::insert) 1812 // factories. Those loaded factories in this set are candidates for being 1813 // released on an unloading notification. 1814 m_SetLoadedFactories.insert( ret); 1815 } 1816 } 1817 catch (InvalidRegistryException &) 1818 { 1819 } 1820 1821 return ret; 1822 } 1823 1824 /** 1825 * Return all implementation out of the registry. 1826 */ 1827 Sequence<OUString> ORegistryServiceManager::getFromServiceName( 1828 const OUString& serviceName ) 1829 { 1830 OUStringBuffer buf; 1831 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/SERVICES/" ) ); 1832 buf.append( serviceName ); 1833 return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() ); 1834 } 1835 1836 /** 1837 * Create a service provider from the registry 1838 */ 1839 Reference<XInterface > ORegistryServiceManager::loadWithServiceName( 1840 const OUString& serviceName, Reference< XComponentContext > const & xContext ) 1841 { 1842 Sequence<OUString> implEntries = getFromServiceName( serviceName ); 1843 for (sal_Int32 i = 0; i < implEntries.getLength(); i++) 1844 { 1845 Reference< XInterface > x( 1846 loadWithImplementationName( implEntries.getConstArray()[i], xContext ) ); 1847 if (x.is()) 1848 return x; 1849 } 1850 1851 return Reference<XInterface >(); 1852 } 1853 1854 /** 1855 * Return a sequence of all service names from the registry. 1856 */ 1857 void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet ) 1858 { 1859 Reference<XRegistryKey > xRootKey = getRootKey(); 1860 if( !xRootKey.is() ) 1861 return; 1862 1863 try 1864 { 1865 Reference<XRegistryKey > xServicesKey = xRootKey->openKey( 1866 OUString( RTL_CONSTASCII_USTRINGPARAM("SERVICES") ) ); 1867 // root + /Services + / 1868 if( xServicesKey.is() ) 1869 { 1870 sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1; 1871 Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys(); 1872 for( sal_Int32 i = 0; i < aKeys.getLength(); i++ ) 1873 rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) ); 1874 } 1875 } 1876 catch (InvalidRegistryException &) 1877 { 1878 } 1879 } 1880 1881 // XInitialization 1882 void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments) 1883 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1884 { 1885 check_undisposed(); 1886 MutexGuard aGuard( m_mutex ); 1887 if (Arguments.getLength() > 0) 1888 { 1889 m_xRootKey.clear(); 1890 Arguments[ 0 ] >>= m_xRegistry; 1891 } 1892 #if OSL_DEBUG_LEVEL > 0 1893 // to find all bootstrapping processes to be fixed... 1894 OSL_ENSURE( !m_init, "### second init of service manager instance!" ); 1895 m_init = true; 1896 #endif 1897 } 1898 1899 // XMultiServiceFactory, XContentEnumeration 1900 Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames() 1901 throw(::com::sun::star::uno::RuntimeException) 1902 { 1903 check_undisposed(); 1904 MutexGuard aGuard( m_mutex ); 1905 // all names 1906 HashSet_OWString aNameSet; 1907 1908 // all names from the registry 1909 fillAllNamesFromRegistry( aNameSet ); 1910 1911 return OServiceManager::getUniqueAvailableServiceNames( aNameSet ); 1912 } 1913 1914 // XServiceInfo 1915 Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames() 1916 throw(::com::sun::star::uno::RuntimeException) 1917 { 1918 check_undisposed(); 1919 return stoc_bootstrap::regsmgr_getSupportedServiceNames(); 1920 } 1921 1922 1923 // OServiceManager 1924 Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories( 1925 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) 1926 { 1927 Sequence< Reference< XInterface > > ret( 1928 OServiceManager::queryServiceFactories( aServiceName, xContext ) ); 1929 if (ret.getLength()) 1930 { 1931 return ret; 1932 } 1933 else 1934 { 1935 MutexGuard aGuard( m_mutex ); 1936 Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) ); 1937 if (! x.is()) 1938 x = loadWithImplementationName( aServiceName, xContext ); 1939 return Sequence< Reference< XInterface > >( &x, 1 ); 1940 } 1941 } 1942 1943 // XContentEnumerationAccess 1944 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration( 1945 const OUString& aServiceName, Reference< XComponentContext > const & xContext ) 1946 throw(::com::sun::star::uno::RuntimeException) 1947 { 1948 check_undisposed(); 1949 MutexGuard aGuard( ((ORegistryServiceManager *)this)->m_mutex ); 1950 // get all implementation names registered under this service name from the registry 1951 Sequence<OUString> aImpls = ((ORegistryServiceManager *)this)->getFromServiceName( aServiceName ); 1952 // load and insert all factories specified by the registry 1953 sal_Int32 i; 1954 OUString aImplName; 1955 for( i = 0; i < aImpls.getLength(); i++ ) 1956 { 1957 aImplName = aImpls.getConstArray()[i]; 1958 if ( !haveFactoryWithThisImplementation(aImplName) ) 1959 { 1960 loadWithImplementationName( aImplName, xContext ); 1961 } 1962 } 1963 // call the superclass to enumerate all contents 1964 return OServiceManager::createContentEnumeration( aServiceName, xContext ); 1965 } 1966 Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration( 1967 const OUString& aServiceName ) 1968 throw(::com::sun::star::uno::RuntimeException) 1969 { 1970 return createContentEnumeration( aServiceName, m_xContext ); 1971 } 1972 1973 // OServiceManager 1974 Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo() 1975 throw(::com::sun::star::uno::RuntimeException) 1976 { 1977 check_undisposed(); 1978 if (! m_xPropertyInfo.is()) 1979 { 1980 Sequence< beans::Property > seq( 2 ); 1981 seq[ 0 ] = beans::Property( 1982 OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 ); 1983 seq[ 1 ] = beans::Property( 1984 OUSTR("Registry"), -1, ::getCppuType( &m_xRegistry ), 1985 beans::PropertyAttribute::READONLY ); 1986 Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) ); 1987 1988 MutexGuard aGuard( m_mutex ); 1989 if (! m_xPropertyInfo.is()) 1990 { 1991 m_xPropertyInfo = xInfo; 1992 } 1993 } 1994 return m_xPropertyInfo; 1995 } 1996 1997 Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName) 1998 throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 1999 { 2000 check_undisposed(); 2001 if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Registry") )) 2002 { 2003 MutexGuard aGuard( m_mutex ); 2004 if( m_xRegistry.is() ) 2005 return makeAny( m_xRegistry ); 2006 else 2007 return Any(); 2008 } 2009 return OServiceManager::getPropertyValue( PropertyName ); 2010 } 2011 2012 /* This is the listener function used by the service manager in order 2013 to implement the unloading mechanism, id is the this pointer of the 2014 service manager instances. On notification, that is the function is being called 2015 by rtl_unloadUnusedModules, the cached factroies are being removed from the 2016 service manager ( except manually inserted factories). 2017 */ 2018 extern "C" void SAL_CALL smgrUnloadingListener(void* id) 2019 { 2020 stoc_smgr::OServiceManager* pMgr= reinterpret_cast<stoc_smgr::OServiceManager*>( id); 2021 pMgr->onUnloadingNotify(); 2022 } 2023 2024 } // namespace 2025 2026 namespace stoc_bootstrap 2027 { 2028 /** 2029 * Create the ServiceManager 2030 */ 2031 Reference<XInterface > SAL_CALL OServiceManager_CreateInstance( 2032 const Reference< XComponentContext > & xContext ) 2033 { 2034 return Reference<XInterface >( 2035 SAL_STATIC_CAST( 2036 XInterface *, SAL_STATIC_CAST( 2037 OWeakObject *, new stoc_smgr::OServiceManager( xContext ) ) ) ); 2038 } 2039 2040 /** 2041 * Create the ServiceManager 2042 */ 2043 Reference<XInterface > SAL_CALL ORegistryServiceManager_CreateInstance( 2044 const Reference< XComponentContext > & xContext ) 2045 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 2046 { 2047 return Reference<XInterface >( 2048 SAL_STATIC_CAST( 2049 XInterface *, SAL_STATIC_CAST( 2050 OWeakObject *, new stoc_smgr::ORegistryServiceManager( xContext ) ) ) ); 2051 } 2052 2053 Reference<XInterface > SAL_CALL OServiceManagerWrapper_CreateInstance( 2054 const Reference< XComponentContext > & xContext ) 2055 throw (Exception) 2056 { 2057 return (OWeakObject *)new stoc_smgr::OServiceManagerWrapper( xContext ); 2058 } 2059 } 2060