Allow setting environment value directly in .component files

...for internal loader="com.sun.star.loader.SharedLibrary" components, instead
of exported component_getImplementationEnvironmen (or implicit
CPPU_CURRENT_LANGUAGE_BINDING_NAME).  Adapted a few .component files as proof-
of-concept, more to follow.

Change-Id: I82332e0a48e6fc1da245990bb72265fe6e58447e
This commit is contained in:
Stephan Bergmann 2013-12-16 21:39:14 +01:00
parent 9630b97355
commit b1d65c9f15
12 changed files with 140 additions and 97 deletions

View File

@ -17,8 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<component loader="com.sun.star.loader.SharedLibrary" prefix="binaryurp"
xmlns="http://openoffice.org/2010/uno-components">
<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
prefix="binaryurp" xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.bridge.BridgeFactory">
<service name="com.sun.star.bridge.BridgeFactory"/>
</implementation>

View File

@ -17,8 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<component loader="com.sun.star.loader.SharedLibrary" prefix="configmgr"
xmlns="http://openoffice.org/2010/uno-components">
<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
prefix="configmgr" xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.configuration.ConfigurationProvider">
<service name="com.sun.star.configuration.ConfigurationProvider"/>
</implementation>

View File

@ -19,7 +19,6 @@
#include "ado/ADriver.hxx"
#include <cppuhelper/factory.hxx>
#include <uno/lbnames.h>
using namespace connectivity::ado;
using ::com::sun::star::uno::Reference;
@ -74,14 +73,6 @@ struct ProviderRequest
void* getProvider() const { return xRet.get(); }
};
//---------------------------------------------------------------------------------------
extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ado_component_getImplementationEnvironment(
const sal_Char **ppEnvTypeName,
uno_Environment ** /*ppEnv*/)
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ":affine";
}
//---------------------------------------------------------------------------------------
extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL ado_component_getFactory(
const sal_Char* pImplementationName,

View File

@ -17,7 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<component loader="com.sun.star.loader.SharedLibrary" prefix="ado"
<component loader="com.sun.star.loader.SharedLibrary"
environment="@CPPU_ENV@:affine" prefix="ado"
xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.sdbc.ado.ODriver">
<service name="com.sun.star.sdbc.Driver"/>

View File

@ -17,7 +17,18 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<component loader="com.sun.star.loader.SharedLibrary" prefix="jdbc"
<!-- Recent Java 6 VMs make calls to JNI Attach/DetachCurrentThread (which this
code does extensively) very expensive. A follow-up JVM fix reduced the
overhead significantly again for all threads but the main thread. So a
quick hack to improve performance of this component again is to confine it
in the affine apartment (where all code will run on a single, dedicated
thread that is guaranteed no to be the main thread). However, a better fix
would still be to redesign the code so that it does not call
Attach/DetachCurrentThread so frequently:
-->
<component loader="com.sun.star.loader.SharedLibrary"
environment="@CPPU_ENV@:affine" prefix="jdbc"
xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.sdbc.JDBCDriver">
<service name="com.sun.star.sdbc.Driver"/>

View File

@ -19,7 +19,6 @@
#include "java/sql/Driver.hxx"
#include <cppuhelper/factory.hxx>
#include <uno/lbnames.h>
using namespace connectivity;
using ::com::sun::star::uno::Reference;
@ -76,21 +75,6 @@ struct ProviderRequest
void* getProvider() const { return xRet.get(); }
};
extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL
jdbc_component_getImplementationEnvironment(
char const ** ppEnvTypeName, uno_Environment **)
{
// Recent Java 6 VMs make calls to JNI Attach/DetachCurrentThread (which
// this code does extensively) very expensive. A follow-up JVM fix reduced
// the overhead significantly again for all threads but the main thread. So
// a quick hack to improve performance of this component again is to confine
// it in the affine apartment (where all code will run on a single,
// dedicated thread that is guaranteed no to be the main thread). However,
// a better fix would still be to redesign the code so that it does not call
// Attach/DetachCurrentThread so frequently:
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ":affine";
}
extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL jdbc_component_getFactory(
const sal_Char* pImplementationName,
void* pServiceManager,

View File

@ -23,8 +23,8 @@ namespace rtl { class OUString; }
namespace cppuhelper { namespace detail {
css::uno::Reference<css::uno::XInterface> loadSharedLibComponentFactory(
rtl::OUString const & uri, rtl::OUString const & prefix,
rtl::OUString const & rImplName,
rtl::OUString const & uri, rtl::OUString const & environment,
rtl::OUString const & prefix, rtl::OUString const & rImplName,
css::uno::Reference<css::lang::XMultiServiceFactory> const & xMgr);
} }

View File

@ -125,6 +125,7 @@ private:
cppuhelper::ServiceManager::Data * data_;
rtl::OUString attrLoader_;
rtl::OUString attrUri_;
rtl::OUString attrEnvironment_;
rtl::OUString attrPrefix_;
boost::shared_ptr< cppuhelper::ServiceManager::Data::Implementation >
implementation_;
@ -244,6 +245,7 @@ Parser::Parser(
void Parser::handleComponent() {
attrLoader_ = rtl::OUString();
attrUri_ = rtl::OUString();
attrEnvironment_ = rtl::OUString();
attrPrefix_ = rtl::OUString();
xmlreader::Span name;
int nsId;
@ -280,6 +282,23 @@ void Parser::handleComponent() {
+ ": <component> has empty \"uri\" attribute"),
css::uno::Reference< css::uno::XInterface >());
}
} else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
&& name.equals(RTL_CONSTASCII_STRINGPARAM("environment")))
{
if (!attrEnvironment_.isEmpty()) {
throw css::registry::InvalidRegistryException(
(reader_.getUrl() +
": <component> has multiple \"environment\" attributes"),
css::uno::Reference< css::uno::XInterface >());
}
attrEnvironment_ = reader_.getAttributeValue(false)
.convertFromUtf8();
if (attrEnvironment_.isEmpty()) {
throw css::registry::InvalidRegistryException(
(reader_.getUrl() +
": <component> has empty \"environment\" attribute"),
css::uno::Reference< css::uno::XInterface >());
}
} else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE
&& name.equals(RTL_CONSTASCII_STRINGPARAM("prefix")))
{
@ -328,8 +347,8 @@ void Parser::handleImplementation() {
OUString name(getNameAttribute());
implementation_.reset(
new cppuhelper::ServiceManager::Data::Implementation(
name, attrLoader_, attrUri_, attrPrefix_, alienContext_,
reader_.getUrl()));
name, attrLoader_, attrUri_, attrEnvironment_, attrPrefix_,
alienContext_, reader_.getUrl()));
if (!data_->namedImplementations.insert(
cppuhelper::ServiceManager::Data::NamedImplementations::value_type(
name, implementation_)).
@ -643,15 +662,18 @@ void cppuhelper::ServiceManager::loadImplementation(
static_cast< cppu::OWeakObject * >(this));
}
css::uno::Reference< css::uno::XInterface > f0;
// Shortcut loading via SharedLibrary loader, to pass in prefix argument
// (which the loader's activate implementation would normally obtain through
// the legacy xKey argument):
// Shortcut loading via SharedLibrary loader, to pass in environment and
// prefix arguments:
if (!info->alienContext.is()
&& info->loader == "com.sun.star.loader.SharedLibrary")
{
f0 = cppuhelper::detail::loadSharedLibComponentFactory(
uri, info->prefix, info->name, this);
uri, info->environment, info->prefix, info->name, this);
} else {
SAL_WARN_IF(
!info->environment.isEmpty(), "cppuhelper",
"Loader " << info->loader << " and non-empty environment "
<< info->environment);
SAL_WARN_IF(
!info->prefix.isEmpty(), "cppuhelper",
"Loader " << info->loader << " and non-empty prefix "
@ -1287,8 +1309,7 @@ bool cppuhelper::ServiceManager::readLegacyRdbFile(rtl::OUString const & uri) {
boost::shared_ptr< Data::Implementation > impl(
new Data::Implementation(
name, readLegacyRdbString(uri, implKey, "UNO/ACTIVATOR"),
readLegacyRdbString(uri, implKey, "UNO/LOCATION"),
rtl::OUString(),
readLegacyRdbString(uri, implKey, "UNO/LOCATION"), "", "",
css::uno::Reference< css::uno::XComponentContext >(), uri));
if (!data_.namedImplementations.insert(
Data::NamedImplementations::value_type(name, impl)).

View File

@ -53,13 +53,15 @@ public:
struct ImplementationInfo: private boost::noncopyable {
ImplementationInfo(
rtl::OUString const & theName, rtl::OUString const & theLoader,
rtl::OUString const & theUri, rtl::OUString const & thePrefix,
rtl::OUString const & theUri,
rtl::OUString const & theEnvironment,
rtl::OUString const & thePrefix,
css::uno::Reference< css::uno::XComponentContext > const &
theAlienContext,
rtl::OUString const & theRdbFile):
name(theName), loader(theLoader), uri(theUri),
prefix(thePrefix), alienContext(theAlienContext),
rdbFile(theRdbFile)
environment(theEnvironment), prefix(thePrefix),
alienContext(theAlienContext), rdbFile(theRdbFile)
{}
explicit ImplementationInfo(rtl::OUString const & theName):
@ -68,6 +70,7 @@ public:
rtl::OUString const name;
rtl::OUString const loader;
rtl::OUString const uri;
rtl::OUString const environment;
rtl::OUString const prefix;
css::uno::Reference< css::uno::XComponentContext > const
alienContext;
@ -79,13 +82,15 @@ public:
struct Implementation: private boost::noncopyable {
Implementation(
rtl::OUString const & name, rtl::OUString const & loader,
rtl::OUString const & uri, rtl::OUString const & prefix,
rtl::OUString const & uri, rtl::OUString const & environment,
rtl::OUString const & prefix,
css::uno::Reference< css::uno::XComponentContext > const &
alienContext,
rtl::OUString const & rdbFile):
info(
new ImplementationInfo(
name, loader, uri, prefix, alienContext, rdbFile)),
name, loader, uri, environment, prefix, alienContext,
rdbFile)),
loaded(false)
{}

View File

@ -19,6 +19,8 @@
#include "sal/config.h"
#include <cassert>
#include "osl/module.hxx"
#include "uno/environment.h"
#include <uno/lbnames.h>
@ -49,11 +51,33 @@ using rtl::OUString;
namespace {
uno::Environment getEnvironment(
OUString const & name, OUString const & cImplName)
{
OUString n(name);
static const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" );
if (pUNO_ENV_LOG && rtl_str_getLength(pUNO_ENV_LOG) )
{
OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
OString aEnv( pUNO_ENV_LOG );
sal_Int32 nIndex = 0;
do
{
const OString aStr( aEnv.getToken( 0, ';', nIndex ) );
if ( aStr.equals(implName) )
{
n += ::rtl::OUString(":log");
break;
}
} while( nIndex != -1 );
}
return uno::Environment(n);
}
#ifndef DISABLE_DYNLOADING
void getLibEnv(oslModule lib,
uno::Environment * pEnv,
OUString * pSourceEnv_name,
uno::Environment const & cTargetEnv,
OUString const & cImplName = OUString(),
OUString const & rPrefix = OUString())
@ -84,23 +108,8 @@ void getLibEnv(oslModule lib,
if (!pEnv->is() && pEnvTypeName)
{
*pSourceEnv_name = OUString::createFromAscii(pEnvTypeName);
static const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" );
if (pUNO_ENV_LOG && rtl_str_getLength(pUNO_ENV_LOG) )
{
OString implName(OUStringToOString(cImplName, RTL_TEXTENCODING_ASCII_US));
OString aEnv( pUNO_ENV_LOG );
sal_Int32 nIndex = 0;
do
{
const OString aStr( aEnv.getToken( 0, ';', nIndex ) );
if ( aStr.equals(implName) )
{
*pSourceEnv_name += ::rtl::OUString(":log");
break;
}
} while( nIndex != -1 );
}
*pEnv = getEnvironment(
OUString::createFromAscii(pEnvTypeName), cImplName);
}
}
@ -134,7 +143,7 @@ Reference< XInterface > SAL_CALL loadSharedLibComponentFactory(
(void) rPath;
(void) xKey;
return cppuhelper::detail::loadSharedLibComponentFactory(
uri, "", rImplName, xMgr);
uri, "", "", rImplName, xMgr);
}
}
@ -143,41 +152,19 @@ namespace
{
Reference< XInterface > invokeComponentFactory(
uno::Environment const & env,
oslGenericFunction pGetter,
oslModule lib,
OUString const & rModulePath,
OUString const & rImplName,
Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr,
OUString const & rPrefix,
OUString &rExcMsg )
{
Reference< XInterface > xRet;
uno::Environment currentEnv(Environment::getCurrent());
uno::Environment env;
OUString aEnvTypeName;
#ifdef DISABLE_DYNLOADING
(void) lib;
(void) rPrefix;
// It seems that the only UNO components that have
// component_getImplementationEnvironment functions are the JDBC
// and ADO (whatever that is) database connectivity thingies
// neither of which make sense on iOS and Android (which are the
// only platforms for which DISABLE_DYNLOADING is intended,
// really). So we can simply bypass the getLibEnv() stuff and
// don't need to wonder how to find out what function to call at
// this point if statically linked.
aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
#else
getLibEnv(lib, &env, &aEnvTypeName, currentEnv, rImplName, rPrefix);
#endif
OString aImplName(
OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
if (!env.is())
env = uno::Environment(aEnvTypeName);
if (env.is() && currentEnv.is())
{
#if OSL_DEBUG_LEVEL > 1
@ -282,7 +269,8 @@ extern "C"
namespace cppuhelper { namespace detail {
css::uno::Reference<css::uno::XInterface> loadSharedLibComponentFactory(
OUString const & uri, OUString const & rPrefix, OUString const & rImplName,
OUString const & uri, OUString const & rEnvironment,
OUString const & rPrefix, OUString const & rImplName,
css::uno::Reference<css::lang::XMultiServiceFactory> const & xMgr)
{
#ifndef DISABLE_DYNLOADING
@ -388,7 +376,22 @@ css::uno::Reference<css::uno::XInterface> loadSharedLibComponentFactory(
if (pSym != 0)
{
xRet = invokeComponentFactory( pSym, lib, moduleUri, rImplName, xMgr, aFullPrefix, aExcMsg );
uno::Environment env;
if (rEnvironment.isEmpty()) {
#if defined DISABLE_DYNLOADING
//TODO: assert(false); // this cannot happen
env = getEnvironment(CPPU_CURRENT_LANGUAGE_BINDING_NAME, rImplName);
#else
getLibEnv(
lib, &env, Environment::getCurrent(), rImplName, aFullPrefix);
#endif
} else {
env = getEnvironment(rEnvironment, rImplName);
}
xRet = invokeComponentFactory(
env, pSym, moduleUri, rImplName, xMgr, aExcMsg );
}
else
{
@ -451,18 +454,14 @@ void SAL_CALL writeSharedLibComponentInfo(
uno::Environment currentEnv(Environment::getCurrent());
uno::Environment env;
OUString aEnvTypeName;
OUString aExcMsg;
getLibEnv(lib, &env, &aEnvTypeName, currentEnv);
getLibEnv(lib, &env, currentEnv);
OUString aWriteInfoName = COMPONENT_WRITEINFO;
oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData );
if (pSym != 0)
{
if (!env.is())
env = uno::Environment(aEnvTypeName);
if (env.is() && currentEnv.is())
{
Mapping aCurrent2Env( currentEnv, env );

View File

@ -22,6 +22,7 @@
xmlns="http://openoffice.org/2010/uno-components"
xmlns:uc="http://openoffice.org/2010/uno-components">
<xsl:param name="uri"/>
<xsl:param name="cppu_env"/>
<xsl:strip-space elements="*"/>
<xsl:template match="uc:component">
<components>
@ -40,7 +41,36 @@
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="@environment">
<xsl:attribute name="environment">
<xsl:call-template name="replace">
<xsl:with-param name="input" select="current()"/>
<xsl:with-param name="pattern" select="'@CPPU_ENV@'"/>
<xsl:with-param name="replace" select="$cppu_env"/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="input"/>
<xsl:param name="pattern"/>
<xsl:param name="replace"/>
<xsl:choose>
<xsl:when test="contains($input, $pattern)">
<xsl:value-of select="substring-before($input, $pattern)"/>
<xsl:value-of select="$replace"/>
<xsl:call-template name="replace">
<xsl:with-param
name="input" select="substring-after($input, $pattern)"/>
<xsl:with-param name="pattern" select="$pattern"/>
<xsl:with-param name="replace" select="$replace"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@ -30,8 +30,9 @@ $(call gb_Output_announce,$(3),$(true),CMP,1)
$(if $(LIBFILENAME),,$(call gb_Output_error,No LIBFILENAME set at component target: $(1)))
$(call gb_Helper_abbreviate_dirs,\
mkdir -p $(dir $(1)) && \
$(call gb_ExternalExecutable_get_command,xsltproc) --nonet --stringparam uri \
'$(if $(filter TRUE,$(DISABLE_DYNLOADING)),,$(subst \d,$$,$(COMPONENTPREFIX)))$(LIBFILENAME)' -o $(1) \
$(call gb_ExternalExecutable_get_command,xsltproc) --nonet \
--stringparam uri '$(if $(filter TRUE,$(DISABLE_DYNLOADING)),,$(subst \d,$$,$(COMPONENTPREFIX)))$(LIBFILENAME)' \
--stringparam cppu_env $(gb_CPPU_ENV) -o $(1) \
$(gb_ComponentTarget_XSLTCOMMANDFILE) $(2))
endef