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