Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : // #define TEST_LIST_CLASSES
20 :
21 : #include <osl/diagnose.h>
22 : #include <osl/mutex.hxx>
23 : #include <uno/mapping.hxx>
24 : #include <uno/dispatcher.h>
25 : #include <cppuhelper/weak.hxx>
26 : #include <cppuhelper/factory.hxx>
27 : #include <cppuhelper/component.hxx>
28 : #include <cppuhelper/typeprovider.hxx>
29 :
30 : #include "lrucache.hxx"
31 :
32 : #ifdef TEST_LIST_CLASSES
33 : #include <list>
34 : #include <algorithm>
35 : #endif
36 : #include <boost/unordered_map.hpp>
37 :
38 : #include <com/sun/star/uno/XComponentContext.hpp>
39 : #include <com/sun/star/lang/XServiceInfo.hpp>
40 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
41 :
42 : #include <com/sun/star/reflection/XIdlClass.hpp>
43 : #include <com/sun/star/reflection/XIdlReflection.hpp>
44 : #include <com/sun/star/reflection/XIdlField.hpp>
45 : #include <com/sun/star/reflection/XIdlField2.hpp>
46 : #include <com/sun/star/reflection/XIdlMethod.hpp>
47 :
48 : using namespace std;
49 : using namespace osl;
50 : using namespace cppu;
51 : using namespace com::sun::star::uno;
52 : using namespace com::sun::star::lang;
53 : using namespace com::sun::star::reflection;
54 : using namespace com::sun::star::container;
55 : using ::rtl::OUString;
56 :
57 :
58 : namespace stoc_corefl
59 : {
60 :
61 : #ifdef TEST_LIST_CLASSES
62 : typedef list< OUString > ClassNameList;
63 : extern ClassNameList g_aClassNames;
64 : #endif
65 :
66 : //--------------------------------------------------------------------------------------------------
67 : Mutex & getMutexAccess();
68 :
69 : //--------------------------------------------------------------------------------------------------
70 0 : inline bool td_equals( typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
71 : {
72 : return (pTD->pWeakRef == pType ||
73 : (pTD->pTypeName->length == pType->pTypeName->length &&
74 0 : rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
75 : }
76 : //--------------------------------------------------------------------------------------------------
77 : inline typelib_TypeDescription * getTypeByName( const OUString & rName )
78 : {
79 : typelib_TypeDescription * pTypeDescr = 0;
80 : typelib_typedescription_getByName( &pTypeDescr, rName.pData );
81 : if (! pTypeDescr->bComplete)
82 : typelib_typedescription_complete( &pTypeDescr );
83 : return pTypeDescr;
84 : }
85 :
86 : typedef boost::unordered_map< OUString, WeakReference< XIdlField >,
87 : FctHashOUString, equal_to< OUString > > OUString2Field;
88 : typedef boost::unordered_map< OUString, WeakReference< XIdlMethod >,
89 : FctHashOUString, equal_to< OUString > > OUString2Method;
90 :
91 : //==================================================================================================
92 : class IdlReflectionServiceImpl
93 : : public OComponentHelper
94 : , public XIdlReflection
95 : , public XHierarchicalNameAccess
96 : , public XServiceInfo
97 : {
98 : Mutex _aComponentMutex;
99 : Reference< XMultiServiceFactory > _xMgr;
100 : Reference< XHierarchicalNameAccess > _xTDMgr;
101 :
102 : // caching
103 : LRU_CacheAnyByOUString _aElements;
104 :
105 : Mapping _aCpp2Uno;
106 : Mapping _aUno2Cpp;
107 :
108 : inline Reference< XIdlClass > constructClass( typelib_TypeDescription * pTypeDescr );
109 : public:
110 : Reference< XHierarchicalNameAccess > getTDMgr() const
111 : { return _xTDMgr; }
112 : Reference< XMultiServiceFactory > getSMgr() const
113 : { return _xMgr; }
114 :
115 : const Mapping & getCpp2Uno() throw(::com::sun::star::uno::RuntimeException);
116 : const Mapping & getUno2Cpp() throw(::com::sun::star::uno::RuntimeException);
117 : uno_Interface * mapToUno( const Any & rObj, typelib_InterfaceTypeDescription * pTo ) throw(::com::sun::star::uno::RuntimeException);
118 :
119 : // ctor/ dtor
120 : IdlReflectionServiceImpl( const Reference< XComponentContext > & xContext );
121 : virtual ~IdlReflectionServiceImpl();
122 :
123 : // XInterface
124 : virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
125 : virtual void SAL_CALL acquire() throw();
126 : virtual void SAL_CALL release() throw();
127 :
128 : // some XComponent part from OComponentHelper
129 : virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
130 :
131 : // XServiceInfo
132 : virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
133 : virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
134 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
135 :
136 : // XTypeProvider
137 : virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
138 : virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
139 :
140 : // XIdlReflection
141 : virtual Reference< XIdlClass > SAL_CALL forName( const OUString & rTypeName ) throw(::com::sun::star::uno::RuntimeException);
142 : virtual Reference< XIdlClass > SAL_CALL getType( const Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
143 :
144 : // XHierarchicalNameAccess
145 : virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
146 : virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
147 :
148 : Reference< XIdlClass > forType( typelib_TypeDescription * pTypeDescr ) throw(::com::sun::star::uno::RuntimeException);
149 : Reference< XIdlClass > forType( typelib_TypeDescriptionReference * pRef ) throw(::com::sun::star::uno::RuntimeException);
150 : };
151 :
152 : //==================================================================================================
153 : class IdlClassImpl
154 : : public WeakImplHelper1< XIdlClass >
155 : {
156 : IdlReflectionServiceImpl * _pReflection;
157 :
158 : OUString _aName;
159 : TypeClass _eTypeClass;
160 :
161 : typelib_TypeDescription * _pTypeDescr;
162 :
163 : public:
164 36120 : typelib_TypeDescription * getTypeDescr() const
165 36120 : { return _pTypeDescr; }
166 30715 : IdlReflectionServiceImpl * getReflection() const
167 30715 : { return _pReflection; }
168 : Reference< XMultiServiceFactory > getSMgr() const
169 : { return _pReflection->getSMgr(); }
170 : Reference< XHierarchicalNameAccess > getTDMgr() const
171 : { return getReflection()->getTDMgr(); }
172 :
173 : // Ctor
174 : IdlClassImpl( IdlReflectionServiceImpl * pReflection,
175 : const OUString & rName, typelib_TypeClass eTypeClass,
176 : typelib_TypeDescription * pTypeDescr );
177 : virtual ~IdlClassImpl();
178 :
179 : // XIdlClassImpl default implementation
180 : virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
181 : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
182 : virtual sal_Bool SAL_CALL equals( const Reference< XIdlClass >& xType ) throw(::com::sun::star::uno::RuntimeException);
183 :
184 : virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
185 : virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
186 :
187 : // def impl ????
188 : virtual Sequence< Reference< XIdlClass > > SAL_CALL getClasses() throw(::com::sun::star::uno::RuntimeException);
189 : virtual Reference< XIdlClass > SAL_CALL getClass( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
190 : virtual Sequence< Reference< XIdlClass > > SAL_CALL getInterfaces() throw(::com::sun::star::uno::RuntimeException);
191 :
192 : // structs, interfaces
193 : virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException);
194 : // structs
195 : virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
196 : virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
197 : // interfaces
198 : virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException);
199 : virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
200 : virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException);
201 : // array
202 : virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException);
203 : virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException);
204 : };
205 :
206 : //==================================================================================================
207 : class InterfaceIdlClassImpl
208 : : public IdlClassImpl
209 : {
210 : typedef pair< OUString, typelib_TypeDescription * > MemberInit;
211 :
212 : Sequence< Reference< XIdlClass > > _xSuperClasses;
213 :
214 : MemberInit * _pSortedMemberInit; // first methods, then attributes
215 : OUString2Field _aName2Field;
216 : OUString2Method _aName2Method;
217 : sal_Int32 _nMethods;
218 : sal_Int32 _nAttributes;
219 :
220 : void initMembers();
221 :
222 : public:
223 6439 : typelib_InterfaceTypeDescription * getTypeDescr() const
224 6439 : { return (typelib_InterfaceTypeDescription *)IdlClassImpl::getTypeDescr(); }
225 :
226 : // ctor/ dtor
227 2310 : InterfaceIdlClassImpl( IdlReflectionServiceImpl * pReflection,
228 : const OUString & rName, typelib_TypeClass eTypeClass,
229 : typelib_TypeDescription * pTypeDescr )
230 : : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
231 : , _pSortedMemberInit( 0 )
232 : , _nMethods( 0 )
233 2310 : , _nAttributes( 0 )
234 2310 : {}
235 : virtual ~InterfaceIdlClassImpl();
236 :
237 : // IdlClassImpl modifications
238 : virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
239 : virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException);
240 : virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException);
241 : virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
242 : virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException);
243 : virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
244 : virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
245 : virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
246 : };
247 :
248 : //==================================================================================================
249 : class CompoundIdlClassImpl
250 : : public IdlClassImpl
251 : {
252 : Reference< XIdlClass > _xSuperClass;
253 :
254 : Sequence< Reference< XIdlField > > * _pFields;
255 : OUString2Field _aName2Field;
256 :
257 : public:
258 4 : typelib_CompoundTypeDescription * getTypeDescr() const
259 4 : { return (typelib_CompoundTypeDescription *)IdlClassImpl::getTypeDescr(); }
260 :
261 : // ctor/ dtor
262 37 : CompoundIdlClassImpl( IdlReflectionServiceImpl * pReflection,
263 : const OUString & rName, typelib_TypeClass eTypeClass,
264 : typelib_TypeDescription * pTypeDescr )
265 : : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
266 37 : , _pFields( 0 )
267 37 : {}
268 : virtual ~CompoundIdlClassImpl();
269 :
270 : // IdlClassImpl modifications
271 : virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
272 : virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException);
273 : virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
274 : virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
275 : };
276 :
277 : //==================================================================================================
278 0 : class ArrayIdlClassImpl
279 : : public IdlClassImpl
280 : , public XIdlArray
281 : {
282 : public:
283 0 : typelib_IndirectTypeDescription * getTypeDescr() const
284 0 : { return (typelib_IndirectTypeDescription *)IdlClassImpl::getTypeDescr(); }
285 :
286 : // ctor
287 73 : ArrayIdlClassImpl( IdlReflectionServiceImpl * pReflection,
288 : const OUString & rName, typelib_TypeClass eTypeClass,
289 : typelib_TypeDescription * pTypeDescr )
290 73 : : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
291 73 : {}
292 :
293 : virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
294 : virtual void SAL_CALL acquire() throw();
295 : virtual void SAL_CALL release() throw();
296 :
297 : // XTypeProvider
298 : virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
299 : virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
300 :
301 : // IdlClassImpl modifications
302 : virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
303 : virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException);
304 : virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException);
305 :
306 : // XIdlArray
307 : virtual void SAL_CALL realloc( Any & rArray, sal_Int32 nLen ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
308 : virtual sal_Int32 SAL_CALL getLen( const Any & rArray ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
309 : virtual Any SAL_CALL get( const Any & rArray, sal_Int32 nIndex ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
310 : virtual void SAL_CALL set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
311 : };
312 :
313 : //==================================================================================================
314 : class EnumIdlClassImpl
315 : : public IdlClassImpl
316 : {
317 : Sequence< Reference< XIdlField > > * _pFields;
318 : OUString2Field _aName2Field;
319 :
320 : public:
321 0 : typelib_EnumTypeDescription * getTypeDescr() const
322 0 : { return (typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr(); }
323 :
324 : // ctor/ dtor
325 0 : EnumIdlClassImpl( IdlReflectionServiceImpl * pReflection,
326 : const OUString & rName, typelib_TypeClass eTypeClass,
327 : typelib_TypeDescription * pTypeDescr )
328 : : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
329 0 : , _pFields( 0 )
330 0 : {}
331 : virtual ~EnumIdlClassImpl();
332 :
333 : // IdlClassImpl modifications
334 : virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
335 : virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
336 : virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
337 : };
338 :
339 : //==================================================================================================
340 : class IdlMemberImpl
341 : : public WeakImplHelper1< XIdlMember >
342 : {
343 : IdlReflectionServiceImpl * _pReflection;
344 : OUString _aName;
345 :
346 : typelib_TypeDescription * _pTypeDescr;
347 : typelib_TypeDescription * _pDeclTypeDescr;
348 :
349 : protected:
350 : Reference< XIdlClass > _xDeclClass;
351 :
352 : public:
353 40686 : IdlReflectionServiceImpl * getReflection() const
354 40686 : { return _pReflection; }
355 : Reference< XMultiServiceFactory > getSMgr() const
356 : { return _pReflection->getSMgr(); }
357 49495 : typelib_TypeDescription * getTypeDescr() const
358 49495 : { return _pTypeDescr; }
359 19 : typelib_TypeDescription * getDeclTypeDescr() const
360 19 : { return _pDeclTypeDescr; }
361 :
362 : // ctor/ dtor
363 : IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
364 : typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr );
365 : virtual ~IdlMemberImpl();
366 :
367 : // XIdlMember
368 : virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
369 : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
370 : };
371 :
372 : //--------------------------------------------------------------------------------------------------
373 : // coerces to type descr pTo else queries for it: the interface pointer is returned via rDest
374 : // ## type to XidlClass coercion possible
375 12 : inline sal_Bool extract(
376 : const Any & rObj, typelib_InterfaceTypeDescription * pTo,
377 : Reference< XInterface > & rDest,
378 : IdlReflectionServiceImpl * pRefl )
379 : {
380 12 : rDest.clear();
381 12 : if (0 != pTo)
382 : {
383 12 : if (! rObj.hasValue())
384 0 : return sal_True;
385 12 : if (rObj.getValueTypeClass() == TypeClass_INTERFACE)
386 : {
387 : return ::uno_type_assignData(
388 : &rDest, ((typelib_TypeDescription *)pTo)->pWeakRef,
389 12 : const_cast< void * >( rObj.getValue() ), rObj.getValueTypeRef(),
390 : reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
391 : reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
392 24 : reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
393 : }
394 0 : else if (rObj.getValueTypeClass() == TypeClass_TYPE)
395 : {
396 0 : rDest = pRefl->forType( reinterpret_cast< const Type * >( rObj.getValue() )->getTypeLibType() );
397 0 : return rDest.is();
398 : }
399 : }
400 0 : return sal_False;
401 : }
402 : //--------------------------------------------------------------------------------------------------
403 5 : inline sal_Bool coerce_assign(
404 : void * pDest, typelib_TypeDescription * pTD, const Any & rSource,
405 : IdlReflectionServiceImpl * pRefl )
406 : {
407 5 : if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
408 : {
409 0 : Reference< XInterface > xVal;
410 0 : if (extract( rSource, (typelib_InterfaceTypeDescription *)pTD, xVal, pRefl ))
411 : {
412 0 : if (*(XInterface **)pDest)
413 0 : (*(XInterface **)pDest)->release();
414 0 : *(XInterface **)pDest = xVal.get();
415 0 : if (*(XInterface **)pDest)
416 0 : (*(XInterface **)pDest)->acquire();
417 0 : return sal_True;
418 : }
419 0 : return sal_False;
420 : }
421 5 : else if (pTD->eTypeClass == typelib_TypeClass_ANY)
422 : {
423 : return uno_assignData(
424 : pDest, pTD,
425 : (void *)&rSource, pTD,
426 : reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
427 : reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
428 0 : reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
429 : }
430 : else
431 : {
432 : return uno_type_assignData(
433 : pDest, pTD->pWeakRef,
434 5 : (void *)rSource.getValue(), rSource.getValueTypeRef(),
435 : reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
436 : reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
437 10 : reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
438 : }
439 : }
440 :
441 : }
442 :
443 :
444 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|