xref: /AOO41X/main/cppuhelper/source/component_context.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir  /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #ifdef DIAG
32*cdf0e10cSrcweir #define CONTEXT_DIAG
33*cdf0e10cSrcweir #endif
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
36*cdf0e10cSrcweir #include <stdio.h>
37*cdf0e10cSrcweir #endif
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <vector>
40*cdf0e10cSrcweir #include <hash_map>
41*cdf0e10cSrcweir #ifdef CONTEXT_DIAG
42*cdf0e10cSrcweir #include <map>
43*cdf0e10cSrcweir #endif
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #include <osl/diagnose.h>
46*cdf0e10cSrcweir #include <osl/mutex.hxx>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include <uno/mapping.hxx>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
53*cdf0e10cSrcweir #include <cppuhelper/compbase2.hxx>
54*cdf0e10cSrcweir #include <cppuhelper/component_context.hxx>
55*cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
58*cdf0e10cSrcweir #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
59*cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
60*cdf0e10cSrcweir #include <com/sun/star/lang/XSingleComponentFactory.hpp>
61*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiComponentFactory.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
63*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
64*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir #include <hash_map>
67*cdf0e10cSrcweir #include <memory>
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir #define SMGR_SINGLETON "/singletons/com.sun.star.lang.theServiceManager"
70*cdf0e10cSrcweir #define TDMGR_SINGLETON "/singletons/com.sun.star.reflection.theTypeDescriptionManager"
71*cdf0e10cSrcweir #define AC_SINGLETON "/singletons/com.sun.star.security.theAccessController"
72*cdf0e10cSrcweir #define AC_POLICY "/singletons/com.sun.star.security.thePolicy"
73*cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir using namespace ::osl;
77*cdf0e10cSrcweir using namespace ::rtl;
78*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
79*cdf0e10cSrcweir using namespace ::com::sun::star;
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir namespace cppu
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir #ifdef CONTEXT_DIAG
85*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
86*cdf0e10cSrcweir static OUString val2str( void const * pVal, typelib_TypeDescriptionReference * pTypeRef )
87*cdf0e10cSrcweir {
88*cdf0e10cSrcweir 	OSL_ASSERT( pVal );
89*cdf0e10cSrcweir 	if (pTypeRef->eTypeClass == typelib_TypeClass_VOID)
90*cdf0e10cSrcweir 		return OUSTR("void");
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir 	OUStringBuffer buf( 64 );
93*cdf0e10cSrcweir 	buf.append( (sal_Unicode)'(' );
94*cdf0e10cSrcweir 	buf.append( pTypeRef->pTypeName );
95*cdf0e10cSrcweir 	buf.append( (sal_Unicode)')' );
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	switch (pTypeRef->eTypeClass)
98*cdf0e10cSrcweir 	{
99*cdf0e10cSrcweir 	case typelib_TypeClass_INTERFACE:
100*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
101*cdf0e10cSrcweir 		buf.append( (sal_Int64)*(void **)pVal, 16 );
102*cdf0e10cSrcweir 		break;
103*cdf0e10cSrcweir 	case typelib_TypeClass_STRUCT:
104*cdf0e10cSrcweir 	case typelib_TypeClass_EXCEPTION:
105*cdf0e10cSrcweir 	{
106*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
107*cdf0e10cSrcweir 		typelib_TypeDescription * pTypeDescr = 0;
108*cdf0e10cSrcweir 		::typelib_typedescriptionreference_getDescription( &pTypeDescr, pTypeRef );
109*cdf0e10cSrcweir 		OSL_ASSERT( pTypeDescr );
110*cdf0e10cSrcweir 		if (! pTypeDescr->bComplete)
111*cdf0e10cSrcweir 			::typelib_typedescription_complete( &pTypeDescr );
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir 		typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr;
114*cdf0e10cSrcweir 		sal_Int32 nDescr = pCompType->nMembers;
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 		if (pCompType->pBaseTypeDescription)
117*cdf0e10cSrcweir 		{
118*cdf0e10cSrcweir 			buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->pWeakRef ) );
119*cdf0e10cSrcweir 			if (nDescr)
120*cdf0e10cSrcweir 				buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
121*cdf0e10cSrcweir 		}
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir 		typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
124*cdf0e10cSrcweir 		sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
125*cdf0e10cSrcweir 		rtl_uString ** ppMemberNames = pCompType->ppMemberNames;
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir 		for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
128*cdf0e10cSrcweir 		{
129*cdf0e10cSrcweir 			buf.append( ppMemberNames[ nPos ] );
130*cdf0e10cSrcweir 			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
131*cdf0e10cSrcweir 			typelib_TypeDescription * pMemberType = 0;
132*cdf0e10cSrcweir 			TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[ nPos ] );
133*cdf0e10cSrcweir 			buf.append( val2str( (char *)pVal + pMemberOffsets[ nPos ], pMemberType->pWeakRef ) );
134*cdf0e10cSrcweir 			TYPELIB_DANGER_RELEASE( pMemberType );
135*cdf0e10cSrcweir 			if (nPos < (nDescr -1))
136*cdf0e10cSrcweir 				buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
137*cdf0e10cSrcweir 		}
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 		::typelib_typedescription_release( pTypeDescr );
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
142*cdf0e10cSrcweir 		break;
143*cdf0e10cSrcweir 	}
144*cdf0e10cSrcweir 	case typelib_TypeClass_SEQUENCE:
145*cdf0e10cSrcweir 	{
146*cdf0e10cSrcweir 		typelib_TypeDescription * pTypeDescr = 0;
147*cdf0e10cSrcweir 		TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir 		uno_Sequence * pSequence = *(uno_Sequence **)pVal;
150*cdf0e10cSrcweir 		typelib_TypeDescription * pElementTypeDescr = 0;
151*cdf0e10cSrcweir 		TYPELIB_DANGER_GET( &pElementTypeDescr, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 		sal_Int32 nElementSize = pElementTypeDescr->nSize;
154*cdf0e10cSrcweir 		sal_Int32 nElements	   = pSequence->nElements;
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 		if (nElements)
157*cdf0e10cSrcweir 		{
158*cdf0e10cSrcweir 			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
159*cdf0e10cSrcweir 			char * pElements = pSequence->elements;
160*cdf0e10cSrcweir 			for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
161*cdf0e10cSrcweir 			{
162*cdf0e10cSrcweir 				buf.append( val2str( pElements + (nElementSize * nPos), pElementTypeDescr->pWeakRef ) );
163*cdf0e10cSrcweir 				if (nPos < (nElements -1))
164*cdf0e10cSrcweir 					buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
165*cdf0e10cSrcweir 			}
166*cdf0e10cSrcweir 			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
167*cdf0e10cSrcweir 		}
168*cdf0e10cSrcweir 		else
169*cdf0e10cSrcweir 		{
170*cdf0e10cSrcweir 			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
171*cdf0e10cSrcweir 		}
172*cdf0e10cSrcweir 		TYPELIB_DANGER_RELEASE( pElementTypeDescr );
173*cdf0e10cSrcweir 		TYPELIB_DANGER_RELEASE( pTypeDescr );
174*cdf0e10cSrcweir 		break;
175*cdf0e10cSrcweir 	}
176*cdf0e10cSrcweir 	case typelib_TypeClass_ANY:
177*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
178*cdf0e10cSrcweir 		buf.append( val2str( ((uno_Any *)pVal)->pData,
179*cdf0e10cSrcweir 							 ((uno_Any *)pVal)->pType ) );
180*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
181*cdf0e10cSrcweir 		break;
182*cdf0e10cSrcweir 	case typelib_TypeClass_TYPE:
183*cdf0e10cSrcweir 		buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName );
184*cdf0e10cSrcweir 		break;
185*cdf0e10cSrcweir 	case typelib_TypeClass_STRING:
186*cdf0e10cSrcweir 		buf.append( (sal_Unicode)'\"' );
187*cdf0e10cSrcweir 		buf.append( *(rtl_uString **)pVal );
188*cdf0e10cSrcweir 		buf.append( (sal_Unicode)'\"' );
189*cdf0e10cSrcweir 		break;
190*cdf0e10cSrcweir 	case typelib_TypeClass_ENUM:
191*cdf0e10cSrcweir 	{
192*cdf0e10cSrcweir 		typelib_TypeDescription * pTypeDescr = 0;
193*cdf0e10cSrcweir 		::typelib_typedescriptionreference_getDescription( &pTypeDescr, pTypeRef );
194*cdf0e10cSrcweir 		OSL_ASSERT( pTypeDescr );
195*cdf0e10cSrcweir 		if (! pTypeDescr->bComplete)
196*cdf0e10cSrcweir 			::typelib_typedescription_complete( &pTypeDescr );
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir 		sal_Int32 * pValues = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues;
199*cdf0e10cSrcweir 		sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues;
200*cdf0e10cSrcweir 		while (nPos--)
201*cdf0e10cSrcweir 		{
202*cdf0e10cSrcweir 			if (pValues[ nPos ] == *(sal_Int32 *)pVal)
203*cdf0e10cSrcweir 				break;
204*cdf0e10cSrcweir 		}
205*cdf0e10cSrcweir 		if (nPos >= 0)
206*cdf0e10cSrcweir 			buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[ nPos ] );
207*cdf0e10cSrcweir 		else
208*cdf0e10cSrcweir 			buf.append( (sal_Unicode)'?' );
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir 		::typelib_typedescription_release( pTypeDescr );
211*cdf0e10cSrcweir 		break;
212*cdf0e10cSrcweir 	}
213*cdf0e10cSrcweir 	case typelib_TypeClass_BOOLEAN:
214*cdf0e10cSrcweir 		if (*(sal_Bool *)pVal)
215*cdf0e10cSrcweir 			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
216*cdf0e10cSrcweir 		else
217*cdf0e10cSrcweir 			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
218*cdf0e10cSrcweir 		break;
219*cdf0e10cSrcweir 	case typelib_TypeClass_CHAR:
220*cdf0e10cSrcweir 		buf.append( (sal_Unicode)'\'' );
221*cdf0e10cSrcweir 		buf.append( *(sal_Unicode *)pVal );
222*cdf0e10cSrcweir 		buf.append( (sal_Unicode)'\'' );
223*cdf0e10cSrcweir 		break;
224*cdf0e10cSrcweir 	case typelib_TypeClass_FLOAT:
225*cdf0e10cSrcweir 		buf.append( *(float *)pVal );
226*cdf0e10cSrcweir 		break;
227*cdf0e10cSrcweir 	case typelib_TypeClass_DOUBLE:
228*cdf0e10cSrcweir 		buf.append( *(double *)pVal );
229*cdf0e10cSrcweir 		break;
230*cdf0e10cSrcweir 	case typelib_TypeClass_BYTE:
231*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
232*cdf0e10cSrcweir 		buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 );
233*cdf0e10cSrcweir 		break;
234*cdf0e10cSrcweir 	case typelib_TypeClass_SHORT:
235*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
236*cdf0e10cSrcweir 		buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 );
237*cdf0e10cSrcweir 		break;
238*cdf0e10cSrcweir 	case typelib_TypeClass_UNSIGNED_SHORT:
239*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
240*cdf0e10cSrcweir 		buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 );
241*cdf0e10cSrcweir 		break;
242*cdf0e10cSrcweir 	case typelib_TypeClass_LONG:
243*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
244*cdf0e10cSrcweir 		buf.append( *(sal_Int32 *)pVal, 16 );
245*cdf0e10cSrcweir 		break;
246*cdf0e10cSrcweir 	case typelib_TypeClass_UNSIGNED_LONG:
247*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
248*cdf0e10cSrcweir 		buf.append( (sal_Int64)*(sal_uInt32 *)pVal, 16 );
249*cdf0e10cSrcweir 		break;
250*cdf0e10cSrcweir 	case typelib_TypeClass_HYPER:
251*cdf0e10cSrcweir 	case typelib_TypeClass_UNSIGNED_HYPER:
252*cdf0e10cSrcweir 		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
253*cdf0e10cSrcweir #if defined(GCC) && defined(SPARC)
254*cdf0e10cSrcweir 		{
255*cdf0e10cSrcweir 			sal_Int64 aVal;
256*cdf0e10cSrcweir 			*(sal_Int32 *)&aVal = *(sal_Int32 *)pVal;
257*cdf0e10cSrcweir 			*((sal_Int32 *)&aVal +1)= *((sal_Int32 *)pVal +1);
258*cdf0e10cSrcweir 			buf.append( aVal, 16 );
259*cdf0e10cSrcweir 		}
260*cdf0e10cSrcweir #else
261*cdf0e10cSrcweir 		buf.append( *(sal_Int64 *)pVal, 16 );
262*cdf0e10cSrcweir #endif
263*cdf0e10cSrcweir 		break;
264*cdf0e10cSrcweir 	default:
265*cdf0e10cSrcweir 		buf.append( (sal_Unicode)'?' );
266*cdf0e10cSrcweir 	}
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir 	return buf.makeStringAndClear();
269*cdf0e10cSrcweir }
270*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
271*cdf0e10cSrcweir static void dumpEntry( OUString const & key, Any const & value )
272*cdf0e10cSrcweir {
273*cdf0e10cSrcweir     OUString val( val2str( value.getValue(), value.getValueTypeRef() ) );
274*cdf0e10cSrcweir     OString key_str( OUStringToOString( key, RTL_TEXTENCODING_ASCII_US ) );
275*cdf0e10cSrcweir     OString val_str( OUStringToOString( val, RTL_TEXTENCODING_ASCII_US ) );
276*cdf0e10cSrcweir     ::fprintf( stderr, "| %s = %s\n", key_str.getStr(), val_str.getStr() );
277*cdf0e10cSrcweir }
278*cdf0e10cSrcweir #endif
279*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
280*cdf0e10cSrcweir static inline void try_dispose( Reference< XInterface > const & xInstance )
281*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
282*cdf0e10cSrcweir {
283*cdf0e10cSrcweir     Reference< lang::XComponent > xComp( xInstance, UNO_QUERY );
284*cdf0e10cSrcweir     if (xComp.is())
285*cdf0e10cSrcweir     {
286*cdf0e10cSrcweir         xComp->dispose();
287*cdf0e10cSrcweir     }
288*cdf0e10cSrcweir }
289*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
290*cdf0e10cSrcweir static inline void try_dispose( Reference< lang::XComponent > const & xComp )
291*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir     if (xComp.is())
294*cdf0e10cSrcweir     {
295*cdf0e10cSrcweir         xComp->dispose();
296*cdf0e10cSrcweir     }
297*cdf0e10cSrcweir }
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir //==================================================================================================
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir class DisposingForwarder
302*cdf0e10cSrcweir     : public WeakImplHelper1< lang::XEventListener >
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir     Reference< lang::XComponent > m_xTarget;
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir     inline DisposingForwarder( Reference< lang::XComponent > const & xTarget )
307*cdf0e10cSrcweir         SAL_THROW( () )
308*cdf0e10cSrcweir         : m_xTarget( xTarget )
309*cdf0e10cSrcweir         { OSL_ASSERT( m_xTarget.is() ); }
310*cdf0e10cSrcweir public:
311*cdf0e10cSrcweir     // listens at source for disposing, then disposes target
312*cdf0e10cSrcweir     static inline void listen(
313*cdf0e10cSrcweir         Reference< lang::XComponent > const & xSource,
314*cdf0e10cSrcweir         Reference< lang::XComponent > const & xTarget )
315*cdf0e10cSrcweir         SAL_THROW( (RuntimeException) );
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir     virtual void SAL_CALL disposing( lang::EventObject const & rSource )
318*cdf0e10cSrcweir         throw (RuntimeException);
319*cdf0e10cSrcweir };
320*cdf0e10cSrcweir //__________________________________________________________________________________________________
321*cdf0e10cSrcweir inline void DisposingForwarder::listen(
322*cdf0e10cSrcweir     Reference< lang::XComponent > const & xSource,
323*cdf0e10cSrcweir     Reference< lang::XComponent > const & xTarget )
324*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
325*cdf0e10cSrcweir {
326*cdf0e10cSrcweir     if (xSource.is())
327*cdf0e10cSrcweir     {
328*cdf0e10cSrcweir         xSource->addEventListener( new DisposingForwarder( xTarget ) );
329*cdf0e10cSrcweir     }
330*cdf0e10cSrcweir }
331*cdf0e10cSrcweir //__________________________________________________________________________________________________
332*cdf0e10cSrcweir void DisposingForwarder::disposing( lang::EventObject const & )
333*cdf0e10cSrcweir     throw (RuntimeException)
334*cdf0e10cSrcweir {
335*cdf0e10cSrcweir     m_xTarget->dispose();
336*cdf0e10cSrcweir     m_xTarget.clear();
337*cdf0e10cSrcweir }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir //==================================================================================================
340*cdf0e10cSrcweir struct MutexHolder
341*cdf0e10cSrcweir {
342*cdf0e10cSrcweir protected:
343*cdf0e10cSrcweir     Mutex m_mutex;
344*cdf0e10cSrcweir };
345*cdf0e10cSrcweir //==================================================================================================
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir class ComponentContext
348*cdf0e10cSrcweir     : private MutexHolder
349*cdf0e10cSrcweir     , public WeakComponentImplHelper2< XComponentContext,
350*cdf0e10cSrcweir                                        container::XNameContainer >
351*cdf0e10cSrcweir {
352*cdf0e10cSrcweir protected:
353*cdf0e10cSrcweir     Reference< XComponentContext > m_xDelegate;
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir     struct ContextEntry
356*cdf0e10cSrcweir     {
357*cdf0e10cSrcweir         Any value;
358*cdf0e10cSrcweir         bool lateInit;
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir         inline ContextEntry( Any const & value_, bool lateInit_ )
361*cdf0e10cSrcweir             : value( value_ )
362*cdf0e10cSrcweir             , lateInit( lateInit_ )
363*cdf0e10cSrcweir             {}
364*cdf0e10cSrcweir     };
365*cdf0e10cSrcweir     typedef ::std::hash_map< OUString, ContextEntry * , OUStringHash > t_map;
366*cdf0e10cSrcweir     t_map m_map;
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir     Reference< lang::XMultiComponentFactory > m_xSMgr;
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir protected:
371*cdf0e10cSrcweir     Any lookupMap( OUString const & rName )
372*cdf0e10cSrcweir         SAL_THROW( (RuntimeException) );
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 	virtual void SAL_CALL disposing();
375*cdf0e10cSrcweir public:
376*cdf0e10cSrcweir     ComponentContext(
377*cdf0e10cSrcweir         ContextEntry_Init const * pEntries, sal_Int32 nEntries,
378*cdf0e10cSrcweir         Reference< XComponentContext > const & xDelegate );
379*cdf0e10cSrcweir     virtual ~ComponentContext()
380*cdf0e10cSrcweir         SAL_THROW( () );
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir     // XComponentContext
383*cdf0e10cSrcweir     virtual Any SAL_CALL getValueByName( OUString const & rName )
384*cdf0e10cSrcweir         throw (RuntimeException);
385*cdf0e10cSrcweir     virtual Reference<lang::XMultiComponentFactory> SAL_CALL getServiceManager()
386*cdf0e10cSrcweir         throw (RuntimeException);
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir     // XNameContainer
389*cdf0e10cSrcweir     virtual void SAL_CALL insertByName(
390*cdf0e10cSrcweir         OUString const & name, Any const & element )
391*cdf0e10cSrcweir         throw (lang::IllegalArgumentException, container::ElementExistException,
392*cdf0e10cSrcweir                lang::WrappedTargetException, RuntimeException);
393*cdf0e10cSrcweir     virtual void SAL_CALL removeByName( OUString const & name )
394*cdf0e10cSrcweir         throw (container::NoSuchElementException,
395*cdf0e10cSrcweir                lang::WrappedTargetException, RuntimeException);
396*cdf0e10cSrcweir     // XNameReplace
397*cdf0e10cSrcweir     virtual void SAL_CALL replaceByName(
398*cdf0e10cSrcweir         OUString const & name, Any const & element )
399*cdf0e10cSrcweir         throw (lang::IllegalArgumentException,container::NoSuchElementException,
400*cdf0e10cSrcweir                lang::WrappedTargetException, RuntimeException);
401*cdf0e10cSrcweir     // XNameAccess
402*cdf0e10cSrcweir     virtual Any SAL_CALL getByName( OUString const & name )
403*cdf0e10cSrcweir         throw (container::NoSuchElementException,
404*cdf0e10cSrcweir                lang::WrappedTargetException, RuntimeException);
405*cdf0e10cSrcweir     virtual Sequence<OUString> SAL_CALL getElementNames()
406*cdf0e10cSrcweir         throw (RuntimeException);
407*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasByName( OUString const & name )
408*cdf0e10cSrcweir         throw (RuntimeException);
409*cdf0e10cSrcweir     // XElementAccess
410*cdf0e10cSrcweir     virtual Type SAL_CALL getElementType() throw (RuntimeException);
411*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException);
412*cdf0e10cSrcweir };
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir // XNameContainer
415*cdf0e10cSrcweir //______________________________________________________________________________
416*cdf0e10cSrcweir void ComponentContext::insertByName(
417*cdf0e10cSrcweir     OUString const & name, Any const & element )
418*cdf0e10cSrcweir     throw (lang::IllegalArgumentException, container::ElementExistException,
419*cdf0e10cSrcweir            lang::WrappedTargetException, RuntimeException)
420*cdf0e10cSrcweir {
421*cdf0e10cSrcweir     t_map::mapped_type entry(
422*cdf0e10cSrcweir         new ContextEntry(
423*cdf0e10cSrcweir             element,
424*cdf0e10cSrcweir             /* lateInit_: */
425*cdf0e10cSrcweir             name.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
426*cdf0e10cSrcweir             !element.hasValue() ) );
427*cdf0e10cSrcweir     MutexGuard guard( m_mutex );
428*cdf0e10cSrcweir     ::std::pair<t_map::iterator, bool> insertion( m_map.insert(
429*cdf0e10cSrcweir         t_map::value_type( name, entry ) ) );
430*cdf0e10cSrcweir     if (! insertion.second)
431*cdf0e10cSrcweir         throw container::ElementExistException(
432*cdf0e10cSrcweir             OUSTR("element already exists: ") + name,
433*cdf0e10cSrcweir             static_cast<OWeakObject *>(this) );
434*cdf0e10cSrcweir }
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir //______________________________________________________________________________
437*cdf0e10cSrcweir void ComponentContext::removeByName( OUString const & name )
438*cdf0e10cSrcweir         throw (container::NoSuchElementException,
439*cdf0e10cSrcweir                lang::WrappedTargetException, RuntimeException)
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir     MutexGuard guard( m_mutex );
442*cdf0e10cSrcweir     t_map::iterator iFind( m_map.find( name ) );
443*cdf0e10cSrcweir     if (iFind == m_map.end())
444*cdf0e10cSrcweir         throw container::NoSuchElementException(
445*cdf0e10cSrcweir             OUSTR("no such element: ") + name,
446*cdf0e10cSrcweir             static_cast<OWeakObject *>(this) );
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir     delete iFind->second;
449*cdf0e10cSrcweir     m_map.erase(iFind);
450*cdf0e10cSrcweir }
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir // XNameReplace
453*cdf0e10cSrcweir //______________________________________________________________________________
454*cdf0e10cSrcweir void ComponentContext::replaceByName(
455*cdf0e10cSrcweir     OUString const & name, Any const & element )
456*cdf0e10cSrcweir     throw (lang::IllegalArgumentException,container::NoSuchElementException,
457*cdf0e10cSrcweir            lang::WrappedTargetException, RuntimeException)
458*cdf0e10cSrcweir {
459*cdf0e10cSrcweir     MutexGuard guard( m_mutex );
460*cdf0e10cSrcweir     t_map::const_iterator const iFind( m_map.find( name ) );
461*cdf0e10cSrcweir     if (iFind == m_map.end())
462*cdf0e10cSrcweir         throw container::NoSuchElementException(
463*cdf0e10cSrcweir             OUSTR("no such element: ") + name,
464*cdf0e10cSrcweir             static_cast<OWeakObject *>(this) );
465*cdf0e10cSrcweir     if (name.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
466*cdf0e10cSrcweir         !element.hasValue())
467*cdf0e10cSrcweir     {
468*cdf0e10cSrcweir         iFind->second->value.clear();
469*cdf0e10cSrcweir         iFind->second->lateInit = true;
470*cdf0e10cSrcweir     }
471*cdf0e10cSrcweir     else
472*cdf0e10cSrcweir     {
473*cdf0e10cSrcweir         iFind->second->value = element;
474*cdf0e10cSrcweir         iFind->second->lateInit = false;
475*cdf0e10cSrcweir     }
476*cdf0e10cSrcweir }
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir // XNameAccess
479*cdf0e10cSrcweir //______________________________________________________________________________
480*cdf0e10cSrcweir Any ComponentContext::getByName( OUString const & name )
481*cdf0e10cSrcweir     throw (container::NoSuchElementException,
482*cdf0e10cSrcweir            lang::WrappedTargetException, RuntimeException)
483*cdf0e10cSrcweir {
484*cdf0e10cSrcweir     return getValueByName( name );
485*cdf0e10cSrcweir }
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir //______________________________________________________________________________
488*cdf0e10cSrcweir Sequence<OUString> ComponentContext::getElementNames()
489*cdf0e10cSrcweir     throw (RuntimeException)
490*cdf0e10cSrcweir {
491*cdf0e10cSrcweir     MutexGuard guard( m_mutex );
492*cdf0e10cSrcweir     Sequence<OUString> ret( m_map.size() );
493*cdf0e10cSrcweir     OUString * pret = ret.getArray();
494*cdf0e10cSrcweir     sal_Int32 pos = 0;
495*cdf0e10cSrcweir     t_map::const_iterator iPos( m_map.begin() );
496*cdf0e10cSrcweir     t_map::const_iterator const iEnd( m_map.end() );
497*cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
498*cdf0e10cSrcweir         pret[pos++] = iPos->first;
499*cdf0e10cSrcweir     return ret;
500*cdf0e10cSrcweir }
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir //______________________________________________________________________________
503*cdf0e10cSrcweir sal_Bool ComponentContext::hasByName( OUString const & name )
504*cdf0e10cSrcweir     throw (RuntimeException)
505*cdf0e10cSrcweir {
506*cdf0e10cSrcweir     MutexGuard guard( m_mutex );
507*cdf0e10cSrcweir     return m_map.find( name ) != m_map.end();
508*cdf0e10cSrcweir }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir // XElementAccess
511*cdf0e10cSrcweir //______________________________________________________________________________
512*cdf0e10cSrcweir Type ComponentContext::getElementType() throw (RuntimeException)
513*cdf0e10cSrcweir {
514*cdf0e10cSrcweir     return ::getVoidCppuType();
515*cdf0e10cSrcweir }
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir //______________________________________________________________________________
518*cdf0e10cSrcweir sal_Bool ComponentContext::hasElements() throw (RuntimeException)
519*cdf0e10cSrcweir {
520*cdf0e10cSrcweir     MutexGuard guard( m_mutex );
521*cdf0e10cSrcweir     return ! m_map.empty();
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir //__________________________________________________________________________________________________
525*cdf0e10cSrcweir Any ComponentContext::lookupMap( OUString const & rName )
526*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
527*cdf0e10cSrcweir {
528*cdf0e10cSrcweir #ifdef CONTEXT_DIAG
529*cdf0e10cSrcweir     if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("dump_maps") ))
530*cdf0e10cSrcweir     {
531*cdf0e10cSrcweir         ::fprintf( stderr, ">>> dumping out ComponentContext %p m_map:\n", this );
532*cdf0e10cSrcweir         typedef ::std::map< OUString, ContextEntry * > t_sorted; // sorted map
533*cdf0e10cSrcweir         t_sorted sorted;
534*cdf0e10cSrcweir         for ( t_map::const_iterator iPos( m_map.begin() ); iPos != m_map.end(); ++iPos )
535*cdf0e10cSrcweir         {
536*cdf0e10cSrcweir             sorted[ iPos->first ] = iPos->second;
537*cdf0e10cSrcweir         }
538*cdf0e10cSrcweir         {
539*cdf0e10cSrcweir         for ( t_sorted::const_iterator iPos( sorted.begin() ); iPos != sorted.end(); ++iPos )
540*cdf0e10cSrcweir         {
541*cdf0e10cSrcweir             dumpEntry( iPos->first, iPos->second->value );
542*cdf0e10cSrcweir         }
543*cdf0e10cSrcweir         }
544*cdf0e10cSrcweir         return Any();
545*cdf0e10cSrcweir     }
546*cdf0e10cSrcweir #endif
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir     ResettableMutexGuard guard( m_mutex );
549*cdf0e10cSrcweir     t_map::const_iterator iFind( m_map.find( rName ) );
550*cdf0e10cSrcweir     if (iFind == m_map.end())
551*cdf0e10cSrcweir         return Any();
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir     t_map::mapped_type pEntry = iFind->second;
554*cdf0e10cSrcweir     if (! pEntry->lateInit)
555*cdf0e10cSrcweir         return pEntry->value;
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir     // late init singleton entry
558*cdf0e10cSrcweir     Reference< XInterface > xInstance;
559*cdf0e10cSrcweir     guard.clear();
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir     try
562*cdf0e10cSrcweir     {
563*cdf0e10cSrcweir         Any usesService( getValueByName( rName + OUSTR("/service") ) );
564*cdf0e10cSrcweir         Any args_( getValueByName( rName + OUSTR("/arguments") ) );
565*cdf0e10cSrcweir         Sequence<Any> args;
566*cdf0e10cSrcweir         if (args_.hasValue() && !(args_ >>= args))
567*cdf0e10cSrcweir         {
568*cdf0e10cSrcweir             args.realloc( 1 );
569*cdf0e10cSrcweir             args[ 0 ] = args_;
570*cdf0e10cSrcweir         }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir         Reference< lang::XSingleComponentFactory > xFac;
573*cdf0e10cSrcweir         if (usesService >>= xFac) // try via factory
574*cdf0e10cSrcweir         {
575*cdf0e10cSrcweir             xInstance = args.getLength()
576*cdf0e10cSrcweir                 ? xFac->createInstanceWithArgumentsAndContext( args, this )
577*cdf0e10cSrcweir                 : xFac->createInstanceWithContext( this );
578*cdf0e10cSrcweir         }
579*cdf0e10cSrcweir         else
580*cdf0e10cSrcweir         {
581*cdf0e10cSrcweir             Reference< lang::XSingleServiceFactory > xFac2;
582*cdf0e10cSrcweir             if (usesService >>= xFac2)
583*cdf0e10cSrcweir             {
584*cdf0e10cSrcweir                 // try via old XSingleServiceFactory
585*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
586*cdf0e10cSrcweir                 ::fprintf(
587*cdf0e10cSrcweir                     stderr,
588*cdf0e10cSrcweir                     "### omitting context for service instanciation!\n" );
589*cdf0e10cSrcweir #endif
590*cdf0e10cSrcweir                 xInstance = args.getLength()
591*cdf0e10cSrcweir                     ? xFac2->createInstanceWithArguments( args )
592*cdf0e10cSrcweir                     : xFac2->createInstance();
593*cdf0e10cSrcweir             }
594*cdf0e10cSrcweir             else if (m_xSMgr.is()) // optionally service name
595*cdf0e10cSrcweir             {
596*cdf0e10cSrcweir                 OUString serviceName;
597*cdf0e10cSrcweir                 if ((usesService >>= serviceName) &&
598*cdf0e10cSrcweir                     serviceName.getLength())
599*cdf0e10cSrcweir                 {
600*cdf0e10cSrcweir                     xInstance = args.getLength()
601*cdf0e10cSrcweir                         ? m_xSMgr->createInstanceWithArgumentsAndContext(
602*cdf0e10cSrcweir                             serviceName, args, this )
603*cdf0e10cSrcweir                         : m_xSMgr->createInstanceWithContext(
604*cdf0e10cSrcweir                             serviceName, this );
605*cdf0e10cSrcweir                 }
606*cdf0e10cSrcweir             }
607*cdf0e10cSrcweir         }
608*cdf0e10cSrcweir     }
609*cdf0e10cSrcweir     catch (RuntimeException &)
610*cdf0e10cSrcweir     {
611*cdf0e10cSrcweir         throw;
612*cdf0e10cSrcweir     }
613*cdf0e10cSrcweir     catch (Exception & exc) // rethrow as WrappedTargetRuntimeException
614*cdf0e10cSrcweir     {
615*cdf0e10cSrcweir         Any caught( getCaughtException() );
616*cdf0e10cSrcweir         OUStringBuffer buf;
617*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
618*cdf0e10cSrcweir                              "exception occured raising singleton \"") );
619*cdf0e10cSrcweir         buf.append( rName );
620*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\": ") );
621*cdf0e10cSrcweir         buf.append( exc.Message );
622*cdf0e10cSrcweir         throw lang::WrappedTargetRuntimeException(
623*cdf0e10cSrcweir             buf.makeStringAndClear(), static_cast<OWeakObject *>(this),caught );
624*cdf0e10cSrcweir     }
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir     if (! xInstance.is())
627*cdf0e10cSrcweir     {
628*cdf0e10cSrcweir         throw RuntimeException(
629*cdf0e10cSrcweir             OUSTR("no service object raising singleton ") + rName,
630*cdf0e10cSrcweir             static_cast<OWeakObject *>(this) );
631*cdf0e10cSrcweir     }
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir     Any ret;
634*cdf0e10cSrcweir     guard.reset();
635*cdf0e10cSrcweir     iFind = m_map.find( rName );
636*cdf0e10cSrcweir     if (iFind != m_map.end())
637*cdf0e10cSrcweir     {
638*cdf0e10cSrcweir         pEntry = iFind->second;
639*cdf0e10cSrcweir         if (pEntry->lateInit)
640*cdf0e10cSrcweir         {
641*cdf0e10cSrcweir             pEntry->value <<= xInstance;
642*cdf0e10cSrcweir             pEntry->lateInit = false;
643*cdf0e10cSrcweir             return pEntry->value;
644*cdf0e10cSrcweir         }
645*cdf0e10cSrcweir         else
646*cdf0e10cSrcweir             ret = pEntry->value;
647*cdf0e10cSrcweir     }
648*cdf0e10cSrcweir     guard.clear();
649*cdf0e10cSrcweir     try_dispose( xInstance );
650*cdf0e10cSrcweir     return ret;
651*cdf0e10cSrcweir }
652*cdf0e10cSrcweir 
653*cdf0e10cSrcweir //__________________________________________________________________________________________________
654*cdf0e10cSrcweir Any ComponentContext::getValueByName( OUString const & rName )
655*cdf0e10cSrcweir     throw (RuntimeException)
656*cdf0e10cSrcweir {
657*cdf0e10cSrcweir     // to determine the root context:
658*cdf0e10cSrcweir     if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_root") ))
659*cdf0e10cSrcweir     {
660*cdf0e10cSrcweir         if (m_xDelegate.is())
661*cdf0e10cSrcweir             return m_xDelegate->getValueByName( rName );
662*cdf0e10cSrcweir         else
663*cdf0e10cSrcweir             return makeAny( Reference<XComponentContext>(this) );
664*cdf0e10cSrcweir     }
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir     Any ret( lookupMap( rName ) );
667*cdf0e10cSrcweir     if (!ret.hasValue() && m_xDelegate.is())
668*cdf0e10cSrcweir     {
669*cdf0e10cSrcweir         return m_xDelegate->getValueByName( rName );
670*cdf0e10cSrcweir     }
671*cdf0e10cSrcweir     return ret;
672*cdf0e10cSrcweir }
673*cdf0e10cSrcweir //__________________________________________________________________________________________________
674*cdf0e10cSrcweir Reference< lang::XMultiComponentFactory > ComponentContext::getServiceManager()
675*cdf0e10cSrcweir     throw (RuntimeException)
676*cdf0e10cSrcweir {
677*cdf0e10cSrcweir     return m_xSMgr;
678*cdf0e10cSrcweir }
679*cdf0e10cSrcweir //__________________________________________________________________________________________________
680*cdf0e10cSrcweir ComponentContext::~ComponentContext()
681*cdf0e10cSrcweir     SAL_THROW( () )
682*cdf0e10cSrcweir {
683*cdf0e10cSrcweir #ifdef CONTEXT_DIAG
684*cdf0e10cSrcweir     ::fprintf( stderr, "> destructed context %p\n", this );
685*cdf0e10cSrcweir #endif
686*cdf0e10cSrcweir     t_map::const_iterator iPos( m_map.begin() );
687*cdf0e10cSrcweir     t_map::const_iterator const iEnd( m_map.end() );
688*cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
689*cdf0e10cSrcweir         delete iPos->second;
690*cdf0e10cSrcweir     m_map.clear();
691*cdf0e10cSrcweir }
692*cdf0e10cSrcweir //__________________________________________________________________________________________________
693*cdf0e10cSrcweir void ComponentContext::disposing()
694*cdf0e10cSrcweir {
695*cdf0e10cSrcweir #ifdef CONTEXT_DIAG
696*cdf0e10cSrcweir     ::fprintf( stderr, "> disposing context %p\n", this );
697*cdf0e10cSrcweir #endif
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir     Reference< lang::XComponent > xTDMgr, xAC, xPolicy; // to be disposed separately
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir     // dispose all context objects
702*cdf0e10cSrcweir     t_map::const_iterator iPos( m_map.begin() );
703*cdf0e10cSrcweir     t_map::const_iterator const iEnd( m_map.end() );
704*cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
705*cdf0e10cSrcweir     {
706*cdf0e10cSrcweir         t_map::mapped_type pEntry = iPos->second;
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir         // service manager disposed separately
709*cdf0e10cSrcweir         if (!m_xSMgr.is() ||
710*cdf0e10cSrcweir             !iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON) ))
711*cdf0e10cSrcweir         {
712*cdf0e10cSrcweir             if (pEntry->lateInit)
713*cdf0e10cSrcweir             {
714*cdf0e10cSrcweir                 // late init
715*cdf0e10cSrcweir                 MutexGuard guard( m_mutex );
716*cdf0e10cSrcweir                 if (pEntry->lateInit)
717*cdf0e10cSrcweir                 {
718*cdf0e10cSrcweir                     pEntry->value.clear(); // release factory
719*cdf0e10cSrcweir                     pEntry->lateInit = false;
720*cdf0e10cSrcweir                     continue;
721*cdf0e10cSrcweir                 }
722*cdf0e10cSrcweir             }
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir             Reference< lang::XComponent > xComp;
725*cdf0e10cSrcweir             pEntry->value >>= xComp;
726*cdf0e10cSrcweir             if (xComp.is())
727*cdf0e10cSrcweir             {
728*cdf0e10cSrcweir                 if (iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(TDMGR_SINGLETON) ))
729*cdf0e10cSrcweir                 {
730*cdf0e10cSrcweir                     xTDMgr = xComp;
731*cdf0e10cSrcweir                 }
732*cdf0e10cSrcweir                 else if (iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(AC_SINGLETON) ))
733*cdf0e10cSrcweir                 {
734*cdf0e10cSrcweir                     xAC = xComp;
735*cdf0e10cSrcweir                 }
736*cdf0e10cSrcweir                 else if (iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(AC_POLICY) ))
737*cdf0e10cSrcweir                 {
738*cdf0e10cSrcweir                     xPolicy = xComp;
739*cdf0e10cSrcweir                 }
740*cdf0e10cSrcweir                 else // dispose immediately
741*cdf0e10cSrcweir                 {
742*cdf0e10cSrcweir                     xComp->dispose();
743*cdf0e10cSrcweir                 }
744*cdf0e10cSrcweir             }
745*cdf0e10cSrcweir         }
746*cdf0e10cSrcweir     }
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir     // dispose service manager
749*cdf0e10cSrcweir     try_dispose( m_xSMgr );
750*cdf0e10cSrcweir     m_xSMgr.clear();
751*cdf0e10cSrcweir     // dispose ac
752*cdf0e10cSrcweir     try_dispose( xAC );
753*cdf0e10cSrcweir     // dispose policy
754*cdf0e10cSrcweir     try_dispose( xPolicy );
755*cdf0e10cSrcweir     // dispose tdmgr; revokes callback from cppu runtime
756*cdf0e10cSrcweir     try_dispose( xTDMgr );
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir     iPos = m_map.begin();
759*cdf0e10cSrcweir     for ( ; iPos != iEnd; ++iPos )
760*cdf0e10cSrcweir         delete iPos->second;
761*cdf0e10cSrcweir     m_map.clear();
762*cdf0e10cSrcweir }
763*cdf0e10cSrcweir //__________________________________________________________________________________________________
764*cdf0e10cSrcweir ComponentContext::ComponentContext(
765*cdf0e10cSrcweir     ContextEntry_Init const * pEntries, sal_Int32 nEntries,
766*cdf0e10cSrcweir     Reference< XComponentContext > const & xDelegate )
767*cdf0e10cSrcweir     : WeakComponentImplHelper2< XComponentContext, container::XNameContainer >(
768*cdf0e10cSrcweir         m_mutex ),
769*cdf0e10cSrcweir       m_xDelegate( xDelegate )
770*cdf0e10cSrcweir {
771*cdf0e10cSrcweir     for ( sal_Int32 nPos = 0; nPos < nEntries; ++nPos )
772*cdf0e10cSrcweir     {
773*cdf0e10cSrcweir         ContextEntry_Init const & rEntry = pEntries[ nPos ];
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir         if (rEntry.name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON) ))
776*cdf0e10cSrcweir         {
777*cdf0e10cSrcweir             rEntry.value >>= m_xSMgr;
778*cdf0e10cSrcweir         }
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir         if (rEntry.bLateInitService)
781*cdf0e10cSrcweir         {
782*cdf0e10cSrcweir             // singleton entry
783*cdf0e10cSrcweir             m_map[ rEntry.name ] = new ContextEntry( Any(), true );
784*cdf0e10cSrcweir             // /service
785*cdf0e10cSrcweir             m_map[ rEntry.name + OUSTR("/service") ] = new ContextEntry( rEntry.value, false );
786*cdf0e10cSrcweir             // /initial-arguments are provided as optional context entry
787*cdf0e10cSrcweir         }
788*cdf0e10cSrcweir         else
789*cdf0e10cSrcweir         {
790*cdf0e10cSrcweir             // only value, no late init factory nor string
791*cdf0e10cSrcweir             m_map[ rEntry.name ] = new ContextEntry( rEntry.value, false );
792*cdf0e10cSrcweir         }
793*cdf0e10cSrcweir     }
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir     if (!m_xSMgr.is() && m_xDelegate.is())
796*cdf0e10cSrcweir     {
797*cdf0e10cSrcweir         // wrap delegate's smgr XPropertySet into new smgr
798*cdf0e10cSrcweir         Reference< lang::XMultiComponentFactory > xMgr( m_xDelegate->getServiceManager() );
799*cdf0e10cSrcweir         if (xMgr.is())
800*cdf0e10cSrcweir         {
801*cdf0e10cSrcweir             osl_incrementInterlockedCount( &m_refCount );
802*cdf0e10cSrcweir             try
803*cdf0e10cSrcweir             {
804*cdf0e10cSrcweir                 // create new smgr based on delegate's one
805*cdf0e10cSrcweir                 m_xSMgr.set(
806*cdf0e10cSrcweir                     xMgr->createInstanceWithContext(
807*cdf0e10cSrcweir                         OUSTR("com.sun.star.comp.stoc.OServiceManagerWrapper"), xDelegate ),
808*cdf0e10cSrcweir                     UNO_QUERY );
809*cdf0e10cSrcweir                 // patch DefaultContext property of new one
810*cdf0e10cSrcweir                 Reference< beans::XPropertySet > xProps( m_xSMgr, UNO_QUERY );
811*cdf0e10cSrcweir                 OSL_ASSERT( xProps.is() );
812*cdf0e10cSrcweir                 if (xProps.is())
813*cdf0e10cSrcweir                 {
814*cdf0e10cSrcweir                     Reference< XComponentContext > xThis( this );
815*cdf0e10cSrcweir                     xProps->setPropertyValue( OUSTR("DefaultContext"), makeAny( xThis ) );
816*cdf0e10cSrcweir                 }
817*cdf0e10cSrcweir             }
818*cdf0e10cSrcweir             catch (...)
819*cdf0e10cSrcweir             {
820*cdf0e10cSrcweir                 osl_decrementInterlockedCount( &m_refCount );
821*cdf0e10cSrcweir                 throw;
822*cdf0e10cSrcweir             }
823*cdf0e10cSrcweir             osl_decrementInterlockedCount( &m_refCount );
824*cdf0e10cSrcweir             OSL_ASSERT( m_xSMgr.is() );
825*cdf0e10cSrcweir         }
826*cdf0e10cSrcweir     }
827*cdf0e10cSrcweir }
828*cdf0e10cSrcweir 
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir //##################################################################################################
831*cdf0e10cSrcweir extern "C" { static void s_createComponentContext_v(va_list * pParam)
832*cdf0e10cSrcweir {
833*cdf0e10cSrcweir     ContextEntry_Init const  * pEntries     = va_arg(*pParam, ContextEntry_Init const *);
834*cdf0e10cSrcweir 	sal_Int32                  nEntries     = va_arg(*pParam, sal_Int32);
835*cdf0e10cSrcweir 	XComponentContext        * pDelegatee   = va_arg(*pParam, XComponentContext *);
836*cdf0e10cSrcweir 	void                    ** ppContext    = va_arg(*pParam, void **);
837*cdf0e10cSrcweir 	uno::Mapping             * pTarget2curr = va_arg(*pParam, uno::Mapping *);
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir 	Reference<XComponentContext> xDelegate(pDelegatee, SAL_NO_ACQUIRE);
840*cdf0e10cSrcweir 	Reference<XComponentContext> xContext;
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir     if (nEntries > 0)
843*cdf0e10cSrcweir     {
844*cdf0e10cSrcweir         try
845*cdf0e10cSrcweir         {
846*cdf0e10cSrcweir 			ComponentContext * p = new ComponentContext( pEntries, nEntries, xDelegate );
847*cdf0e10cSrcweir             xContext.set(p);
848*cdf0e10cSrcweir             // listen delegate for disposing, to dispose this (wrapping) context first.
849*cdf0e10cSrcweir             DisposingForwarder::listen( Reference< lang::XComponent >::query( xDelegate ), p );
850*cdf0e10cSrcweir         }
851*cdf0e10cSrcweir         catch (Exception & exc)
852*cdf0e10cSrcweir         {
853*cdf0e10cSrcweir             (void) exc; // avoid warning about unused variable
854*cdf0e10cSrcweir             OSL_ENSURE( 0, OUStringToOString(
855*cdf0e10cSrcweir                             exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
856*cdf0e10cSrcweir 			xContext.clear();
857*cdf0e10cSrcweir         }
858*cdf0e10cSrcweir     }
859*cdf0e10cSrcweir     else
860*cdf0e10cSrcweir     {
861*cdf0e10cSrcweir         xContext = xDelegate;
862*cdf0e10cSrcweir     }
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir 	delete[] pEntries;
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir 	*ppContext = pTarget2curr->mapInterface(xContext.get(), ::getCppuType(&xContext));
867*cdf0e10cSrcweir }}
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir Reference< XComponentContext > SAL_CALL createComponentContext(
870*cdf0e10cSrcweir     ContextEntry_Init const * pEntries, sal_Int32 nEntries,
871*cdf0e10cSrcweir     Reference< XComponentContext > const & xDelegate )
872*cdf0e10cSrcweir     SAL_THROW( () )
873*cdf0e10cSrcweir {
874*cdf0e10cSrcweir 	uno::Environment curr_env(Environment::getCurrent());
875*cdf0e10cSrcweir 	uno::Environment source_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))));
876*cdf0e10cSrcweir 
877*cdf0e10cSrcweir 	uno::Mapping curr2source(curr_env, source_env);
878*cdf0e10cSrcweir 	uno::Mapping source2curr(source_env, curr_env);
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir 	ContextEntry_Init * mapped_entries = new ContextEntry_Init[nEntries];
881*cdf0e10cSrcweir 	for (sal_Int32 nPos = 0; nPos < nEntries; ++ nPos)
882*cdf0e10cSrcweir 	{
883*cdf0e10cSrcweir 		mapped_entries[nPos].bLateInitService = pEntries[nPos].bLateInitService;
884*cdf0e10cSrcweir 		mapped_entries[nPos].name             = pEntries[nPos].name;
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir 		uno_type_any_constructAndConvert(&mapped_entries[nPos].value,
887*cdf0e10cSrcweir 										 const_cast<void *>(pEntries[nPos].value.getValue()),
888*cdf0e10cSrcweir 										 pEntries[nPos].value.getValueTypeRef(),
889*cdf0e10cSrcweir 										 curr2source.get());
890*cdf0e10cSrcweir 	}
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir 	void * mapped_delegate = curr2source.mapInterface(xDelegate.get(), ::getCppuType(&xDelegate));
893*cdf0e10cSrcweir 	XComponentContext * pXComponentContext = NULL;
894*cdf0e10cSrcweir 	source_env.invoke(s_createComponentContext_v, mapped_entries, nEntries, mapped_delegate, &pXComponentContext, &source2curr);
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir 	return Reference<XComponentContext>(pXComponentContext, SAL_NO_ACQUIRE);
897*cdf0e10cSrcweir }
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir }
900