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