xref: /AOO41X/main/stoc/source/servicemanager/servicemanager.cxx (revision 647a425c57429e1e89af1c7acf2de6af6f1bb730)
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 {
smgr_wrapper_getSupportedServiceNames()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 
smgr_wrapper_getImplementationName()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 
smgr_getSupportedServiceNames()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 
smgr_getImplementationName()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 
regsmgr_getSupportedServiceNames()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 
regsmgr_getImplementationName()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 {
smgr_getImplementationId()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 
retrieveAsciiValueList(const Reference<XSimpleRegistry> & xReg,const OUString & keyName)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 {
operator ()stoc_smgr::hashRef_Impl271     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 {
operator ()stoc_smgr::equaltoRef_Impl281     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:
ServiceEnumeration_Impl(const Sequence<Reference<XInterface>> & rFactories)296     ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
297         : aFactories( rFactories )
298         , nIt( 0 )
299         { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); }
~ServiceEnumeration_Impl()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
hasMoreElements()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
nextElement()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 //__________________________________________________________________________________________________
getProperties()351 Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
352     throw (RuntimeException)
353 {
354     return m_properties;
355 }
356 //__________________________________________________________________________________________________
getPropertyByName(OUString const & name)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 //__________________________________________________________________________________________________
hasPropertyByName(OUString const & name)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:
ImplementationEnumeration_Impl(const HashSet_Ref & rImplementationMap)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 
~ImplementationEnumeration_Impl()411 ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl()
412 {
413     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
414 }
415 
416 // XEnumeration
hasMoreElements()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
nextElement()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 {
operator ()stoc_smgr::equalOWString_Impl442   sal_Bool operator()(const OUString & s1, const OUString & s2) const
443         { return s1 == s2; }
444 };
445 
446 struct hashOWString_Impl
447 {
operator ()stoc_smgr::hashOWString_Impl448     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:
OServiceManager_Listener(const Reference<XSet> & rSMgr)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 
disposing(const EventObject & rEvt)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);
getImplementationName_Static()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 //______________________________________________________________________________
is_disposed() const651 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 //______________________________________________________________________________
check_undisposed() const659 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;
getRoot()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
getSomething(Sequence<sal_Int8> const & id)699     sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id ) throw (RuntimeException)
700         { return getRoot()->getSomething( id ); }
701 
702     // XInitialization
initialize(Sequence<Any> const & args)703     void SAL_CALL initialize( Sequence< Any > const & args ) throw (Exception)
704         { getRoot()->initialize( args ); }
705 
706     // XServiceInfo
getImplementationName()707     virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
708         { return getRoot()->getImplementationName(); }
supportsService(const OUString & ServiceName)709     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException)
710         { return getRoot()->supportsService( ServiceName ); }
getSupportedServiceNames()711     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException)
712         { return getRoot()->getSupportedServiceNames(); }
713 
714     // XMultiComponentFactory
createInstanceWithContext(OUString const & rServiceSpecifier,Reference<XComponentContext> const & xContext)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 ); }
createInstanceWithArgumentsAndContext(OUString const & rServiceSpecifier,Sequence<Any> const & rArguments,Reference<XComponentContext> const & 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
getAvailableServiceNames()729     virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException)
730         { return getRoot()->getAvailableServiceNames(); }
createInstance(const OUString & name)731     virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) throw (Exception)
732         { return getRoot()->createInstanceWithContext( name, m_xContext ); }
createInstanceWithArguments(const OUString & name,const Sequence<Any> & Arguments)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
getElementType()737     virtual Type SAL_CALL getElementType() throw (RuntimeException)
738         { return getRoot()->getElementType(); }
hasElements()739     virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException)
740         { return getRoot()->hasElements(); }
741 
742     // XEnumerationAccess
createEnumeration()743     virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException)
744         { return getRoot()->createEnumeration(); }
745 
746     // XSet
has(const Any & Element)747     virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException)
748         { return getRoot()->has( Element ); }
insert(const Any & Element)749     virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException)
750         { getRoot()->insert( Element ); }
remove(const Any & 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) );
createContentEnumeration(const OUString & aServiceName)756     virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException)
757         { return getRoot()->createContentEnumeration( aServiceName, m_xContext ); }
758 
759     // XPropertySet
getPropertySetInfo()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 
addPropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & aListener)768     void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
769         throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
770         { getRoot()->addPropertyChangeListener( PropertyName, aListener ); }
removePropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & 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 ); }
addVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & 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 ); }
removeVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & 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 //__________________________________________________________________________________________________
setPropertyValue(const OUString & PropertyName,const Any & aValue)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 //__________________________________________________________________________________________________
getPropertyValue(const OUString & PropertyName)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 //__________________________________________________________________________________________________
disposing()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 //__________________________________________________________________________________________________
~OServiceManagerWrapper()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 //__________________________________________________________________________________________________
OServiceManagerWrapper(Reference<XComponentContext> const & xContext)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
getSomething(Sequence<sal_Int8> const & id)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  */
OServiceManager(Reference<XComponentContext> const & xContext)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  */
~OServiceManager()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.
onUnloadingNotify()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
dispose()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 
disposing()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
getPropertySetInfo()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 
setPropertyValue(const OUString & PropertyName,const Any & aValue)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 
getPropertyValue(const OUString & PropertyName)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 
addPropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)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 
removePropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)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 
addVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)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 
removeVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)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
getFactoryListener()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
getUniqueAvailableServiceNames(HashSet_OWString & aNameSet)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
createInstanceWithContext(OUString const & rServiceSpecifier,Reference<XComponentContext> const & xContext)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
createInstanceWithArgumentsAndContext(OUString const & rServiceSpecifier,Sequence<Any> const & rArguments,Reference<XComponentContext> const & xContext)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
getAvailableServiceNames()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
createInstance(const OUString & rServiceSpecifier)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
createInstanceWithArguments(const OUString & rServiceSpecifier,const Sequence<Any> & rArguments)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
initialize(Sequence<Any> const &)1370 void OServiceManager::initialize( Sequence< Any > const & )
1371     throw (Exception)
1372 {
1373     check_undisposed();
1374     OSL_ENSURE( 0, "not impl!" );
1375 }
1376 
1377 // XServiceInfo
getImplementationName()1378 OUString OServiceManager::getImplementationName()
1379     throw(::com::sun::star::uno::RuntimeException)
1380 {
1381     check_undisposed();
1382     return getImplementationName_Static();
1383 }
1384 
1385 // XServiceInfo
supportsService(const OUString & ServiceName)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
getSupportedServiceNames()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 
queryServiceFactories(const OUString & aServiceName,Reference<XComponentContext> const &)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
createContentEnumeration(const OUString & aServiceName,Reference<XComponentContext> const & xContext)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 }
createContentEnumeration(const OUString & aServiceName)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
createEnumeration()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
getElementType()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
hasElements()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
has(const Any & Element)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
insert(const Any & Element)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
haveFactoryWithThisImplementation(const OUString & aImplName)1564 sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
1565 {
1566     return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
1567 }
1568 
1569 // XSet
remove(const Any & Element)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
getImplementationName()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  */
ORegistryServiceManager(Reference<XComponentContext> const & xContext)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  */
~ORegistryServiceManager()1733 ORegistryServiceManager::~ORegistryServiceManager()
1734 {
1735 }
1736 
1737 // XComponent
dispose()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 
getRootKey()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  */
loadWithImplementationName(const OUString & name,Reference<XComponentContext> const & xContext)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  */
getFromServiceName(const OUString & serviceName)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  */
loadWithServiceName(const OUString & serviceName,Reference<XComponentContext> const & xContext)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  */
fillAllNamesFromRegistry(HashSet_OWString & rSet)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
initialize(const Sequence<Any> & Arguments)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
getAvailableServiceNames()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
getSupportedServiceNames()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
queryServiceFactories(const OUString & aServiceName,Reference<XComponentContext> const & xContext)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
createContentEnumeration(const OUString & aServiceName,Reference<XComponentContext> const & xContext)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 }
createContentEnumeration(const OUString & aServiceName)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
getPropertySetInfo()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 
getPropertyValue(const OUString & PropertyName)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 */
smgrUnloadingListener(void * id)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  */
OServiceManager_CreateInstance(const Reference<XComponentContext> & xContext)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  */
ORegistryServiceManager_CreateInstance(const Reference<XComponentContext> & xContext)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 
OServiceManagerWrapper_CreateInstance(const Reference<XComponentContext> & xContext)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