cURL: follow redirects
[LibreOffice.git] / cppuhelper / source / factory.cxx
blob891db88d22665c55ba4a847621a2eef9db6554bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
33 #include <cppuhelper/propshlp.hxx>
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>
45 #include <memory>
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;
55 using ::rtl::OUString;
57 namespace cppu
60 class OSingleFactoryHelper
61 : public XServiceInfo
62 , public XSingleServiceFactory
63 , public lang::XSingleComponentFactory
64 , public XUnloadingPreference
66 public:
67 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 , aImplementationName( rImplementationName_ )
78 if( pServiceNames_ )
79 aServiceNames = *pServiceNames_;
82 virtual ~OSingleFactoryHelper();
84 // XInterface
85 Any SAL_CALL queryInterface( const Type & rType )
86 throw(css::uno::RuntimeException, std::exception) override;
88 // XSingleServiceFactory
89 Reference<XInterface > SAL_CALL createInstance()
90 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) override;
91 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
92 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) override;
93 // XSingleComponentFactory
94 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
95 Reference< XComponentContext > const & xContext )
96 throw (Exception, RuntimeException, std::exception) override;
97 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
98 Sequence< Any > const & rArguments,
99 Reference< XComponentContext > const & xContext )
100 throw (Exception, RuntimeException, std::exception) override;
102 // XServiceInfo
103 OUString SAL_CALL getImplementationName()
104 throw(css::uno::RuntimeException, std::exception) override;
105 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
106 throw(css::uno::RuntimeException, std::exception) override;
107 Sequence< OUString > SAL_CALL getSupportedServiceNames()
108 throw(css::uno::RuntimeException, std::exception) override;
110 protected:
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.
116 virtual Reference<XInterface > createInstanceEveryTime(
117 Reference< XComponentContext > const & xContext )
118 throw(css::uno::Exception, css::uno::RuntimeException);
120 Reference<XMultiServiceFactory > xSMgr;
121 ComponentInstantiation pCreateFunction;
122 ComponentFactoryFunc m_fptr;
123 Sequence< OUString > aServiceNames;
124 OUString aImplementationName;
126 OSingleFactoryHelper::~OSingleFactoryHelper()
131 Any OSingleFactoryHelper::queryInterface( const Type & rType )
132 throw(css::uno::RuntimeException, std::exception)
134 return ::cppu::queryInterface(
135 rType,
136 static_cast< XSingleComponentFactory * >( this ),
137 static_cast< XSingleServiceFactory * >( this ),
138 static_cast< XServiceInfo * >( this ) ,
139 static_cast< XUnloadingPreference * >( this ));
142 // OSingleFactoryHelper
143 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
144 Reference< XComponentContext > const & xContext )
145 throw(css::uno::Exception, css::uno::RuntimeException)
147 if (m_fptr)
149 return (*m_fptr)( xContext );
151 else if( pCreateFunction )
153 if (xContext.is())
155 Reference< lang::XMultiServiceFactory > xContextMgr(
156 xContext->getServiceManager(), UNO_QUERY );
157 if (xContextMgr.is())
158 return (*pCreateFunction)( xContextMgr );
160 return (*pCreateFunction)( xSMgr );
162 else
164 return Reference< XInterface >();
168 // XSingleServiceFactory
169 Reference<XInterface > OSingleFactoryHelper::createInstance()
170 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
172 return createInstanceWithContext( Reference< XComponentContext >() );
175 // XSingleServiceFactory
176 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
177 const Sequence<Any>& Arguments )
178 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
180 return createInstanceWithArgumentsAndContext(
181 Arguments, Reference< XComponentContext >() );
184 // XSingleComponentFactory
186 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
187 Reference< XComponentContext > const & xContext )
188 throw (Exception, RuntimeException, std::exception)
190 return createInstanceEveryTime( xContext );
193 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
194 Sequence< Any > const & rArguments,
195 Reference< XComponentContext > const & xContext )
196 throw (Exception, RuntimeException, std::exception)
198 Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
200 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 if (xInit.is())
205 xInit->initialize( rArguments );
207 else
209 if ( rArguments.getLength() )
211 // dispose the here created UNO object before throwing out exception
212 // to avoid risk of memory leaks #i113722#
213 Reference<XComponent> xComp( xRet, UNO_QUERY );
214 if (xComp.is())
215 xComp->dispose();
217 throw lang::IllegalArgumentException(
218 OUString("cannot pass arguments to component => no XInitialization implemented!"),
219 Reference< XInterface >(), 0 );
223 return xRet;
226 // XServiceInfo
227 OUString OSingleFactoryHelper::getImplementationName()
228 throw(css::uno::RuntimeException, std::exception)
230 return aImplementationName;
233 // XServiceInfo
234 sal_Bool OSingleFactoryHelper::supportsService(
235 const OUString& ServiceName )
236 throw(css::uno::RuntimeException, std::exception)
238 return cppu::supportsService(this, ServiceName);
241 // XServiceInfo
242 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames()
243 throw(css::uno::RuntimeException, std::exception)
245 return aServiceNames;
248 struct OFactoryComponentHelper_Mutex
250 Mutex aMutex;
253 class OFactoryComponentHelper
254 : public OFactoryComponentHelper_Mutex
255 , public OComponentHelper
256 , public OSingleFactoryHelper
258 public:
259 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 , bOneInstance( bOneInstance_ )
272 // XInterface
273 Any SAL_CALL queryInterface( const Type & rType )
274 throw(css::uno::RuntimeException, std::exception) override;
275 void SAL_CALL acquire() throw() override
276 { OComponentHelper::acquire(); }
277 void SAL_CALL release() throw() override
278 { OComponentHelper::release(); }
280 // XSingleServiceFactory
281 Reference<XInterface > SAL_CALL createInstance()
282 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) override;
283 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments )
284 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) override;
285 // XSingleComponentFactory
286 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
287 Reference< XComponentContext > const & xContext )
288 throw (Exception, RuntimeException, std::exception) override;
289 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
290 Sequence< Any > const & rArguments,
291 Reference< XComponentContext > const & xContext )
292 throw (Exception, RuntimeException, std::exception) override;
294 // XTypeProvider
295 virtual Sequence< Type > SAL_CALL getTypes() throw (css::uno::RuntimeException, std::exception) override;
296 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(css::uno::RuntimeException, std::exception) override;
298 // XAggregation
299 Any SAL_CALL queryAggregation( const Type & rType )
300 throw(css::uno::RuntimeException, std::exception) override;
302 // XUnloadingPreference
303 virtual sal_Bool SAL_CALL releaseOnNotification()
304 throw(css::uno::RuntimeException, std::exception) override;
306 // OComponentHelper
307 void SAL_CALL dispose() throw(css::uno::RuntimeException, std::exception) override;
309 private:
310 Reference<XInterface > xTheInstance;
311 bool bOneInstance;
312 protected:
313 // needed for implementing XUnloadingPreference in inheriting classes
314 bool isOneInstance() {return bOneInstance;}
315 bool isInstance() {return xTheInstance.is();}
319 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
320 throw(css::uno::RuntimeException, std::exception)
322 if( rType == cppu::UnoType<XUnloadingPreference>::get() )
324 return makeAny(
325 Reference< XUnloadingPreference >(
326 static_cast< XUnloadingPreference * >(this) ) );
328 return OComponentHelper::queryInterface( rType );
331 // XAggregation
332 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
333 throw(css::uno::RuntimeException, std::exception)
335 Any aRet( OComponentHelper::queryAggregation( rType ) );
336 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
339 // XTypeProvider
340 Sequence< Type > OFactoryComponentHelper::getTypes()
341 throw (css::uno::RuntimeException, std::exception)
343 Type ar[ 4 ];
344 ar[ 0 ] = cppu::UnoType<XSingleServiceFactory>::get();
345 ar[ 1 ] = cppu::UnoType<XServiceInfo>::get();
346 ar[ 2 ] = cppu::UnoType<XUnloadingPreference>::get();
348 if (m_fptr)
349 ar[ 3 ] = cppu::UnoType<XSingleComponentFactory>::get();
351 return Sequence< Type >( ar, m_fptr ? 4 : 3 );
354 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
355 throw (css::uno::RuntimeException, std::exception)
357 return css::uno::Sequence<sal_Int8>();
360 // XSingleServiceFactory
361 Reference<XInterface > OFactoryComponentHelper::createInstance()
362 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
364 if( bOneInstance )
366 if( !xTheInstance.is() )
368 MutexGuard aGuard( aMutex );
369 if( !xTheInstance.is() )
370 xTheInstance = OSingleFactoryHelper::createInstance();
372 return xTheInstance;
374 return OSingleFactoryHelper::createInstance();
377 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
378 const Sequence<Any>& Arguments )
379 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
381 if( bOneInstance )
383 if( !xTheInstance.is() )
385 MutexGuard aGuard( aMutex );
386 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
387 if( !xTheInstance.is() )
388 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
390 return xTheInstance;
392 return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
395 // XSingleComponentFactory
397 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
398 Reference< XComponentContext > const & xContext )
399 throw (Exception, RuntimeException, std::exception)
401 if( bOneInstance )
403 if( !xTheInstance.is() )
405 MutexGuard aGuard( aMutex );
406 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
407 if( !xTheInstance.is() )
408 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
410 return xTheInstance;
412 return OSingleFactoryHelper::createInstanceWithContext( xContext );
415 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
416 Sequence< Any > const & rArguments,
417 Reference< XComponentContext > const & xContext )
418 throw (Exception, RuntimeException, std::exception)
420 if( bOneInstance )
422 if( !xTheInstance.is() )
424 MutexGuard aGuard( aMutex );
425 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
426 if( !xTheInstance.is() )
427 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
429 return xTheInstance;
431 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
435 // OComponentHelper
436 void OFactoryComponentHelper::dispose()
437 throw(css::uno::RuntimeException, std::exception)
439 OComponentHelper::dispose();
441 Reference<XInterface > x;
443 // do not delete in the guard section
444 MutexGuard aGuard( aMutex );
445 x = xTheInstance;
446 xTheInstance.clear();
448 // if it is a component call dispose at the component
449 Reference<XComponent > xComp( x, UNO_QUERY );
450 if( xComp.is() )
451 xComp->dispose();
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 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(css::uno::RuntimeException, std::exception)
463 if( bOneInstance)
464 return false;
465 return true;
468 class ORegistryFactoryHelper : public OFactoryComponentHelper,
469 public OPropertySetHelper
472 public:
473 ORegistryFactoryHelper(
474 const Reference<XMultiServiceFactory > & rServiceManager,
475 const OUString & rImplementationName_,
476 const Reference<XRegistryKey > & xImplementationKey_,
477 bool bOneInstance_ = false )
478 : OFactoryComponentHelper(
479 rServiceManager, rImplementationName_, nullptr, nullptr, nullptr, bOneInstance_ ),
480 OPropertySetHelper( OComponentHelper::rBHelper ),
481 xImplementationKey( xImplementationKey_ )
484 // XInterface
485 virtual Any SAL_CALL queryInterface( Type const & type )
486 throw (RuntimeException, std::exception) override;
487 virtual void SAL_CALL acquire() throw () override;
488 virtual void SAL_CALL release() throw () override;
489 // XTypeProvider
490 virtual Sequence< Type > SAL_CALL getTypes()
491 throw (RuntimeException, std::exception) override;
492 // XPropertySet
493 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
494 throw (RuntimeException, std::exception) override;
496 // OPropertySetHelper
497 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper() override;
498 virtual sal_Bool SAL_CALL convertFastPropertyValue(
499 Any & rConvertedValue, Any & rOldValue,
500 sal_Int32 nHandle, Any const & rValue )
501 throw (lang::IllegalArgumentException) override;
502 virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
503 sal_Int32 nHandle, Any const & rValue )
504 throw (Exception, std::exception) override;
505 using OPropertySetHelper::getFastPropertyValue;
506 virtual void SAL_CALL getFastPropertyValue(
507 Any & rValue, sal_Int32 nHandle ) const override;
509 // OSingleFactoryHelper
510 Reference<XInterface > createInstanceEveryTime(
511 Reference< XComponentContext > const & xContext )
512 throw(css::uno::Exception, css::uno::RuntimeException) override;
514 // XSingleServiceFactory
515 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
516 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) 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) override;
523 // XServiceInfo
524 Sequence< OUString > SAL_CALL getSupportedServiceNames()
525 throw(css::uno::RuntimeException, std::exception) override;
526 // XUnloadingPreference
527 sal_Bool SAL_CALL releaseOnNotification()
528 throw( RuntimeException, std::exception) override;
531 private:
532 Reference< XInterface > createModuleFactory()
533 throw(css::uno::Exception, css::uno::RuntimeException);
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;
546 // XInterface
548 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
549 Type const & type ) throw (RuntimeException, std::exception)
551 Any ret( OFactoryComponentHelper::queryInterface( type ) );
552 if (ret.hasValue())
553 return ret;
554 else
555 return OPropertySetHelper::queryInterface( type );
559 void ORegistryFactoryHelper::acquire() throw ()
561 OFactoryComponentHelper::acquire();
565 void ORegistryFactoryHelper::release() throw ()
567 OFactoryComponentHelper::release();
570 // XTypeProvider
572 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException, std::exception)
574 Sequence< Type > types( OFactoryComponentHelper::getTypes() );
575 sal_Int32 pos = types.getLength();
576 types.realloc( pos + 3 );
577 Type * p = types.getArray();
578 p[ pos++ ] = cppu::UnoType<beans::XMultiPropertySet>::get();
579 p[ pos++ ] = cppu::UnoType<beans::XFastPropertySet>::get();
580 p[ pos++ ] = cppu::UnoType<beans::XPropertySet>::get();
581 return types;
584 // XPropertySet
586 Reference< beans::XPropertySetInfo >
587 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException, std::exception)
589 ::osl::MutexGuard guard( aMutex );
590 if (! m_xInfo.is())
591 m_xInfo = createPropertySetInfo( getInfoHelper() );
592 return m_xInfo;
595 // OPropertySetHelper
597 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
599 ::osl::MutexGuard guard( aMutex );
600 if (m_property_array_helper.get() == nullptr)
602 beans::Property prop(
603 "ImplementationKey" /* name */,
604 0 /* handle */,
605 cppu::UnoType<decltype(xImplementationKey)>::get(),
606 beans::PropertyAttribute::READONLY |
607 beans::PropertyAttribute::OPTIONAL );
608 m_property_array_helper.reset(
609 new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
611 return *m_property_array_helper.get();
615 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
616 Any &, Any &, sal_Int32, Any const & )
617 throw (lang::IllegalArgumentException)
619 OSL_FAIL( "unexpected!" );
620 return false;
624 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
625 sal_Int32, Any const & )
626 throw (Exception, std::exception)
628 throw beans::PropertyVetoException(
629 "unexpected: only readonly properties!",
630 static_cast< OWeakObject * >(this) );
634 void ORegistryFactoryHelper::getFastPropertyValue(
635 Any & rValue, sal_Int32 nHandle ) const
637 if (nHandle == 0)
639 rValue <<= xImplementationKey;
641 else
643 rValue.clear();
644 throw beans::UnknownPropertyException(
645 "unknown property!", static_cast< OWeakObject * >(
646 const_cast< ORegistryFactoryHelper * >(this) ) );
650 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
651 Reference< XComponentContext > const & xContext )
652 throw(css::uno::Exception, css::uno::RuntimeException)
654 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
656 Reference< XInterface > x( createModuleFactory() );
657 if (x.is())
659 MutexGuard aGuard( aMutex );
660 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
662 xModuleFactory.set( x, UNO_QUERY );
663 xModuleFactoryDepr.set( x, UNO_QUERY );
667 if( xModuleFactory.is() )
669 return xModuleFactory->createInstanceWithContext( xContext );
671 else if( xModuleFactoryDepr.is() )
673 return xModuleFactoryDepr->createInstance();
676 return Reference<XInterface >();
679 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
680 const Sequence<Any>& Arguments )
681 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
683 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
685 Reference< XInterface > x( createModuleFactory() );
686 if (x.is())
688 MutexGuard aGuard( aMutex );
689 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
691 xModuleFactory.set( x, UNO_QUERY );
692 xModuleFactoryDepr.set( x, UNO_QUERY );
696 if( xModuleFactoryDepr.is() )
698 return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
700 else if( xModuleFactory.is() )
702 SAL_INFO("cppuhelper", "no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!");
703 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
706 return Reference<XInterface >();
709 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
710 Sequence< Any > const & rArguments,
711 Reference< XComponentContext > const & xContext )
712 throw (Exception, RuntimeException, std::exception)
714 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
716 Reference< XInterface > x( createModuleFactory() );
717 if (x.is())
719 MutexGuard aGuard( aMutex );
720 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
722 xModuleFactory.set( x, UNO_QUERY );
723 xModuleFactoryDepr.set( x, UNO_QUERY );
727 if( xModuleFactory.is() )
729 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
731 else if( xModuleFactoryDepr.is() )
733 SAL_INFO_IF(xContext.is(), "cppuhelper", "ignoring context calling ORegistryFactoryHelper::createInstaceWithArgumentsAndContext()!");
734 return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
737 return Reference<XInterface >();
741 // OSingleFactoryHelper
742 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
743 throw(css::uno::Exception, css::uno::RuntimeException)
745 OUString aActivatorUrl;
746 OUString aActivatorName;
747 OUString aLocation;
749 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
750 "/UNO/ACTIVATOR" );
751 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
753 aActivatorUrl = xActivatorKey->getAsciiValue();
755 OUString tmpActivator(aActivatorUrl.getStr());
756 sal_Int32 nIndex = 0;
757 aActivatorName = tmpActivator.getToken(0, ':', nIndex );
759 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
760 "/UNO/LOCATION" );
761 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
762 aLocation = xLocationKey->getAsciiValue();
764 else
766 // old style"url"
767 // the location of the program code of the implementation
768 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
769 "/UNO/URL" );
770 // is the key of the right type ?
771 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
773 // one implementation found -> try to activate
774 aLocation = xLocationKey->getAsciiValue();
776 // search protocol delimiter
777 sal_Int32 nPos = aLocation.indexOf("://");
778 if( nPos != -1 )
780 aActivatorName = aLocation.copy( 0, nPos );
781 if( aActivatorName == "java" )
782 aActivatorName = "com.sun.star.loader.Java";
783 else if( aActivatorName == "module" )
784 aActivatorName = "com.sun.star.loader.SharedLibrary";
785 aLocation = aLocation.copy( nPos + 3 );
790 Reference< XInterface > xFactory;
791 if( !aActivatorName.isEmpty() )
793 Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
794 Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
795 Reference<XInterface > xMF;
796 if (xLoader.is())
798 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
801 return xFactory;
804 // XServiceInfo
805 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames()
806 throw(css::uno::RuntimeException, std::exception)
808 MutexGuard aGuard( aMutex );
809 if( aServiceNames.getLength() == 0 )
811 // not yet loaded
814 Reference<XRegistryKey > xKey = xImplementationKey->openKey( "UNO/SERVICES" );
816 if (xKey.is())
818 // length of prefix. +1 for the '/' at the end
819 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
821 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
822 Sequence<OUString> seqKeys = xKey->getKeyNames();
823 OUString* pKeys = seqKeys.getArray();
824 for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
825 pKeys[i] = pKeys[i].copy(nPrefixLen);
827 aServiceNames = seqKeys;
830 catch (InvalidRegistryException &)
834 return aServiceNames;
837 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(css::uno::RuntimeException, std::exception)
839 bool retVal= true;
840 if( isOneInstance() && isInstance())
842 retVal= false;
844 else if( ! isOneInstance())
846 // try to delegate
847 if( xModuleFactory.is())
849 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
850 if( xunloading.is())
851 retVal= xunloading->releaseOnNotification();
853 else if( xModuleFactoryDepr.is())
855 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
856 if( xunloading.is())
857 retVal= xunloading->releaseOnNotification();
860 return retVal;
863 class OFactoryProxyHelper : public WeakImplHelper< XServiceInfo, XSingleServiceFactory,
864 XUnloadingPreference >
866 Reference<XSingleServiceFactory > xFactory;
868 public:
870 explicit OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
871 : xFactory( rFactory )
874 // XSingleServiceFactory
875 Reference<XInterface > SAL_CALL createInstance()
876 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) override;
877 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
878 throw(css::uno::Exception, css::uno::RuntimeException, std::exception) override;
880 // XServiceInfo
881 OUString SAL_CALL getImplementationName()
882 throw(css::uno::RuntimeException, std::exception) override;
883 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
884 throw(css::uno::RuntimeException, std::exception) override;
885 Sequence< OUString > SAL_CALL getSupportedServiceNames()
886 throw(css::uno::RuntimeException, std::exception) override;
887 //XUnloadingPreference
888 sal_Bool SAL_CALL releaseOnNotification()
889 throw(css::uno::RuntimeException, std::exception) override;
893 // XSingleServiceFactory
894 Reference<XInterface > OFactoryProxyHelper::createInstance()
895 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
897 return xFactory->createInstance();
900 // XSingleServiceFactory
901 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
903 const Sequence<Any>& Arguments
905 throw(css::uno::Exception, css::uno::RuntimeException, std::exception)
907 return xFactory->createInstanceWithArguments( Arguments );
910 // XServiceInfo
911 OUString OFactoryProxyHelper::getImplementationName()
912 throw(css::uno::RuntimeException, std::exception)
914 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
915 if( xInfo.is() )
916 return xInfo->getImplementationName();
917 return OUString();
920 // XServiceInfo
921 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
922 throw(css::uno::RuntimeException, std::exception)
924 return cppu::supportsService(this, ServiceName);
927 // XServiceInfo
928 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames()
929 throw(css::uno::RuntimeException, std::exception)
931 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
932 if( xInfo.is() )
933 return xInfo->getSupportedServiceNames();
934 return Sequence< OUString >();
937 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(css::uno::RuntimeException, std::exception)
940 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
941 if( pref.is())
942 return pref->releaseOnNotification();
943 return true;
946 // global function
947 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
948 const Reference<XMultiServiceFactory > & rServiceManager,
949 const OUString & rImplementationName,
950 ComponentInstantiation pCreateFunction,
951 const Sequence< OUString > & rServiceNames,
952 rtl_ModuleCount * )
954 return new OFactoryComponentHelper(
955 rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, false );
958 // global function
959 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
960 SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
961 const Reference<XSingleServiceFactory > & rFactory )
963 return new OFactoryProxyHelper( rFactory );
966 // global function
967 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
968 const Reference<XMultiServiceFactory > & rServiceManager,
969 const OUString & rImplementationName,
970 ComponentInstantiation pCreateFunction,
971 const Sequence< OUString > & rServiceNames,
972 rtl_ModuleCount * )
974 return new OFactoryComponentHelper(
975 rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, true );
978 // global function
979 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
980 const Reference<XMultiServiceFactory > & rServiceManager,
981 const OUString & rImplementationName,
982 const Reference<XRegistryKey > & rImplementationKey )
984 return new ORegistryFactoryHelper(
985 rServiceManager, rImplementationName, rImplementationKey, false );
988 // global function
989 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
990 const Reference<XMultiServiceFactory > & rServiceManager,
991 const OUString & rImplementationName,
992 const Reference<XRegistryKey > & rImplementationKey )
994 return new ORegistryFactoryHelper(
995 rServiceManager, rImplementationName, rImplementationKey, true );
999 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1000 ComponentFactoryFunc fptr,
1001 OUString const & rImplementationName,
1002 Sequence< OUString > const & rServiceNames,
1003 rtl_ModuleCount *)
1005 return new OFactoryComponentHelper(
1006 Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, false );
1009 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1010 ComponentFactoryFunc fptr,
1011 OUString const & rImplementationName,
1012 Sequence< OUString > const & rServiceNames,
1013 rtl_ModuleCount *)
1015 return new OFactoryComponentHelper(
1016 Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, true );
1022 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */