Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / stoc / source / corereflection / crefl.cxx
blob434776be2abfc34d12f5f854c8b521b0fae9b01c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <cppuhelper/queryinterface.hxx>
21 #include <cppuhelper/implementationentry.hxx>
22 #include <cppuhelper/supportsservice.hxx>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <com/sun/star/reflection/XConstantTypeDescription.hpp>
26 #include <com/sun/star/reflection/XTypeDescription.hpp>
27 #include <com/sun/star/uno/RuntimeException.hpp>
28 #include <o3tl/any.hxx>
29 #include <uno/lbnames.h>
31 using namespace css;
32 using namespace css::uno;
33 using namespace css::lang;
34 using namespace css::reflection;
35 using namespace css::registry;
36 using namespace cppu;
37 using namespace osl;
40 #include "base.hxx"
43 namespace stoc_corefl
46 #define IMPLNAME "com.sun.star.comp.stoc.CoreReflection"
48 static Sequence< OUString > core_getSupportedServiceNames()
50 Sequence< OUString > seqNames { "com.sun.star.reflection.CoreReflection" };
51 return seqNames;
54 static OUString core_getImplementationName()
56 return OUString(IMPLNAME);
59 IdlReflectionServiceImpl::IdlReflectionServiceImpl(
60 const Reference< XComponentContext > & xContext )
61 : OComponentHelper( _aComponentMutex )
62 , _aElements()
64 xContext->getValueByName(
65 "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) >>= _xTDMgr;
66 OSL_ENSURE( _xTDMgr.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
69 IdlReflectionServiceImpl::~IdlReflectionServiceImpl() {}
71 // XInterface
73 Any IdlReflectionServiceImpl::queryInterface( const Type & rType )
75 Any aRet( ::cppu::queryInterface(
76 rType,
77 static_cast< XIdlReflection * >( this ),
78 static_cast< XHierarchicalNameAccess * >( this ),
79 static_cast< XServiceInfo * >( this ) ) );
81 return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
84 void IdlReflectionServiceImpl::acquire() throw()
86 OComponentHelper::acquire();
89 void IdlReflectionServiceImpl::release() throw()
91 OComponentHelper::release();
94 // XTypeProvider
96 Sequence< Type > IdlReflectionServiceImpl::getTypes()
98 static OTypeCollection * s_pTypes = nullptr;
99 if (! s_pTypes)
101 MutexGuard aGuard( _aComponentMutex );
102 if (! s_pTypes)
104 static OTypeCollection s_aTypes(
105 cppu::UnoType<XIdlReflection>::get(),
106 cppu::UnoType<XHierarchicalNameAccess>::get(),
107 cppu::UnoType<XServiceInfo>::get(),
108 OComponentHelper::getTypes() );
109 s_pTypes = &s_aTypes;
112 return s_pTypes->getTypes();
115 Sequence< sal_Int8 > IdlReflectionServiceImpl::getImplementationId()
117 return css::uno::Sequence<sal_Int8>();
120 // XComponent
122 void IdlReflectionServiceImpl::dispose()
124 OComponentHelper::dispose();
126 MutexGuard aGuard( _aComponentMutex );
127 _aElements.clear();
128 #ifdef TEST_LIST_CLASSES
129 OSL_ENSURE( g_aClassNames.empty(), "### idl classes still alive!" );
130 ClassNameList::const_iterator iPos( g_aClassNames.begin() );
131 while (iPos != g_aClassNames.end())
133 OUString aName( *iPos );
134 ++iPos;
136 #endif
139 // XServiceInfo
141 OUString IdlReflectionServiceImpl::getImplementationName()
143 return core_getImplementationName();
146 sal_Bool IdlReflectionServiceImpl::supportsService( const OUString & rServiceName )
148 return cppu::supportsService(this, rServiceName);
151 Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames()
153 return core_getSupportedServiceNames();
156 // XIdlReflection
158 Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj )
160 return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >());
164 inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass(
165 typelib_TypeDescription * pTypeDescr )
167 OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" );
169 switch (pTypeDescr->eTypeClass)
171 case typelib_TypeClass_VOID:
172 case typelib_TypeClass_CHAR:
173 case typelib_TypeClass_BOOLEAN:
174 case typelib_TypeClass_BYTE:
175 case typelib_TypeClass_SHORT:
176 case typelib_TypeClass_UNSIGNED_SHORT:
177 case typelib_TypeClass_LONG:
178 case typelib_TypeClass_UNSIGNED_LONG:
179 case typelib_TypeClass_HYPER:
180 case typelib_TypeClass_UNSIGNED_HYPER:
181 case typelib_TypeClass_FLOAT:
182 case typelib_TypeClass_DOUBLE:
183 case typelib_TypeClass_STRING:
184 case typelib_TypeClass_ANY:
185 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
187 case typelib_TypeClass_ENUM:
188 return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
190 case typelib_TypeClass_STRUCT:
191 case typelib_TypeClass_EXCEPTION:
192 return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
194 case typelib_TypeClass_SEQUENCE:
195 return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
197 case typelib_TypeClass_INTERFACE:
198 return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
200 case typelib_TypeClass_TYPE:
201 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
203 default:
204 SAL_INFO("stoc", "corereflection type unsupported: " << pTypeDescr->pTypeName);
205 return Reference< XIdlClass >();
209 Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName )
211 Reference< XIdlClass > xRet;
212 Any aAny( _aElements.getValue( rTypeName ) );
214 if (aAny.hasValue())
216 aAny >>= xRet;
218 else
220 // try to get _type_ by name
221 typelib_TypeDescription * pTD = nullptr;
222 typelib_typedescription_getByName( &pTD, rTypeName.pData );
223 if (pTD)
225 if ((xRet = constructClass( pTD )).is())
226 _aElements.setValue( rTypeName, makeAny( xRet ) ); // update
227 typelib_typedescription_release( pTD );
231 return xRet;
234 // XHierarchicalNameAccess
236 Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName )
238 Any aRet( _aElements.getValue( rName ) );
239 if (! aRet.hasValue())
241 aRet = _xTDMgr->getByHierarchicalName( rName );
242 if (aRet.getValueTypeClass() == TypeClass_INTERFACE)
244 // type retrieved from tdmgr
245 OSL_ASSERT( (*o3tl::forceAccess<Reference<XInterface>>(aRet))->queryInterface(
246 cppu::UnoType<XTypeDescription>::get()).hasValue() );
248 css::uno::Reference< css::reflection::XConstantTypeDescription >
249 ctd;
250 if (aRet >>= ctd)
252 aRet = ctd->getConstantValue();
254 else
256 // if you are interested in a type then CALL forName()!!!
257 // this way is NOT recommended for types, because this method looks for constants first
259 // if td manager found some type, it will be in the cache (hopefully.. we just got it)
260 // so the second retrieving via c typelib callback chain should succeed...
262 // try to get _type_ by name
263 typelib_TypeDescription * pTD = nullptr;
264 typelib_typedescription_getByName( &pTD, rName.pData );
266 aRet.clear(); // kick XTypeDescription interface
268 if (pTD)
270 Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
271 aRet.setValue( &xIdlClass, cppu::UnoType<XIdlClass>::get());
272 typelib_typedescription_release( pTD );
276 // else is enum member(?)
278 // update
279 if (aRet.hasValue())
280 _aElements.setValue( rName, aRet );
281 else
283 throw container::NoSuchElementException( rName );
286 return aRet;
289 sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName )
293 return getByHierarchicalName( rName ).hasValue();
295 catch (container::NoSuchElementException &)
298 return false;
302 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr )
304 Reference< XIdlClass > xRet;
305 OUString aName( pTypeDescr->pTypeName );
306 Any aAny( _aElements.getValue( aName ) );
308 if (aAny.hasValue())
310 aAny >>= xRet;
312 else
314 if ((xRet = constructClass( pTypeDescr )).is())
315 _aElements.setValue( aName, makeAny( xRet ) ); // update
318 return xRet;
321 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef )
323 typelib_TypeDescription * pTD = nullptr;
324 TYPELIB_DANGER_GET( &pTD, pRef );
325 if (pTD)
327 Reference< XIdlClass > xRet = forType( pTD );
328 TYPELIB_DANGER_RELEASE( pTD );
329 return xRet;
331 throw RuntimeException(
332 "IdlReflectionServiceImpl::forType() failed!",
333 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
337 const Mapping & IdlReflectionServiceImpl::getCpp2Uno()
339 if (! _aCpp2Uno.is())
341 MutexGuard aGuard( getMutexAccess() );
342 if (! _aCpp2Uno.is())
344 _aCpp2Uno = Mapping(
345 OUString( CPPU_CURRENT_LANGUAGE_BINDING_NAME ),
346 OUString( UNO_LB_UNO ) );
347 OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" );
348 if (! _aCpp2Uno.is())
350 throw RuntimeException(
351 "cannot get c++ to uno mapping!",
352 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
356 return _aCpp2Uno;
359 const Mapping & IdlReflectionServiceImpl::getUno2Cpp()
361 if (! _aUno2Cpp.is())
363 MutexGuard aGuard( getMutexAccess() );
364 if (! _aUno2Cpp.is())
366 _aUno2Cpp = Mapping(
367 OUString( UNO_LB_UNO ),
368 OUString( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) );
369 OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" );
370 if (! _aUno2Cpp.is())
372 throw RuntimeException(
373 "cannot get uno to c++ mapping!",
374 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
378 return _aUno2Cpp;
381 uno_Interface * IdlReflectionServiceImpl::mapToUno(
382 const Any & rObj, typelib_InterfaceTypeDescription * pTo )
384 Reference< XInterface > xObj;
385 if (extract( rObj, pTo, xObj, this ))
386 return static_cast<uno_Interface *>(getCpp2Uno().mapInterface( xObj.get(), pTo ));
388 throw RuntimeException(
389 "illegal object given!",
390 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
393 /// @throws css::uno::Exception
394 Reference< XInterface > SAL_CALL IdlReflectionServiceImpl_create(
395 const Reference< XComponentContext > & xContext )
397 return Reference< XInterface >( static_cast<XWeak *>(static_cast<OWeakObject *>(new IdlReflectionServiceImpl( xContext ))) );
403 using namespace stoc_corefl;
405 static const struct ImplementationEntry g_entries[] =
408 IdlReflectionServiceImpl_create, core_getImplementationName,
409 core_getSupportedServiceNames, createSingleComponentFactory,
410 nullptr, 0
412 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
415 extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL reflection_component_getFactory(
416 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
418 return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */