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