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