20#include <unordered_map>
22#include <osl/diagnose.h>
23#include <osl/mutex.hxx>
27#include <uno/lbnames.h>
28#include <uno/mapping.hxx>
35#include <com/sun/star/container/XNameContainer.hpp>
36#include <com/sun/star/lang/XSingleServiceFactory.hpp>
37#include <com/sun/star/lang/XSingleComponentFactory.hpp>
38#include <com/sun/star/lang/XMultiComponentFactory.hpp>
39#include <com/sun/star/lang/XComponent.hpp>
40#include <com/sun/star/beans/XPropertySet.hpp>
41#include <com/sun/star/uno/DeploymentException.hpp>
42#include <com/sun/star/uno/RuntimeException.hpp>
49constexpr OUStringLiteral
SMGR_SINGLETON =
u"/singletons/com.sun.star.lang.theServiceManager";
50constexpr OUStringLiteral
TDMGR_SINGLETON =
u"/singletons/com.sun.star.reflection.theTypeDescriptionManager";
51constexpr OUStringLiteral
AC_SINGLETON =
u"/singletons/com.sun.star.security.theAccessController";
60static void try_dispose( Reference< XInterface >
const & xInstance )
62 Reference< lang::XComponent > xComp( xInstance, UNO_QUERY );
69static void try_dispose( Reference< lang::XComponent >
const & xComp )
79class DisposingForwarder
80 :
public WeakImplHelper< lang::XEventListener >
84 explicit DisposingForwarder( Reference< lang::XComponent >
const & xTarget )
91 static inline void listen(
92 Reference< lang::XComponent >
const & xSource,
93 Reference< lang::XComponent >
const & xTarget );
95 virtual void SAL_CALL disposing( lang::EventObject
const & rSource )
override;
100inline void DisposingForwarder::listen(
101 Reference< lang::XComponent >
const & xSource,
102 Reference< lang::XComponent >
const & xTarget )
106 xSource->addEventListener(
new DisposingForwarder( xTarget ) );
110void DisposingForwarder::disposing( lang::EventObject
const & )
118class ComponentContext
120 ,
public WeakComponentImplHelper< XComponentContext,
121 container::XNameContainer >
131 ContextEntry( Any value_,
bool lateInit_ )
136 typedef std::unordered_map< OUString, ContextEntry > t_map;
139 Reference< lang::XMultiComponentFactory >
m_xSMgr;
142 Any lookupMap( OUString
const & rName );
144 virtual void SAL_CALL disposing()
override;
147 ContextEntry_Init
const * pEntries, sal_Int32 nEntries,
148 Reference< XComponentContext >
const & xDelegate );
151 virtual Any SAL_CALL getValueByName( OUString
const & rName )
override;
152 virtual Reference<lang::XMultiComponentFactory> SAL_CALL getServiceManager()
override;
155 virtual void SAL_CALL insertByName(
156 OUString
const & name, Any
const & element )
override;
157 virtual void SAL_CALL removeByName( OUString
const & name )
override;
159 virtual void SAL_CALL replaceByName(
160 OUString
const & name, Any
const & element )
override;
162 virtual Any SAL_CALL getByName( OUString
const & name )
override;
163 virtual Sequence<OUString> SAL_CALL getElementNames()
override;
164 virtual sal_Bool SAL_CALL hasByName( OUString
const & name )
override;
166 virtual Type SAL_CALL getElementType()
override;
167 virtual sal_Bool SAL_CALL hasElements()
override;
174void ComponentContext::insertByName(
175 OUString
const & name, Any
const & element )
180 name.startsWith(
"/singletons/" ) &&
181 !element.hasValue() );
182 MutexGuard guard( m_aMutex );
183 std::pair<t_map::iterator, bool> insertion(
m_map.emplace(
185 if (! insertion.second)
186 throw container::ElementExistException(
187 "element already exists: " + name,
188 static_cast<OWeakObject *
>(
this) );
192void ComponentContext::removeByName( OUString
const & name )
194 MutexGuard guard( m_aMutex );
195 t_map::iterator iFind(
m_map.find( name ) );
196 if (iFind ==
m_map.end())
197 throw container::NoSuchElementException(
198 "no such element: " + name,
199 static_cast<OWeakObject *
>(
this) );
206void ComponentContext::replaceByName(
207 OUString
const & name, Any
const & element )
209 MutexGuard guard( m_aMutex );
210 t_map::iterator iFind(
m_map.find( name ) );
211 if (iFind ==
m_map.end())
212 throw container::NoSuchElementException(
213 "no such element: " + name,
214 static_cast<OWeakObject *
>(
this) );
215 if (
name.startsWith(
"/singletons/" ) &&
218 iFind->second.value.clear();
219 iFind->second.lateInit =
true;
223 iFind->second.value = element;
224 iFind->second.lateInit =
false;
230Any ComponentContext::getByName( OUString
const & name )
232 return getValueByName( name );
236Sequence<OUString> ComponentContext::getElementNames()
238 MutexGuard guard( m_aMutex );
243sal_Bool ComponentContext::hasByName( OUString
const & name )
245 MutexGuard guard( m_aMutex );
251Type ComponentContext::getElementType()
257sal_Bool ComponentContext::hasElements()
259 MutexGuard guard( m_aMutex );
260 return !
m_map.empty();
264Any ComponentContext::lookupMap( OUString
const & rName )
266 ResettableMutexGuard guard( m_aMutex );
267 t_map::iterator iFind(
m_map.find( rName ) );
268 if (iFind ==
m_map.end())
271 ContextEntry& rFindEntry = iFind->second;
272 if (! rFindEntry.lateInit)
273 return rFindEntry.value;
276 Reference< XInterface > xInstance;
281 Any usesService( getValueByName( rName +
"/service" ) );
282 Any args_( getValueByName( rName +
"/arguments" ) );
284 if (args_.hasValue() && !(args_ >>= args))
289 Reference< lang::XSingleComponentFactory > xFac;
290 if (usesService >>= xFac)
292 xInstance =
args.hasElements()
293 ? xFac->createInstanceWithArgumentsAndContext( args,
this )
294 : xFac->createInstanceWithContext(
this );
298 Reference< lang::XSingleServiceFactory > xFac2;
299 if (usesService >>= xFac2)
302 xInstance =
args.hasElements()
303 ? xFac2->createInstanceWithArguments( args )
304 : xFac2->createInstance();
308 OUString serviceName;
309 if ((usesService >>= serviceName) &&
310 !serviceName.isEmpty())
312 xInstance =
args.hasElements()
313 ?
m_xSMgr->createInstanceWithArgumentsAndContext(
314 serviceName, args,
this )
315 :
m_xSMgr->createInstanceWithContext(
325 catch (
const Exception & exc)
329 "exception occurred raising singleton \"" << rName <<
"\": "
334 "cppuhelper",
"no service object raising singleton " << rName);
338 iFind =
m_map.find( rName );
339 if (iFind !=
m_map.end())
341 ContextEntry & rEntry = iFind->second;
344 rEntry.value <<= xInstance;
345 rEntry.lateInit =
false;
351 if (ret != xInstance) {
358Any ComponentContext::getValueByName( OUString
const & rName )
361 if ( rName ==
"_root" )
365 return Any( Reference<XComponentContext>(
this) );
368 Any ret( lookupMap( rName ) );
376Reference< lang::XMultiComponentFactory > ComponentContext::getServiceManager()
380 throw DeploymentException(
381 "null component context service manager",
382 static_cast<OWeakObject *
>(
this) );
387void ComponentContext::disposing()
389 Reference< lang::XComponent > xTDMgr, xAC;
392 for (
auto& [rName, rEntry] :
m_map )
401 MutexGuard guard( m_aMutex );
404 rEntry.value.clear();
405 rEntry.lateInit =
false;
410 Reference< lang::XComponent > xComp;
411 rEntry.value >>= xComp;
446 &envs, &envCount, &rtl_allocateMemory, OUString(
"java").pData);
447 assert(envCount >= 0);
448 assert(envCount == 0 || envs !=
nullptr);
450 for (sal_Int32 i = 0;
i != envCount; ++
i) {
451 assert(envs[i] !=
nullptr);
452 assert(envs[i]->dispose !=
nullptr);
453 (*envs[
i]->dispose)(envs[i]);
459ComponentContext::ComponentContext(
460 ContextEntry_Init
const * pEntries, sal_Int32 nEntries,
461 Reference< XComponentContext >
const & xDelegate )
462 : WeakComponentImplHelper(
m_aMutex ),
465 for ( sal_Int32 nPos = 0;
nPos < nEntries; ++
nPos )
467 ContextEntry_Init
const & rEntry = pEntries[
nPos ];
474 if (rEntry.bLateInitService)
477 m_map.emplace( rEntry.name, ContextEntry(
Any(),
true ) );
479 m_map.emplace( rEntry.name +
"/service", ContextEntry( rEntry.value,
false ) );
485 m_map.emplace( rEntry.name, ContextEntry( rEntry.value,
false ) );
493 Reference< lang::XMultiComponentFactory > xMgr(
m_xDelegate->getServiceManager() );
497 osl_atomic_increment( &m_refCount );
502 xMgr->createInstanceWithContext(
503 "com.sun.star.comp.stoc.OServiceManagerWrapper", xDelegate ),
506 Reference< beans::XPropertySet > xProps(
m_xSMgr, UNO_QUERY );
507 OSL_ASSERT( xProps.is() );
510 Reference< XComponentContext > xThis(
this );
511 xProps->setPropertyValue(
"DefaultContext",
Any( xThis ) );
516 osl_atomic_decrement( &m_refCount );
519 osl_atomic_decrement( &m_refCount );
527 sal_Int32 nEntries = va_arg(*pParam, sal_Int32);
528 XComponentContext * pDelegatee = va_arg(*pParam, XComponentContext *);
529 void ** ppContext = va_arg(*pParam,
void **);
530 uno::Mapping * pTarget2curr = va_arg(*pParam, uno::Mapping *);
532 Reference<XComponentContext> xDelegate(pDelegatee, SAL_NO_ACQUIRE);
533 Reference<XComponentContext> xContext;
539 ComponentContext *
p =
new ComponentContext( pEntries, nEntries, xDelegate );
542 DisposingForwarder::listen( Reference< lang::XComponent >::query( xDelegate ),
p );
552 xContext = xDelegate;
555 *ppContext = pTarget2curr->mapInterface(xContext.get(),
cppu::UnoType<
decltype(xContext)>::get());
560 Reference< XComponentContext >
const & xDelegate )
562 uno::Environment curr_env(Environment::getCurrent());
563 uno::Environment source_env(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
565 uno::Mapping curr2source(curr_env, source_env);
566 uno::Mapping source2curr(source_env, curr_env);
568 std::unique_ptr<ContextEntry_Init[]> mapped_entries(
new ContextEntry_Init[nEntries]);
575 const_cast<void *
>(pEntries[
nPos].
value.getValue()),
580 void * mapped_delegate = curr2source.mapInterface(xDelegate.get(),
cppu::UnoType<
decltype(xDelegate)>::get());
581 XComponentContext * pXComponentContext =
nullptr;
582 source_env.invoke(
s_createComponentContext_v, mapped_entries.get(), nEntries, mapped_delegate, &pXComponentContext, &source2curr);
583 mapped_entries.reset();
585 return Reference<XComponentContext>(pXComponentContext, SAL_NO_ACQUIRE);
void SAL_CALL uno_type_any_constructAndConvert(uno_Any *pDest, void *pSource, typelib_TypeDescriptionReference *pType, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
base class for all classes who want derive from cppu::WeakComponentImplHelperXX.
css::uno::Type const & get()
Reference< lang::XMultiComponentFactory > m_xSMgr
constexpr OUStringLiteral SMGR_SINGLETON
constexpr OUStringLiteral TDMGR_SINGLETON
Reference< XComponentContext > m_xDelegate
Reference< lang::XComponent > m_xTarget
constexpr OUStringLiteral AC_SINGLETON
Reference< XInterface > xTarget
struct _uno_Environment uno_Environment
void SAL_CALL uno_getRegisteredEnvironments(uno_Environment ***pppEnvs, sal_Int32 *pnLen, uno_memAlloc memAlloc, rtl_uString *pEnvDcp) SAL_THROW_EXTERN_C()
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
static void try_dispose(Reference< XInterface > const &xInstance)
static void s_createComponentContext_v(va_list *pParam)
Reference< XComponentContext > SAL_CALL createComponentContext(ContextEntry_Init const *pEntries, sal_Int32 nEntries, Reference< XComponentContext > const &xDelegate)
Context entries init struct calling createComponentContext().
::rtl::OUString name
name of context value
bool bLateInitService
late init denotes an object that will be raised when first get() is calling for it
css::uno::Any value
context value