1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: component_context.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppuhelper.hxx"
38 #if OSL_DEBUG_LEVEL > 0
48 #include <osl/diagnose.h>
49 #include <osl/mutex.hxx>
51 #include <rtl/ustrbuf.hxx>
53 #include <uno/mapping.hxx>
55 #include <cppuhelper/implbase1.hxx>
56 #include <cppuhelper/compbase2.hxx>
57 #include <cppuhelper/component_context.hxx>
58 #include <cppuhelper/exc_hlp.hxx>
60 #include <com/sun/star/container/XNameContainer.hpp>
61 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
62 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
63 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
64 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
65 #include <com/sun/star/lang/XComponent.hpp>
66 #include <com/sun/star/beans/XPropertySet.hpp>
67 #include "com/sun/star/uno/RuntimeException.hpp"
72 #define SMGR_SINGLETON "/singletons/com.sun.star.lang.theServiceManager"
73 #define TDMGR_SINGLETON "/singletons/com.sun.star.reflection.theTypeDescriptionManager"
74 #define AC_SINGLETON "/singletons/com.sun.star.security.theAccessController"
75 #define AC_POLICY "/singletons/com.sun.star.security.thePolicy"
76 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
79 using namespace ::osl
;
80 using namespace ::rtl
;
81 using namespace ::com::sun::star::uno
;
82 using namespace ::com::sun::star
;
88 //--------------------------------------------------------------------------------------------------
89 static OUString
val2str( void const * pVal
, typelib_TypeDescriptionReference
* pTypeRef
)
92 if (pTypeRef
->eTypeClass
== typelib_TypeClass_VOID
)
95 OUStringBuffer
buf( 64 );
96 buf
.append( (sal_Unicode
)'(' );
97 buf
.append( pTypeRef
->pTypeName
);
98 buf
.append( (sal_Unicode
)')' );
100 switch (pTypeRef
->eTypeClass
)
102 case typelib_TypeClass_INTERFACE
:
103 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
104 buf
.append( (sal_Int64
)*(void **)pVal
, 16 );
106 case typelib_TypeClass_STRUCT
:
107 case typelib_TypeClass_EXCEPTION
:
109 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
110 typelib_TypeDescription
* pTypeDescr
= 0;
111 ::typelib_typedescriptionreference_getDescription( &pTypeDescr
, pTypeRef
);
112 OSL_ASSERT( pTypeDescr
);
113 if (! pTypeDescr
->bComplete
)
114 ::typelib_typedescription_complete( &pTypeDescr
);
116 typelib_CompoundTypeDescription
* pCompType
= (typelib_CompoundTypeDescription
*)pTypeDescr
;
117 sal_Int32 nDescr
= pCompType
->nMembers
;
119 if (pCompType
->pBaseTypeDescription
)
121 buf
.append( val2str( pVal
, ((typelib_TypeDescription
*)pCompType
->pBaseTypeDescription
)->pWeakRef
) );
123 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
126 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompType
->ppTypeRefs
;
127 sal_Int32
* pMemberOffsets
= pCompType
->pMemberOffsets
;
128 rtl_uString
** ppMemberNames
= pCompType
->ppMemberNames
;
130 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
132 buf
.append( ppMemberNames
[ nPos
] );
133 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
134 typelib_TypeDescription
* pMemberType
= 0;
135 TYPELIB_DANGER_GET( &pMemberType
, ppTypeRefs
[ nPos
] );
136 buf
.append( val2str( (char *)pVal
+ pMemberOffsets
[ nPos
], pMemberType
->pWeakRef
) );
137 TYPELIB_DANGER_RELEASE( pMemberType
);
138 if (nPos
< (nDescr
-1))
139 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
142 ::typelib_typedescription_release( pTypeDescr
);
144 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
147 case typelib_TypeClass_SEQUENCE
:
149 typelib_TypeDescription
* pTypeDescr
= 0;
150 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
152 uno_Sequence
* pSequence
= *(uno_Sequence
**)pVal
;
153 typelib_TypeDescription
* pElementTypeDescr
= 0;
154 TYPELIB_DANGER_GET( &pElementTypeDescr
, ((typelib_IndirectTypeDescription
*)pTypeDescr
)->pType
);
156 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
157 sal_Int32 nElements
= pSequence
->nElements
;
161 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
162 char * pElements
= pSequence
->elements
;
163 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
165 buf
.append( val2str( pElements
+ (nElementSize
* nPos
), pElementTypeDescr
->pWeakRef
) );
166 if (nPos
< (nElements
-1))
167 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
169 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
173 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
175 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
176 TYPELIB_DANGER_RELEASE( pTypeDescr
);
179 case typelib_TypeClass_ANY
:
180 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
181 buf
.append( val2str( ((uno_Any
*)pVal
)->pData
,
182 ((uno_Any
*)pVal
)->pType
) );
183 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
185 case typelib_TypeClass_TYPE
:
186 buf
.append( (*(typelib_TypeDescriptionReference
**)pVal
)->pTypeName
);
188 case typelib_TypeClass_STRING
:
189 buf
.append( (sal_Unicode
)'\"' );
190 buf
.append( *(rtl_uString
**)pVal
);
191 buf
.append( (sal_Unicode
)'\"' );
193 case typelib_TypeClass_ENUM
:
195 typelib_TypeDescription
* pTypeDescr
= 0;
196 ::typelib_typedescriptionreference_getDescription( &pTypeDescr
, pTypeRef
);
197 OSL_ASSERT( pTypeDescr
);
198 if (! pTypeDescr
->bComplete
)
199 ::typelib_typedescription_complete( &pTypeDescr
);
201 sal_Int32
* pValues
= ((typelib_EnumTypeDescription
*)pTypeDescr
)->pEnumValues
;
202 sal_Int32 nPos
= ((typelib_EnumTypeDescription
*)pTypeDescr
)->nEnumValues
;
205 if (pValues
[ nPos
] == *(sal_Int32
*)pVal
)
209 buf
.append( ((typelib_EnumTypeDescription
*)pTypeDescr
)->ppEnumNames
[ nPos
] );
211 buf
.append( (sal_Unicode
)'?' );
213 ::typelib_typedescription_release( pTypeDescr
);
216 case typelib_TypeClass_BOOLEAN
:
217 if (*(sal_Bool
*)pVal
)
218 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
220 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
222 case typelib_TypeClass_CHAR
:
223 buf
.append( (sal_Unicode
)'\'' );
224 buf
.append( *(sal_Unicode
*)pVal
);
225 buf
.append( (sal_Unicode
)'\'' );
227 case typelib_TypeClass_FLOAT
:
228 buf
.append( *(float *)pVal
);
230 case typelib_TypeClass_DOUBLE
:
231 buf
.append( *(double *)pVal
);
233 case typelib_TypeClass_BYTE
:
234 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
235 buf
.append( (sal_Int32
)*(sal_Int8
*)pVal
, 16 );
237 case typelib_TypeClass_SHORT
:
238 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
239 buf
.append( (sal_Int32
)*(sal_Int16
*)pVal
, 16 );
241 case typelib_TypeClass_UNSIGNED_SHORT
:
242 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
243 buf
.append( (sal_Int32
)*(sal_uInt16
*)pVal
, 16 );
245 case typelib_TypeClass_LONG
:
246 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
247 buf
.append( *(sal_Int32
*)pVal
, 16 );
249 case typelib_TypeClass_UNSIGNED_LONG
:
250 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
251 buf
.append( (sal_Int64
)*(sal_uInt32
*)pVal
, 16 );
253 case typelib_TypeClass_HYPER
:
254 case typelib_TypeClass_UNSIGNED_HYPER
:
255 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
256 #if defined(GCC) && defined(SPARC)
259 *(sal_Int32
*)&aVal
= *(sal_Int32
*)pVal
;
260 *((sal_Int32
*)&aVal
+1)= *((sal_Int32
*)pVal
+1);
261 buf
.append( aVal
, 16 );
264 buf
.append( *(sal_Int64
*)pVal
, 16 );
268 buf
.append( (sal_Unicode
)'?' );
271 return buf
.makeStringAndClear();
273 //--------------------------------------------------------------------------------------------------
274 static void dumpEntry( OUString
const & key
, Any
const & value
)
276 OUString
val( val2str( value
.getValue(), value
.getValueTypeRef() ) );
277 OString
key_str( OUStringToOString( key
, RTL_TEXTENCODING_ASCII_US
) );
278 OString
val_str( OUStringToOString( val
, RTL_TEXTENCODING_ASCII_US
) );
279 ::fprintf( stderr
, "| %s = %s\n", key_str
.getStr(), val_str
.getStr() );
282 //--------------------------------------------------------------------------------------------------
283 static inline void try_dispose( Reference
< XInterface
> const & xInstance
)
284 SAL_THROW( (RuntimeException
) )
286 Reference
< lang::XComponent
> xComp( xInstance
, UNO_QUERY
);
292 //--------------------------------------------------------------------------------------------------
293 static inline void try_dispose( Reference
< lang::XComponent
> const & xComp
)
294 SAL_THROW( (RuntimeException
) )
302 //==================================================================================================
304 class DisposingForwarder
305 : public WeakImplHelper1
< lang::XEventListener
>
307 Reference
< lang::XComponent
> m_xTarget
;
309 inline DisposingForwarder( Reference
< lang::XComponent
> const & xTarget
)
311 : m_xTarget( xTarget
)
312 { OSL_ASSERT( m_xTarget
.is() ); }
314 // listens at source for disposing, then disposes target
315 static inline void listen(
316 Reference
< lang::XComponent
> const & xSource
,
317 Reference
< lang::XComponent
> const & xTarget
)
318 SAL_THROW( (RuntimeException
) );
320 virtual void SAL_CALL
disposing( lang::EventObject
const & rSource
)
321 throw (RuntimeException
);
323 //__________________________________________________________________________________________________
324 inline void DisposingForwarder::listen(
325 Reference
< lang::XComponent
> const & xSource
,
326 Reference
< lang::XComponent
> const & xTarget
)
327 SAL_THROW( (RuntimeException
) )
331 xSource
->addEventListener( new DisposingForwarder( xTarget
) );
334 //__________________________________________________________________________________________________
335 void DisposingForwarder::disposing( lang::EventObject
const & )
336 throw (RuntimeException
)
338 m_xTarget
->dispose();
342 //==================================================================================================
348 //==================================================================================================
350 class ComponentContext
351 : private MutexHolder
352 , public WeakComponentImplHelper2
< XComponentContext
,
353 container::XNameContainer
>
356 Reference
< XComponentContext
> m_xDelegate
;
363 inline ContextEntry( Any
const & value_
, bool lateInit_
)
365 , lateInit( lateInit_
)
368 typedef ::std::hash_map
< OUString
, ContextEntry
* , OUStringHash
> t_map
;
371 Reference
< lang::XMultiComponentFactory
> m_xSMgr
;
374 Any
lookupMap( OUString
const & rName
)
375 SAL_THROW( (RuntimeException
) );
377 virtual void SAL_CALL
disposing();
380 ContextEntry_Init
const * pEntries
, sal_Int32 nEntries
,
381 Reference
< XComponentContext
> const & xDelegate
);
382 virtual ~ComponentContext()
386 virtual Any SAL_CALL
getValueByName( OUString
const & rName
)
387 throw (RuntimeException
);
388 virtual Reference
<lang::XMultiComponentFactory
> SAL_CALL
getServiceManager()
389 throw (RuntimeException
);
392 virtual void SAL_CALL
insertByName(
393 OUString
const & name
, Any
const & element
)
394 throw (lang::IllegalArgumentException
, container::ElementExistException
,
395 lang::WrappedTargetException
, RuntimeException
);
396 virtual void SAL_CALL
removeByName( OUString
const & name
)
397 throw (container::NoSuchElementException
,
398 lang::WrappedTargetException
, RuntimeException
);
400 virtual void SAL_CALL
replaceByName(
401 OUString
const & name
, Any
const & element
)
402 throw (lang::IllegalArgumentException
,container::NoSuchElementException
,
403 lang::WrappedTargetException
, RuntimeException
);
405 virtual Any SAL_CALL
getByName( OUString
const & name
)
406 throw (container::NoSuchElementException
,
407 lang::WrappedTargetException
, RuntimeException
);
408 virtual Sequence
<OUString
> SAL_CALL
getElementNames()
409 throw (RuntimeException
);
410 virtual sal_Bool SAL_CALL
hasByName( OUString
const & name
)
411 throw (RuntimeException
);
413 virtual Type SAL_CALL
getElementType() throw (RuntimeException
);
414 virtual sal_Bool SAL_CALL
hasElements() throw (RuntimeException
);
418 //______________________________________________________________________________
419 void ComponentContext::insertByName(
420 OUString
const & name
, Any
const & element
)
421 throw (lang::IllegalArgumentException
, container::ElementExistException
,
422 lang::WrappedTargetException
, RuntimeException
)
424 t_map::mapped_type
entry(
428 name
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
429 !element
.hasValue() ) );
430 MutexGuard
guard( m_mutex
);
431 ::std::pair
<t_map::iterator
, bool> insertion( m_map
.insert(
432 t_map::value_type( name
, entry
) ) );
433 if (! insertion
.second
)
434 throw container::ElementExistException(
435 OUSTR("element already exists: ") + name
,
436 static_cast<OWeakObject
*>(this) );
439 //______________________________________________________________________________
440 void ComponentContext::removeByName( OUString
const & name
)
441 throw (container::NoSuchElementException
,
442 lang::WrappedTargetException
, RuntimeException
)
444 MutexGuard
guard( m_mutex
);
445 t_map::iterator
iFind( m_map
.find( name
) );
446 if (iFind
== m_map
.end())
447 throw container::NoSuchElementException(
448 OUSTR("no such element: ") + name
,
449 static_cast<OWeakObject
*>(this) );
451 delete iFind
->second
;
456 //______________________________________________________________________________
457 void ComponentContext::replaceByName(
458 OUString
const & name
, Any
const & element
)
459 throw (lang::IllegalArgumentException
,container::NoSuchElementException
,
460 lang::WrappedTargetException
, RuntimeException
)
462 MutexGuard
guard( m_mutex
);
463 t_map::const_iterator
const iFind( m_map
.find( name
) );
464 if (iFind
== m_map
.end())
465 throw container::NoSuchElementException(
466 OUSTR("no such element: ") + name
,
467 static_cast<OWeakObject
*>(this) );
468 if (name
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
471 iFind
->second
->value
.clear();
472 iFind
->second
->lateInit
= true;
476 iFind
->second
->value
= element
;
477 iFind
->second
->lateInit
= false;
482 //______________________________________________________________________________
483 Any
ComponentContext::getByName( OUString
const & name
)
484 throw (container::NoSuchElementException
,
485 lang::WrappedTargetException
, RuntimeException
)
487 return getValueByName( name
);
490 //______________________________________________________________________________
491 Sequence
<OUString
> ComponentContext::getElementNames()
492 throw (RuntimeException
)
494 MutexGuard
guard( m_mutex
);
495 Sequence
<OUString
> ret( m_map
.size() );
496 OUString
* pret
= ret
.getArray();
498 t_map::const_iterator
iPos( m_map
.begin() );
499 t_map::const_iterator
const iEnd( m_map
.end() );
500 for ( ; iPos
!= iEnd
; ++iPos
)
501 pret
[pos
++] = iPos
->first
;
505 //______________________________________________________________________________
506 sal_Bool
ComponentContext::hasByName( OUString
const & name
)
507 throw (RuntimeException
)
509 MutexGuard
guard( m_mutex
);
510 return m_map
.find( name
) != m_map
.end();
514 //______________________________________________________________________________
515 Type
ComponentContext::getElementType() throw (RuntimeException
)
517 return ::getVoidCppuType();
520 //______________________________________________________________________________
521 sal_Bool
ComponentContext::hasElements() throw (RuntimeException
)
523 MutexGuard
guard( m_mutex
);
524 return ! m_map
.empty();
527 //__________________________________________________________________________________________________
528 Any
ComponentContext::lookupMap( OUString
const & rName
)
529 SAL_THROW( (RuntimeException
) )
532 if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("dump_maps") ))
534 ::fprintf( stderr
, ">>> dumping out ComponentContext %p m_map:\n", this );
535 typedef ::std::map
< OUString
, ContextEntry
* > t_sorted
; // sorted map
537 for ( t_map::const_iterator
iPos( m_map
.begin() ); iPos
!= m_map
.end(); ++iPos
)
539 sorted
[ iPos
->first
] = iPos
->second
;
542 for ( t_sorted::const_iterator
iPos( sorted
.begin() ); iPos
!= sorted
.end(); ++iPos
)
544 dumpEntry( iPos
->first
, iPos
->second
->value
);
551 ResettableMutexGuard
guard( m_mutex
);
552 t_map::const_iterator
iFind( m_map
.find( rName
) );
553 if (iFind
== m_map
.end())
556 t_map::mapped_type pEntry
= iFind
->second
;
557 if (! pEntry
->lateInit
)
558 return pEntry
->value
;
560 // late init singleton entry
561 Reference
< XInterface
> xInstance
;
566 Any
usesService( getValueByName( rName
+ OUSTR("/service") ) );
567 Any
args_( getValueByName( rName
+ OUSTR("/arguments") ) );
569 if (args_
.hasValue() && !(args_
>>= args
))
575 Reference
< lang::XSingleComponentFactory
> xFac
;
576 if (usesService
>>= xFac
) // try via factory
578 xInstance
= args
.getLength()
579 ? xFac
->createInstanceWithArgumentsAndContext( args
, this )
580 : xFac
->createInstanceWithContext( this );
584 Reference
< lang::XSingleServiceFactory
> xFac2
;
585 if (usesService
>>= xFac2
)
587 // try via old XSingleServiceFactory
588 #if OSL_DEBUG_LEVEL > 0
591 "### omitting context for service instanciation!\n" );
593 xInstance
= args
.getLength()
594 ? xFac2
->createInstanceWithArguments( args
)
595 : xFac2
->createInstance();
597 else if (m_xSMgr
.is()) // optionally service name
599 OUString serviceName
;
600 if ((usesService
>>= serviceName
) &&
601 serviceName
.getLength())
603 xInstance
= args
.getLength()
604 ? m_xSMgr
->createInstanceWithArgumentsAndContext(
605 serviceName
, args
, this )
606 : m_xSMgr
->createInstanceWithContext(
612 catch (RuntimeException
&)
616 catch (Exception
& exc
) // rethrow as WrappedTargetRuntimeException
618 Any
caught( getCaughtException() );
620 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
621 "exception occured raising singleton \"") );
623 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\": ") );
624 buf
.append( exc
.Message
);
625 throw lang::WrappedTargetRuntimeException(
626 buf
.makeStringAndClear(), static_cast<OWeakObject
*>(this),caught
);
629 if (! xInstance
.is())
631 throw RuntimeException(
632 OUSTR("no service object raising singleton ") + rName
,
633 static_cast<OWeakObject
*>(this) );
638 iFind
= m_map
.find( rName
);
639 if (iFind
!= m_map
.end())
641 pEntry
= iFind
->second
;
642 if (pEntry
->lateInit
)
644 pEntry
->value
<<= xInstance
;
645 pEntry
->lateInit
= false;
646 return pEntry
->value
;
652 try_dispose( xInstance
);
656 //__________________________________________________________________________________________________
657 Any
ComponentContext::getValueByName( OUString
const & rName
)
658 throw (RuntimeException
)
660 // to determine the root context:
661 if (rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_root") ))
663 if (m_xDelegate
.is())
664 return m_xDelegate
->getValueByName( rName
);
666 return makeAny( Reference
<XComponentContext
>(this) );
669 Any
ret( lookupMap( rName
) );
670 if (!ret
.hasValue() && m_xDelegate
.is())
672 return m_xDelegate
->getValueByName( rName
);
676 //__________________________________________________________________________________________________
677 Reference
< lang::XMultiComponentFactory
> ComponentContext::getServiceManager()
678 throw (RuntimeException
)
682 //__________________________________________________________________________________________________
683 ComponentContext::~ComponentContext()
687 ::fprintf( stderr
, "> destructed context %p\n", this );
689 t_map::const_iterator
iPos( m_map
.begin() );
690 t_map::const_iterator
const iEnd( m_map
.end() );
691 for ( ; iPos
!= iEnd
; ++iPos
)
695 //__________________________________________________________________________________________________
696 void ComponentContext::disposing()
699 ::fprintf( stderr
, "> disposing context %p\n", this );
702 Reference
< lang::XComponent
> xTDMgr
, xAC
, xPolicy
; // to be disposed separately
704 // dispose all context objects
705 t_map::const_iterator
iPos( m_map
.begin() );
706 t_map::const_iterator
const iEnd( m_map
.end() );
707 for ( ; iPos
!= iEnd
; ++iPos
)
709 t_map::mapped_type pEntry
= iPos
->second
;
711 // service manager disposed separately
713 !iPos
->first
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON
) ))
715 if (pEntry
->lateInit
)
718 MutexGuard
guard( m_mutex
);
719 if (pEntry
->lateInit
)
721 pEntry
->value
.clear(); // release factory
722 pEntry
->lateInit
= false;
727 Reference
< lang::XComponent
> xComp
;
728 pEntry
->value
>>= xComp
;
731 if (iPos
->first
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(TDMGR_SINGLETON
) ))
735 else if (iPos
->first
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(AC_SINGLETON
) ))
739 else if (iPos
->first
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(AC_POLICY
) ))
743 else // dispose immediately
751 // dispose service manager
752 try_dispose( m_xSMgr
);
757 try_dispose( xPolicy
);
758 // dispose tdmgr; revokes callback from cppu runtime
759 try_dispose( xTDMgr
);
761 iPos
= m_map
.begin();
762 for ( ; iPos
!= iEnd
; ++iPos
)
766 //__________________________________________________________________________________________________
767 ComponentContext::ComponentContext(
768 ContextEntry_Init
const * pEntries
, sal_Int32 nEntries
,
769 Reference
< XComponentContext
> const & xDelegate
)
770 : WeakComponentImplHelper2
< XComponentContext
, container::XNameContainer
>(
772 m_xDelegate( xDelegate
)
774 for ( sal_Int32 nPos
= 0; nPos
< nEntries
; ++nPos
)
776 ContextEntry_Init
const & rEntry
= pEntries
[ nPos
];
778 if (rEntry
.name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON
) ))
780 rEntry
.value
>>= m_xSMgr
;
783 if (rEntry
.bLateInitService
)
786 m_map
[ rEntry
.name
] = new ContextEntry( Any(), true );
788 m_map
[ rEntry
.name
+ OUSTR("/service") ] = new ContextEntry( rEntry
.value
, false );
789 // /initial-arguments are provided as optional context entry
793 // only value, no late init factory nor string
794 m_map
[ rEntry
.name
] = new ContextEntry( rEntry
.value
, false );
798 if (!m_xSMgr
.is() && m_xDelegate
.is())
800 // wrap delegate's smgr XPropertySet into new smgr
801 Reference
< lang::XMultiComponentFactory
> xMgr( m_xDelegate
->getServiceManager() );
804 osl_incrementInterlockedCount( &m_refCount
);
807 // create new smgr based on delegate's one
809 xMgr
->createInstanceWithContext(
810 OUSTR("com.sun.star.comp.stoc.OServiceManagerWrapper"), xDelegate
),
812 // patch DefaultContext property of new one
813 Reference
< beans::XPropertySet
> xProps( m_xSMgr
, UNO_QUERY
);
814 OSL_ASSERT( xProps
.is() );
817 Reference
< XComponentContext
> xThis( this );
818 xProps
->setPropertyValue( OUSTR("DefaultContext"), makeAny( xThis
) );
823 osl_decrementInterlockedCount( &m_refCount
);
826 osl_decrementInterlockedCount( &m_refCount
);
827 OSL_ASSERT( m_xSMgr
.is() );
833 //##################################################################################################
834 extern "C" { static void s_createComponentContext_v(va_list * pParam
)
836 ContextEntry_Init
const * pEntries
= va_arg(*pParam
, ContextEntry_Init
const *);
837 sal_Int32 nEntries
= va_arg(*pParam
, sal_Int32
);
838 XComponentContext
* pDelegatee
= va_arg(*pParam
, XComponentContext
*);
839 void ** ppContext
= va_arg(*pParam
, void **);
840 uno::Mapping
* pTarget2curr
= va_arg(*pParam
, uno::Mapping
*);
842 Reference
<XComponentContext
> xDelegate(pDelegatee
, SAL_NO_ACQUIRE
);
843 Reference
<XComponentContext
> xContext
;
849 ComponentContext
* p
= new ComponentContext( pEntries
, nEntries
, xDelegate
);
851 // listen delegate for disposing, to dispose this (wrapping) context first.
852 DisposingForwarder::listen( Reference
< lang::XComponent
>::query( xDelegate
), p
);
854 catch (Exception
& exc
)
856 (void) exc
; // avoid warning about unused variable
857 OSL_ENSURE( 0, OUStringToOString(
858 exc
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
864 xContext
= xDelegate
;
869 *ppContext
= pTarget2curr
->mapInterface(xContext
.get(), ::getCppuType(&xContext
));
872 Reference
< XComponentContext
> SAL_CALL
createComponentContext(
873 ContextEntry_Init
const * pEntries
, sal_Int32 nEntries
,
874 Reference
< XComponentContext
> const & xDelegate
)
877 uno::Environment
curr_env(Environment::getCurrent());
878 uno::Environment
source_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV
))));
880 uno::Mapping
curr2source(curr_env
, source_env
);
881 uno::Mapping
source2curr(source_env
, curr_env
);
883 ContextEntry_Init
* mapped_entries
= new ContextEntry_Init
[nEntries
];
884 for (sal_Int32 nPos
= 0; nPos
< nEntries
; ++ nPos
)
886 mapped_entries
[nPos
].bLateInitService
= pEntries
[nPos
].bLateInitService
;
887 mapped_entries
[nPos
].name
= pEntries
[nPos
].name
;
889 uno_type_any_constructAndConvert(&mapped_entries
[nPos
].value
,
890 const_cast<void *>(pEntries
[nPos
].value
.getValue()),
891 pEntries
[nPos
].value
.getValueTypeRef(),
895 void * mapped_delegate
= curr2source
.mapInterface(xDelegate
.get(), ::getCppuType(&xDelegate
));
896 XComponentContext
* pXComponentContext
= NULL
;
897 source_env
.invoke(s_createComponentContext_v
, mapped_entries
, nEntries
, mapped_delegate
, &pXComponentContext
, &source2curr
);
899 return Reference
<XComponentContext
>(pXComponentContext
, SAL_NO_ACQUIRE
);