diff options
author | Jan Holesovsky <kendy@collabora.com> | 2014-01-21 15:45:43 +0100 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2014-01-21 21:25:22 +0100 |
commit | f278397787f7b79cee8536e806e8b7113800f2ef (patch) | |
tree | 1760bce432d466cf9f3ca444c89ec8f44306ab04 /cppuhelper | |
parent | 3780738154b8c3b3f9d85c64cccf621d97574886 (diff) |
Change _get_implementation()'s not to do initialization directly.
Many of the initalizations (in eg. framework) have to be done on an
acquire()'d object, so instead of doing the initialization directly, return
the initialization member function back to the createInstance() /
createInstanceWithContext() / ... and perform the initialization there.
As a sideeffect, I belive the calling initialize() from servicemanager is not
that much a hack any more - whoever converts the implementation to be
constructor-base has the choice to provide the callback, or still initialize
through XInitialization, where the callback is preferred by servicemanager
when it exists.
Change-Id: I8a87b75c54c1441ca0f184967d31ff4902fc4081
Diffstat (limited to 'cppuhelper')
-rw-r--r-- | cppuhelper/source/servicemanager.cxx | 69 | ||||
-rw-r--r-- | cppuhelper/source/servicemanager.hxx | 3 |
2 files changed, 50 insertions, 22 deletions
diff --git a/cppuhelper/source/servicemanager.cxx b/cppuhelper/source/servicemanager.cxx index 0eb30aa0e9c1..3d81b8b68dc6 100644 --- a/cppuhelper/source/servicemanager.cxx +++ b/cppuhelper/source/servicemanager.cxx @@ -704,9 +704,14 @@ cppuhelper::ServiceManager::Data::Implementation::createInstance( if (info->singletons.empty()) { assert(!singletonRequest); if (constructor != 0) { - return css::uno::Reference<css::uno::XInterface>( - (*constructor)( - context.get(), css::uno::Sequence<css::uno::Any>())); + cppu::constructor_InitializationFunc init = NULL; + css::uno::Reference<css::uno::XInterface> inst( + (*constructor)(context.get(), init)); + // call the initialization on the acquired instance + if (init) + (static_cast<OWeakObject*>(inst.get())->*init)( + css::uno::Sequence<css::uno::Any>()); + return inst; } if (factory1.is()) { return factory1->createInstanceWithContext(context); @@ -722,9 +727,13 @@ cppuhelper::ServiceManager::Data::Implementation::createInstance( return singleton; } if (constructor != 0) { + cppu::constructor_InitializationFunc init = NULL; singleton.set( - (*constructor)( - context.get(), css::uno::Sequence<css::uno::Any>())); + (*constructor)(context.get(), init)); + // call the initialization on the acquired instance + if (init) + (static_cast<OWeakObject*>(singleton.get())->*init)( + css::uno::Sequence<css::uno::Any>()); } else if (factory1.is()) { singleton = factory1->createInstanceWithContext(context); } else { @@ -744,17 +753,24 @@ cppuhelper::ServiceManager::Data::Implementation::createInstanceWithArguments( if (info->singletons.empty()) { assert(!singletonRequest); if (constructor != 0) { - //HACK: The constructor will either observe arguments and return - // inst that does not implement XInitialization (or null), or ignore - // arguments and return inst that implements XInitialization; this - // should be removed again once XInitialization-based - // implementations have become rare: + cppu::constructor_InitializationFunc init = NULL; css::uno::Reference<css::uno::XInterface> inst( - (*constructor)(context.get(), arguments)); - css::uno::Reference<css::lang::XInitialization> init( - inst, css::uno::UNO_QUERY); - if (init.is()) { - init->initialize(arguments); + (*constructor)(context.get(), init)); + // call the initialization on the acquired instance + if (init) + (static_cast<OWeakObject*>(inst.get())->*init)( + arguments); + else { + // The service can implement XInitialization, and it is just + // too easy to do a mistake during conversion to the + // constructor-based initialization, and forget to add the + // above callback that would call it; so allow initialization + // through XInitialization still too. + css::uno::Reference<css::lang::XInitialization> xinit( + inst, css::uno::UNO_QUERY); + if (xinit.is()) { + xinit->initialize(arguments); + } } return inst; } @@ -777,12 +793,23 @@ cppuhelper::ServiceManager::Data::Implementation::createInstanceWithArguments( return singleton; } if (constructor != 0) { - //HACK: see above - singleton.set((*constructor)(context.get(), arguments)); - css::uno::Reference<css::lang::XInitialization> init( - singleton, css::uno::UNO_QUERY); - if (init.is()) { - init->initialize(arguments); + cppu::constructor_InitializationFunc init = NULL; + singleton.set((*constructor)(context.get(), init)); + // call the initialization on the acquired instance + if (init) + (static_cast<OWeakObject*>(singleton.get())->*init)( + arguments); + else { + // The service can implement XInitialization, and it is just + // too easy to do a mistake during conversion to the + // constructor-based initialization, and forget to add the + // above callback that would call it; so allow initialization + // through XInitialization still too. + css::uno::Reference<css::lang::XInitialization> xinit( + singleton, css::uno::UNO_QUERY); + if (xinit.is()) { + xinit->initialize(arguments); + } } } else if (factory1.is()) { singleton = factory1->createInstanceWithArgumentsAndContext( diff --git a/cppuhelper/source/servicemanager.hxx b/cppuhelper/source/servicemanager.hxx index a9522a564e5e..2d29f58b48ca 100644 --- a/cppuhelper/source/servicemanager.hxx +++ b/cppuhelper/source/servicemanager.hxx @@ -33,6 +33,7 @@ #include "osl/mutex.hxx" #include "registry/registry.hxx" #include "rtl/ustring.hxx" +#include "cppuhelper/weak.hxx" namespace com { namespace sun { namespace star { namespace lang { class XSingleComponentFactory; @@ -44,7 +45,7 @@ namespace cppuhelper { extern "C" { typedef css::uno::XInterface * SAL_CALL ImplementationConstructorFn( - css::uno::XComponentContext *, css::uno::Sequence<css::uno::Any> const &); + css::uno::XComponentContext *, cppu::constructor_InitializationFunc &); } |