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