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

View File

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

View File

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

View File

@@ -17,7 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * 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"> xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.sdbc.ado.ODriver"> <implementation name="com.sun.star.comp.sdbc.ado.ODriver">
<service name="com.sun.star.sdbc.Driver"/> <service name="com.sun.star.sdbc.Driver"/>

View File

@@ -17,7 +17,18 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * 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"> xmlns="http://openoffice.org/2010/uno-components">
<implementation name="com.sun.star.comp.sdbc.JDBCDriver"> <implementation name="com.sun.star.comp.sdbc.JDBCDriver">
<service name="com.sun.star.sdbc.Driver"/> <service name="com.sun.star.sdbc.Driver"/>

View File

@@ -19,7 +19,6 @@
#include "java/sql/Driver.hxx" #include "java/sql/Driver.hxx"
#include <cppuhelper/factory.hxx> #include <cppuhelper/factory.hxx>
#include <uno/lbnames.h>
using namespace connectivity; using namespace connectivity;
using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Reference;
@@ -76,21 +75,6 @@ struct ProviderRequest
void* getProvider() const { return xRet.get(); } 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( extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL jdbc_component_getFactory(
const sal_Char* pImplementationName, const sal_Char* pImplementationName,
void* pServiceManager, void* pServiceManager,

View File

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

View File

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

View File

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

View File

@@ -19,6 +19,8 @@
#include "sal/config.h" #include "sal/config.h"
#include <cassert>
#include "osl/module.hxx" #include "osl/module.hxx"
#include "uno/environment.h" #include "uno/environment.h"
#include <uno/lbnames.h> #include <uno/lbnames.h>
@@ -49,11 +51,33 @@ using rtl::OUString;
namespace { 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 #ifndef DISABLE_DYNLOADING
void getLibEnv(oslModule lib, void getLibEnv(oslModule lib,
uno::Environment * pEnv, uno::Environment * pEnv,
OUString * pSourceEnv_name,
uno::Environment const & cTargetEnv, uno::Environment const & cTargetEnv,
OUString const & cImplName = OUString(), OUString const & cImplName = OUString(),
OUString const & rPrefix = OUString()) OUString const & rPrefix = OUString())
@@ -84,23 +108,8 @@ void getLibEnv(oslModule lib,
if (!pEnv->is() && pEnvTypeName) if (!pEnv->is() && pEnvTypeName)
{ {
*pSourceEnv_name = OUString::createFromAscii(pEnvTypeName); *pEnv = getEnvironment(
static const char * pUNO_ENV_LOG = ::getenv( "UNO_ENV_LOG" ); OUString::createFromAscii(pEnvTypeName), cImplName);
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 );
}
} }
} }
@@ -134,7 +143,7 @@ Reference< XInterface > SAL_CALL loadSharedLibComponentFactory(
(void) rPath; (void) rPath;
(void) xKey; (void) xKey;
return cppuhelper::detail::loadSharedLibComponentFactory( return cppuhelper::detail::loadSharedLibComponentFactory(
uri, "", rImplName, xMgr); uri, "", "", rImplName, xMgr);
} }
} }
@@ -143,41 +152,19 @@ namespace
{ {
Reference< XInterface > invokeComponentFactory( Reference< XInterface > invokeComponentFactory(
uno::Environment const & env,
oslGenericFunction pGetter, oslGenericFunction pGetter,
oslModule lib,
OUString const & rModulePath, OUString const & rModulePath,
OUString const & rImplName, OUString const & rImplName,
Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr, Reference< ::com::sun::star::lang::XMultiServiceFactory > const & xMgr,
OUString const & rPrefix,
OUString &rExcMsg ) OUString &rExcMsg )
{ {
Reference< XInterface > xRet; Reference< XInterface > xRet;
uno::Environment currentEnv(Environment::getCurrent()); 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( OString aImplName(
OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) ); OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
if (!env.is())
env = uno::Environment(aEnvTypeName);
if (env.is() && currentEnv.is()) if (env.is() && currentEnv.is())
{ {
#if OSL_DEBUG_LEVEL > 1 #if OSL_DEBUG_LEVEL > 1
@@ -282,7 +269,8 @@ extern "C"
namespace cppuhelper { namespace detail { namespace cppuhelper { namespace detail {
css::uno::Reference<css::uno::XInterface> loadSharedLibComponentFactory( 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) css::uno::Reference<css::lang::XMultiServiceFactory> const & xMgr)
{ {
#ifndef DISABLE_DYNLOADING #ifndef DISABLE_DYNLOADING
@@ -388,7 +376,22 @@ css::uno::Reference<css::uno::XInterface> loadSharedLibComponentFactory(
if (pSym != 0) 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 else
{ {
@@ -451,18 +454,14 @@ void SAL_CALL writeSharedLibComponentInfo(
uno::Environment currentEnv(Environment::getCurrent()); uno::Environment currentEnv(Environment::getCurrent());
uno::Environment env; uno::Environment env;
OUString aEnvTypeName;
OUString aExcMsg; OUString aExcMsg;
getLibEnv(lib, &env, &aEnvTypeName, currentEnv); getLibEnv(lib, &env, currentEnv);
OUString aWriteInfoName = COMPONENT_WRITEINFO; OUString aWriteInfoName = COMPONENT_WRITEINFO;
oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData ); oslGenericFunction pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData );
if (pSym != 0) if (pSym != 0)
{ {
if (!env.is())
env = uno::Environment(aEnvTypeName);
if (env.is() && currentEnv.is()) if (env.is() && currentEnv.is())
{ {
Mapping aCurrent2Env( currentEnv, env ); Mapping aCurrent2Env( currentEnv, env );

View File

@@ -22,6 +22,7 @@
xmlns="http://openoffice.org/2010/uno-components" xmlns="http://openoffice.org/2010/uno-components"
xmlns:uc="http://openoffice.org/2010/uno-components"> xmlns:uc="http://openoffice.org/2010/uno-components">
<xsl:param name="uri"/> <xsl:param name="uri"/>
<xsl:param name="cppu_env"/>
<xsl:strip-space elements="*"/> <xsl:strip-space elements="*"/>
<xsl:template match="uc:component"> <xsl:template match="uc:component">
<components> <components>
@@ -40,7 +41,36 @@
<xsl:apply-templates/> <xsl:apply-templates/>
</xsl:copy> </xsl:copy>
</xsl:template> </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:template match="@*">
<xsl:copy/> <xsl:copy/>
</xsl:template> </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> </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))) $(if $(LIBFILENAME),,$(call gb_Output_error,No LIBFILENAME set at component target: $(1)))
$(call gb_Helper_abbreviate_dirs,\ $(call gb_Helper_abbreviate_dirs,\
mkdir -p $(dir $(1)) && \ mkdir -p $(dir $(1)) && \
$(call gb_ExternalExecutable_get_command,xsltproc) --nonet --stringparam uri \ $(call gb_ExternalExecutable_get_command,xsltproc) --nonet \
'$(if $(filter TRUE,$(DISABLE_DYNLOADING)),,$(subst \d,$$,$(COMPONENTPREFIX)))$(LIBFILENAME)' -o $(1) \ --stringparam uri '$(if $(filter TRUE,$(DISABLE_DYNLOADING)),,$(subst \d,$$,$(COMPONENTPREFIX)))$(LIBFILENAME)' \
--stringparam cppu_env $(gb_CPPU_ENV) -o $(1) \
$(gb_ComponentTarget_XSLTCOMMANDFILE) $(2)) $(gb_ComponentTarget_XSLTCOMMANDFILE) $(2))
endef endef