update dev300-m58
[ooovba.git] / stoc / source / corereflection / crefl.cxx
blobff32395b0678eec859a5a22868d0e53be66b7931
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: crefl.cxx,v $
10 * $Revision: 1.14 $
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>
36 #endif
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;
46 using namespace cppu;
47 using namespace osl;
48 using namespace rtl;
50 #include "base.hxx"
53 namespace stoc_corefl
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;
68 if( ! pNames )
70 MutexGuard guard( Mutex::getGlobalMutex() );
71 if( !pNames )
73 static Sequence< OUString > seqNames(1);
74 seqNames.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
75 pNames = &seqNames;
78 return *pNames;
81 static OUString core_getImplementationName()
83 static OUString *pImplName = 0;
84 if( ! pImplName )
86 MutexGuard guard( Mutex::getGlobalMutex() );
87 if( ! pImplName )
89 static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
90 pImplName = &implName;
93 return *pImplName;
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 );
114 // XInterface
115 //__________________________________________________________________________________________________
116 Any IdlReflectionServiceImpl::queryInterface( const Type & rType )
117 throw(::com::sun::star::uno::RuntimeException)
119 Any aRet( ::cppu::queryInterface(
120 rType,
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();
138 // XTypeProvider
139 //__________________________________________________________________________________________________
140 Sequence< Type > IdlReflectionServiceImpl::getTypes()
141 throw (::com::sun::star::uno::RuntimeException)
143 static OTypeCollection * s_pTypes = 0;
144 if (! s_pTypes)
146 MutexGuard aGuard( _aComponentMutex );
147 if (! s_pTypes)
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;
164 if (! s_pId)
166 MutexGuard aGuard( _aComponentMutex );
167 if (! s_pId)
169 static OImplementationId s_aId;
170 s_pId = &s_aId;
173 return s_pId->getImplementationId();
176 // XComponent
177 //__________________________________________________________________________________________________
178 void IdlReflectionServiceImpl::dispose()
179 throw(::com::sun::star::uno::RuntimeException)
181 TRACE( "> disposing corereflection... <" );
182 OComponentHelper::dispose();
184 MutexGuard aGuard( _aComponentMutex );
185 _aElements.clear();
186 _xTDMgr.clear();
187 _xMgr.clear();
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 );
194 ++iPos;
196 #endif
199 // XServiceInfo
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)
215 return sal_True;
217 return sal_False;
219 //__________________________________________________________________________________________________
220 Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames()
221 throw(::com::sun::star::uno::RuntimeException)
223 return core_getSupportedServiceNames();
226 // XIdlReflection
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 );
258 case TypeClass_ENUM:
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 );
276 default:
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() );
281 OSL_TRACE( "\n" );
282 #endif
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 ) );
293 if (aAny.hasValue())
295 if (aAny.getValueTypeClass() == TypeClass_INTERFACE)
296 xRet = *(const Reference< XIdlClass > *)aAny.getValue();
298 else
300 // try to get _type_ by name
301 typelib_TypeDescription * pTD = 0;
302 typelib_typedescription_getByName( &pTD, rTypeName.pData );
303 if (pTD)
305 if ((xRet = constructClass( pTD )).is())
306 _aElements.setValue( rTypeName, makeAny( xRet ) ); // update
307 typelib_typedescription_release( pTD );
311 return xRet;
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
343 if (pTD)
345 Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
346 aRet.setValue( &xIdlClass, ::getCppuType( (const Reference< XIdlClass > *)0 ) );
347 typelib_typedescription_release( pTD );
350 // else is constant
352 // update
353 if (aRet.hasValue())
354 _aElements.setValue( rName, aRet );
355 else
357 throw NoSuchElementException( rName, Reference< XInterface >() );
360 return aRet;
362 //__________________________________________________________________________________________________
363 sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName )
364 throw(::com::sun::star::uno::RuntimeException)
368 return getByHierarchicalName( rName ).hasValue();
370 catch (NoSuchElementException &)
373 return sal_False;
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 ) );
384 if (aAny.hasValue())
386 if (aAny.getValueTypeClass() == TypeClass_INTERFACE)
387 xRet = *(const Reference< XIdlClass > *)aAny.getValue();
389 else
391 if (pTypeDescr && (xRet = constructClass( pTypeDescr )).is())
392 _aElements.setValue( aName, makeAny( xRet ) ); // update
395 return xRet;
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 );
403 if (pTD)
405 Reference< XIdlClass > xRet = forType( pTD );
406 TYPELIB_DANGER_RELEASE( pTD );
407 return xRet;
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())
423 _aCpp2Uno = Mapping(
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 );
435 return _aCpp2Uno;
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())
446 _aUno2Cpp = Mapping(
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 );
458 return _aUno2Cpp;
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
498 { 0, 0, 0, 0, 0, 0 }
501 extern "C"
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(
526 pKey->createKey(
527 OUSTR(IMPLNAME "/UNO/SINGLETONS/com.sun.star.reflection.theCoreReflection") ) );
528 xKey->setStringValue( OUSTR("com.sun.star.reflection.CoreReflection") );
529 return sal_True;
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() );
536 #else
537 (void) exc; // unused
538 #endif
541 return sal_False;
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 );