nss: upgrade to release 3.73
[LibreOffice.git] / stoc / source / corereflection / crefl.cxx
blobe4f879495c3f07a061d7b8f54414782200b463a9
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>
32 using namespace css;
33 using namespace css::uno;
34 using namespace css::lang;
35 using namespace css::reflection;
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_aTypes(
86 cppu::UnoType<XIdlReflection>::get(),
87 cppu::UnoType<XHierarchicalNameAccess>::get(),
88 cppu::UnoType<XServiceInfo>::get(),
89 OComponentHelper::getTypes() );
91 return s_aTypes.getTypes();
94 Sequence< sal_Int8 > IdlReflectionServiceImpl::getImplementationId()
96 return css::uno::Sequence<sal_Int8>();
99 // XComponent
101 void IdlReflectionServiceImpl::dispose()
103 OComponentHelper::dispose();
105 MutexGuard aGuard( _aComponentMutex );
106 _aElements.clear();
107 #ifdef TEST_LIST_CLASSES
108 OSL_ENSURE( g_aClassNames.empty(), "### idl classes still alive!" );
109 for (auto const& className : g_aClassNames)
111 OUString aName(className);
113 #endif
116 // XServiceInfo
118 OUString IdlReflectionServiceImpl::getImplementationName()
120 return "com.sun.star.comp.stoc.CoreReflection";
123 sal_Bool IdlReflectionServiceImpl::supportsService( const OUString & rServiceName )
125 return cppu::supportsService(this, rServiceName);
128 Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames()
130 Sequence< OUString > seqNames { "com.sun.star.reflection.CoreReflection" };
131 return seqNames;
134 // XIdlReflection
136 Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj )
138 return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >());
142 inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass(
143 typelib_TypeDescription * pTypeDescr )
145 OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" );
147 switch (pTypeDescr->eTypeClass)
149 case typelib_TypeClass_VOID:
150 case typelib_TypeClass_CHAR:
151 case typelib_TypeClass_BOOLEAN:
152 case typelib_TypeClass_BYTE:
153 case typelib_TypeClass_SHORT:
154 case typelib_TypeClass_UNSIGNED_SHORT:
155 case typelib_TypeClass_LONG:
156 case typelib_TypeClass_UNSIGNED_LONG:
157 case typelib_TypeClass_HYPER:
158 case typelib_TypeClass_UNSIGNED_HYPER:
159 case typelib_TypeClass_FLOAT:
160 case typelib_TypeClass_DOUBLE:
161 case typelib_TypeClass_STRING:
162 case typelib_TypeClass_ANY:
163 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
165 case typelib_TypeClass_ENUM:
166 return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
168 case typelib_TypeClass_STRUCT:
169 case typelib_TypeClass_EXCEPTION:
170 return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
172 case typelib_TypeClass_SEQUENCE:
173 return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
175 case typelib_TypeClass_INTERFACE:
176 return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
178 case typelib_TypeClass_TYPE:
179 return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
181 default:
182 SAL_INFO("stoc", "corereflection type unsupported: " << pTypeDescr->pTypeName);
183 return Reference< XIdlClass >();
187 Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName )
189 Reference< XIdlClass > xRet;
190 Any aAny( _aElements.getValue( rTypeName ) );
192 if (aAny.hasValue())
194 aAny >>= xRet;
196 else
198 // try to get _type_ by name
199 typelib_TypeDescription * pTD = nullptr;
200 typelib_typedescription_getByName( &pTD, rTypeName.pData );
201 if (pTD)
203 xRet = constructClass( pTD );
204 if (xRet.is())
205 _aElements.setValue( rTypeName, makeAny( xRet ) ); // update
206 typelib_typedescription_release( pTD );
210 return xRet;
213 // XHierarchicalNameAccess
215 Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName )
217 Any aRet( _aElements.getValue( rName ) );
218 if (! aRet.hasValue())
220 aRet = _xTDMgr->getByHierarchicalName( rName );
221 if (aRet.getValueTypeClass() == TypeClass_INTERFACE)
223 // type retrieved from tdmgr
224 OSL_ASSERT( (*o3tl::forceAccess<Reference<XInterface>>(aRet))->queryInterface(
225 cppu::UnoType<XTypeDescription>::get()).hasValue() );
227 css::uno::Reference< css::reflection::XConstantTypeDescription >
228 ctd;
229 if (aRet >>= ctd)
231 aRet = ctd->getConstantValue();
233 else
235 // if you are interested in a type then CALL forName()!!!
236 // this way is NOT recommended for types, because this method looks for constants first
238 // if td manager found some type, it will be in the cache (hopefully... we just got it)
239 // so the second retrieving via c typelib callback chain should succeed...
241 // try to get _type_ by name
242 typelib_TypeDescription * pTD = nullptr;
243 typelib_typedescription_getByName( &pTD, rName.pData );
245 aRet.clear(); // kick XTypeDescription interface
247 if (pTD)
249 Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
250 aRet.setValue( &xIdlClass, cppu::UnoType<XIdlClass>::get());
251 typelib_typedescription_release( pTD );
255 // else is enum member(?)
257 // update
258 if (!aRet.hasValue())
259 throw container::NoSuchElementException( rName );
261 _aElements.setValue( rName, aRet );
263 return aRet;
266 sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName )
270 return getByHierarchicalName( rName ).hasValue();
272 catch (container::NoSuchElementException &)
275 return false;
279 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr )
281 Reference< XIdlClass > xRet;
282 OUString aName( pTypeDescr->pTypeName );
283 Any aAny( _aElements.getValue( aName ) );
285 if (aAny.hasValue())
287 aAny >>= xRet;
289 else
291 xRet = constructClass( pTypeDescr );
292 if (xRet.is())
293 _aElements.setValue( aName, makeAny( xRet ) ); // update
296 return xRet;
299 Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef )
301 typelib_TypeDescription * pTD = nullptr;
302 TYPELIB_DANGER_GET( &pTD, pRef );
303 if (pTD)
305 Reference< XIdlClass > xRet = forType( pTD );
306 TYPELIB_DANGER_RELEASE( pTD );
307 return xRet;
309 throw RuntimeException(
310 "IdlReflectionServiceImpl::forType() failed!",
311 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
315 const Mapping & IdlReflectionServiceImpl::getCpp2Uno()
317 if (! _aCpp2Uno.is())
319 MutexGuard aGuard( getMutexAccess() );
320 if (! _aCpp2Uno.is())
322 _aCpp2Uno = Mapping( CPPU_CURRENT_LANGUAGE_BINDING_NAME, UNO_LB_UNO );
323 OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" );
324 if (! _aCpp2Uno.is())
326 throw RuntimeException(
327 "cannot get c++ to uno mapping!",
328 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
332 return _aCpp2Uno;
335 const Mapping & IdlReflectionServiceImpl::getUno2Cpp()
337 if (! _aUno2Cpp.is())
339 MutexGuard aGuard( getMutexAccess() );
340 if (! _aUno2Cpp.is())
342 _aUno2Cpp = Mapping( UNO_LB_UNO, CPPU_CURRENT_LANGUAGE_BINDING_NAME );
343 OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" );
344 if (! _aUno2Cpp.is())
346 throw RuntimeException(
347 "cannot get uno to c++ mapping!",
348 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
352 return _aUno2Cpp;
355 uno_Interface * IdlReflectionServiceImpl::mapToUno(
356 const Any & rObj, typelib_InterfaceTypeDescription * pTo )
358 Reference< XInterface > xObj;
359 if (extract( rObj, pTo, xObj, this ))
360 return static_cast<uno_Interface *>(getCpp2Uno().mapInterface( xObj.get(), pTo ));
362 throw RuntimeException(
363 "illegal object given!",
364 static_cast<XWeak *>(static_cast<OWeakObject *>(this)) );
370 namespace {
372 struct Instance {
373 explicit Instance(
374 css::uno::Reference<css::uno::XComponentContext> const & context):
375 instance(new stoc_corefl::IdlReflectionServiceImpl(context))
378 rtl::Reference<cppu::OWeakObject> instance;
381 struct Singleton:
382 public rtl::StaticWithArg<
383 Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
388 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
389 com_sun_star_comp_stoc_CoreReflection_get_implementation(
390 css::uno::XComponentContext * context,
391 css::uno::Sequence<css::uno::Any> const & arguments)
393 SAL_WARN_IF(
394 arguments.hasElements(), "stoc", "unexpected singleton arguments");
395 return cppu::acquire(Singleton::get(context).instance.get());
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */