xref: /aoo42x/main/cppuhelper/source/factory.cxx (revision cdf0e10c)
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_cppuhelper.hxx"
30 #include <osl/diagnose.h>
31 #include <osl/mutex.hxx>
32 #include <cppuhelper/weak.hxx>
33 #include <cppuhelper/component.hxx>
34 #include <cppuhelper/factory.hxx>
35 #ifndef _CPPUHELPER_IMPLBASE3_HXX
36 #include <cppuhelper/implbase3.hxx>
37 #endif
38 #include <cppuhelper/typeprovider.hxx>
39 #include <rtl/unload.h>
40 
41 #include "cppuhelper/propshlp.hxx"
42 
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
45 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
46 #include <com/sun/star/lang/XInitialization.hpp>
47 #include <com/sun/star/loader/XImplementationLoader.hpp>
48 #include <com/sun/star/lang/XComponent.hpp>
49 #include <com/sun/star/lang/IllegalArgumentException.hpp>
50 #include <com/sun/star/uno/XUnloadingPreference.hpp>
51 #include "com/sun/star/beans/PropertyAttribute.hpp"
52 
53 #include <memory>
54 
55 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
56 
57 
58 using namespace osl;
59 using namespace rtl;
60 using namespace com::sun::star;
61 using namespace com::sun::star::uno;
62 using namespace com::sun::star::lang;
63 using namespace com::sun::star::loader;
64 using namespace com::sun::star::registry;
65 
66 namespace cppu
67 {
68 
69 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
72 class OSingleFactoryHelper
73 	: public XServiceInfo
74 	, public XSingleServiceFactory
75     , public lang::XSingleComponentFactory
76 	, public XUnloadingPreference
77 {
78 public:
79 	OSingleFactoryHelper(
80 		const Reference<XMultiServiceFactory > & rServiceManager,
81 		const OUString & rImplementationName_,
82 		ComponentInstantiation pCreateFunction_,
83         ComponentFactoryFunc fptr,
84 		const Sequence< OUString > * pServiceNames_ )
85 		SAL_THROW( () )
86 		: xSMgr( rServiceManager )
87 		, pCreateFunction( pCreateFunction_ )
88         , m_fptr( fptr )
89 		, aImplementationName( rImplementationName_ )
90 		{
91 			if( pServiceNames_ )
92 				aServiceNames = *pServiceNames_;
93 		}
94 
95 	// old function, only for backward compatibility
96 	OSingleFactoryHelper(
97 		const Reference<XMultiServiceFactory > & rServiceManager,
98 		const OUString & rImplementationName_ )
99 		SAL_THROW( () )
100 		: xSMgr( rServiceManager )
101 		, pCreateFunction( NULL )
102         , m_fptr( 0 )
103 		, aImplementationName( rImplementationName_ )
104 		{}
105 
106     virtual ~OSingleFactoryHelper();
107 
108 	// XInterface
109 	Any SAL_CALL queryInterface( const Type & rType )
110 		throw(::com::sun::star::uno::RuntimeException);
111 
112 	// XSingleServiceFactory
113     Reference<XInterface > SAL_CALL createInstance()
114 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
115     virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
116 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
117     // XSingleComponentFactory
118     virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
119         Reference< XComponentContext > const & xContext )
120         throw (Exception, RuntimeException);
121     virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
122         Sequence< Any > const & rArguments,
123         Reference< XComponentContext > const & xContext )
124         throw (Exception, RuntimeException);
125 
126 	// XServiceInfo
127 	OUString SAL_CALL getImplementationName()
128 		throw(::com::sun::star::uno::RuntimeException);
129     sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
130 		throw(::com::sun::star::uno::RuntimeException);
131     Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
132 		throw(::com::sun::star::uno::RuntimeException);
133 
134 protected:
135 	/**
136 	 * Create an instance specified by the factory. The one instance logic is implemented
137 	 * in the createInstance and createInstanceWithArguments methods.
138 	 * @return the newly created instance. Do not return a previous (one instance) instance.
139 	 */
140 	virtual Reference<XInterface >	createInstanceEveryTime(
141         Reference< XComponentContext > const & xContext )
142 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
143 
144 	Reference<XMultiServiceFactory > xSMgr;
145 	ComponentInstantiation			 pCreateFunction;
146     ComponentFactoryFunc             m_fptr;
147 	Sequence< OUString >			 aServiceNames;
148 	OUString						 aImplementationName;
149 };
150 OSingleFactoryHelper::~OSingleFactoryHelper()
151 {
152 }
153 
154 
155 //-----------------------------------------------------------------------------
156 Any OSingleFactoryHelper::queryInterface( const Type & rType )
157 	throw(::com::sun::star::uno::RuntimeException)
158 {
159     return ::cppu::queryInterface(
160         rType,
161         static_cast< XSingleComponentFactory * >( this ),
162         static_cast< XSingleServiceFactory * >( this ),
163         static_cast< XServiceInfo * >( this ) ,
164         static_cast< XUnloadingPreference * >( this ));
165 }
166 
167 // OSingleFactoryHelper
168 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
169     Reference< XComponentContext > const & xContext )
170 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
171 {
172     if (m_fptr)
173     {
174         return (*m_fptr)( xContext );
175     }
176     else if( pCreateFunction )
177     {
178         if (xContext.is())
179         {
180             Reference< lang::XMultiServiceFactory > xContextMgr(
181                 xContext->getServiceManager(), UNO_QUERY );
182             if (xContextMgr.is())
183                 return (*pCreateFunction)( xContextMgr );
184         }
185         return (*pCreateFunction)( xSMgr );
186     }
187 	else
188     {
189 		return Reference< XInterface >();
190     }
191 }
192 
193 // XSingleServiceFactory
194 Reference<XInterface > OSingleFactoryHelper::createInstance()
195 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
196 {
197     return createInstanceWithContext( Reference< XComponentContext >() );
198 }
199 
200 // XSingleServiceFactory
201 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
202 	const Sequence<Any>& Arguments )
203 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
204 {
205     return createInstanceWithArgumentsAndContext(
206         Arguments, Reference< XComponentContext >() );
207 }
208 
209 // XSingleComponentFactory
210 //__________________________________________________________________________________________________
211 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
212     Reference< XComponentContext > const & xContext )
213     throw (Exception, RuntimeException)
214 {
215     return createInstanceEveryTime( xContext );
216 }
217 //__________________________________________________________________________________________________
218 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
219     Sequence< Any > const & rArguments,
220     Reference< XComponentContext > const & xContext )
221     throw (Exception, RuntimeException)
222 {
223 	Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
224 
225 	Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
226     // always call initialize, even if there are no arguments.
227     // #i63511# / 2006-03-27 / frank.schoenheit@sun.com
228 	if (xInit.is())
229     {
230 		xInit->initialize( rArguments );
231     }
232 	else
233     {
234 		if ( rArguments.getLength() )
235         {
236             // dispose the here created UNO object before throwing out exception
237             // to avoid risk of memory leaks #i113722#
238             Reference<XComponent> xComp( xRet, UNO_QUERY );
239             if (xComp.is())
240                 xComp->dispose();
241 
242 		    throw lang::IllegalArgumentException(
243                 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot pass arguments to component => no XInitialization implemented!") ),
244                 Reference< XInterface >(), 0 );
245 		}
246     }
247 
248 	return xRet;
249 }
250 
251 // XServiceInfo
252 OUString OSingleFactoryHelper::getImplementationName()
253 	throw(::com::sun::star::uno::RuntimeException)
254 {
255 	return aImplementationName;
256 }
257 
258 // XServiceInfo
259 sal_Bool OSingleFactoryHelper::supportsService(
260     const OUString& ServiceName )
261 	throw(::com::sun::star::uno::RuntimeException)
262 {
263 	Sequence< OUString > seqServices = getSupportedServiceNames();
264 	const OUString * pServices = seqServices.getConstArray();
265 	for( sal_Int32 i = 0; i < seqServices.getLength(); i++ )
266 		if( pServices[i] == ServiceName )
267 			return sal_True;
268 
269 	return sal_False;
270 }
271 
272 // XServiceInfo
273 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void)
274 	throw(::com::sun::star::uno::RuntimeException)
275 {
276 	return aServiceNames;
277 }
278 
279 
280 //----------------------------------------------------------------------
281 //----------------------------------------------------------------------
282 //----------------------------------------------------------------------
283 struct OFactoryComponentHelper_Mutex
284 {
285 	Mutex	aMutex;
286 };
287 
288 class OFactoryComponentHelper
289 	: public OFactoryComponentHelper_Mutex
290 	, public OComponentHelper
291 	, public OSingleFactoryHelper
292 {
293 public:
294 	OFactoryComponentHelper(
295 		const Reference<XMultiServiceFactory > & rServiceManager,
296 		const OUString & rImplementationName_,
297 		ComponentInstantiation pCreateFunction_,
298         ComponentFactoryFunc fptr,
299 		const Sequence< OUString > * pServiceNames_,
300 		sal_Bool bOneInstance_ = sal_False )
301 		SAL_THROW( () )
302 		: OComponentHelper( aMutex )
303 		, OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
304 		, bOneInstance( bOneInstance_ )
305 		, pModuleCount(0)
306 		{
307 		}
308 
309 	// Used by the createXXXFactory functions. The argument pModCount is used to  prevent the unloading of the module
310 	// which contains pCreateFunction_
311 	OFactoryComponentHelper(
312 		const Reference<XMultiServiceFactory > & rServiceManager,
313 		const OUString & rImplementationName_,
314 		ComponentInstantiation pCreateFunction_,
315         ComponentFactoryFunc fptr,
316 		const Sequence< OUString > * pServiceNames_,
317 		rtl_ModuleCount * pModCount,
318 		sal_Bool bOneInstance_ = sal_False )
319 		SAL_THROW( () )
320 		: OComponentHelper( aMutex )
321 		, OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
322 		, bOneInstance( bOneInstance_ )
323 		, pModuleCount(pModCount)
324 		{
325 			if(pModuleCount)
326 				pModuleCount->acquire( pModuleCount);
327 		}
328 
329 	// old function, only for backward compatibility
330 	OFactoryComponentHelper(
331 		const Reference<XMultiServiceFactory > & rServiceManager,
332 		const OUString & rImplementationName_,
333 		sal_Bool bOneInstance_ = sal_False )
334 		SAL_THROW( () )
335 		: OComponentHelper( aMutex )
336 		, OSingleFactoryHelper( rServiceManager, rImplementationName_ )
337 		, bOneInstance( bOneInstance_ )
338 		, pModuleCount(0)
339 		{
340 		}
341 
342 	~OFactoryComponentHelper()
343 	{
344 		if(pModuleCount)
345 			pModuleCount->release( pModuleCount);
346 	}
347 
348 	// XInterface
349 	Any SAL_CALL queryInterface( const Type & rType )
350 		throw(::com::sun::star::uno::RuntimeException);
351 	void SAL_CALL acquire() throw()
352 		{ OComponentHelper::acquire(); }
353 	void SAL_CALL release() throw()
354 		{ OComponentHelper::release(); }
355 
356 	// XSingleServiceFactory
357     Reference<XInterface > SAL_CALL createInstance()
358 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
359 	Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments )
360 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
361     // XSingleComponentFactory
362     virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
363         Reference< XComponentContext > const & xContext )
364         throw (Exception, RuntimeException);
365     virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
366         Sequence< Any > const & rArguments,
367         Reference< XComponentContext > const & xContext )
368         throw (Exception, RuntimeException);
369 
370 	// XTypeProvider
371 	virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
372 	virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
373 
374 	// XAggregation
375 	Any SAL_CALL queryAggregation( const Type & rType )
376 		throw(::com::sun::star::uno::RuntimeException);
377 
378 	// XUnloadingPreference
379 	virtual sal_Bool SAL_CALL releaseOnNotification()
380 		throw(::com::sun::star::uno::RuntimeException);
381 
382 	// OComponentHelper
383 	void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
384 
385 private:
386 	Reference<XInterface >	xTheInstance;
387 	sal_Bool				bOneInstance;
388 	rtl_ModuleCount	*		pModuleCount;
389 protected:
390 	// needed for implementing XUnloadingPreference in inheriting classes
391 	sal_Bool isOneInstance() {return bOneInstance;}
392 	sal_Bool isInstance() {return xTheInstance.is();}
393 };
394 
395 
396 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
397 	throw(::com::sun::star::uno::RuntimeException)
398 {
399 	if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0))
400 	{
401 		return makeAny(
402             Reference< XUnloadingPreference >(
403                 static_cast< XUnloadingPreference * >(this) ) );
404 	}
405 	return OComponentHelper::queryInterface( rType );
406 }
407 
408 // XAggregation
409 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
410 	throw(::com::sun::star::uno::RuntimeException)
411 {
412 	Any aRet( OComponentHelper::queryAggregation( rType ) );
413 	return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
414 }
415 
416 // XTypeProvider
417 Sequence< Type > OFactoryComponentHelper::getTypes()
418 	throw (::com::sun::star::uno::RuntimeException)
419 {
420     Type ar[ 4 ];
421     ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 );
422     ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 );
423     ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 );
424 
425     if (m_fptr)
426         ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 );
427 
428     return Sequence< Type >( ar, m_fptr ? 4 : 3 );
429 }
430 
431 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
432 	throw (::com::sun::star::uno::RuntimeException)
433 {
434 	static OImplementationId * pId = 0;
435 	if (! pId)
436 	{
437 		MutexGuard aGuard( Mutex::getGlobalMutex() );
438 		if (! pId)
439 		{
440 			static OImplementationId aId;
441 			pId = &aId;
442 		}
443 	}
444 	return pId->getImplementationId();
445 }
446 
447 // XSingleServiceFactory
448 Reference<XInterface > OFactoryComponentHelper::createInstance()
449 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
450 {
451 	if( bOneInstance )
452 	{
453 		if( !xTheInstance.is() )
454         {
455             MutexGuard aGuard( aMutex );
456             if( !xTheInstance.is() )
457                 xTheInstance = OSingleFactoryHelper::createInstance();
458         }
459 		return xTheInstance;
460 	}
461 	return OSingleFactoryHelper::createInstance();
462 }
463 
464 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
465 	const Sequence<Any>& Arguments )
466 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
467 {
468 	if( bOneInstance )
469 	{
470 		if( !xTheInstance.is() )
471         {
472             MutexGuard aGuard( aMutex );
473 //          OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
474             if( !xTheInstance.is() )
475                 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
476         }
477         return xTheInstance;
478 	}
479 	return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
480 }
481 
482 // XSingleComponentFactory
483 //__________________________________________________________________________________________________
484 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
485     Reference< XComponentContext > const & xContext )
486     throw (Exception, RuntimeException)
487 {
488 	if( bOneInstance )
489 	{
490 		if( !xTheInstance.is() )
491         {
492             MutexGuard aGuard( aMutex );
493 //          OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
494             if( !xTheInstance.is() )
495                 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
496         }
497 		return xTheInstance;
498 	}
499 	return OSingleFactoryHelper::createInstanceWithContext( xContext );
500 }
501 //__________________________________________________________________________________________________
502 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
503     Sequence< Any > const & rArguments,
504     Reference< XComponentContext > const & xContext )
505     throw (Exception, RuntimeException)
506 {
507 	if( bOneInstance )
508 	{
509 		if( !xTheInstance.is() )
510         {
511             MutexGuard aGuard( aMutex );
512 //          OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
513             if( !xTheInstance.is() )
514                 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
515         }
516 		return xTheInstance;
517 	}
518 	return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
519 }
520 
521 
522 // OComponentHelper
523 void OFactoryComponentHelper::dispose()
524 	throw(::com::sun::star::uno::RuntimeException)
525 {
526 	OComponentHelper::dispose();
527 
528 	Reference<XInterface > x;
529 	{
530 		// do not delete in the guard section
531 		MutexGuard aGuard( aMutex );
532 		x = xTheInstance;
533 		xTheInstance = Reference<XInterface >();
534 	}
535 	// if it is a component call dispose at the component
536 	Reference<XComponent > xComp( x, UNO_QUERY );
537 	if( xComp.is() )
538 		xComp->dispose();
539 }
540 
541 // XUnloadingPreference
542 // This class is used for single factories, component factories and
543 // one-instance factories. Depending on the usage this function has
544 // to return different values.
545 // one-instance factory: sal_False
546 // single factory: sal_True
547 // component factory: sal_True
548 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
549 {
550 	if( bOneInstance)
551 		return sal_False;
552 	return sal_True;
553 }
554 
555 
556 //-----------------------------------------------------------------------------
557 //-----------------------------------------------------------------------------
558 //-----------------------------------------------------------------------------
559 class ORegistryFactoryHelper : public OFactoryComponentHelper,
560                                public OPropertySetHelper
561 
562 {
563 public:
564 	ORegistryFactoryHelper(
565 		const Reference<XMultiServiceFactory > & rServiceManager,
566 		const OUString & rImplementationName_,
567 		const Reference<XRegistryKey > & xImplementationKey_,
568 		sal_Bool bOneInstance_ = sal_False ) SAL_THROW( () )
569             : OFactoryComponentHelper(
570                 rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ),
571               OPropertySetHelper( OComponentHelper::rBHelper ),
572               xImplementationKey( xImplementationKey_ )
573 		{}
574 
575     // XInterface
576     virtual Any SAL_CALL queryInterface( Type const & type )
577         throw (RuntimeException);
578     virtual void SAL_CALL acquire() throw ();
579     virtual void SAL_CALL release() throw ();
580     // XTypeProvider
581     virtual Sequence< Type > SAL_CALL getTypes()
582         throw (RuntimeException);
583     // XPropertySet
584     virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
585         throw (RuntimeException);
586 
587     // OPropertySetHelper
588     virtual IPropertyArrayHelper & SAL_CALL getInfoHelper();
589     virtual sal_Bool SAL_CALL convertFastPropertyValue(
590         Any & rConvertedValue, Any & rOldValue,
591         sal_Int32 nHandle, Any const & rValue )
592         throw (lang::IllegalArgumentException);
593     virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
594         sal_Int32 nHandle, Any const & rValue )
595         throw (Exception);
596     using OPropertySetHelper::getFastPropertyValue;
597     virtual void SAL_CALL getFastPropertyValue(
598         Any & rValue, sal_Int32 nHandle ) const;
599 
600 	// OSingleFactoryHelper
601 	Reference<XInterface > createInstanceEveryTime(
602         Reference< XComponentContext > const & xContext )
603 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
604 
605 	// XSingleServiceFactory
606 	Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
607 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
608     // XSingleComponentFactory
609     Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
610         Sequence< Any > const & rArguments,
611         Reference< XComponentContext > const & xContext )
612         throw (Exception, RuntimeException);
613 
614 	// XServiceInfo
615     Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
616 		throw(::com::sun::star::uno::RuntimeException);
617 	// XUnloadingPreference
618 	sal_Bool SAL_CALL releaseOnNotification()
619 		throw( RuntimeException);
620 
621 
622 private:
623 	Reference< XInterface > createModuleFactory()
624 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
625 
626 	/** The registry key of the implementation section */
627 	Reference<XRegistryKey >	xImplementationKey;
628 	/** The factory created with the loader. */
629 	Reference<XSingleComponentFactory >	xModuleFactory;
630 	Reference<XSingleServiceFactory >	xModuleFactoryDepr;
631     Reference< beans::XPropertySetInfo > m_xInfo;
632     ::std::auto_ptr< IPropertyArrayHelper > m_property_array_helper;
633 protected:
634     using OPropertySetHelper::getTypes;
635 };
636 
637 // XInterface
638 //______________________________________________________________________________
639 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
640     Type const & type ) throw (RuntimeException)
641 {
642     Any ret( OFactoryComponentHelper::queryInterface( type ) );
643     if (ret.hasValue())
644         return ret;
645     else
646         return OPropertySetHelper::queryInterface( type );
647 }
648 
649 //______________________________________________________________________________
650 void ORegistryFactoryHelper::acquire() throw ()
651 {
652     OFactoryComponentHelper::acquire();
653 }
654 
655 //______________________________________________________________________________
656 void ORegistryFactoryHelper::release() throw ()
657 {
658     OFactoryComponentHelper::release();
659 }
660 
661 // XTypeProvider
662 //______________________________________________________________________________
663 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException)
664 {
665     Sequence< Type > types( OFactoryComponentHelper::getTypes() );
666     sal_Int32 pos = types.getLength();
667     types.realloc( pos + 3 );
668     Type * p = types.getArray();
669     p[ pos++ ] = ::getCppuType(
670         reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) );
671     p[ pos++ ] = ::getCppuType(
672         reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) );
673     p[ pos++ ] = ::getCppuType(
674         reinterpret_cast< Reference< beans::XPropertySet > const * >(0) );
675     return types;
676 }
677 
678 // XPropertySet
679 //______________________________________________________________________________
680 Reference< beans::XPropertySetInfo >
681 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException)
682 {
683     ::osl::MutexGuard guard( aMutex );
684     if (! m_xInfo.is())
685         m_xInfo = createPropertySetInfo( getInfoHelper() );
686     return m_xInfo;
687 }
688 
689 // OPropertySetHelper
690 //______________________________________________________________________________
691 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
692 {
693     ::osl::MutexGuard guard( aMutex );
694     if (m_property_array_helper.get() == 0)
695     {
696         beans::Property prop(
697             OUSTR("ImplementationKey") /* name */,
698             0 /* handle */,
699             ::getCppuType( &xImplementationKey ),
700             beans::PropertyAttribute::READONLY |
701             beans::PropertyAttribute::OPTIONAL );
702         m_property_array_helper.reset(
703             new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
704     }
705     return *m_property_array_helper.get();
706 }
707 
708 //______________________________________________________________________________
709 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
710     Any &, Any &, sal_Int32, Any const & )
711     throw (lang::IllegalArgumentException)
712 {
713     OSL_ENSURE( 0, "unexpected!" );
714     return false;
715 }
716 
717 //______________________________________________________________________________
718 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
719     sal_Int32, Any const & )
720     throw (Exception)
721 {
722     throw beans::PropertyVetoException(
723         OUSTR("unexpected: only readonly properties!"),
724         static_cast< OWeakObject * >(this) );
725 }
726 
727 //______________________________________________________________________________
728 void ORegistryFactoryHelper::getFastPropertyValue(
729     Any & rValue, sal_Int32 nHandle ) const
730 {
731     if (nHandle == 0)
732     {
733         rValue <<= xImplementationKey;
734     }
735     else
736     {
737         rValue.clear();
738         throw beans::UnknownPropertyException(
739             OUSTR("unknown property!"), static_cast< OWeakObject * >(
740                 const_cast< ORegistryFactoryHelper * >(this) ) );
741     }
742 }
743 
744 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
745     Reference< XComponentContext > const & xContext )
746 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
747 {
748 	if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
749 	{
750         Reference< XInterface > x( createModuleFactory() );
751         if (x.is())
752         {
753             MutexGuard aGuard( aMutex );
754             if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
755             {
756                 xModuleFactory.set( x, UNO_QUERY );
757                 xModuleFactoryDepr.set( x, UNO_QUERY );
758             }
759         }
760 	}
761 	if( xModuleFactory.is() )
762     {
763 		return xModuleFactory->createInstanceWithContext( xContext );
764     }
765     else if( xModuleFactoryDepr.is() )
766     {
767 		return xModuleFactoryDepr->createInstance();
768     }
769 
770 	return Reference<XInterface >();
771 }
772 
773 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
774     const Sequence<Any>& Arguments )
775     throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
776 {
777 	if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
778 	{
779         Reference< XInterface > x( createModuleFactory() );
780         if (x.is())
781         {
782             MutexGuard aGuard( aMutex );
783             if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
784             {
785                 xModuleFactory.set( x, UNO_QUERY );
786                 xModuleFactoryDepr.set( x, UNO_QUERY );
787             }
788         }
789 	}
790     if( xModuleFactoryDepr.is() )
791     {
792 		return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
793     }
794 	else if( xModuleFactory.is() )
795     {
796 #if OSL_DEBUG_LEVEL > 1
797         OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" );
798 #endif
799 		return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
800     }
801 
802 	return Reference<XInterface >();
803 }
804 
805 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
806     Sequence< Any > const & rArguments,
807     Reference< XComponentContext > const & xContext )
808     throw (Exception, RuntimeException)
809 {
810 	if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
811 	{
812         Reference< XInterface > x( createModuleFactory() );
813         if (x.is())
814         {
815             MutexGuard aGuard( aMutex );
816             if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
817             {
818                 xModuleFactory.set( x, UNO_QUERY );
819                 xModuleFactoryDepr.set( x, UNO_QUERY );
820             }
821         }
822 	}
823 	if( xModuleFactory.is() )
824     {
825 		return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
826     }
827     else if( xModuleFactoryDepr.is() )
828     {
829 #if OSL_DEBUG_LEVEL > 1
830         if (xContext.is())
831         {
832             OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" );
833         }
834 #endif
835 		return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
836     }
837 
838 	return Reference<XInterface >();
839 }
840 
841 
842 // OSingleFactoryHelper
843 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
844 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
845 {
846     OUString aActivatorUrl;
847     OUString aActivatorName;
848     OUString aLocation;
849 
850     Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
851         OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) );
852     if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
853     {
854         aActivatorUrl = xActivatorKey->getAsciiValue();
855 
856         OUString tmpActivator(aActivatorUrl.getStr());
857         sal_Int32 nIndex = 0;
858         aActivatorName = tmpActivator.getToken(0, ':', nIndex );
859 
860         Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
861             OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) );
862         if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
863             aLocation = xLocationKey->getAsciiValue();
864     }
865     else
866     {
867         // old style"url"
868         // the location of the program code of the implementation
869         Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
870             OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/URL") ) );
871         // is the the key of the right type ?
872         if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
873         {
874             // one implementation found -> try to activate
875             aLocation = xLocationKey->getAsciiValue();
876 
877             // search protocol delemitter
878             sal_Int32 nPos = aLocation.indexOf(
879                 OUString( RTL_CONSTASCII_USTRINGPARAM("://") ) );
880             if( nPos != -1 )
881             {
882                 aActivatorName = aLocation.copy( 0, nPos );
883                 if( aActivatorName.compareToAscii( "java" ) == 0 )
884                     aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") );
885                 else if( aActivatorName.compareToAscii( "module" ) == 0 )
886                     aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") );
887                 aLocation = aLocation.copy( nPos + 3 );
888             }
889         }
890     }
891 
892 	Reference< XInterface >	xFactory;
893     if( aActivatorName.getLength() != 0 )
894     {
895         Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
896         Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
897         Reference<XInterface > xMF;
898         if (xLoader.is())
899         {
900             xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
901         }
902     }
903 	return xFactory;
904 }
905 
906 // XServiceInfo
907 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void)
908 	throw(::com::sun::star::uno::RuntimeException)
909 {
910 	MutexGuard aGuard( aMutex );
911 	if( aServiceNames.getLength() == 0 )
912 	{
913 		// not yet loaded
914 		try
915 		{
916 			Reference<XRegistryKey > xKey = xImplementationKey->openKey(
917 				OUString( RTL_CONSTASCII_USTRINGPARAM("UNO/SERVICES") ) );
918 
919 			if (xKey.is())
920 			{
921 				// length of prefix. +1 for the '/' at the end
922 				sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
923 
924 				// Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
925 				Sequence<OUString> seqKeys = xKey->getKeyNames();
926 				OUString* pKeys = seqKeys.getArray();
927 				for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
928 					pKeys[i] = pKeys[i].copy(nPrefixLen);
929 
930 				aServiceNames = seqKeys;
931 			}
932 		}
933 		catch (InvalidRegistryException &)
934 		{
935 		}
936 	}
937 	return aServiceNames;
938 }
939 
940 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
941 {
942 	sal_Bool retVal= sal_True;
943 	if( isOneInstance() && isInstance())
944 	{
945 		retVal= sal_False;
946 	}
947 	else if( ! isOneInstance())
948 	{
949 		// try to delegate
950 		if( xModuleFactory.is())
951 		{
952 			Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
953 			if( xunloading.is())
954 				retVal= xunloading->releaseOnNotification();
955 		}
956 		else if( xModuleFactoryDepr.is())
957 		{
958 			Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
959 			if( xunloading.is())
960 				retVal= xunloading->releaseOnNotification();
961 		}
962 	}
963 	return retVal;
964 }
965 
966 //-----------------------------------------------------------------------------
967 //-----------------------------------------------------------------------------
968 //-----------------------------------------------------------------------------
969 
970 class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory,
971 													XUnloadingPreference >
972 {
973 	Reference<XSingleServiceFactory >	xFactory;
974 
975 public:
976 
977 	OFactoryProxyHelper(
978 		const Reference<XMultiServiceFactory > & /*rServiceManager*/,
979 		const Reference<XSingleServiceFactory > & rFactory )
980 		SAL_THROW( () )
981 		: xFactory( rFactory )
982 		{}
983 
984 	// XSingleServiceFactory
985     Reference<XInterface > SAL_CALL createInstance()
986 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
987     Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
988 		throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
989 
990 	// XServiceInfo
991 	OUString SAL_CALL getImplementationName()
992 		throw(::com::sun::star::uno::RuntimeException);
993     sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
994 		throw(::com::sun::star::uno::RuntimeException);
995     Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
996 		throw(::com::sun::star::uno::RuntimeException);
997 	//XUnloadingPreference
998 	sal_Bool SAL_CALL releaseOnNotification()
999 		throw(::com::sun::star::uno::RuntimeException);
1000 
1001 };
1002 
1003 // XSingleServiceFactory
1004 Reference<XInterface > OFactoryProxyHelper::createInstance()
1005 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1006 {
1007 	return xFactory->createInstance();
1008 }
1009 
1010 // XSingleServiceFactory
1011 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
1012 (
1013 	const Sequence<Any>& Arguments
1014 )
1015 	throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1016 {
1017 	return xFactory->createInstanceWithArguments( Arguments );
1018 }
1019 
1020 // XServiceInfo
1021 OUString OFactoryProxyHelper::getImplementationName()
1022 	throw(::com::sun::star::uno::RuntimeException)
1023 {
1024 	Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY  );
1025 	if( xInfo.is() )
1026 		return xInfo->getImplementationName();
1027 	return OUString();
1028 }
1029 
1030 // XServiceInfo
1031 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
1032 	throw(::com::sun::star::uno::RuntimeException)
1033 {
1034 	Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY  );
1035 	if( xInfo.is() )
1036 		return xInfo->supportsService( ServiceName );
1037 	return sal_False;
1038 }
1039 
1040 // XServiceInfo
1041 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void)
1042 	throw(::com::sun::star::uno::RuntimeException)
1043 {
1044 	Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY  );
1045 	if( xInfo.is() )
1046 		return xInfo->getSupportedServiceNames();
1047 	return Sequence< OUString >();
1048 }
1049 
1050 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
1051 {
1052 
1053 	Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
1054 	if( pref.is())
1055 		return pref->releaseOnNotification();
1056 	return sal_True;
1057 }
1058 
1059 
1060 //-----------------------------------------------------------------------------
1061 //-----------------------------------------------------------------------------
1062 //-----------------------------------------------------------------------------
1063 // global function
1064 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
1065 	const Reference<XMultiServiceFactory > & rServiceManager,
1066 	const OUString & rImplementationName,
1067 	ComponentInstantiation pCreateFunction,
1068 	const Sequence< OUString > & rServiceNames,
1069 	rtl_ModuleCount *pModCount )
1070 	SAL_THROW( () )
1071 {
1072 	return new OFactoryComponentHelper(
1073         rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_False );
1074 }
1075 
1076 // global function
1077 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
1078 	const Reference<XMultiServiceFactory > & rServiceManager,
1079 	const Reference<XSingleServiceFactory > & rFactory )
1080 	SAL_THROW( () )
1081 {
1082 	return new OFactoryProxyHelper(
1083         rServiceManager, rFactory );
1084 }
1085 
1086 // global function
1087 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
1088 	const Reference<XMultiServiceFactory > & rServiceManager,
1089 	const OUString & rImplementationName,
1090 	ComponentInstantiation pCreateFunction,
1091 	const Sequence< OUString > & rServiceNames,
1092 	rtl_ModuleCount *pModCount )
1093 	SAL_THROW( () )
1094 {
1095 	return new OFactoryComponentHelper(
1096         rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True );
1097 //	return new OFactoryUnloadableComponentHelper(
1098 //		rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True );
1099 }
1100 
1101 // global function
1102 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
1103 	const Reference<XMultiServiceFactory > & rServiceManager,
1104 	const OUString & rImplementationName,
1105 	const Reference<XRegistryKey > & rImplementationKey )
1106 	SAL_THROW( () )
1107 {
1108 	return new ORegistryFactoryHelper(
1109         rServiceManager, rImplementationName, rImplementationKey, sal_False );
1110 }
1111 
1112 // global function
1113 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
1114 	const Reference<XMultiServiceFactory > & rServiceManager,
1115 	const OUString & rImplementationName,
1116 	const Reference<XRegistryKey > & rImplementationKey )
1117 	SAL_THROW( () )
1118 {
1119 	return new ORegistryFactoryHelper(
1120         rServiceManager, rImplementationName, rImplementationKey, sal_True );
1121 }
1122 
1123 //##################################################################################################
1124 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1125 	ComponentFactoryFunc fptr,
1126     OUString const & rImplementationName,
1127     Sequence< OUString > const & rServiceNames,
1128 	rtl_ModuleCount * pModCount)
1129 	SAL_THROW( () )
1130 {
1131 	return new OFactoryComponentHelper(
1132         Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_False );
1133 }
1134 
1135 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1136 	ComponentFactoryFunc fptr,
1137     OUString const & rImplementationName,
1138     Sequence< OUString > const & rServiceNames,
1139 	rtl_ModuleCount * pModCount)
1140 	SAL_THROW( () )
1141 {
1142 	return new OFactoryComponentHelper(
1143         Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_True );
1144 }
1145 
1146 }
1147 
1148 
1149