summaryrefslogtreecommitdiff
path: root/cppuhelper
diff options
context:
space:
mode:
authorHenry Castro <hcastro@collabora.com>2015-09-07 17:11:45 -0400
committerTor Lillqvist <tml@collabora.com>2016-02-15 22:23:11 +0200
commit6b41b89cc51b65fe3aa69099638ec4432782886a (patch)
treeac6464fc4e6659cae0ee4bc5a075a307c9c858ac /cppuhelper
parent682c48afd989a89680a4d5ee18c8a15d10e5a58b (diff)
In loadAllImplementations(), also invoke component factory
Change-Id: Ie6f6d769b611c8440ddab802545e6bdc482d1476
Diffstat (limited to 'cppuhelper')
-rw-r--r--cppuhelper/source/servicemanager.cxx86
1 files changed, 81 insertions, 5 deletions
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx
index 0c71a046b67a..0f709ef9190c 100644
--- a/cppuhelper/source/servicemanager.cxx
+++ b/cppuhelper/source/servicemanager.cxx
@@ -33,6 +33,8 @@
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/shlib.hxx>
#include <osl/file.hxx>
#include <osl/module.hxx>
#include <rtl/ref.hxx>
@@ -883,13 +885,16 @@ void cppuhelper::ServiceManager::loadAllImplementations()
#else
rtl::OUString aUri;
osl::MutexGuard g(rBHelper.rMutex);
+ css::uno::Environment aSourceEnv(css::uno::Environment::getCurrent());
+ // loop all implementations
for (Data::NamedImplementations::const_iterator iterator(
data_.namedImplementations.begin());
iterator != data_.namedImplementations.end(); ++iterator)
{
try
{
+ // expand absolute URI implementation component library
aUri = cppu::bootstrap_expandUri(iterator->second->info->uri);
}
catch (css::lang::IllegalArgumentException& aError)
@@ -902,13 +907,84 @@ void cppuhelper::ServiceManager::loadAllImplementations()
if (iterator->second->info->loader == "com.sun.star.loader.SharedLibrary" &&
iterator->second->status != Data::Implementation::STATUS_LOADED)
{
- oslModule aModule = osl_loadModule( aUri.pData, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL );
- SAL_INFO("lok", "loaded component library " << aUri << ( aModule ? " ok" : " no"));
+ // load component library
+ osl::Module aModule(aUri, SAL_LOADMODULE_NOW | SAL_LOADMODULE_GLOBAL);
+ SAL_INFO("lok", "loaded component library " << aUri << ( aModule.is() ? " ok" : " no"));
- // leak aModule
- // osl_unloadModule(aModule);
- if ( aModule )
+ if (aModule.is() &&
+ !iterator->second->info->environment.isEmpty())
+ {
+ OUString aSymFactory;
+ oslGenericFunction fpFactory;
+ css::uno::Environment aTargetEnv;
+ css::uno::Reference<css::uno::XInterface> xFactory;
+
+ if(iterator->second->info->constructor.isEmpty())
+ {
+ // expand full name component factory symbol
+ if (iterator->second->info->prefix == "direct")
+ aSymFactory = iterator->second->info->name.replace('.', '_') + "_" COMPONENT_GETFACTORY;
+ else if (!iterator->second->info->prefix.isEmpty())
+ aSymFactory = iterator->second->info->prefix + "_" COMPONENT_GETFACTORY;
+ else
+ aSymFactory = COMPONENT_GETFACTORY;
+
+ // get function symbol component factory
+ fpFactory = aModule.getFunctionSymbol(aSymFactory);
+ if (fpFactory == nullptr)
+ {
+ throw css::loader::CannotActivateFactoryException(
+ ("no factory symbol \"" + aSymFactory + "\" in component library :" + aUri),
+ css::uno::Reference<css::uno::XInterface>());
+ }
+
+ aTargetEnv = cppuhelper::detail::getEnvironment(iterator->second->info->environment, iterator->second->info->name);
+ component_getFactoryFunc fpComponentFactory = reinterpret_cast<component_getFactoryFunc>(fpFactory);
+
+ if (aSourceEnv.get() == aTargetEnv.get())
+ {
+ // invoke function component factory
+ OString aImpl(rtl::OUStringToOString(iterator->second->info->name, RTL_TEXTENCODING_ASCII_US));
+ xFactory.set(css::uno::Reference<css::uno::XInterface>(static_cast<css::uno::XInterface *>(
+ (*fpComponentFactory)(aImpl.getStr(), this, nullptr)), SAL_NO_ACQUIRE));
+ }
+ }
+ else
+ {
+ // get function symbol component factory
+ fpFactory = aModule.getFunctionSymbol(iterator->second->info->constructor);
+ }
+
+ css::uno::Reference<css::lang::XSingleComponentFactory> xSCFactory;
+ css::uno::Reference<css::lang::XSingleServiceFactory> xSSFactory;
+
+ // query interface XSingleComponentFactory or XSingleServiceFactory
+ if (xFactory.is())
+ {
+ xSCFactory.set(xFactory, css::uno::UNO_QUERY);
+ if (!xSCFactory.is())
+ {
+ xSSFactory.set(xFactory, css::uno::UNO_QUERY);
+ if (!xSSFactory.is())
+ {
+ throw css::uno::DeploymentException(
+ ("Implementation " + iterator->second->info->name
+ + " does not provide a constructor or factory"),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ }
+ }
+
+ if (!iterator->second->info->constructor.isEmpty() && fpFactory)
+ iterator->second->constructor = reinterpret_cast<ImplementationConstructorFn *>(fpFactory);
+
+ iterator->second->factory1 = xSCFactory;
+ iterator->second->factory2 = xSSFactory;
iterator->second->status = Data::Implementation::STATUS_LOADED;
+
+ }
+ // leak aModule
+ aModule.release();
}
}
#endif