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