1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: crefl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
33 #include <cppuhelper/queryinterface.hxx>
34 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
35 #include <cppuhelper/implementationentry.hxx>
38 #include <com/sun/star/registry/XRegistryKey.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/reflection/XTypeDescription.hpp>
41 #include "com/sun/star/uno/RuntimeException.hpp"
43 using namespace com::sun::star
;
44 using namespace com::sun::star::lang
;
45 using namespace com::sun::star::registry
;
56 static const sal_Int32 CACHE_SIZE
= 256;
58 #define SERVICENAME "com.sun.star.reflection.CoreReflection"
59 #define IMPLNAME "com.sun.star.comp.stoc.CoreReflection"
61 // can be static, as every client of the core reflection keeps a reference to the
62 // core reflection, so refcounting can be done here.
63 static rtl_StandardModuleCount g_moduleCount
= MODULE_COUNT_INIT
;
65 static Sequence
< OUString
> core_getSupportedServiceNames()
67 static Sequence
< OUString
> *pNames
= 0;
70 MutexGuard
guard( Mutex::getGlobalMutex() );
73 static Sequence
< OUString
> seqNames(1);
74 seqNames
.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
) );
81 static OUString
core_getImplementationName()
83 static OUString
*pImplName
= 0;
86 MutexGuard
guard( Mutex::getGlobalMutex() );
89 static OUString
implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME
) );
90 pImplName
= &implName
;
95 //__________________________________________________________________________________________________
96 IdlReflectionServiceImpl::IdlReflectionServiceImpl(
97 const Reference
< XComponentContext
> & xContext
)
98 : OComponentHelper( _aComponentMutex
)
99 , _xMgr( xContext
->getServiceManager(), UNO_QUERY
)
100 , _aElements( CACHE_SIZE
)
102 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
103 xContext
->getValueByName( OUString( RTL_CONSTASCII_USTRINGPARAM(
104 "/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) ) >>= _xTDMgr
;
105 OSL_ENSURE( _xTDMgr
.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
107 //__________________________________________________________________________________________________
108 IdlReflectionServiceImpl::~IdlReflectionServiceImpl()
110 TRACE( "> IdlReflectionServiceImpl dtor <\n" );
111 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
115 //__________________________________________________________________________________________________
116 Any
IdlReflectionServiceImpl::queryInterface( const Type
& rType
)
117 throw(::com::sun::star::uno::RuntimeException
)
119 Any
aRet( ::cppu::queryInterface(
121 static_cast< XIdlReflection
* >( this ),
122 static_cast< XHierarchicalNameAccess
* >( this ),
123 static_cast< XServiceInfo
* >( this ) ) );
125 return (aRet
.hasValue() ? aRet
: OComponentHelper::queryInterface( rType
));
127 //__________________________________________________________________________________________________
128 void IdlReflectionServiceImpl::acquire() throw()
130 OComponentHelper::acquire();
132 //__________________________________________________________________________________________________
133 void IdlReflectionServiceImpl::release() throw()
135 OComponentHelper::release();
139 //__________________________________________________________________________________________________
140 Sequence
< Type
> IdlReflectionServiceImpl::getTypes()
141 throw (::com::sun::star::uno::RuntimeException
)
143 static OTypeCollection
* s_pTypes
= 0;
146 MutexGuard
aGuard( _aComponentMutex
);
149 static OTypeCollection
s_aTypes(
150 ::getCppuType( (const Reference
< XIdlReflection
> *)0 ),
151 ::getCppuType( (const Reference
< XHierarchicalNameAccess
> *)0 ),
152 ::getCppuType( (const Reference
< XServiceInfo
> *)0 ),
153 OComponentHelper::getTypes() );
154 s_pTypes
= &s_aTypes
;
157 return s_pTypes
->getTypes();
159 //__________________________________________________________________________________________________
160 Sequence
< sal_Int8
> IdlReflectionServiceImpl::getImplementationId()
161 throw (::com::sun::star::uno::RuntimeException
)
163 static OImplementationId
* s_pId
= 0;
166 MutexGuard
aGuard( _aComponentMutex
);
169 static OImplementationId s_aId
;
173 return s_pId
->getImplementationId();
177 //__________________________________________________________________________________________________
178 void IdlReflectionServiceImpl::dispose()
179 throw(::com::sun::star::uno::RuntimeException
)
181 TRACE( "> disposing corereflection... <" );
182 OComponentHelper::dispose();
184 MutexGuard
aGuard( _aComponentMutex
);
188 #ifdef TEST_LIST_CLASSES
189 OSL_ENSURE( g_aClassNames
.size() == 0, "### idl classes still alive!" );
190 ClassNameList::const_iterator
iPos( g_aClassNames
.begin() );
191 while (iPos
!= g_aClassNames
.end())
193 OUString
aName( *iPos
);
200 //__________________________________________________________________________________________________
201 OUString
IdlReflectionServiceImpl::getImplementationName()
202 throw(::com::sun::star::uno::RuntimeException
)
204 return core_getImplementationName();
206 //__________________________________________________________________________________________________
207 sal_Bool
IdlReflectionServiceImpl::supportsService( const OUString
& rServiceName
)
208 throw(::com::sun::star::uno::RuntimeException
)
210 const Sequence
< OUString
> & rSNL
= getSupportedServiceNames();
211 const OUString
* pArray
= rSNL
.getConstArray();
212 for ( sal_Int32 nPos
= rSNL
.getLength(); nPos
--; )
214 if (pArray
[nPos
] == rServiceName
)
219 //__________________________________________________________________________________________________
220 Sequence
< OUString
> IdlReflectionServiceImpl::getSupportedServiceNames()
221 throw(::com::sun::star::uno::RuntimeException
)
223 return core_getSupportedServiceNames();
227 //__________________________________________________________________________________________________
228 Reference
< XIdlClass
> IdlReflectionServiceImpl::getType( const Any
& rObj
)
229 throw(::com::sun::star::uno::RuntimeException
)
231 return (rObj
.hasValue() ? forType( rObj
.getValueTypeRef() ) : Reference
< XIdlClass
>());
234 //__________________________________________________________________________________________________
235 inline Reference
< XIdlClass
> IdlReflectionServiceImpl::constructClass(
236 typelib_TypeDescription
* pTypeDescr
)
238 OSL_ENSURE( pTypeDescr
->eTypeClass
!= typelib_TypeClass_TYPEDEF
, "### unexpected typedef!" );
240 switch (pTypeDescr
->eTypeClass
)
242 case typelib_TypeClass_VOID
:
243 case typelib_TypeClass_CHAR
:
244 case typelib_TypeClass_BOOLEAN
:
245 case typelib_TypeClass_BYTE
:
246 case typelib_TypeClass_SHORT
:
247 case typelib_TypeClass_UNSIGNED_SHORT
:
248 case typelib_TypeClass_LONG
:
249 case typelib_TypeClass_UNSIGNED_LONG
:
250 case typelib_TypeClass_HYPER
:
251 case typelib_TypeClass_UNSIGNED_HYPER
:
252 case typelib_TypeClass_FLOAT
:
253 case typelib_TypeClass_DOUBLE
:
254 case typelib_TypeClass_STRING
:
255 case typelib_TypeClass_ANY
:
256 return new IdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
259 return new EnumIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
261 case typelib_TypeClass_STRUCT
:
262 case typelib_TypeClass_UNION
:
263 case typelib_TypeClass_EXCEPTION
:
264 return new CompoundIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
266 case typelib_TypeClass_ARRAY
:
267 case typelib_TypeClass_SEQUENCE
:
268 return new ArrayIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
270 case typelib_TypeClass_INTERFACE
:
271 return new InterfaceIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
273 case typelib_TypeClass_TYPE
:
274 return new IdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
277 #if OSL_DEBUG_LEVEL > 1
278 OSL_TRACE( "### corereflection type unsupported: " );
279 OString
aName( OUStringToOString( pTypeDescr
->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
280 OSL_TRACE( aName
.getStr() );
283 return Reference
< XIdlClass
>();
286 //__________________________________________________________________________________________________
287 Reference
< XIdlClass
> IdlReflectionServiceImpl::forName( const OUString
& rTypeName
)
288 throw(::com::sun::star::uno::RuntimeException
)
290 Reference
< XIdlClass
> xRet
;
291 Any
aAny( _aElements
.getValue( rTypeName
) );
295 if (aAny
.getValueTypeClass() == TypeClass_INTERFACE
)
296 xRet
= *(const Reference
< XIdlClass
> *)aAny
.getValue();
300 // try to get _type_ by name
301 typelib_TypeDescription
* pTD
= 0;
302 typelib_typedescription_getByName( &pTD
, rTypeName
.pData
);
305 if ((xRet
= constructClass( pTD
)).is())
306 _aElements
.setValue( rTypeName
, makeAny( xRet
) ); // update
307 typelib_typedescription_release( pTD
);
314 // XHierarchicalNameAccess
315 //__________________________________________________________________________________________________
316 Any
IdlReflectionServiceImpl::getByHierarchicalName( const OUString
& rName
)
317 throw(::com::sun::star::container::NoSuchElementException
, ::com::sun::star::uno::RuntimeException
)
319 Any
aRet( _aElements
.getValue( rName
) );
320 if (! aRet
.hasValue())
322 // first look for constants exclusivly!
323 aRet
= _xTDMgr
->getByHierarchicalName( rName
);
324 if (aRet
.getValueTypeClass() == TypeClass_INTERFACE
) // if no constant,
325 // i.e. XTypeDescription for a type
327 // type retrieved from tdmgr
328 OSL_ASSERT( (*(Reference
< XInterface
> *)aRet
.getValue())->queryInterface(
329 ::getCppuType( (const Reference
< XTypeDescription
> *)0 ) ).hasValue() );
331 // if you are interested in a type then CALL forName()!!!
332 // this way is NOT recommended for types, because this method looks for constants first
334 // if td manager found some type, it will be in the cache (hopefully.. we just got it)
335 // so the second retrieving via c typelib callback chain should succeed...
337 // try to get _type_ by name
338 typelib_TypeDescription
* pTD
= 0;
339 typelib_typedescription_getByName( &pTD
, rName
.pData
);
341 aRet
.clear(); // kick XTypeDescription interface
345 Reference
< XIdlClass
> xIdlClass( constructClass( pTD
) );
346 aRet
.setValue( &xIdlClass
, ::getCppuType( (const Reference
< XIdlClass
> *)0 ) );
347 typelib_typedescription_release( pTD
);
354 _aElements
.setValue( rName
, aRet
);
357 throw NoSuchElementException( rName
, Reference
< XInterface
>() );
362 //__________________________________________________________________________________________________
363 sal_Bool
IdlReflectionServiceImpl::hasByHierarchicalName( const OUString
& rName
)
364 throw(::com::sun::star::uno::RuntimeException
)
368 return getByHierarchicalName( rName
).hasValue();
370 catch (NoSuchElementException
&)
376 //__________________________________________________________________________________________________
377 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescription
* pTypeDescr
)
378 throw(::com::sun::star::uno::RuntimeException
)
380 Reference
< XIdlClass
> xRet
;
381 OUString
aName( pTypeDescr
->pTypeName
);
382 Any
aAny( _aElements
.getValue( aName
) );
386 if (aAny
.getValueTypeClass() == TypeClass_INTERFACE
)
387 xRet
= *(const Reference
< XIdlClass
> *)aAny
.getValue();
391 if (pTypeDescr
&& (xRet
= constructClass( pTypeDescr
)).is())
392 _aElements
.setValue( aName
, makeAny( xRet
) ); // update
397 //__________________________________________________________________________________________________
398 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference
* pRef
)
399 throw(::com::sun::star::uno::RuntimeException
)
401 typelib_TypeDescription
* pTD
= 0;
402 TYPELIB_DANGER_GET( &pTD
, pRef
);
405 Reference
< XIdlClass
> xRet
= forType( pTD
);
406 TYPELIB_DANGER_RELEASE( pTD
);
409 throw RuntimeException(
410 OUString( RTL_CONSTASCII_USTRINGPARAM("IdlReflectionServiceImpl::forType() failed!") ),
411 (XWeak
*)(OWeakObject
*)this );
414 //__________________________________________________________________________________________________
415 const Mapping
& IdlReflectionServiceImpl::getCpp2Uno()
416 throw(::com::sun::star::uno::RuntimeException
)
418 if (! _aCpp2Uno
.is())
420 MutexGuard
aGuard( getMutexAccess() );
421 if (! _aCpp2Uno
.is())
424 OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) ),
425 OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO
) ) );
426 OSL_ENSURE( _aCpp2Uno
.is(), "### cannot get c++ to uno mapping!" );
427 if (! _aCpp2Uno
.is())
429 throw RuntimeException(
430 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get c++ to uno mapping!") ),
431 (XWeak
*)(OWeakObject
*)this );
437 //__________________________________________________________________________________________________
438 const Mapping
& IdlReflectionServiceImpl::getUno2Cpp()
439 throw(::com::sun::star::uno::RuntimeException
)
441 if (! _aUno2Cpp
.is())
443 MutexGuard
aGuard( getMutexAccess() );
444 if (! _aUno2Cpp
.is())
447 OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO
) ),
448 OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) ) );
449 OSL_ENSURE( _aUno2Cpp
.is(), "### cannot get uno to c++ mapping!" );
450 if (! _aUno2Cpp
.is())
452 throw RuntimeException(
453 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get uno to c++ mapping!") ),
454 (XWeak
*)(OWeakObject
*)this );
460 //__________________________________________________________________________________________________
461 uno_Interface
* IdlReflectionServiceImpl::mapToUno(
462 const Any
& rObj
, typelib_InterfaceTypeDescription
* pTo
)
463 throw(::com::sun::star::uno::RuntimeException
)
465 Reference
< XInterface
> xObj
;
466 if (extract( rObj
, pTo
, xObj
, this ))
467 return (uno_Interface
*)getCpp2Uno().mapInterface( xObj
.get(), pTo
);
469 throw RuntimeException(
470 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
471 (XWeak
*)(OWeakObject
*)this );
474 //==================================================================================================
475 Reference
< XInterface
> SAL_CALL
IdlReflectionServiceImpl_create(
476 const Reference
< XComponentContext
> & xContext
)
477 throw(::com::sun::star::uno::Exception
)
479 return Reference
< XInterface
>( (XWeak
*)(OWeakObject
*)new IdlReflectionServiceImpl( xContext
) );
485 //##################################################################################################
486 //##################################################################################################
487 //##################################################################################################
489 using namespace stoc_corefl
;
491 static struct ImplementationEntry g_entries
[] =
494 IdlReflectionServiceImpl_create
, core_getImplementationName
,
495 core_getSupportedServiceNames
, createSingleComponentFactory
,
496 &g_moduleCount
.modCnt
, 0
503 sal_Bool SAL_CALL
component_canUnload( TimeValue
*pTime
)
505 return g_moduleCount
.canUnload( &g_moduleCount
, pTime
);
508 //==================================================================================================
509 void SAL_CALL
component_getImplementationEnvironment(
510 const sal_Char
** ppEnvTypeName
, uno_Environment
** )
512 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
514 //==================================================================================================
515 sal_Bool SAL_CALL
component_writeInfo(
516 void * pServiceManager
, void * pRegistryKey
)
518 if (component_writeInfoHelper( pServiceManager
, pRegistryKey
, g_entries
))
522 // register singleton
523 registry::XRegistryKey
* pKey
=
524 reinterpret_cast< registry::XRegistryKey
* >( pRegistryKey
);
525 Reference
< registry::XRegistryKey
> xKey(
527 OUSTR(IMPLNAME
"/UNO/SINGLETONS/com.sun.star.reflection.theCoreReflection") ) );
528 xKey
->setStringValue( OUSTR("com.sun.star.reflection.CoreReflection") );
531 catch (Exception
& exc
)
533 #if OSL_DEBUG_LEVEL > 0
534 OString
cstr( OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
535 OSL_ENSURE( 0, cstr
.getStr() );
537 (void) exc
; // unused
543 //==================================================================================================
544 void * SAL_CALL
component_getFactory(
545 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
547 return component_getFactoryHelper( pImplName
, pServiceManager
, pRegistryKey
, g_entries
);