cid#1636693 COPY_INSTEAD_OF_MOVE
[LibreOffice.git] / stoc / source / corereflection / crefl.cxx
blobf9ca56720fed58170e583614fb76083f8f9db28a
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/supportsservice.hxx>
22 #include <cppuhelper/typeprovider.hxx>
23 #include <sal/log.hxx>
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 #include "base.hxx"
33 using namespace css;
34 using namespace css::uno;
35 using namespace css::lang;
36 using namespace css::reflection;
37 using namespace cppu;
38 using namespace osl;
40 namespace stoc_corefl
43 IdlReflectionServiceImpl::IdlReflectionServiceImpl(
44 const Reference< XComponentContext > & xContext )
45 : WeakComponentImplHelper( _aComponentMutex )
47 xContext->getValueByName(
48 u"/singletons/com.sun.star.reflection.theTypeDescriptionManager"_ustr ) >>= _xTDMgr;
49 OSL_ENSURE( _xTDMgr.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
52 IdlReflectionServiceImpl::~IdlReflectionServiceImpl() {}
54 // XComponent
56 void IdlReflectionServiceImpl::disposing()
58 MutexGuard aGuard( _aComponentMutex );
59 _aElements.clear();
60 #ifdef TEST_LIST_CLASSES
61 OSL_ENSURE( g_aClassNames.empty(), "### idl classes still alive!" );
62 for (auto const& className : g_aClassNames)
64 OUString aName(className);
66 #endif
69 // XServiceInfo
71 OUString IdlReflectionServiceImpl::getImplementationName()
73 return u"com.sun.star.comp.stoc.CoreReflection"_ustr;
76 sal_Bool IdlReflectionServiceImpl::supportsService( const OUString & rServiceName )
78 return cppu::supportsService(this, rServiceName);
81 Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames()
83 Sequence< OUString > seqNames { u"com.sun.star.reflection.CoreReflection"_ustr };
84 return seqNames;
87 // XIdlReflection
89 Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj )
91 return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >());
95 inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass(
96 typelib_TypeDescription * pTypeDescr )
98 OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" );
100 switch (pTypeDescr->eTypeClass)
102 case typelib_TypeClass_VOID:
103 case typelib_TypeClass_CHAR:
104 case typelib_TypeClass_BOOLEAN:
105 case typelib_TypeClass_BYTE:
106 case typelib_TypeClass_SHORT:
107 case typelib_TypeClass_UNSIGNED_SHORT:
108 case typelib_TypeClass_LONG:
109 case typelib_TypeClass_UNSIGNED_LONG:
110 case typelib_TypeClass_HYPER:
111 case typelib_TypeClass_UNSIGNED_HYPER:
112 case typelib_TypeClass_FLOAT:
113 case typelib_TypeClass_DOUBLE:
114 case typelib_TypeClass_STRING:
115 case typelib_TypeClass_ANY:
116 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
118 case typelib_TypeClass_ENUM:
119 return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
121 case typelib_TypeClass_STRUCT:
122 case typelib_TypeClass_EXCEPTION:
123 return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
125 case typelib_TypeClass_SEQUENCE:
126 return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
128 case typelib_TypeClass_INTERFACE:
129 return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
131 case typelib_TypeClass_TYPE:
132 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
134 default:
135 SAL_INFO("stoc", "corereflection type unsupported: " << pTypeDescr->pTypeName);
136 return Reference< XIdlClass >();
140 Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName )
142 Reference< XIdlClass > xRet;
143 Any aAny( _aElements.getValue( rTypeName ) );
145 if (aAny.hasValue())
147 aAny >>= xRet;
149 else
151 // try to get _type_ by name
152 typelib_TypeDescription * pTD = nullptr;
153 typelib_typedescription_getByName( &pTD, rTypeName.pData );
154 if (pTD)
156 xRet = constructClass( pTD );
157 if (xRet.is())
158 _aElements.setValue( rTypeName, Any( xRet ) ); // update
159 typelib_typedescription_release( pTD );
163 return xRet;
166 // XHierarchicalNameAccess
168 Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName )
170 Any aRet( _aElements.getValue( rName ) );
171 if (! aRet.hasValue())
173 aRet = _xTDMgr->getByHierarchicalName( rName );
174 if (aRet.getValueTypeClass() == TypeClass_INTERFACE)
176 // type retrieved from tdmgr
177 OSL_ASSERT( (*o3tl::forceAccess<Reference<XInterface>>(aRet))->queryInterface(
178 cppu::UnoType<XTypeDescription>::get()).hasValue() );
180 css::uno::Reference< css::reflection::XConstantTypeDescription >
181 ctd;
182 if (aRet >>= ctd)
184 aRet = ctd->getConstantValue();
186 else
188 // if you are interested in a type then CALL forName()!!!
189 // this way is NOT recommended for types, because this method looks for constants first
191 // if td manager found some type, it will be in the cache (hopefully... we just got it)
192 // so the second retrieving via c typelib callback chain should succeed...
194 // try to get _type_ by name
195 typelib_TypeDescription * pTD = nullptr;
196 typelib_typedescription_getByName( &pTD, rName.pData );
198 aRet.clear(); // kick XTypeDescription interface
200 if (pTD)
202 Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
203 aRet.setValue( &xIdlClass, cppu::UnoType<XIdlClass>::get());
204 typelib_typedescription_release( pTD );
208 // else is enum member(?)
210 // update
211 if (!aRet.hasValue())
212 throw container::NoSuchElementException( rName );
214 _aElements.setValue( rName, aRet );
216 return aRet;
219 sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName )
223 return getByHierarchicalName( rName ).hasValue();
225 catch (container::NoSuchElementException &)
228 return false;
232 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr )
234 Reference< XIdlClass > xRet;
235 OUString aName( pTypeDescr->pTypeName );
236 Any aAny( _aElements.getValue( aName ) );
238 if (aAny.hasValue())
240 aAny >>= xRet;
242 else
244 xRet = constructClass( pTypeDescr );
245 if (xRet.is())
246 _aElements.setValue( aName, Any( xRet ) ); // update
249 return xRet;
252 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef )
254 typelib_TypeDescription * pTD = nullptr;
255 TYPELIB_DANGER_GET( &pTD, pRef );
256 if (pTD)
258 Reference< XIdlClass > xRet = forType( pTD );
259 TYPELIB_DANGER_RELEASE( pTD );
260 return xRet;
262 throw RuntimeException(
263 u"IdlReflectionServiceImpl::forType() failed!"_ustr,
264 getXWeak() );
268 const Mapping & IdlReflectionServiceImpl::getCpp2Uno()
270 if (! _aCpp2Uno.is())
272 MutexGuard aGuard( getMutexAccess() );
273 if (! _aCpp2Uno.is())
275 _aCpp2Uno = Mapping( CPPU_CURRENT_LANGUAGE_BINDING_NAME, u"" UNO_LB_UNO ""_ustr );
276 OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" );
277 if (! _aCpp2Uno.is())
279 throw RuntimeException(
280 u"cannot get c++ to uno mapping!"_ustr,
281 getXWeak() );
285 return _aCpp2Uno;
288 const Mapping & IdlReflectionServiceImpl::getUno2Cpp()
290 if (! _aUno2Cpp.is())
292 MutexGuard aGuard( getMutexAccess() );
293 if (! _aUno2Cpp.is())
295 _aUno2Cpp = Mapping( u"" UNO_LB_UNO ""_ustr, CPPU_CURRENT_LANGUAGE_BINDING_NAME );
296 OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" );
297 if (! _aUno2Cpp.is())
299 throw RuntimeException(
300 u"cannot get uno to c++ mapping!"_ustr,
301 getXWeak() );
305 return _aUno2Cpp;
308 uno_Interface * IdlReflectionServiceImpl::mapToUno(
309 const Any & rObj, typelib_InterfaceTypeDescription * pTo )
311 Reference< XInterface > xObj;
312 if (extract( rObj, pTo, xObj, this ))
313 return static_cast<uno_Interface *>(getCpp2Uno().mapInterface( xObj.get(), pTo ));
315 throw RuntimeException(
316 u"illegal object given!"_ustr,
317 getXWeak() );
323 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
324 com_sun_star_comp_stoc_CoreReflection_get_implementation(
325 css::uno::XComponentContext * context,
326 css::uno::Sequence<css::uno::Any> const & arguments)
328 SAL_WARN_IF(
329 arguments.hasElements(), "stoc", "unexpected singleton arguments");
330 return cppu::acquire(new stoc_corefl::IdlReflectionServiceImpl(context));
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */