Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / stoc / source / corereflection / crefl.cxx
blobd7d59c769dccc34d799a18a63654a2196d223d76
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 IdlReflectionServiceImpl::IdlReflectionServiceImpl(
47 const Reference< XComponentContext > & xContext )
48 : OComponentHelper( _aComponentMutex )
49 , _aElements()
51 xContext->getValueByName(
52 "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) >>= _xTDMgr;
53 OSL_ENSURE( _xTDMgr.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
56 IdlReflectionServiceImpl::~IdlReflectionServiceImpl() {}
58 // XInterface
60 Any IdlReflectionServiceImpl::queryInterface( const Type & rType )
62 Any aRet( ::cppu::queryInterface(
63 rType,
64 static_cast< XIdlReflection * >( this ),
65 static_cast< XHierarchicalNameAccess * >( this ),
66 static_cast< XServiceInfo * >( this ) ) );
68 return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
71 void IdlReflectionServiceImpl::acquire() throw()
73 OComponentHelper::acquire();
76 void IdlReflectionServiceImpl::release() throw()
78 OComponentHelper::release();
81 // XTypeProvider
83 Sequence< Type > IdlReflectionServiceImpl::getTypes()
85 static OTypeCollection * s_pTypes = nullptr;
86 if (! s_pTypes)
88 MutexGuard aGuard( _aComponentMutex );
89 if (! s_pTypes)
91 static OTypeCollection s_aTypes(
92 cppu::UnoType<XIdlReflection>::get(),
93 cppu::UnoType<XHierarchicalNameAccess>::get(),
94 cppu::UnoType<XServiceInfo>::get(),
95 OComponentHelper::getTypes() );
96 s_pTypes = &s_aTypes;
99 return s_pTypes->getTypes();
102 Sequence< sal_Int8 > IdlReflectionServiceImpl::getImplementationId()
104 return css::uno::Sequence<sal_Int8>();
107 // XComponent
109 void IdlReflectionServiceImpl::dispose()
111 OComponentHelper::dispose();
113 MutexGuard aGuard( _aComponentMutex );
114 _aElements.clear();
115 #ifdef TEST_LIST_CLASSES
116 OSL_ENSURE( g_aClassNames.empty(), "### idl classes still alive!" );
117 for (auto const& className : g_aClassNames)
119 OUString aName(className);
121 #endif
124 // XServiceInfo
126 OUString IdlReflectionServiceImpl::getImplementationName()
128 return OUString("com.sun.star.comp.stoc.CoreReflection");
131 sal_Bool IdlReflectionServiceImpl::supportsService( const OUString & rServiceName )
133 return cppu::supportsService(this, rServiceName);
136 Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames()
138 Sequence< OUString > seqNames { "com.sun.star.reflection.CoreReflection" };
139 return seqNames;
142 // XIdlReflection
144 Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj )
146 return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >());
150 inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass(
151 typelib_TypeDescription * pTypeDescr )
153 OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" );
155 switch (pTypeDescr->eTypeClass)
157 case typelib_TypeClass_VOID:
158 case typelib_TypeClass_CHAR:
159 case typelib_TypeClass_BOOLEAN:
160 case typelib_TypeClass_BYTE:
161 case typelib_TypeClass_SHORT:
162 case typelib_TypeClass_UNSIGNED_SHORT:
163 case typelib_TypeClass_LONG:
164 case typelib_TypeClass_UNSIGNED_LONG:
165 case typelib_TypeClass_HYPER:
166 case typelib_TypeClass_UNSIGNED_HYPER:
167 case typelib_TypeClass_FLOAT:
168 case typelib_TypeClass_DOUBLE:
169 case typelib_TypeClass_STRING:
170 case typelib_TypeClass_ANY:
171 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
173 case typelib_TypeClass_ENUM:
174 return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
176 case typelib_TypeClass_STRUCT:
177 case typelib_TypeClass_EXCEPTION:
178 return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
180 case typelib_TypeClass_SEQUENCE:
181 return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
183 case typelib_TypeClass_INTERFACE:
184 return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
186 case typelib_TypeClass_TYPE:
187 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
189 default:
190 SAL_INFO("stoc", "corereflection type unsupported: " << pTypeDescr->pTypeName);
191 return Reference< XIdlClass >();
195 Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName )
197 Reference< XIdlClass > xRet;
198 Any aAny( _aElements.getValue( rTypeName ) );
200 if (aAny.hasValue())
202 aAny >>= xRet;
204 else
206 // try to get _type_ by name
207 typelib_TypeDescription * pTD = nullptr;
208 typelib_typedescription_getByName( &pTD, rTypeName.pData );
209 if (pTD)
211 if ((xRet = constructClass( pTD )).is())
212 _aElements.setValue( rTypeName, makeAny( xRet ) ); // update
213 typelib_typedescription_release( pTD );
217 return xRet;
220 // XHierarchicalNameAccess
222 Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName )
224 Any aRet( _aElements.getValue( rName ) );
225 if (! aRet.hasValue())
227 aRet = _xTDMgr->getByHierarchicalName( rName );
228 if (aRet.getValueTypeClass() == TypeClass_INTERFACE)
230 // type retrieved from tdmgr
231 OSL_ASSERT( (*o3tl::forceAccess<Reference<XInterface>>(aRet))->queryInterface(
232 cppu::UnoType<XTypeDescription>::get()).hasValue() );
234 css::uno::Reference< css::reflection::XConstantTypeDescription >
235 ctd;
236 if (aRet >>= ctd)
238 aRet = ctd->getConstantValue();
240 else
242 // if you are interested in a type then CALL forName()!!!
243 // this way is NOT recommended for types, because this method looks for constants first
245 // if td manager found some type, it will be in the cache (hopefully.. we just got it)
246 // so the second retrieving via c typelib callback chain should succeed...
248 // try to get _type_ by name
249 typelib_TypeDescription * pTD = nullptr;
250 typelib_typedescription_getByName( &pTD, rName.pData );
252 aRet.clear(); // kick XTypeDescription interface
254 if (pTD)
256 Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
257 aRet.setValue( &xIdlClass, cppu::UnoType<XIdlClass>::get());
258 typelib_typedescription_release( pTD );
262 // else is enum member(?)
264 // update
265 if (!aRet.hasValue())
266 throw container::NoSuchElementException( rName );
268 _aElements.setValue( rName, aRet );
270 return aRet;
273 sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName )
277 return getByHierarchicalName( rName ).hasValue();
279 catch (container::NoSuchElementException &)
282 return false;
286 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr )
288 Reference< XIdlClass > xRet;
289 OUString aName( pTypeDescr->pTypeName );
290 Any aAny( _aElements.getValue( aName ) );
292 if (aAny.hasValue())
294 aAny >>= xRet;
296 else
298 if ((xRet = constructClass( pTypeDescr )).is())
299 _aElements.setValue( aName, makeAny( xRet ) ); // update
302 return xRet;
305 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef )
307 typelib_TypeDescription * pTD = nullptr;
308 TYPELIB_DANGER_GET( &pTD, pRef );
309 if (pTD)
311 Reference< XIdlClass > xRet = forType( pTD );
312 TYPELIB_DANGER_RELEASE( pTD );
313 return xRet;
315 throw RuntimeException(
316 "IdlReflectionServiceImpl::forType() failed!",
317 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
321 const Mapping & IdlReflectionServiceImpl::getCpp2Uno()
323 if (! _aCpp2Uno.is())
325 MutexGuard aGuard( getMutexAccess() );
326 if (! _aCpp2Uno.is())
328 _aCpp2Uno = Mapping(
329 OUString( CPPU_CURRENT_LANGUAGE_BINDING_NAME ),
330 OUString( UNO_LB_UNO ) );
331 OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" );
332 if (! _aCpp2Uno.is())
334 throw RuntimeException(
335 "cannot get c++ to uno mapping!",
336 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
340 return _aCpp2Uno;
343 const Mapping & IdlReflectionServiceImpl::getUno2Cpp()
345 if (! _aUno2Cpp.is())
347 MutexGuard aGuard( getMutexAccess() );
348 if (! _aUno2Cpp.is())
350 _aUno2Cpp = Mapping(
351 OUString( UNO_LB_UNO ),
352 OUString( CPPU_CURRENT_LANGUAGE_BINDING_NAME ) );
353 OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" );
354 if (! _aUno2Cpp.is())
356 throw RuntimeException(
357 "cannot get uno to c++ mapping!",
358 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
362 return _aUno2Cpp;
365 uno_Interface * IdlReflectionServiceImpl::mapToUno(
366 const Any & rObj, typelib_InterfaceTypeDescription * pTo )
368 Reference< XInterface > xObj;
369 if (extract( rObj, pTo, xObj, this ))
370 return static_cast<uno_Interface *>(getCpp2Uno().mapInterface( xObj.get(), pTo ));
372 throw RuntimeException(
373 "illegal object given!",
374 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
380 namespace {
382 struct Instance {
383 explicit Instance(
384 css::uno::Reference<css::uno::XComponentContext> const & context):
385 instance(new stoc_corefl::IdlReflectionServiceImpl(context))
388 rtl::Reference<cppu::OWeakObject> instance;
391 struct Singleton:
392 public rtl::StaticWithArg<
393 Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
398 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
399 com_sun_star_comp_stoc_CoreReflection_get_implementation(
400 css::uno::XComponentContext * context,
401 css::uno::Sequence<css::uno::Any> const & arguments)
403 SAL_WARN_IF(
404 arguments.hasElements(), "stoc", "unexpected singleton arguments");
405 return cppu::acquire(Singleton::get(context).instance.get());
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */