1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
33 using namespace css::uno
;
34 using namespace css::lang
;
35 using namespace css::reflection
;
46 IdlReflectionServiceImpl::IdlReflectionServiceImpl(
47 const Reference
< XComponentContext
> & xContext
)
48 : OComponentHelper( _aComponentMutex
)
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() {}
60 Any
IdlReflectionServiceImpl::queryInterface( const Type
& rType
)
62 Any
aRet( ::cppu::queryInterface(
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();
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
>();
101 void IdlReflectionServiceImpl::dispose()
103 OComponentHelper::dispose();
105 MutexGuard
aGuard( _aComponentMutex
);
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
);
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" };
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
);
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
) );
198 // try to get _type_ by name
199 typelib_TypeDescription
* pTD
= nullptr;
200 typelib_typedescription_getByName( &pTD
, rTypeName
.pData
);
203 xRet
= constructClass( pTD
);
205 _aElements
.setValue( rTypeName
, makeAny( xRet
) ); // update
206 typelib_typedescription_release( pTD
);
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
>
231 aRet
= ctd
->getConstantValue();
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
249 Reference
< XIdlClass
> xIdlClass( constructClass( pTD
) );
250 aRet
.setValue( &xIdlClass
, cppu::UnoType
<XIdlClass
>::get());
251 typelib_typedescription_release( pTD
);
255 // else is enum member(?)
258 if (!aRet
.hasValue())
259 throw container::NoSuchElementException( rName
);
261 _aElements
.setValue( rName
, aRet
);
266 sal_Bool
IdlReflectionServiceImpl::hasByHierarchicalName( const OUString
& rName
)
270 return getByHierarchicalName( rName
).hasValue();
272 catch (container::NoSuchElementException
&)
279 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescription
* pTypeDescr
)
281 Reference
< XIdlClass
> xRet
;
282 OUString
aName( pTypeDescr
->pTypeName
);
283 Any
aAny( _aElements
.getValue( aName
) );
291 xRet
= constructClass( pTypeDescr
);
293 _aElements
.setValue( aName
, makeAny( xRet
) ); // update
299 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference
* pRef
)
301 typelib_TypeDescription
* pTD
= nullptr;
302 TYPELIB_DANGER_GET( &pTD
, pRef
);
305 Reference
< XIdlClass
> xRet
= forType( pTD
);
306 TYPELIB_DANGER_RELEASE( pTD
);
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)) );
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)) );
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)) );
374 css::uno::Reference
<css::uno::XComponentContext
> const & context
):
375 instance(new stoc_corefl::IdlReflectionServiceImpl(context
))
378 rtl::Reference
<cppu::OWeakObject
> instance
;
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
)
394 arguments
.hasElements(), "stoc", "unexpected singleton arguments");
395 return cppu::acquire(Singleton::get(context
).instance
.get());
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */