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