1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
25 #if OSL_DEBUG_LEVEL > 0
30 #include <boost/unordered_map.hpp>
35 #include <osl/diagnose.h>
36 #include <osl/mutex.hxx>
38 #include <rtl/ustrbuf.hxx>
40 #include <uno/mapping.hxx>
42 #include <cppuhelper/implbase1.hxx>
43 #include <cppuhelper/compbase2.hxx>
44 #include <cppuhelper/component_context.hxx>
45 #include <cppuhelper/exc_hlp.hxx>
47 #include <com/sun/star/container/XNameContainer.hpp>
48 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
49 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
50 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
51 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
52 #include <com/sun/star/lang/XComponent.hpp>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include "com/sun/star/uno/DeploymentException.hpp"
55 #include "com/sun/star/uno/RuntimeException.hpp"
59 #define SMGR_SINGLETON "/singletons/com.sun.star.lang.theServiceManager"
60 #define TDMGR_SINGLETON "/singletons/com.sun.star.reflection.theTypeDescriptionManager"
61 #define AC_SINGLETON "/singletons/com.sun.star.security.theAccessController"
64 using namespace ::osl
;
65 using namespace ::rtl
;
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star
;
73 //--------------------------------------------------------------------------------------------------
74 static OUString
val2str( void const * pVal
, typelib_TypeDescriptionReference
* pTypeRef
)
77 if (pTypeRef
->eTypeClass
== typelib_TypeClass_VOID
)
80 OUStringBuffer
buf( 64 );
81 buf
.append( (sal_Unicode
)'(' );
82 buf
.append( pTypeRef
->pTypeName
);
83 buf
.append( (sal_Unicode
)')' );
85 switch (pTypeRef
->eTypeClass
)
87 case typelib_TypeClass_INTERFACE
:
88 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
89 buf
.append( (sal_Int64
)*(void **)pVal
, 16 );
91 case typelib_TypeClass_STRUCT
:
92 case typelib_TypeClass_EXCEPTION
:
94 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
95 typelib_TypeDescription
* pTypeDescr
= 0;
96 ::typelib_typedescriptionreference_getDescription( &pTypeDescr
, pTypeRef
);
97 OSL_ASSERT( pTypeDescr
);
98 if (! pTypeDescr
->bComplete
)
99 ::typelib_typedescription_complete( &pTypeDescr
);
101 typelib_CompoundTypeDescription
* pCompType
= (typelib_CompoundTypeDescription
*)pTypeDescr
;
102 sal_Int32 nDescr
= pCompType
->nMembers
;
104 if (pCompType
->pBaseTypeDescription
)
106 buf
.append( val2str( pVal
, ((typelib_TypeDescription
*)pCompType
->pBaseTypeDescription
)->pWeakRef
) );
108 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
111 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompType
->ppTypeRefs
;
112 sal_Int32
* pMemberOffsets
= pCompType
->pMemberOffsets
;
113 rtl_uString
** ppMemberNames
= pCompType
->ppMemberNames
;
115 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
117 buf
.append( ppMemberNames
[ nPos
] );
118 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
119 typelib_TypeDescription
* pMemberType
= 0;
120 TYPELIB_DANGER_GET( &pMemberType
, ppTypeRefs
[ nPos
] );
121 buf
.append( val2str( (char *)pVal
+ pMemberOffsets
[ nPos
], pMemberType
->pWeakRef
) );
122 TYPELIB_DANGER_RELEASE( pMemberType
);
123 if (nPos
< (nDescr
-1))
124 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
127 ::typelib_typedescription_release( pTypeDescr
);
129 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
132 case typelib_TypeClass_SEQUENCE
:
134 typelib_TypeDescription
* pTypeDescr
= 0;
135 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
137 uno_Sequence
* pSequence
= *(uno_Sequence
**)pVal
;
138 typelib_TypeDescription
* pElementTypeDescr
= 0;
139 TYPELIB_DANGER_GET( &pElementTypeDescr
, ((typelib_IndirectTypeDescription
*)pTypeDescr
)->pType
);
141 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
142 sal_Int32 nElements
= pSequence
->nElements
;
146 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
147 char * pElements
= pSequence
->elements
;
148 for ( sal_Int32 nPos
= 0; nPos
< nElements
; ++nPos
)
150 buf
.append( val2str( pElements
+ (nElementSize
* nPos
), pElementTypeDescr
->pWeakRef
) );
151 if (nPos
< (nElements
-1))
152 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
154 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
158 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
160 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
161 TYPELIB_DANGER_RELEASE( pTypeDescr
);
164 case typelib_TypeClass_ANY
:
165 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
166 buf
.append( val2str( ((uno_Any
*)pVal
)->pData
,
167 ((uno_Any
*)pVal
)->pType
) );
168 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
170 case typelib_TypeClass_TYPE
:
171 buf
.append( (*(typelib_TypeDescriptionReference
**)pVal
)->pTypeName
);
173 case typelib_TypeClass_STRING
:
174 buf
.append( (sal_Unicode
)'\"' );
175 buf
.append( *(rtl_uString
**)pVal
);
176 buf
.append( (sal_Unicode
)'\"' );
178 case typelib_TypeClass_ENUM
:
180 typelib_TypeDescription
* pTypeDescr
= 0;
181 ::typelib_typedescriptionreference_getDescription( &pTypeDescr
, pTypeRef
);
182 OSL_ASSERT( pTypeDescr
);
183 if (! pTypeDescr
->bComplete
)
184 ::typelib_typedescription_complete( &pTypeDescr
);
186 sal_Int32
* pValues
= ((typelib_EnumTypeDescription
*)pTypeDescr
)->pEnumValues
;
187 sal_Int32 nPos
= ((typelib_EnumTypeDescription
*)pTypeDescr
)->nEnumValues
;
190 if (pValues
[ nPos
] == *(sal_Int32
*)pVal
)
194 buf
.append( ((typelib_EnumTypeDescription
*)pTypeDescr
)->ppEnumNames
[ nPos
] );
196 buf
.append( (sal_Unicode
)'?' );
198 ::typelib_typedescription_release( pTypeDescr
);
201 case typelib_TypeClass_BOOLEAN
:
202 if (*(sal_Bool
*)pVal
)
203 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
205 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
207 case typelib_TypeClass_CHAR
:
208 buf
.append( (sal_Unicode
)'\'' );
209 buf
.append( *(sal_Unicode
*)pVal
);
210 buf
.append( (sal_Unicode
)'\'' );
212 case typelib_TypeClass_FLOAT
:
213 buf
.append( *(float *)pVal
);
215 case typelib_TypeClass_DOUBLE
:
216 buf
.append( *(double *)pVal
);
218 case typelib_TypeClass_BYTE
:
219 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
220 buf
.append( (sal_Int32
)*(sal_Int8
*)pVal
, 16 );
222 case typelib_TypeClass_SHORT
:
223 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
224 buf
.append( (sal_Int32
)*(sal_Int16
*)pVal
, 16 );
226 case typelib_TypeClass_UNSIGNED_SHORT
:
227 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
228 buf
.append( (sal_Int32
)*(sal_uInt16
*)pVal
, 16 );
230 case typelib_TypeClass_LONG
:
231 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
232 buf
.append( *(sal_Int32
*)pVal
, 16 );
234 case typelib_TypeClass_UNSIGNED_LONG
:
235 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
236 buf
.append( (sal_Int64
)*(sal_uInt32
*)pVal
, 16 );
238 case typelib_TypeClass_HYPER
:
239 case typelib_TypeClass_UNSIGNED_HYPER
:
240 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
241 #if defined(__GNUC__) && defined(SPARC)
242 // I guess this really should check if there are strict alignment
243 // requirements, not just "GCC on SPARC".
246 *(sal_Int32
*)&aVal
= *(sal_Int32
*)pVal
;
247 *((sal_Int32
*)&aVal
+1)= *((sal_Int32
*)pVal
+1);
248 buf
.append( aVal
, 16 );
251 buf
.append( *(sal_Int64
*)pVal
, 16 );
255 buf
.append( (sal_Unicode
)'?' );
258 return buf
.makeStringAndClear();
260 //--------------------------------------------------------------------------------------------------
261 static void dumpEntry( OUString
const & key
, Any
const & value
)
263 OUString
val( val2str( value
.getValue(), value
.getValueTypeRef() ) );
264 OString
key_str( OUStringToOString( key
, RTL_TEXTENCODING_ASCII_US
) );
265 OString
val_str( OUStringToOString( val
, RTL_TEXTENCODING_ASCII_US
) );
266 ::fprintf( stderr
, "| %s = %s\n", key_str
.getStr(), val_str
.getStr() );
269 //--------------------------------------------------------------------------------------------------
270 static inline void try_dispose( Reference
< XInterface
> const & xInstance
)
271 SAL_THROW( (RuntimeException
) )
273 Reference
< lang::XComponent
> xComp( xInstance
, UNO_QUERY
);
279 //--------------------------------------------------------------------------------------------------
280 static inline void try_dispose( Reference
< lang::XComponent
> const & xComp
)
281 SAL_THROW( (RuntimeException
) )
289 //==================================================================================================
291 class DisposingForwarder
292 : public WeakImplHelper1
< lang::XEventListener
>
294 Reference
< lang::XComponent
> m_xTarget
;
296 inline DisposingForwarder( Reference
< lang::XComponent
> const & xTarget
)
298 : m_xTarget( xTarget
)
299 { OSL_ASSERT( m_xTarget
.is() ); }
301 // listens at source for disposing, then disposes target
302 static inline void listen(
303 Reference
< lang::XComponent
> const & xSource
,
304 Reference
< lang::XComponent
> const & xTarget
)
305 SAL_THROW( (RuntimeException
) );
307 virtual void SAL_CALL
disposing( lang::EventObject
const & rSource
)
308 throw (RuntimeException
);
310 //__________________________________________________________________________________________________
311 inline void DisposingForwarder::listen(
312 Reference
< lang::XComponent
> const & xSource
,
313 Reference
< lang::XComponent
> const & xTarget
)
314 SAL_THROW( (RuntimeException
) )
318 xSource
->addEventListener( new DisposingForwarder( xTarget
) );
321 //__________________________________________________________________________________________________
322 void DisposingForwarder::disposing( lang::EventObject
const & )
323 throw (RuntimeException
)
325 m_xTarget
->dispose();
329 //==================================================================================================
335 //==================================================================================================
337 class ComponentContext
338 : private MutexHolder
339 , public WeakComponentImplHelper2
< XComponentContext
,
340 container::XNameContainer
>
343 Reference
< XComponentContext
> m_xDelegate
;
350 inline ContextEntry( Any
const & value_
, bool lateInit_
)
352 , lateInit( lateInit_
)
355 typedef ::boost::unordered_map
< OUString
, ContextEntry
* , OUStringHash
> t_map
;
358 Reference
< lang::XMultiComponentFactory
> m_xSMgr
;
361 Any
lookupMap( OUString
const & rName
)
362 SAL_THROW( (RuntimeException
) );
364 virtual void SAL_CALL
disposing();
367 ContextEntry_Init
const * pEntries
, sal_Int32 nEntries
,
368 Reference
< XComponentContext
> const & xDelegate
);
369 virtual ~ComponentContext()
373 virtual Any SAL_CALL
getValueByName( OUString
const & rName
)
374 throw (RuntimeException
);
375 virtual Reference
<lang::XMultiComponentFactory
> SAL_CALL
getServiceManager()
376 throw (RuntimeException
);
379 virtual void SAL_CALL
insertByName(
380 OUString
const & name
, Any
const & element
)
381 throw (lang::IllegalArgumentException
, container::ElementExistException
,
382 lang::WrappedTargetException
, RuntimeException
);
383 virtual void SAL_CALL
removeByName( OUString
const & name
)
384 throw (container::NoSuchElementException
,
385 lang::WrappedTargetException
, RuntimeException
);
387 virtual void SAL_CALL
replaceByName(
388 OUString
const & name
, Any
const & element
)
389 throw (lang::IllegalArgumentException
,container::NoSuchElementException
,
390 lang::WrappedTargetException
, RuntimeException
);
392 virtual Any SAL_CALL
getByName( OUString
const & name
)
393 throw (container::NoSuchElementException
,
394 lang::WrappedTargetException
, RuntimeException
);
395 virtual Sequence
<OUString
> SAL_CALL
getElementNames()
396 throw (RuntimeException
);
397 virtual sal_Bool SAL_CALL
hasByName( OUString
const & name
)
398 throw (RuntimeException
);
400 virtual Type SAL_CALL
getElementType() throw (RuntimeException
);
401 virtual sal_Bool SAL_CALL
hasElements() throw (RuntimeException
);
405 //______________________________________________________________________________
406 void ComponentContext::insertByName(
407 OUString
const & name
, Any
const & element
)
408 throw (lang::IllegalArgumentException
, container::ElementExistException
,
409 lang::WrappedTargetException
, RuntimeException
)
411 t_map::mapped_type
entry(
415 name
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
416 !element
.hasValue() ) );
417 MutexGuard
guard( m_mutex
);
418 ::std::pair
<t_map::iterator
, bool> insertion( m_map
.insert(
419 t_map::value_type( name
, entry
) ) );
420 if (! insertion
.second
)
421 throw container::ElementExistException(
422 "element already exists: " + name
,
423 static_cast<OWeakObject
*>(this) );
426 //______________________________________________________________________________
427 void ComponentContext::removeByName( OUString
const & name
)
428 throw (container::NoSuchElementException
,
429 lang::WrappedTargetException
, RuntimeException
)
431 MutexGuard
guard( m_mutex
);
432 t_map::iterator
iFind( m_map
.find( name
) );
433 if (iFind
== m_map
.end())
434 throw container::NoSuchElementException(
435 "no such element: " + name
,
436 static_cast<OWeakObject
*>(this) );
438 delete iFind
->second
;
443 //______________________________________________________________________________
444 void ComponentContext::replaceByName(
445 OUString
const & name
, Any
const & element
)
446 throw (lang::IllegalArgumentException
,container::NoSuchElementException
,
447 lang::WrappedTargetException
, RuntimeException
)
449 MutexGuard
guard( m_mutex
);
450 t_map::const_iterator
const iFind( m_map
.find( name
) );
451 if (iFind
== m_map
.end())
452 throw container::NoSuchElementException(
453 "no such element: " + name
,
454 static_cast<OWeakObject
*>(this) );
455 if (name
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
458 iFind
->second
->value
.clear();
459 iFind
->second
->lateInit
= true;
463 iFind
->second
->value
= element
;
464 iFind
->second
->lateInit
= false;
469 //______________________________________________________________________________
470 Any
ComponentContext::getByName( OUString
const & name
)
471 throw (container::NoSuchElementException
,
472 lang::WrappedTargetException
, RuntimeException
)
474 return getValueByName( name
);
477 //______________________________________________________________________________
478 Sequence
<OUString
> ComponentContext::getElementNames()
479 throw (RuntimeException
)
481 MutexGuard
guard( m_mutex
);
482 Sequence
<OUString
> ret( m_map
.size() );
483 OUString
* pret
= ret
.getArray();
485 t_map::const_iterator
iPos( m_map
.begin() );
486 t_map::const_iterator
const iEnd( m_map
.end() );
487 for ( ; iPos
!= iEnd
; ++iPos
)
488 pret
[pos
++] = iPos
->first
;
492 //______________________________________________________________________________
493 sal_Bool
ComponentContext::hasByName( OUString
const & name
)
494 throw (RuntimeException
)
496 MutexGuard
guard( m_mutex
);
497 return m_map
.find( name
) != m_map
.end();
501 //______________________________________________________________________________
502 Type
ComponentContext::getElementType() throw (RuntimeException
)
504 return ::getVoidCppuType();
507 //______________________________________________________________________________
508 sal_Bool
ComponentContext::hasElements() throw (RuntimeException
)
510 MutexGuard
guard( m_mutex
);
511 return ! m_map
.empty();
514 //__________________________________________________________________________________________________
515 Any
ComponentContext::lookupMap( OUString
const & rName
)
516 SAL_THROW( (RuntimeException
) )
519 if ( rName
== "dump_maps" )
521 ::fprintf( stderr
, ">>> dumping out ComponentContext %p m_map:\n", this );
522 typedef ::std::map
< OUString
, ContextEntry
* > t_sorted
; // sorted map
524 for ( t_map::const_iterator
iPos( m_map
.begin() ); iPos
!= m_map
.end(); ++iPos
)
526 sorted
[ iPos
->first
] = iPos
->second
;
529 for ( t_sorted::const_iterator
iPos( sorted
.begin() ); iPos
!= sorted
.end(); ++iPos
)
531 dumpEntry( iPos
->first
, iPos
->second
->value
);
538 ResettableMutexGuard
guard( m_mutex
);
539 t_map::const_iterator
iFind( m_map
.find( rName
) );
540 if (iFind
== m_map
.end())
543 t_map::mapped_type pEntry
= iFind
->second
;
544 if (! pEntry
->lateInit
)
545 return pEntry
->value
;
547 // late init singleton entry
548 Reference
< XInterface
> xInstance
;
553 Any
usesService( getValueByName( rName
+ "/service" ) );
554 Any
args_( getValueByName( rName
+ "/arguments" ) );
556 if (args_
.hasValue() && !(args_
>>= args
))
562 Reference
< lang::XSingleComponentFactory
> xFac
;
563 if (usesService
>>= xFac
) // try via factory
565 xInstance
= args
.getLength()
566 ? xFac
->createInstanceWithArgumentsAndContext( args
, this )
567 : xFac
->createInstanceWithContext( this );
571 Reference
< lang::XSingleServiceFactory
> xFac2
;
572 if (usesService
>>= xFac2
)
574 // try via old XSingleServiceFactory
575 #if OSL_DEBUG_LEVEL > 0
578 "### omitting context for service instanciation!\n" );
580 xInstance
= args
.getLength()
581 ? xFac2
->createInstanceWithArguments( args
)
582 : xFac2
->createInstance();
584 else if (m_xSMgr
.is()) // optionally service name
586 OUString serviceName
;
587 if ((usesService
>>= serviceName
) &&
588 !serviceName
.isEmpty())
590 xInstance
= args
.getLength()
591 ? m_xSMgr
->createInstanceWithArgumentsAndContext(
592 serviceName
, args
, this )
593 : m_xSMgr
->createInstanceWithContext(
599 catch (RuntimeException
&)
603 catch (Exception
& exc
) // rethrow as WrappedTargetRuntimeException
605 Any
caught( getCaughtException() );
607 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
608 "exception occurred raising singleton \"") );
610 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\": ") );
611 buf
.append( exc
.Message
);
612 throw lang::WrappedTargetRuntimeException(
613 buf
.makeStringAndClear(), static_cast<OWeakObject
*>(this),caught
);
616 if (! xInstance
.is())
618 throw RuntimeException(
619 "no service object raising singleton " + rName
,
620 static_cast<OWeakObject
*>(this) );
625 iFind
= m_map
.find( rName
);
626 if (iFind
!= m_map
.end())
628 pEntry
= iFind
->second
;
629 if (pEntry
->lateInit
)
631 pEntry
->value
<<= xInstance
;
632 pEntry
->lateInit
= false;
633 return pEntry
->value
;
639 try_dispose( xInstance
);
643 //__________________________________________________________________________________________________
644 Any
ComponentContext::getValueByName( OUString
const & rName
)
645 throw (RuntimeException
)
647 // to determine the root context:
648 if ( rName
== "_root" )
650 if (m_xDelegate
.is())
651 return m_xDelegate
->getValueByName( rName
);
653 return makeAny( Reference
<XComponentContext
>(this) );
656 Any
ret( lookupMap( rName
) );
657 if (!ret
.hasValue() && m_xDelegate
.is())
659 return m_xDelegate
->getValueByName( rName
);
663 //__________________________________________________________________________________________________
664 Reference
< lang::XMultiComponentFactory
> ComponentContext::getServiceManager()
665 throw (RuntimeException
)
669 throw DeploymentException(
670 "null component context service manager",
671 static_cast<OWeakObject
*>(this) );
675 //__________________________________________________________________________________________________
676 ComponentContext::~ComponentContext()
680 ::fprintf( stderr
, "> destructed context %p\n", this );
682 t_map::const_iterator
iPos( m_map
.begin() );
683 t_map::const_iterator
const iEnd( m_map
.end() );
684 for ( ; iPos
!= iEnd
; ++iPos
)
688 //__________________________________________________________________________________________________
689 void ComponentContext::disposing()
692 ::fprintf( stderr
, "> disposing context %p\n", this );
695 Reference
< lang::XComponent
> xTDMgr
, xAC
; // to be disposed separately
697 // dispose all context objects
698 t_map::const_iterator
iPos( m_map
.begin() );
699 t_map::const_iterator
const iEnd( m_map
.end() );
700 for ( ; iPos
!= iEnd
; ++iPos
)
702 t_map::mapped_type pEntry
= iPos
->second
;
704 // service manager disposed separately
706 !iPos
->first
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON
) ))
708 if (pEntry
->lateInit
)
711 MutexGuard
guard( m_mutex
);
712 if (pEntry
->lateInit
)
714 pEntry
->value
.clear(); // release factory
715 pEntry
->lateInit
= false;
720 Reference
< lang::XComponent
> xComp
;
721 pEntry
->value
>>= xComp
;
724 if ( iPos
->first
== TDMGR_SINGLETON
)
728 else if ( iPos
->first
== AC_SINGLETON
)
732 else // dispose immediately
740 // dispose service manager
741 try_dispose( m_xSMgr
);
745 // dispose tdmgr; revokes callback from cppu runtime
746 try_dispose( xTDMgr
);
748 iPos
= m_map
.begin();
749 for ( ; iPos
!= iEnd
; ++iPos
)
753 //__________________________________________________________________________________________________
754 ComponentContext::ComponentContext(
755 ContextEntry_Init
const * pEntries
, sal_Int32 nEntries
,
756 Reference
< XComponentContext
> const & xDelegate
)
757 : WeakComponentImplHelper2
< XComponentContext
, container::XNameContainer
>(
759 m_xDelegate( xDelegate
)
761 for ( sal_Int32 nPos
= 0; nPos
< nEntries
; ++nPos
)
763 ContextEntry_Init
const & rEntry
= pEntries
[ nPos
];
765 if ( rEntry
.name
== SMGR_SINGLETON
)
767 rEntry
.value
>>= m_xSMgr
;
770 if (rEntry
.bLateInitService
)
773 m_map
[ rEntry
.name
] = new ContextEntry( Any(), true );
775 m_map
[ rEntry
.name
+ "/service" ] = new ContextEntry( rEntry
.value
, false );
776 // /initial-arguments are provided as optional context entry
780 // only value, no late init factory nor string
781 m_map
[ rEntry
.name
] = new ContextEntry( rEntry
.value
, false );
785 if (!m_xSMgr
.is() && m_xDelegate
.is())
787 // wrap delegate's smgr XPropertySet into new smgr
788 Reference
< lang::XMultiComponentFactory
> xMgr( m_xDelegate
->getServiceManager() );
791 osl_atomic_increment( &m_refCount
);
794 // create new smgr based on delegate's one
796 xMgr
->createInstanceWithContext(
797 "com.sun.star.comp.stoc.OServiceManagerWrapper", xDelegate
),
799 // patch DefaultContext property of new one
800 Reference
< beans::XPropertySet
> xProps( m_xSMgr
, UNO_QUERY
);
801 OSL_ASSERT( xProps
.is() );
804 Reference
< XComponentContext
> xThis( this );
805 xProps
->setPropertyValue( "DefaultContext", makeAny( xThis
) );
810 osl_atomic_decrement( &m_refCount
);
813 osl_atomic_decrement( &m_refCount
);
814 OSL_ASSERT( m_xSMgr
.is() );
820 //##################################################################################################
821 extern "C" { static void s_createComponentContext_v(va_list * pParam
)
823 ContextEntry_Init
const * pEntries
= va_arg(*pParam
, ContextEntry_Init
const *);
824 sal_Int32 nEntries
= va_arg(*pParam
, sal_Int32
);
825 XComponentContext
* pDelegatee
= va_arg(*pParam
, XComponentContext
*);
826 void ** ppContext
= va_arg(*pParam
, void **);
827 uno::Mapping
* pTarget2curr
= va_arg(*pParam
, uno::Mapping
*);
829 Reference
<XComponentContext
> xDelegate(pDelegatee
, SAL_NO_ACQUIRE
);
830 Reference
<XComponentContext
> xContext
;
836 ComponentContext
* p
= new ComponentContext( pEntries
, nEntries
, xDelegate
);
838 // listen delegate for disposing, to dispose this (wrapping) context first.
839 DisposingForwarder::listen( Reference
< lang::XComponent
>::query( xDelegate
), p
);
841 catch (Exception
& exc
)
843 (void) exc
; // avoid warning about unused variable
844 OSL_FAIL( OUStringToOString(
845 exc
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
851 xContext
= xDelegate
;
854 *ppContext
= pTarget2curr
->mapInterface(xContext
.get(), ::getCppuType(&xContext
));
857 Reference
< XComponentContext
> SAL_CALL
createComponentContext(
858 ContextEntry_Init
const * pEntries
, sal_Int32 nEntries
,
859 Reference
< XComponentContext
> const & xDelegate
)
862 uno::Environment
curr_env(Environment::getCurrent());
863 uno::Environment
source_env(rtl::OUString(CPPU_STRINGIFY(CPPU_ENV
)));
865 uno::Mapping
curr2source(curr_env
, source_env
);
866 uno::Mapping
source2curr(source_env
, curr_env
);
868 ContextEntry_Init
* mapped_entries
= new ContextEntry_Init
[nEntries
];
869 for (sal_Int32 nPos
= 0; nPos
< nEntries
; ++ nPos
)
871 mapped_entries
[nPos
].bLateInitService
= pEntries
[nPos
].bLateInitService
;
872 mapped_entries
[nPos
].name
= pEntries
[nPos
].name
;
874 uno_type_any_constructAndConvert(&mapped_entries
[nPos
].value
,
875 const_cast<void *>(pEntries
[nPos
].value
.getValue()),
876 pEntries
[nPos
].value
.getValueTypeRef(),
880 void * mapped_delegate
= curr2source
.mapInterface(xDelegate
.get(), ::getCppuType(&xDelegate
));
881 XComponentContext
* pXComponentContext
= NULL
;
882 source_env
.invoke(s_createComponentContext_v
, mapped_entries
, nEntries
, mapped_delegate
, &pXComponentContext
, &source2curr
);
883 delete[] mapped_entries
;
885 return Reference
<XComponentContext
>(pXComponentContext
, SAL_NO_ACQUIRE
);
890 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */