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