Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / cppuhelper / source / factory.cxx
blob2503245330b83574e34f63deb1840aada84f8588
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 ) override;
87 // XSingleServiceFactory
88 Reference<XInterface > SAL_CALL createInstance() override;
89 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
90 // XSingleComponentFactory
91 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
92 Reference< XComponentContext > const & xContext ) override;
93 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
94 Sequence< Any > const & rArguments,
95 Reference< XComponentContext > const & xContext ) override;
97 // XServiceInfo
98 OUString SAL_CALL getImplementationName() override;
99 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
100 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
102 protected:
104 * Create an instance specified by the factory. The one instance logic is implemented
105 * in the createInstance and createInstanceWithArguments methods.
106 * @return the newly created instance. Do not return a previous (one instance) instance.
107 * @throw css::uno::Exception
108 * @throw css::uno::RuntimeException
110 virtual Reference<XInterface > createInstanceEveryTime(
111 Reference< XComponentContext > const & xContext );
113 Reference<XMultiServiceFactory > xSMgr;
114 ComponentInstantiation pCreateFunction;
115 ComponentFactoryFunc m_fptr;
116 Sequence< OUString > aServiceNames;
117 OUString aImplementationName;
119 OSingleFactoryHelper::~OSingleFactoryHelper()
124 Any OSingleFactoryHelper::queryInterface( const Type & rType )
126 return ::cppu::queryInterface(
127 rType,
128 static_cast< XSingleComponentFactory * >( this ),
129 static_cast< XSingleServiceFactory * >( this ),
130 static_cast< XServiceInfo * >( this ) ,
131 static_cast< XUnloadingPreference * >( this ));
134 // OSingleFactoryHelper
135 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
136 Reference< XComponentContext > const & xContext )
138 if (m_fptr)
140 return (*m_fptr)( xContext );
142 if( pCreateFunction )
144 if (xContext.is())
146 Reference< lang::XMultiServiceFactory > xContextMgr(
147 xContext->getServiceManager(), UNO_QUERY );
148 if (xContextMgr.is())
149 return (*pCreateFunction)( xContextMgr );
151 return (*pCreateFunction)( xSMgr );
153 return Reference< XInterface >();
156 // XSingleServiceFactory
157 Reference<XInterface > OSingleFactoryHelper::createInstance()
159 return createInstanceWithContext( Reference< XComponentContext >() );
162 // XSingleServiceFactory
163 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
164 const Sequence<Any>& Arguments )
166 return createInstanceWithArgumentsAndContext(
167 Arguments, Reference< XComponentContext >() );
170 // XSingleComponentFactory
172 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
173 Reference< XComponentContext > const & xContext )
175 return createInstanceEveryTime( xContext );
178 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
179 Sequence< Any > const & rArguments,
180 Reference< XComponentContext > const & xContext )
182 Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
184 Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
185 // always call initialize, even if there are no arguments. #i63511#
186 if (xInit.is())
188 xInit->initialize( rArguments );
190 else
192 if ( rArguments.getLength() )
194 // dispose the here created UNO object before throwing out exception
195 // to avoid risk of memory leaks #i113722#
196 Reference<XComponent> xComp( xRet, UNO_QUERY );
197 if (xComp.is())
198 xComp->dispose();
200 throw lang::IllegalArgumentException(
201 "cannot pass arguments to component => no XInitialization implemented!",
202 Reference< XInterface >(), 0 );
206 return xRet;
209 // XServiceInfo
210 OUString OSingleFactoryHelper::getImplementationName()
212 return aImplementationName;
215 // XServiceInfo
216 sal_Bool OSingleFactoryHelper::supportsService(
217 const OUString& ServiceName )
219 return cppu::supportsService(this, ServiceName);
222 // XServiceInfo
223 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames()
225 return aServiceNames;
228 struct OFactoryComponentHelper_Mutex
230 Mutex aMutex;
233 class OFactoryComponentHelper
234 : public OFactoryComponentHelper_Mutex
235 , public OComponentHelper
236 , public OSingleFactoryHelper
238 public:
239 OFactoryComponentHelper(
240 const Reference<XMultiServiceFactory > & rServiceManager,
241 const OUString & rImplementationName_,
242 ComponentInstantiation pCreateFunction_,
243 ComponentFactoryFunc fptr,
244 const Sequence< OUString > * pServiceNames_,
245 bool bOneInstance_ )
246 : OComponentHelper( aMutex )
247 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
248 , bOneInstance( bOneInstance_ )
252 // XInterface
253 Any SAL_CALL queryInterface( const Type & rType ) override;
254 void SAL_CALL acquire() throw() override
255 { OComponentHelper::acquire(); }
256 void SAL_CALL release() throw() override
257 { OComponentHelper::release(); }
259 // XSingleServiceFactory
260 Reference<XInterface > SAL_CALL createInstance() override;
261 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments ) override;
262 // XSingleComponentFactory
263 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
264 Reference< XComponentContext > const & xContext ) override;
265 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
266 Sequence< Any > const & rArguments,
267 Reference< XComponentContext > const & xContext ) override;
269 // XTypeProvider
270 virtual Sequence< Type > SAL_CALL getTypes() override;
271 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
273 // XAggregation
274 Any SAL_CALL queryAggregation( const Type & rType ) override;
276 // XUnloadingPreference
277 virtual sal_Bool SAL_CALL releaseOnNotification() override;
279 // OComponentHelper
280 void SAL_CALL dispose() override;
282 private:
283 Reference<XInterface > xTheInstance;
284 bool bOneInstance;
285 protected:
286 // needed for implementing XUnloadingPreference in inheriting classes
287 bool isOneInstance() const {return bOneInstance;}
288 bool isInstance() const {return xTheInstance.is();}
292 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
294 if( rType == cppu::UnoType<XUnloadingPreference>::get() )
296 return Any(
297 Reference< XUnloadingPreference >(
298 static_cast< XUnloadingPreference * >(this) ) );
300 return OComponentHelper::queryInterface( rType );
303 // XAggregation
304 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
306 Any aRet( OComponentHelper::queryAggregation( rType ) );
307 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
310 // XTypeProvider
311 Sequence< Type > OFactoryComponentHelper::getTypes()
313 Type ar[ 4 ];
314 ar[ 0 ] = cppu::UnoType<XSingleServiceFactory>::get();
315 ar[ 1 ] = cppu::UnoType<XServiceInfo>::get();
316 ar[ 2 ] = cppu::UnoType<XUnloadingPreference>::get();
318 if (m_fptr)
319 ar[ 3 ] = cppu::UnoType<XSingleComponentFactory>::get();
321 return Sequence< Type >( ar, m_fptr ? 4 : 3 );
324 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
326 return css::uno::Sequence<sal_Int8>();
329 // XSingleServiceFactory
330 Reference<XInterface > OFactoryComponentHelper::createInstance()
332 if( bOneInstance )
334 if( !xTheInstance.is() )
336 MutexGuard aGuard( aMutex );
337 if( !xTheInstance.is() )
338 xTheInstance = OSingleFactoryHelper::createInstance();
340 return xTheInstance;
342 return OSingleFactoryHelper::createInstance();
345 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
346 const Sequence<Any>& Arguments )
348 if( bOneInstance )
350 if( !xTheInstance.is() )
352 MutexGuard aGuard( aMutex );
353 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
354 if( !xTheInstance.is() )
355 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
357 return xTheInstance;
359 return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
362 // XSingleComponentFactory
364 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
365 Reference< XComponentContext > const & xContext )
367 if( bOneInstance )
369 if( !xTheInstance.is() )
371 MutexGuard aGuard( aMutex );
372 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
373 if( !xTheInstance.is() )
374 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
376 return xTheInstance;
378 return OSingleFactoryHelper::createInstanceWithContext( xContext );
381 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
382 Sequence< Any > const & rArguments,
383 Reference< XComponentContext > const & xContext )
385 if( bOneInstance )
387 if( !xTheInstance.is() )
389 MutexGuard aGuard( aMutex );
390 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
391 if( !xTheInstance.is() )
392 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
394 return xTheInstance;
396 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
400 // OComponentHelper
401 void OFactoryComponentHelper::dispose()
403 OComponentHelper::dispose();
405 Reference<XInterface > x;
407 // do not delete in the guard section
408 MutexGuard aGuard( aMutex );
409 x = xTheInstance;
410 xTheInstance.clear();
412 // if it is a component call dispose at the component
413 Reference<XComponent > xComp( x, UNO_QUERY );
414 if( xComp.is() )
415 xComp->dispose();
418 // XUnloadingPreference
419 // This class is used for single factories, component factories and
420 // one-instance factories. Depending on the usage this function has
421 // to return different values.
422 // one-instance factory: sal_False
423 // single factory: sal_True
424 // component factory: sal_True
425 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification()
427 if( bOneInstance)
428 return false;
429 return true;
432 class ORegistryFactoryHelper : public OFactoryComponentHelper,
433 public OPropertySetHelper
436 public:
437 ORegistryFactoryHelper(
438 const Reference<XMultiServiceFactory > & rServiceManager,
439 const OUString & rImplementationName_,
440 const Reference<XRegistryKey > & xImplementationKey_,
441 bool bOneInstance_ )
442 : OFactoryComponentHelper(
443 rServiceManager, rImplementationName_, nullptr, nullptr, nullptr, bOneInstance_ ),
444 OPropertySetHelper( OComponentHelper::rBHelper ),
445 xImplementationKey( xImplementationKey_ )
448 // XInterface
449 virtual Any SAL_CALL queryInterface( Type const & type ) override;
450 virtual void SAL_CALL acquire() throw () override;
451 virtual void SAL_CALL release() throw () override;
452 // XTypeProvider
453 virtual Sequence< Type > SAL_CALL getTypes() override;
454 // XPropertySet
455 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
457 // OPropertySetHelper
458 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper() override;
459 virtual sal_Bool SAL_CALL convertFastPropertyValue(
460 Any & rConvertedValue, Any & rOldValue,
461 sal_Int32 nHandle, Any const & rValue ) override;
462 virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
463 sal_Int32 nHandle, Any const & rValue ) override;
464 using OPropertySetHelper::getFastPropertyValue;
465 virtual void SAL_CALL getFastPropertyValue(
466 Any & rValue, sal_Int32 nHandle ) const override;
468 // OSingleFactoryHelper
469 Reference<XInterface > createInstanceEveryTime(
470 Reference< XComponentContext > const & xContext ) override;
472 // XSingleServiceFactory
473 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
474 // XSingleComponentFactory
475 Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
476 Sequence< Any > const & rArguments,
477 Reference< XComponentContext > const & xContext ) override;
479 // XServiceInfo
480 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
481 // XUnloadingPreference
482 sal_Bool SAL_CALL releaseOnNotification() override;
485 private:
486 /// @throws css::uno::Exception
487 /// @throws css::uno::RuntimeException
488 Reference< XInterface > createModuleFactory();
490 /** The registry key of the implementation section */
491 Reference<XRegistryKey > xImplementationKey;
492 /** The factory created with the loader. */
493 Reference<XSingleComponentFactory > xModuleFactory;
494 Reference<XSingleServiceFactory > xModuleFactoryDepr;
495 Reference< beans::XPropertySetInfo > m_xInfo;
496 std::unique_ptr< IPropertyArrayHelper > m_property_array_helper;
497 protected:
498 using OPropertySetHelper::getTypes;
501 // XInterface
503 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
504 Type const & type )
506 Any ret( OFactoryComponentHelper::queryInterface( type ) );
507 if (ret.hasValue())
508 return ret;
509 return OPropertySetHelper::queryInterface( type );
513 void ORegistryFactoryHelper::acquire() throw ()
515 OFactoryComponentHelper::acquire();
519 void ORegistryFactoryHelper::release() throw ()
521 OFactoryComponentHelper::release();
524 // XTypeProvider
526 Sequence< Type > ORegistryFactoryHelper::getTypes()
528 Sequence< Type > types( OFactoryComponentHelper::getTypes() );
529 sal_Int32 pos = types.getLength();
530 types.realloc( pos + 3 );
531 Type * p = types.getArray();
532 p[ pos++ ] = cppu::UnoType<beans::XMultiPropertySet>::get();
533 p[ pos++ ] = cppu::UnoType<beans::XFastPropertySet>::get();
534 p[ pos++ ] = cppu::UnoType<beans::XPropertySet>::get();
535 return types;
538 // XPropertySet
540 Reference< beans::XPropertySetInfo >
541 ORegistryFactoryHelper::getPropertySetInfo()
543 ::osl::MutexGuard guard( aMutex );
544 if (! m_xInfo.is())
545 m_xInfo = createPropertySetInfo( getInfoHelper() );
546 return m_xInfo;
549 // OPropertySetHelper
551 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
553 ::osl::MutexGuard guard( aMutex );
554 if (m_property_array_helper.get() == nullptr)
556 beans::Property prop(
557 "ImplementationKey" /* name */,
558 0 /* handle */,
559 cppu::UnoType<decltype(xImplementationKey)>::get(),
560 beans::PropertyAttribute::READONLY |
561 beans::PropertyAttribute::OPTIONAL );
562 m_property_array_helper.reset(
563 new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
565 return *m_property_array_helper.get();
569 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
570 Any &, Any &, sal_Int32, Any const & )
572 OSL_FAIL( "unexpected!" );
573 return false;
577 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
578 sal_Int32, Any const & )
580 throw beans::PropertyVetoException(
581 "unexpected: only readonly properties!",
582 static_cast< OWeakObject * >(this) );
586 void ORegistryFactoryHelper::getFastPropertyValue(
587 Any & rValue, sal_Int32 nHandle ) const
589 if (nHandle == 0)
591 rValue <<= xImplementationKey;
593 else
595 rValue.clear();
596 throw beans::UnknownPropertyException(
597 "unknown property!", static_cast< OWeakObject * >(
598 const_cast< ORegistryFactoryHelper * >(this) ) );
602 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
603 Reference< XComponentContext > const & xContext )
605 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
607 Reference< XInterface > x( createModuleFactory() );
608 if (x.is())
610 MutexGuard aGuard( aMutex );
611 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
613 xModuleFactory.set( x, UNO_QUERY );
614 xModuleFactoryDepr.set( x, UNO_QUERY );
618 if( xModuleFactory.is() )
620 return xModuleFactory->createInstanceWithContext( xContext );
622 if( xModuleFactoryDepr.is() )
624 return xModuleFactoryDepr->createInstance();
627 return Reference<XInterface >();
630 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
631 const Sequence<Any>& Arguments )
633 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
635 Reference< XInterface > x( createModuleFactory() );
636 if (x.is())
638 MutexGuard aGuard( aMutex );
639 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
641 xModuleFactory.set( x, UNO_QUERY );
642 xModuleFactoryDepr.set( x, UNO_QUERY );
646 if( xModuleFactoryDepr.is() )
648 return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
650 if( xModuleFactory.is() )
652 SAL_INFO("cppuhelper", "no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!");
653 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
656 return Reference<XInterface >();
659 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
660 Sequence< Any > const & rArguments,
661 Reference< XComponentContext > const & xContext )
663 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
665 Reference< XInterface > x( createModuleFactory() );
666 if (x.is())
668 MutexGuard aGuard( aMutex );
669 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
671 xModuleFactory.set( x, UNO_QUERY );
672 xModuleFactoryDepr.set( x, UNO_QUERY );
676 if( xModuleFactory.is() )
678 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
680 if( xModuleFactoryDepr.is() )
682 SAL_INFO_IF(xContext.is(), "cppuhelper", "ignoring context calling ORegistryFactoryHelper::createInstaceWithArgumentsAndContext()!");
683 return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
686 return Reference<XInterface >();
690 // OSingleFactoryHelper
691 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
693 OUString aActivatorUrl;
694 OUString aActivatorName;
695 OUString aLocation;
697 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
698 "/UNO/ACTIVATOR" );
699 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
701 aActivatorUrl = xActivatorKey->getAsciiValue();
703 sal_Int32 nIndex = 0;
704 aActivatorName = aActivatorUrl.getToken(0, ':', nIndex );
706 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
707 "/UNO/LOCATION" );
708 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
709 aLocation = xLocationKey->getAsciiValue();
711 else
713 // old style"url"
714 // the location of the program code of the implementation
715 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
716 "/UNO/URL" );
717 // is the key of the right type ?
718 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
720 // one implementation found -> try to activate
721 aLocation = xLocationKey->getAsciiValue();
723 // search protocol delimiter
724 sal_Int32 nPos = aLocation.indexOf("://");
725 if( nPos != -1 )
727 aActivatorName = aLocation.copy( 0, nPos );
728 if( aActivatorName == "java" )
729 aActivatorName = "com.sun.star.loader.Java";
730 else if( aActivatorName == "module" )
731 aActivatorName = "com.sun.star.loader.SharedLibrary";
732 aLocation = aLocation.copy( nPos + 3 );
737 Reference< XInterface > xFactory;
738 if( !aActivatorName.isEmpty() )
740 Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
741 Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
742 if (xLoader.is())
744 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
747 return xFactory;
750 // XServiceInfo
751 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames()
753 MutexGuard aGuard( aMutex );
754 if( aServiceNames.getLength() == 0 )
756 // not yet loaded
759 Reference<XRegistryKey > xKey = xImplementationKey->openKey( "UNO/SERVICES" );
761 if (xKey.is())
763 // length of prefix. +1 for the '/' at the end
764 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
766 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
767 Sequence<OUString> seqKeys = xKey->getKeyNames();
768 for( OUString & key : seqKeys )
769 key = key.copy(nPrefixLen);
771 aServiceNames = seqKeys;
774 catch (InvalidRegistryException &)
778 return aServiceNames;
781 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification()
783 bool retVal= true;
784 if( isOneInstance() && isInstance())
786 retVal= false;
788 else if( ! isOneInstance())
790 // try to delegate
791 if( xModuleFactory.is())
793 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
794 if( xunloading.is())
795 retVal= xunloading->releaseOnNotification();
797 else if( xModuleFactoryDepr.is())
799 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
800 if( xunloading.is())
801 retVal= xunloading->releaseOnNotification();
804 return retVal;
807 class OFactoryProxyHelper : public WeakImplHelper< XServiceInfo, XSingleServiceFactory,
808 XUnloadingPreference >
810 Reference<XSingleServiceFactory > xFactory;
812 public:
814 explicit OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
815 : xFactory( rFactory )
818 // XSingleServiceFactory
819 Reference<XInterface > SAL_CALL createInstance() override;
820 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
822 // XServiceInfo
823 OUString SAL_CALL getImplementationName() override;
824 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
825 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
826 //XUnloadingPreference
827 sal_Bool SAL_CALL releaseOnNotification() override;
831 // XSingleServiceFactory
832 Reference<XInterface > OFactoryProxyHelper::createInstance()
834 return xFactory->createInstance();
837 // XSingleServiceFactory
838 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
840 const Sequence<Any>& Arguments
843 return xFactory->createInstanceWithArguments( Arguments );
846 // XServiceInfo
847 OUString OFactoryProxyHelper::getImplementationName()
849 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
850 if( xInfo.is() )
851 return xInfo->getImplementationName();
852 return OUString();
855 // XServiceInfo
856 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
858 return cppu::supportsService(this, ServiceName);
861 // XServiceInfo
862 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames()
864 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
865 if( xInfo.is() )
866 return xInfo->getSupportedServiceNames();
867 return Sequence< OUString >();
870 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification()
873 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
874 if( pref.is())
875 return pref->releaseOnNotification();
876 return true;
879 // global function
880 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
881 const Reference<XMultiServiceFactory > & rServiceManager,
882 const OUString & rImplementationName,
883 ComponentInstantiation pCreateFunction,
884 const Sequence< OUString > & rServiceNames,
885 rtl_ModuleCount * )
887 return new OFactoryComponentHelper(
888 rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, false );
891 // global function
892 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
893 SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
894 const Reference<XSingleServiceFactory > & rFactory )
896 return new OFactoryProxyHelper( rFactory );
899 // global function
900 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
901 const Reference<XMultiServiceFactory > & rServiceManager,
902 const OUString & rImplementationName,
903 ComponentInstantiation pCreateFunction,
904 const Sequence< OUString > & rServiceNames,
905 rtl_ModuleCount * )
907 return new OFactoryComponentHelper(
908 rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, true );
911 // global function
912 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
913 const Reference<XMultiServiceFactory > & rServiceManager,
914 const OUString & rImplementationName,
915 const Reference<XRegistryKey > & rImplementationKey )
917 return new ORegistryFactoryHelper(
918 rServiceManager, rImplementationName, rImplementationKey, false );
921 // global function
922 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
923 const Reference<XMultiServiceFactory > & rServiceManager,
924 const OUString & rImplementationName,
925 const Reference<XRegistryKey > & rImplementationKey )
927 return new ORegistryFactoryHelper(
928 rServiceManager, rImplementationName, rImplementationKey, true );
932 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
933 ComponentFactoryFunc fptr,
934 OUString const & rImplementationName,
935 Sequence< OUString > const & rServiceNames,
936 rtl_ModuleCount *)
938 return new OFactoryComponentHelper(
939 Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, false );
942 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
943 ComponentFactoryFunc fptr,
944 OUString const & rImplementationName,
945 Sequence< OUString > const & rServiceNames,
946 rtl_ModuleCount *)
948 return new OFactoryComponentHelper(
949 Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, true );
955 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */