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/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>
32 using namespace css::uno
;
33 using namespace css::lang
;
34 using namespace css::reflection
;
35 using namespace css::registry
;
46 #define IMPLNAME "com.sun.star.comp.stoc.CoreReflection"
48 static Sequence
< OUString
> core_getSupportedServiceNames()
50 Sequence
< OUString
> seqNames
{ "com.sun.star.reflection.CoreReflection" };
54 static OUString
core_getImplementationName()
56 return OUString(IMPLNAME
);
59 IdlReflectionServiceImpl::IdlReflectionServiceImpl(
60 const Reference
< XComponentContext
> & xContext
)
61 : OComponentHelper( _aComponentMutex
)
64 xContext
->getValueByName(
65 "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) >>= _xTDMgr
;
66 OSL_ENSURE( _xTDMgr
.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
69 IdlReflectionServiceImpl::~IdlReflectionServiceImpl() {}
73 Any
IdlReflectionServiceImpl::queryInterface( const Type
& rType
)
75 Any
aRet( ::cppu::queryInterface(
77 static_cast< XIdlReflection
* >( this ),
78 static_cast< XHierarchicalNameAccess
* >( this ),
79 static_cast< XServiceInfo
* >( this ) ) );
81 return (aRet
.hasValue() ? aRet
: OComponentHelper::queryInterface( rType
));
84 void IdlReflectionServiceImpl::acquire() throw()
86 OComponentHelper::acquire();
89 void IdlReflectionServiceImpl::release() throw()
91 OComponentHelper::release();
96 Sequence
< Type
> IdlReflectionServiceImpl::getTypes()
98 static OTypeCollection
* s_pTypes
= nullptr;
101 MutexGuard
aGuard( _aComponentMutex
);
104 static OTypeCollection
s_aTypes(
105 cppu::UnoType
<XIdlReflection
>::get(),
106 cppu::UnoType
<XHierarchicalNameAccess
>::get(),
107 cppu::UnoType
<XServiceInfo
>::get(),
108 OComponentHelper::getTypes() );
109 s_pTypes
= &s_aTypes
;
112 return s_pTypes
->getTypes();
115 Sequence
< sal_Int8
> IdlReflectionServiceImpl::getImplementationId()
117 return css::uno::Sequence
<sal_Int8
>();
122 void IdlReflectionServiceImpl::dispose()
124 OComponentHelper::dispose();
126 MutexGuard
aGuard( _aComponentMutex
);
128 #ifdef TEST_LIST_CLASSES
129 OSL_ENSURE( g_aClassNames
.empty(), "### idl classes still alive!" );
130 ClassNameList::const_iterator
iPos( g_aClassNames
.begin() );
131 while (iPos
!= g_aClassNames
.end())
133 OUString
aName( *iPos
);
141 OUString
IdlReflectionServiceImpl::getImplementationName()
143 return core_getImplementationName();
146 sal_Bool
IdlReflectionServiceImpl::supportsService( const OUString
& rServiceName
)
148 return cppu::supportsService(this, rServiceName
);
151 Sequence
< OUString
> IdlReflectionServiceImpl::getSupportedServiceNames()
153 return core_getSupportedServiceNames();
158 Reference
< XIdlClass
> IdlReflectionServiceImpl::getType( const Any
& rObj
)
160 return (rObj
.hasValue() ? forType( rObj
.getValueTypeRef() ) : Reference
< XIdlClass
>());
164 inline Reference
< XIdlClass
> IdlReflectionServiceImpl::constructClass(
165 typelib_TypeDescription
* pTypeDescr
)
167 OSL_ENSURE( pTypeDescr
->eTypeClass
!= typelib_TypeClass_TYPEDEF
, "### unexpected typedef!" );
169 switch (pTypeDescr
->eTypeClass
)
171 case typelib_TypeClass_VOID
:
172 case typelib_TypeClass_CHAR
:
173 case typelib_TypeClass_BOOLEAN
:
174 case typelib_TypeClass_BYTE
:
175 case typelib_TypeClass_SHORT
:
176 case typelib_TypeClass_UNSIGNED_SHORT
:
177 case typelib_TypeClass_LONG
:
178 case typelib_TypeClass_UNSIGNED_LONG
:
179 case typelib_TypeClass_HYPER
:
180 case typelib_TypeClass_UNSIGNED_HYPER
:
181 case typelib_TypeClass_FLOAT
:
182 case typelib_TypeClass_DOUBLE
:
183 case typelib_TypeClass_STRING
:
184 case typelib_TypeClass_ANY
:
185 return new IdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
187 case typelib_TypeClass_ENUM
:
188 return new EnumIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
190 case typelib_TypeClass_STRUCT
:
191 case typelib_TypeClass_EXCEPTION
:
192 return new CompoundIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
194 case typelib_TypeClass_SEQUENCE
:
195 return new ArrayIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
197 case typelib_TypeClass_INTERFACE
:
198 return new InterfaceIdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
200 case typelib_TypeClass_TYPE
:
201 return new IdlClassImpl( this, pTypeDescr
->pTypeName
, pTypeDescr
->eTypeClass
, pTypeDescr
);
204 SAL_INFO("stoc", "corereflection type unsupported: " << pTypeDescr
->pTypeName
);
205 return Reference
< XIdlClass
>();
209 Reference
< XIdlClass
> IdlReflectionServiceImpl::forName( const OUString
& rTypeName
)
211 Reference
< XIdlClass
> xRet
;
212 Any
aAny( _aElements
.getValue( rTypeName
) );
220 // try to get _type_ by name
221 typelib_TypeDescription
* pTD
= nullptr;
222 typelib_typedescription_getByName( &pTD
, rTypeName
.pData
);
225 if ((xRet
= constructClass( pTD
)).is())
226 _aElements
.setValue( rTypeName
, makeAny( xRet
) ); // update
227 typelib_typedescription_release( pTD
);
234 // XHierarchicalNameAccess
236 Any
IdlReflectionServiceImpl::getByHierarchicalName( const OUString
& rName
)
238 Any
aRet( _aElements
.getValue( rName
) );
239 if (! aRet
.hasValue())
241 aRet
= _xTDMgr
->getByHierarchicalName( rName
);
242 if (aRet
.getValueTypeClass() == TypeClass_INTERFACE
)
244 // type retrieved from tdmgr
245 OSL_ASSERT( (*o3tl::forceAccess
<Reference
<XInterface
>>(aRet
))->queryInterface(
246 cppu::UnoType
<XTypeDescription
>::get()).hasValue() );
248 css::uno::Reference
< css::reflection::XConstantTypeDescription
>
252 aRet
= ctd
->getConstantValue();
256 // if you are interested in a type then CALL forName()!!!
257 // this way is NOT recommended for types, because this method looks for constants first
259 // if td manager found some type, it will be in the cache (hopefully.. we just got it)
260 // so the second retrieving via c typelib callback chain should succeed...
262 // try to get _type_ by name
263 typelib_TypeDescription
* pTD
= nullptr;
264 typelib_typedescription_getByName( &pTD
, rName
.pData
);
266 aRet
.clear(); // kick XTypeDescription interface
270 Reference
< XIdlClass
> xIdlClass( constructClass( pTD
) );
271 aRet
.setValue( &xIdlClass
, cppu::UnoType
<XIdlClass
>::get());
272 typelib_typedescription_release( pTD
);
276 // else is enum member(?)
280 _aElements
.setValue( rName
, aRet
);
283 throw container::NoSuchElementException( rName
);
289 sal_Bool
IdlReflectionServiceImpl::hasByHierarchicalName( const OUString
& rName
)
293 return getByHierarchicalName( rName
).hasValue();
295 catch (container::NoSuchElementException
&)
302 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescription
* pTypeDescr
)
304 Reference
< XIdlClass
> xRet
;
305 OUString
aName( pTypeDescr
->pTypeName
);
306 Any
aAny( _aElements
.getValue( aName
) );
314 if ((xRet
= constructClass( pTypeDescr
)).is())
315 _aElements
.setValue( aName
, makeAny( xRet
) ); // update
321 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference
* pRef
)
323 typelib_TypeDescription
* pTD
= nullptr;
324 TYPELIB_DANGER_GET( &pTD
, pRef
);
327 Reference
< XIdlClass
> xRet
= forType( pTD
);
328 TYPELIB_DANGER_RELEASE( pTD
);
331 throw RuntimeException(
332 "IdlReflectionServiceImpl::forType() failed!",
333 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)) );
337 const Mapping
& IdlReflectionServiceImpl::getCpp2Uno()
339 if (! _aCpp2Uno
.is())
341 MutexGuard
aGuard( getMutexAccess() );
342 if (! _aCpp2Uno
.is())
345 OUString( CPPU_CURRENT_LANGUAGE_BINDING_NAME
),
346 OUString( UNO_LB_UNO
) );
347 OSL_ENSURE( _aCpp2Uno
.is(), "### cannot get c++ to uno mapping!" );
348 if (! _aCpp2Uno
.is())
350 throw RuntimeException(
351 "cannot get c++ to uno mapping!",
352 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)) );
359 const Mapping
& IdlReflectionServiceImpl::getUno2Cpp()
361 if (! _aUno2Cpp
.is())
363 MutexGuard
aGuard( getMutexAccess() );
364 if (! _aUno2Cpp
.is())
367 OUString( UNO_LB_UNO
),
368 OUString( CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
369 OSL_ENSURE( _aUno2Cpp
.is(), "### cannot get uno to c++ mapping!" );
370 if (! _aUno2Cpp
.is())
372 throw RuntimeException(
373 "cannot get uno to c++ mapping!",
374 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)) );
381 uno_Interface
* IdlReflectionServiceImpl::mapToUno(
382 const Any
& rObj
, typelib_InterfaceTypeDescription
* pTo
)
384 Reference
< XInterface
> xObj
;
385 if (extract( rObj
, pTo
, xObj
, this ))
386 return static_cast<uno_Interface
*>(getCpp2Uno().mapInterface( xObj
.get(), pTo
));
388 throw RuntimeException(
389 "illegal object given!",
390 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)) );
393 /// @throws css::uno::Exception
394 Reference
< XInterface
> SAL_CALL
IdlReflectionServiceImpl_create(
395 const Reference
< XComponentContext
> & xContext
)
397 return Reference
< XInterface
>( static_cast<XWeak
*>(static_cast<OWeakObject
*>(new IdlReflectionServiceImpl( xContext
))) );
403 using namespace stoc_corefl
;
405 static const struct ImplementationEntry g_entries
[] =
408 IdlReflectionServiceImpl_create
, core_getImplementationName
,
409 core_getSupportedServiceNames
, createSingleComponentFactory
,
412 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
415 extern "C" SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
reflection_component_getFactory(
416 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
418 return component_getFactoryHelper( pImplName
, pServiceManager
, pRegistryKey
, g_entries
);
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */