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