From b1d65c9f1535c9ef283d2a91a225359e5983f747 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Mon, 16 Dec 2013 21:39:14 +0100 Subject: 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 --- .../source/loadsharedlibcomponentfactory.hxx | 4 +- cppuhelper/source/servicemanager.cxx | 37 +++++++-- cppuhelper/source/servicemanager.hxx | 15 ++-- cppuhelper/source/shlib.cxx | 97 +++++++++++----------- 4 files changed, 89 insertions(+), 64 deletions(-) (limited to 'cppuhelper') diff --git a/cppuhelper/source/loadsharedlibcomponentfactory.hxx b/cppuhelper/source/loadsharedlibcomponentfactory.hxx index b0986dd76f48..9809c558cc09 100644 --- a/cppuhelper/source/loadsharedlibcomponentfactory.hxx +++ b/cppuhelper/source/loadsharedlibcomponentfactory.hxx @@ -23,8 +23,8 @@ namespace rtl { class OUString; } namespace cppuhelper { namespace detail { css::uno::Reference 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 const & xMgr); } } diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx index 512fb6be0320..3420233cc743 100644 --- a/cppuhelper/source/servicemanager.cxx +++ b/cppuhelper/source/servicemanager.cxx @@ -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() { + ": 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() + + ": has multiple \"environment\" attributes"), + css::uno::Reference< css::uno::XInterface >()); + } + attrEnvironment_ = reader_.getAttributeValue(false) + .convertFromUtf8(); + if (attrEnvironment_.isEmpty()) { + throw css::registry::InvalidRegistryException( + (reader_.getUrl() + + ": 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)). diff --git a/cppuhelper/source/servicemanager.hxx b/cppuhelper/source/servicemanager.hxx index 78359a2407d7..b68cd4b95edd 100644 --- a/cppuhelper/source/servicemanager.hxx +++ b/cppuhelper/source/servicemanager.hxx @@ -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) {} diff --git a/cppuhelper/source/shlib.cxx b/cppuhelper/source/shlib.cxx index 24bccf291341..a6a048ff956d 100644 --- a/cppuhelper/source/shlib.cxx +++ b/cppuhelper/source/shlib.cxx @@ -19,6 +19,8 @@ #include "sal/config.h" +#include + #include "osl/module.hxx" #include "uno/environment.h" #include @@ -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 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 const & xMgr) { #ifndef DISABLE_DYNLOADING @@ -388,7 +376,22 @@ css::uno::Reference 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 ); -- cgit