LibreOffice Module stoc (master) 1
crefl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
23#include <sal/log.hxx>
24
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 <com/sun/star/uno/XComponentContext.hpp>
29#include <o3tl/any.hxx>
30#include <uno/lbnames.h>
31
32using namespace css;
33using namespace css::uno;
34using namespace css::lang;
35using namespace css::reflection;
36using namespace cppu;
37using namespace osl;
38
39
40#include "base.hxx"
41
42
43namespace stoc_corefl
44{
45
47 const Reference< XComponentContext > & xContext )
48 : WeakComponentImplHelper( _aComponentMutex )
49{
50 xContext->getValueByName(
51 "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) >>= _xTDMgr;
52 OSL_ENSURE( _xTDMgr.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
53}
54
56
57// XComponent
58
60{
61 MutexGuard aGuard( _aComponentMutex );
63#ifdef TEST_LIST_CLASSES
64 OSL_ENSURE( g_aClassNames.empty(), "### idl classes still alive!" );
65 for (auto const& className : g_aClassNames)
66 {
67 OUString aName(className);
68 }
69#endif
70}
71
72// XServiceInfo
73
75{
76 return "com.sun.star.comp.stoc.CoreReflection";
77}
78
80{
81 return cppu::supportsService(this, rServiceName);
82}
83
85{
86 Sequence< OUString > seqNames { "com.sun.star.reflection.CoreReflection" };
87 return seqNames;
88}
89
90// XIdlReflection
91
92Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj )
93{
94 return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >());
95}
96
97
98inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass(
99 typelib_TypeDescription * pTypeDescr )
100{
101 OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" );
102
103 switch (pTypeDescr->eTypeClass)
104 {
105 case typelib_TypeClass_VOID:
106 case typelib_TypeClass_CHAR:
107 case typelib_TypeClass_BOOLEAN:
108 case typelib_TypeClass_BYTE:
109 case typelib_TypeClass_SHORT:
110 case typelib_TypeClass_UNSIGNED_SHORT:
111 case typelib_TypeClass_LONG:
112 case typelib_TypeClass_UNSIGNED_LONG:
113 case typelib_TypeClass_HYPER:
114 case typelib_TypeClass_UNSIGNED_HYPER:
115 case typelib_TypeClass_FLOAT:
116 case typelib_TypeClass_DOUBLE:
117 case typelib_TypeClass_STRING:
118 case typelib_TypeClass_ANY:
119 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
120
121 case typelib_TypeClass_ENUM:
122 return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
123
124 case typelib_TypeClass_STRUCT:
125 case typelib_TypeClass_EXCEPTION:
126 return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
127
128 case typelib_TypeClass_SEQUENCE:
129 return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
130
131 case typelib_TypeClass_INTERFACE:
132 return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
133
134 case typelib_TypeClass_TYPE:
135 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
136
137 default:
138 SAL_INFO("stoc", "corereflection type unsupported: " << pTypeDescr->pTypeName);
139 return Reference< XIdlClass >();
140 }
141}
142
143Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName )
144{
145 Reference< XIdlClass > xRet;
146 Any aAny( _aElements.getValue( rTypeName ) );
147
148 if (aAny.hasValue())
149 {
150 aAny >>= xRet;
151 }
152 else
153 {
154 // try to get _type_ by name
155 typelib_TypeDescription * pTD = nullptr;
156 typelib_typedescription_getByName( &pTD, rTypeName.pData );
157 if (pTD)
158 {
159 xRet = constructClass( pTD );
160 if (xRet.is())
161 _aElements.setValue( rTypeName, Any( xRet ) ); // update
163 }
164 }
165
166 return xRet;
167}
168
169// XHierarchicalNameAccess
170
172{
173 Any aRet( _aElements.getValue( rName ) );
174 if (! aRet.hasValue())
175 {
176 aRet = _xTDMgr->getByHierarchicalName( rName );
177 if (aRet.getValueTypeClass() == TypeClass_INTERFACE)
178 {
179 // type retrieved from tdmgr
180 OSL_ASSERT( (*o3tl::forceAccess<Reference<XInterface>>(aRet))->queryInterface(
182
183 css::uno::Reference< css::reflection::XConstantTypeDescription >
184 ctd;
185 if (aRet >>= ctd)
186 {
187 aRet = ctd->getConstantValue();
188 }
189 else
190 {
191 // if you are interested in a type then CALL forName()!!!
192 // this way is NOT recommended for types, because this method looks for constants first
193
194 // if td manager found some type, it will be in the cache (hopefully... we just got it)
195 // so the second retrieving via c typelib callback chain should succeed...
196
197 // try to get _type_ by name
198 typelib_TypeDescription * pTD = nullptr;
199 typelib_typedescription_getByName( &pTD, rName.pData );
200
201 aRet.clear(); // kick XTypeDescription interface
202
203 if (pTD)
204 {
205 Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
206 aRet.setValue( &xIdlClass, cppu::UnoType<XIdlClass>::get());
208 }
209 }
210 }
211 // else is enum member(?)
212
213 // update
214 if (!aRet.hasValue())
215 throw container::NoSuchElementException( rName );
216
217 _aElements.setValue( rName, aRet );
218 }
219 return aRet;
220}
221
223{
224 try
225 {
226 return getByHierarchicalName( rName ).hasValue();
227 }
228 catch (container::NoSuchElementException &)
229 {
230 }
231 return false;
232}
233
234
235Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr )
236{
237 Reference< XIdlClass > xRet;
238 OUString aName( pTypeDescr->pTypeName );
239 Any aAny( _aElements.getValue( aName ) );
240
241 if (aAny.hasValue())
242 {
243 aAny >>= xRet;
244 }
245 else
246 {
247 xRet = constructClass( pTypeDescr );
248 if (xRet.is())
249 _aElements.setValue( aName, Any( xRet ) ); // update
250 }
251
252 return xRet;
253}
254
255Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef )
256{
257 typelib_TypeDescription * pTD = nullptr;
258 TYPELIB_DANGER_GET( &pTD, pRef );
259 if (pTD)
260 {
261 Reference< XIdlClass > xRet = forType( pTD );
262 TYPELIB_DANGER_RELEASE( pTD );
263 return xRet;
264 }
265 throw RuntimeException(
266 "IdlReflectionServiceImpl::forType() failed!",
267 getXWeak() );
268}
269
270
272{
273 if (! _aCpp2Uno.is())
274 {
275 MutexGuard aGuard( getMutexAccess() );
276 if (! _aCpp2Uno.is())
277 {
278 _aCpp2Uno = Mapping( CPPU_CURRENT_LANGUAGE_BINDING_NAME, UNO_LB_UNO );
279 OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" );
280 if (! _aCpp2Uno.is())
281 {
282 throw RuntimeException(
283 "cannot get c++ to uno mapping!",
284 getXWeak() );
285 }
286 }
287 }
288 return _aCpp2Uno;
289}
290
292{
293 if (! _aUno2Cpp.is())
294 {
295 MutexGuard aGuard( getMutexAccess() );
296 if (! _aUno2Cpp.is())
297 {
298 _aUno2Cpp = Mapping( UNO_LB_UNO, CPPU_CURRENT_LANGUAGE_BINDING_NAME );
299 OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" );
300 if (! _aUno2Cpp.is())
301 {
302 throw RuntimeException(
303 "cannot get uno to c++ mapping!",
304 getXWeak() );
305 }
306 }
307 }
308 return _aUno2Cpp;
309}
310
312 const Any & rObj, typelib_InterfaceTypeDescription * pTo )
313{
314 Reference< XInterface > xObj;
315 if (extract( rObj, pTo, xObj, this ))
316 return static_cast<uno_Interface *>(getCpp2Uno().mapInterface( xObj.get(), pTo ));
317
318 throw RuntimeException(
319 "illegal object given!",
320 getXWeak() );
321}
322
323}
324
325
326extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
328 css::uno::XComponentContext * context,
329 css::uno::Sequence<css::uno::Any> const & arguments)
330{
332 arguments.hasElements(), "stoc", "unexpected singleton arguments");
333 return cppu::acquire(new stoc_corefl::IdlReflectionServiceImpl(context));
334}
335
336/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void clear()
Clears the cache, thus releasing all cached elements and keys.
Definition: lrucache.hxx:185
void setValue(const t_Key &rKey, const t_Val &rValue)
Sets a value to be cached for given key.
Definition: lrucache.hxx:146
t_Val getValue(const t_Key &rKey) const
Retrieves a value from the cache.
Definition: lrucache.hxx:127
LRU_CacheAnyByOUString _aElements
Definition: base.hxx:86
virtual sal_Bool SAL_CALL hasByHierarchicalName(const OUString &rName) override
Definition: crefl.cxx:222
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: crefl.cxx:79
virtual ~IdlReflectionServiceImpl() override
Definition: crefl.cxx:55
uno_Interface * mapToUno(const css::uno::Any &rObj, typelib_InterfaceTypeDescription *pTo)
Definition: crefl.cxx:311
virtual css::uno::Any SAL_CALL getByHierarchicalName(const OUString &rName) override
Definition: crefl.cxx:171
virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL getType(const css::uno::Any &rObj) override
Definition: crefl.cxx:92
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: crefl.cxx:84
IdlReflectionServiceImpl(const css::uno::Reference< css::uno::XComponentContext > &xContext)
Definition: crefl.cxx:46
virtual css::uno::Reference< css::reflection::XIdlClass > SAL_CALL forName(const OUString &rTypeName) override
Definition: crefl.cxx:143
css::uno::Reference< css::reflection::XIdlClass > constructClass(typelib_TypeDescription *pTypeDescr)
Definition: crefl.cxx:98
const css::uno::Mapping & getCpp2Uno()
Definition: crefl.cxx:271
css::uno::Reference< css::reflection::XIdlClass > forType(typelib_TypeDescription *pTypeDescr)
Definition: crefl.cxx:235
css::uno::Reference< css::container::XHierarchicalNameAccess > _xTDMgr
Definition: base.hxx:83
virtual OUString SAL_CALL getImplementationName() override
Definition: crefl.cxx:74
const css::uno::Mapping & getUno2Cpp()
Definition: crefl.cxx:291
virtual void SAL_CALL disposing() override
Definition: crefl.cxx:59
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_CoreReflection_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &arguments)
Definition: crefl.cxx:327
OUString aName
Definition: invocation.cxx:689
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
struct _typelib_TypeDescription typelib_TypeDescription
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
detail::Optional< T >::type forceAccess(css::uno::Any const &any)
::osl::Mutex & getMutexAccess()
Definition: crbase.cxx:37
bool extract(const css::uno::Any &rObj, typelib_InterfaceTypeDescription *pTo, css::uno::Reference< css::uno::XInterface > &rDest, IdlReflectionServiceImpl *pRefl)
Definition: base.hxx:335
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescription_getByName(typelib_TypeDescription **ppRet, rtl_uString *pName) SAL_THROW_EXTERN_C()
unsigned char sal_Bool