92f5913aef
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
862 lines
27 KiB
C++
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: */
|