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