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