xref: /trunk/main/cppuhelper/source/factory.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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