office-gobmx/cppuhelper/source/factory.cxx
Caolán McNamara 92f5913aef cid#1556442 COPY_INSTEAD_OF_MOVE
and

cid#1607753 COPY_INSTEAD_OF_MOVE
cid#1554790 COPY_INSTEAD_OF_MOVE
cid#1556463 COPY_INSTEAD_OF_MOVE
cid#1554838 COPY_INSTEAD_OF_MOVE
cid#1556231 COPY_INSTEAD_OF_MOVE
cid#1556878 COPY_INSTEAD_OF_MOVE
cid#1554913 COPY_INSTEAD_OF_MOVE
cid#1558064 COPY_INSTEAD_OF_MOVE
cid#1557043 COPY_INSTEAD_OF_MOVE
cid#1556985 COPY_INSTEAD_OF_MOVE
cid#1556766 COPY_INSTEAD_OF_MOVE
cid#1557351 COPY_INSTEAD_OF_MOVE
cid#1554863 COPY_INSTEAD_OF_MOVE
cid#1556764 COPY_INSTEAD_OF_MOVE
cid#1556279 COPY_INSTEAD_OF_MOVE
cid#1555970 COPY_INSTEAD_OF_MOVE
cid#1556942 COPY_INSTEAD_OF_MOVE
cid#1557964 COPY_INSTEAD_OF_MOVE
cid#1555166 COPY_INSTEAD_OF_MOVE
cid#1556496 COPY_INSTEAD_OF_MOVE
cid#1557175 COPY_INSTEAD_OF_MOVE
cid#1558054 COPY_INSTEAD_OF_MOVE
cid#1557392 COPY_INSTEAD_OF_MOVE
cid#1557850 COPY_INSTEAD_OF_MOVE
cid#1555118 COPY_INSTEAD_OF_MOVE
cid#1557131 COPY_INSTEAD_OF_MOVE
cid#1556614 COPY_INSTEAD_OF_MOVE
cid#1609650 COPY_INSTEAD_OF_MOVE
cid#1555114 COPY_INSTEAD_OF_MOVE
cid#1555241 COPY_INSTEAD_OF_MOVE
cid#1555442 COPY_INSTEAD_OF_MOVE
cid#1556473 COPY_INSTEAD_OF_MOVE
cid#1557654 COPY_INSTEAD_OF_MOVE
cid#1554689 COPY_INSTEAD_OF_MOVE
cid#1556316 COPY_INSTEAD_OF_MOVE
cid#1557929 COPY_INSTEAD_OF_MOVE
cid#1554807 COPY_INSTEAD_OF_MOVE
cid#1554858 COPY_INSTEAD_OF_MOVE
cid#1555103 COPY_INSTEAD_OF_MOVE
cid#1555517 COPY_INSTEAD_OF_MOVE
cid#1556424 COPY_INSTEAD_OF_MOVE
cid#1557252 COPY_INSTEAD_OF_MOVE
cid#1557566 COPY_INSTEAD_OF_MOVE
cid#1608020 COPY_INSTEAD_OF_MOVE
cid#1557742 COPY_INSTEAD_OF_MOVE
cid#1555884 COPY_INSTEAD_OF_MOVE
cid#1554809 COPY_INSTEAD_OF_MOVE
cid#1555336 COPY_INSTEAD_OF_MOVE
cid#1555173 COPY_INSTEAD_OF_MOVE
cid#1556067 COPY_INSTEAD_OF_MOVE
cid#1557040 COPY_INSTEAD_OF_MOVE
cid#1556235 COPY_INSTEAD_OF_MOVE
cid#1557366 COPY_INSTEAD_OF_MOVE
cid#1555910 COPY_INSTEAD_OF_MOVE
cid#1556716 COPY_INSTEAD_OF_MOVE
cid#1558022 COPY_INSTEAD_OF_MOVE
cid#1555769 COPY_INSTEAD_OF_MOVE
cid#1555940 COPY_INSTEAD_OF_MOVE
cid#1557077 COPY_INSTEAD_OF_MOVE
cid#1555270 COPY_INSTEAD_OF_MOVE
cid#1555660 COPY_INSTEAD_OF_MOVE
cid#1556302 COPY_INSTEAD_OF_MOVE
cid#1555678 COPY_INSTEAD_OF_MOVE
cid#1556538 COPY_INSTEAD_OF_MOVE
cid#1557689 COPY_INSTEAD_OF_MOVE
cid#1555009 COPY_INSTEAD_OF_MOVE
cid#1555433 COPY_INSTEAD_OF_MOVE
cid#1555671 COPY_INSTEAD_OF_MOVE
cid#1555255 COPY_INSTEAD_OF_MOVE
cid#1557681 COPY_INSTEAD_OF_MOVE
cid#1557512 COPY_INSTEAD_OF_MOVE
cid#1554958 COPY_INSTEAD_OF_MOVE
cid#1555758 COPY_INSTEAD_OF_MOVE
cid#1555597 COPY_INSTEAD_OF_MOVE
cid#1558040 COPY_INSTEAD_OF_MOVE
cid#1556476 COPY_INSTEAD_OF_MOVE
cid#1557646 COPY_INSTEAD_OF_MOVE
cid#1557950 COPY_INSTEAD_OF_MOVE
cid#1557019 COPY_INSTEAD_OF_MOVE
cid#1557885 COPY_INSTEAD_OF_MOVE
cid#1556402 COPY_INSTEAD_OF_MOVE
cid#1557906 COPY_INSTEAD_OF_MOVE
cid#1556619 COPY_INSTEAD_OF_MOVE
cid#1554683 COPY_INSTEAD_OF_MOVE
cid#1556549 COPY_INSTEAD_OF_MOVE
cid#1554747 COPY_INSTEAD_OF_MOVE
cid#1554929 COPY_INSTEAD_OF_MOVE
cid#1555362 COPY_INSTEAD_OF_MOVE
cid#1557053 COPY_INSTEAD_OF_MOVE
cid#1557891 COPY_INSTEAD_OF_MOVE
cid#1555043 COPY_INSTEAD_OF_MOVE
cid#1555107 COPY_INSTEAD_OF_MOVE
cid#1557203 COPY_INSTEAD_OF_MOVE
cid#1556728 COPY_INSTEAD_OF_MOVE
cid#1557773 COPY_INSTEAD_OF_MOVE
cid#1556845 COPY_INSTEAD_OF_MOVE

Change-Id: I001fb67e597b096e992fd8a0cd6f3ec577767c33
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176098
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins
2024-11-06 13:58:54 +01:00

862 lines
27 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sal/log.hxx>
#include <osl/diagnose.h>
#include <osl/mutex.hxx>
#include <cppuhelper/basemutex.hxx>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/compbase.hxx>
#include <cppuhelper/factory.hxx>
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <rtl/unload.h>
#include <cppuhelper/propshlp.hxx>
#include <o3tl/string_view.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/loader/XImplementationLoader.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/uno/XUnloadingPreference.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <memory>
#include <utility>
using namespace osl;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::loader;
using namespace com::sun::star::registry;
namespace cppu
{
namespace {
class OFactoryComponentHelper
: public cppu::BaseMutex
, public WeakComponentImplHelper<
XServiceInfo,
XSingleServiceFactory,
lang::XSingleComponentFactory,
XUnloadingPreference>
{
public:
OFactoryComponentHelper(
const Reference<XMultiServiceFactory > & rServiceManager,
OUString aImplementationName_,
ComponentInstantiation pCreateFunction_,
ComponentFactoryFunc fptr,
const Sequence< OUString > * pServiceNames_,
bool bOneInstance_ )
: WeakComponentImplHelper( m_aMutex )
, bOneInstance( bOneInstance_ )
, xSMgr( rServiceManager )
, pCreateFunction( pCreateFunction_ )
, m_fptr( fptr )
, aImplementationName(std::move( aImplementationName_ ))
{
if( pServiceNames_ )
aServiceNames = *pServiceNames_;
}
// XSingleServiceFactory
Reference<XInterface > SAL_CALL createInstance() override;
Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments ) override;
// XSingleComponentFactory
virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
Reference< XComponentContext > const & xContext ) override;
virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
Sequence< Any > const & rArguments,
Reference< XComponentContext > const & xContext ) override;
// XServiceInfo
OUString SAL_CALL getImplementationName() override;
sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
// XTypeProvider
virtual Sequence< Type > SAL_CALL getTypes() override;
// XUnloadingPreference
virtual sal_Bool SAL_CALL releaseOnNotification() override;
// WeakComponentImplHelper
void SAL_CALL disposing() override;
private:
css::uno::Reference<css::uno::XInterface> createInstanceWithArgumentsEveryTime(
css::uno::Sequence<css::uno::Any> const & rArguments,
css::uno::Reference<css::uno::XComponentContext> const & xContext);
Reference<XInterface > xTheInstance;
bool bOneInstance;
protected:
// needed for implementing XUnloadingPreference in inheriting classes
bool isOneInstance() const {return bOneInstance;}
bool isInstance() const {return xTheInstance.is();}
/**
* Create an instance specified by the factory. The one instance logic is implemented
* in the createInstance and createInstanceWithArguments methods.
* @return the newly created instance. Do not return a previous (one instance) instance.
* @throw css::uno::Exception
* @throw css::uno::RuntimeException
*/
virtual Reference<XInterface > createInstanceEveryTime(
Reference< XComponentContext > const & xContext );
Reference<XMultiServiceFactory > xSMgr;
ComponentInstantiation pCreateFunction;
ComponentFactoryFunc m_fptr;
Sequence< OUString > aServiceNames;
OUString aImplementationName;
};
}
// XTypeProvider
Sequence< Type > OFactoryComponentHelper::getTypes()
{
Type ar[ 4 ];
ar[ 0 ] = cppu::UnoType<XSingleServiceFactory>::get();
ar[ 1 ] = cppu::UnoType<XServiceInfo>::get();
ar[ 2 ] = cppu::UnoType<XUnloadingPreference>::get();
if (m_fptr)
ar[ 3 ] = cppu::UnoType<XSingleComponentFactory>::get();
return Sequence< Type >( ar, m_fptr ? 4 : 3 );
}
// OFactoryComponentHelper
Reference<XInterface > OFactoryComponentHelper::createInstanceEveryTime(
Reference< XComponentContext > const & xContext )
{
if (m_fptr)
{
return (*m_fptr)( xContext );
}
if( pCreateFunction )
{
if (xContext.is())
{
Reference< lang::XMultiServiceFactory > xContextMgr(
xContext->getServiceManager(), UNO_QUERY );
if (xContextMgr.is())
return (*pCreateFunction)( xContextMgr );
}
return (*pCreateFunction)( xSMgr );
}
return Reference< XInterface >();
}
// XSingleServiceFactory
Reference<XInterface > OFactoryComponentHelper::createInstance()
{
if( bOneInstance )
{
if( !xTheInstance.is() )
{
MutexGuard aGuard( m_aMutex );
if( !xTheInstance.is() )
xTheInstance = createInstanceEveryTime( Reference< XComponentContext >() );
}
return xTheInstance;
}
return createInstanceEveryTime( Reference< XComponentContext >() );
}
Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
const Sequence<Any>& Arguments )
{
if( bOneInstance )
{
if( !xTheInstance.is() )
{
MutexGuard aGuard( m_aMutex );
// OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
if( !xTheInstance.is() )
xTheInstance = createInstanceWithArgumentsEveryTime(
Arguments, Reference< XComponentContext >() );
}
return xTheInstance;
}
return createInstanceWithArgumentsEveryTime( Arguments, Reference< XComponentContext >() );
}
// XSingleComponentFactory
Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
Reference< XComponentContext > const & xContext )
{
if( bOneInstance )
{
if( !xTheInstance.is() )
{
MutexGuard aGuard( m_aMutex );
// OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
if( !xTheInstance.is() )
xTheInstance = createInstanceEveryTime( xContext );
}
return xTheInstance;
}
return createInstanceEveryTime( xContext );
}
Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
Sequence< Any > const & rArguments,
Reference< XComponentContext > const & xContext )
{
if( bOneInstance )
{
if( !xTheInstance.is() )
{
MutexGuard aGuard( m_aMutex );
// OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
if( !xTheInstance.is() )
xTheInstance = createInstanceWithArgumentsEveryTime( rArguments, xContext );
}
return xTheInstance;
}
return createInstanceWithArgumentsEveryTime( rArguments, xContext );
}
css::uno::Reference<css::uno::XInterface>
OFactoryComponentHelper::createInstanceWithArgumentsEveryTime(
css::uno::Sequence<css::uno::Any> const & rArguments,
css::uno::Reference<css::uno::XComponentContext> const & xContext)
{
Reference< XInterface > xRet( createInstanceEveryTime( xContext ) );
Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
// always call initialize, even if there are no arguments. #i63511#
if (xInit.is())
{
xInit->initialize( rArguments );
}
else
{
if ( rArguments.hasElements() )
{
// dispose the here created UNO object before throwing out exception
// to avoid risk of memory leaks #i113722#
Reference<XComponent> xComp( xRet, UNO_QUERY );
if (xComp.is())
xComp->dispose();
throw lang::IllegalArgumentException(
u"cannot pass arguments to component => no XInitialization implemented!"_ustr,
Reference< XInterface >(), 0 );
}
}
return xRet;
}
// WeakComponentImplHelper
void OFactoryComponentHelper::disposing()
{
Reference<XInterface > x;
{
// do not delete in the guard section
MutexGuard aGuard( m_aMutex );
x = xTheInstance;
xTheInstance.clear();
}
// if it is a component call dispose at the component
Reference<XComponent > xComp( x, UNO_QUERY );
if( xComp.is() )
xComp->dispose();
}
// XServiceInfo
OUString OFactoryComponentHelper::getImplementationName()
{
return aImplementationName;
}
// XServiceInfo
sal_Bool OFactoryComponentHelper::supportsService(
const OUString& ServiceName )
{
return cppu::supportsService(this, ServiceName);
}
// XServiceInfo
Sequence< OUString > OFactoryComponentHelper::getSupportedServiceNames()
{
return aServiceNames;
}
// XUnloadingPreference
// This class is used for single factories, component factories and
// one-instance factories. Depending on the usage this function has
// to return different values.
// one-instance factory: sal_False
// single factory: sal_True
// component factory: sal_True
sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification()
{
if( bOneInstance)
return false;
return true;
}
namespace {
class ORegistryFactoryHelper : public OFactoryComponentHelper,
public OPropertySetHelper
{
public:
ORegistryFactoryHelper(
const Reference<XMultiServiceFactory > & rServiceManager,
const OUString & rImplementationName_,
const Reference<XRegistryKey > & xImplementationKey_,
bool bOneInstance_ )
: OFactoryComponentHelper(
rServiceManager, rImplementationName_, nullptr, nullptr, nullptr, bOneInstance_ ),
OPropertySetHelper( WeakComponentImplHelper::rBHelper ),
xImplementationKey( xImplementationKey_ )
{}
// XInterface
virtual Any SAL_CALL queryInterface( Type const & type ) override;
virtual void SAL_CALL acquire() noexcept override;
virtual void SAL_CALL release() noexcept override;
// XTypeProvider
virtual Sequence< Type > SAL_CALL getTypes() override;
// XPropertySet
virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
// OPropertySetHelper
virtual IPropertyArrayHelper & SAL_CALL getInfoHelper() override;
virtual sal_Bool SAL_CALL convertFastPropertyValue(
Any & rConvertedValue, Any & rOldValue,
sal_Int32 nHandle, Any const & rValue ) override;
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
sal_Int32 nHandle, Any const & rValue ) override;
using OPropertySetHelper::getFastPropertyValue;
virtual void SAL_CALL getFastPropertyValue(
Any & rValue, sal_Int32 nHandle ) const override;
// OFactoryComponentHelper
Reference<XInterface > createInstanceEveryTime(
Reference< XComponentContext > const & xContext ) override;
// XSingleServiceFactory
Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
// XSingleComponentFactory
Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
Sequence< Any > const & rArguments,
Reference< XComponentContext > const & xContext ) override;
// XServiceInfo
Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
// XUnloadingPreference
sal_Bool SAL_CALL releaseOnNotification() override;
private:
/// @throws css::uno::Exception
/// @throws css::uno::RuntimeException
Reference< XInterface > createModuleFactory();
/** The registry key of the implementation section */
Reference<XRegistryKey > xImplementationKey;
/** The factory created with the loader. */
Reference<XSingleComponentFactory > xModuleFactory;
Reference<XSingleServiceFactory > xModuleFactoryDepr;
Reference< beans::XPropertySetInfo > m_xInfo;
std::unique_ptr< IPropertyArrayHelper > m_property_array_helper;
protected:
using OPropertySetHelper::getTypes;
};
}
// XInterface
Any SAL_CALL ORegistryFactoryHelper::queryInterface(
Type const & type )
{
Any ret( OFactoryComponentHelper::queryInterface( type ) );
if (ret.hasValue())
return ret;
return OPropertySetHelper::queryInterface( type );
}
void ORegistryFactoryHelper::acquire() noexcept
{
OFactoryComponentHelper::acquire();
}
void ORegistryFactoryHelper::release() noexcept
{
OFactoryComponentHelper::release();
}
// XTypeProvider
Sequence< Type > ORegistryFactoryHelper::getTypes()
{
Sequence< Type > types( OFactoryComponentHelper::getTypes() );
sal_Int32 pos = types.getLength();
types.realloc( pos + 3 );
Type * p = types.getArray();
p[ pos++ ] = cppu::UnoType<beans::XMultiPropertySet>::get();
p[ pos++ ] = cppu::UnoType<beans::XFastPropertySet>::get();
p[ pos++ ] = cppu::UnoType<beans::XPropertySet>::get();
return types;
}
// XPropertySet
Reference< beans::XPropertySetInfo >
ORegistryFactoryHelper::getPropertySetInfo()
{
::osl::MutexGuard guard( m_aMutex );
if (! m_xInfo.is())
m_xInfo = createPropertySetInfo( getInfoHelper() );
return m_xInfo;
}
// OPropertySetHelper
IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
{
::osl::MutexGuard guard( m_aMutex );
if (m_property_array_helper == nullptr)
{
beans::Property prop(
u"ImplementationKey"_ustr /* name */,
0 /* handle */,
cppu::UnoType<decltype(xImplementationKey)>::get(),
beans::PropertyAttribute::READONLY |
beans::PropertyAttribute::OPTIONAL );
m_property_array_helper.reset(
new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
}
return *m_property_array_helper;
}
sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
Any &, Any &, sal_Int32, Any const & )
{
OSL_FAIL( "unexpected!" );
return false;
}
void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
sal_Int32, Any const & )
{
throw beans::PropertyVetoException(
u"unexpected: only readonly properties!"_ustr,
static_cast< OWeakObject * >(this) );
}
void ORegistryFactoryHelper::getFastPropertyValue(
Any & rValue, sal_Int32 nHandle ) const
{
if (nHandle == 0)
{
rValue <<= xImplementationKey;
}
else
{
rValue.clear();
throw beans::UnknownPropertyException(
u"unknown property!"_ustr, static_cast< OWeakObject * >(
const_cast< ORegistryFactoryHelper * >(this) ) );
}
}
Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
Reference< XComponentContext > const & xContext )
{
if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
{
Reference< XInterface > x( createModuleFactory() );
if (x.is())
{
MutexGuard aGuard( m_aMutex );
if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
{
xModuleFactory.set( x, UNO_QUERY );
xModuleFactoryDepr.set( x, UNO_QUERY );
}
}
}
if( xModuleFactory.is() )
{
return xModuleFactory->createInstanceWithContext( xContext );
}
if( xModuleFactoryDepr.is() )
{
return xModuleFactoryDepr->createInstance();
}
return Reference<XInterface >();
}
Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
const Sequence<Any>& Arguments )
{
if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
{
Reference< XInterface > x( createModuleFactory() );
if (x.is())
{
MutexGuard aGuard( m_aMutex );
if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
{
xModuleFactory.set( x, UNO_QUERY );
xModuleFactoryDepr.set( x, UNO_QUERY );
}
}
}
if( xModuleFactoryDepr.is() )
{
return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
}
if( xModuleFactory.is() )
{
SAL_INFO("cppuhelper", "no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!");
return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
}
return Reference<XInterface >();
}
Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
Sequence< Any > const & rArguments,
Reference< XComponentContext > const & xContext )
{
if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
{
Reference< XInterface > x( createModuleFactory() );
if (x.is())
{
MutexGuard aGuard( m_aMutex );
if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
{
xModuleFactory.set( x, UNO_QUERY );
xModuleFactoryDepr.set( x, UNO_QUERY );
}
}
}
if( xModuleFactory.is() )
{
return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
}
if( xModuleFactoryDepr.is() )
{
SAL_INFO_IF(xContext.is(), "cppuhelper", "ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!");
return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
}
return Reference<XInterface >();
}
Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
{
OUString aActivatorUrl;
OUString aActivatorName;
OUString aLocation;
Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
u"/UNO/ACTIVATOR"_ustr );
if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
{
aActivatorUrl = xActivatorKey->getAsciiValue();
aActivatorName = o3tl::getToken(aActivatorUrl, 0, ':');
Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
u"/UNO/LOCATION"_ustr );
if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
aLocation = xLocationKey->getAsciiValue();
}
else
{
// old style"url"
// the location of the program code of the implementation
Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
u"/UNO/URL"_ustr );
// is the key of the right type ?
if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
{
// one implementation found -> try to activate
aLocation = xLocationKey->getAsciiValue();
// search protocol delimiter
sal_Int32 nPos = aLocation.indexOf("://");
if( nPos != -1 )
{
aActivatorName = aLocation.subView( 0, nPos );
if( aActivatorName == u"java" )
aActivatorName = u"com.sun.star.loader.Java"_ustr;
else if( aActivatorName == u"module" )
aActivatorName = u"com.sun.star.loader.SharedLibrary"_ustr;
aLocation = aLocation.copy( nPos + 3 );
}
}
}
Reference< XInterface > xFactory;
if( !aActivatorName.isEmpty() )
{
Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
if (xLoader.is())
{
xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
}
}
return xFactory;
}
// XServiceInfo
Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames()
{
MutexGuard aGuard( m_aMutex );
if( !aServiceNames.hasElements() )
{
// not yet loaded
try
{
Reference<XRegistryKey > xKey = xImplementationKey->openKey( u"UNO/SERVICES"_ustr );
if (xKey.is())
{
// length of prefix. +1 for the '/' at the end
sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
// Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
Sequence<OUString> seqKeys = xKey->getKeyNames();
for( OUString & key : asNonConstRange(seqKeys) )
key = key.copy(nPrefixLen);
aServiceNames = std::move(seqKeys);
}
}
catch (InvalidRegistryException &)
{
}
}
return aServiceNames;
}
sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification()
{
bool retVal= true;
if( isOneInstance() && isInstance())
{
retVal= false;
}
else if( ! isOneInstance())
{
// try to delegate
if( xModuleFactory.is())
{
Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
if( xunloading.is())
retVal= xunloading->releaseOnNotification();
}
else if( xModuleFactoryDepr.is())
{
Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
if( xunloading.is())
retVal= xunloading->releaseOnNotification();
}
}
return retVal;
}
namespace {
class OFactoryProxyHelper : public WeakImplHelper< XServiceInfo, XSingleServiceFactory,
XUnloadingPreference >
{
Reference<XSingleServiceFactory > xFactory;
public:
explicit OFactoryProxyHelper( const Reference<XSingleServiceFactory > & rFactory )
: xFactory( rFactory )
{}
// XSingleServiceFactory
Reference<XInterface > SAL_CALL createInstance() override;
Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments) override;
// XServiceInfo
OUString SAL_CALL getImplementationName() override;
sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
//XUnloadingPreference
sal_Bool SAL_CALL releaseOnNotification() override;
};
}
// XSingleServiceFactory
Reference<XInterface > OFactoryProxyHelper::createInstance()
{
return xFactory->createInstance();
}
// XSingleServiceFactory
Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
(
const Sequence<Any>& Arguments
)
{
return xFactory->createInstanceWithArguments( Arguments );
}
// XServiceInfo
OUString OFactoryProxyHelper::getImplementationName()
{
Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
if( xInfo.is() )
return xInfo->getImplementationName();
return OUString();
}
// XServiceInfo
sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
{
return cppu::supportsService(this, ServiceName);
}
// XServiceInfo
Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames()
{
Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
if( xInfo.is() )
return xInfo->getSupportedServiceNames();
return Sequence< OUString >();
}
sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification()
{
Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
if( pref.is())
return pref->releaseOnNotification();
return true;
}
// global function
Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
const Reference<XMultiServiceFactory > & rServiceManager,
const OUString & rImplementationName,
ComponentInstantiation pCreateFunction,
const Sequence< OUString > & rServiceNames,
rtl_ModuleCount * )
{
return new OFactoryComponentHelper(
rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, false );
}
// global function
Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
SAL_UNUSED_PARAMETER const Reference<XMultiServiceFactory > &,
const Reference<XSingleServiceFactory > & rFactory )
{
return new OFactoryProxyHelper( rFactory );
}
// global function
Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
const Reference<XMultiServiceFactory > & rServiceManager,
const OUString & rImplementationName,
ComponentInstantiation pCreateFunction,
const Sequence< OUString > & rServiceNames,
rtl_ModuleCount * )
{
return new OFactoryComponentHelper(
rServiceManager, rImplementationName, pCreateFunction, nullptr, &rServiceNames, true );
}
// global function
Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
const Reference<XMultiServiceFactory > & rServiceManager,
const OUString & rImplementationName,
const Reference<XRegistryKey > & rImplementationKey )
{
return new ORegistryFactoryHelper(
rServiceManager, rImplementationName, rImplementationKey, false );
}
// global function
Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
const Reference<XMultiServiceFactory > & rServiceManager,
const OUString & rImplementationName,
const Reference<XRegistryKey > & rImplementationKey )
{
return new ORegistryFactoryHelper(
rServiceManager, rImplementationName, rImplementationKey, true );
}
Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
ComponentFactoryFunc fptr,
OUString const & rImplementationName,
Sequence< OUString > const & rServiceNames,
rtl_ModuleCount *)
{
return new OFactoryComponentHelper(
Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, false );
}
Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
ComponentFactoryFunc fptr,
OUString const & rImplementationName,
Sequence< OUString > const & rServiceNames,
rtl_ModuleCount *)
{
return new OFactoryComponentHelper(
Reference< XMultiServiceFactory >(), rImplementationName, nullptr, fptr, &rServiceNames, true );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */