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>
34 using namespace css::uno
;
35 using namespace css::lang
;
36 using namespace css::reflection
;
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() {}
56 void IdlReflectionServiceImpl::disposing()
58 MutexGuard
aGuard( _aComponentMutex
);
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
);
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
};
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
);
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
) );
151 // try to get _type_ by name
152 typelib_TypeDescription
* pTD
= nullptr;
153 typelib_typedescription_getByName( &pTD
, rTypeName
.pData
);
156 xRet
= constructClass( pTD
);
158 _aElements
.setValue( rTypeName
, Any( xRet
) ); // update
159 typelib_typedescription_release( pTD
);
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
>
184 aRet
= ctd
->getConstantValue();
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
202 Reference
< XIdlClass
> xIdlClass( constructClass( pTD
) );
203 aRet
.setValue( &xIdlClass
, cppu::UnoType
<XIdlClass
>::get());
204 typelib_typedescription_release( pTD
);
208 // else is enum member(?)
211 if (!aRet
.hasValue())
212 throw container::NoSuchElementException( rName
);
214 _aElements
.setValue( rName
, aRet
);
219 sal_Bool
IdlReflectionServiceImpl::hasByHierarchicalName( const OUString
& rName
)
223 return getByHierarchicalName( rName
).hasValue();
225 catch (container::NoSuchElementException
&)
232 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescription
* pTypeDescr
)
234 Reference
< XIdlClass
> xRet
;
235 OUString
aName( pTypeDescr
->pTypeName
);
236 Any
aAny( _aElements
.getValue( aName
) );
244 xRet
= constructClass( pTypeDescr
);
246 _aElements
.setValue( aName
, Any( xRet
) ); // update
252 Reference
< XIdlClass
> IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference
* pRef
)
254 typelib_TypeDescription
* pTD
= nullptr;
255 TYPELIB_DANGER_GET( &pTD
, pRef
);
258 Reference
< XIdlClass
> xRet
= forType( pTD
);
259 TYPELIB_DANGER_RELEASE( pTD
);
262 throw RuntimeException(
263 u
"IdlReflectionServiceImpl::forType() failed!"_ustr
,
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
,
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
,
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
,
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
)
329 arguments
.hasElements(), "stoc", "unexpected singleton arguments");
330 return cppu::acquire(new stoc_corefl::IdlReflectionServiceImpl(context
));
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */