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