xref: /trunk/main/stoc/source/corereflection/crcomp.cxx (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 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_stoc.hxx"
30 #include <rtl/strbuf.hxx>
31 
32 #include <com/sun/star/reflection/XIdlField.hpp>
33 #include <com/sun/star/reflection/XIdlField2.hpp>
34 #include "com/sun/star/uno/TypeClass.hpp"
35 
36 #include "base.hxx"
37 
38 
39 namespace stoc_corefl
40 {
41 
42 //==================================================================================================
43 class IdlCompFieldImpl
44     : public IdlMemberImpl
45     , public XIdlField
46     , public XIdlField2
47 {
48     sal_Int32                   _nOffset;
49 
50 public:
51     IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
52                       typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr,
53                       sal_Int32 nOffset )
54         : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
55         , _nOffset( nOffset )
56         {}
57 
58     // XInterface
59     virtual Any SAL_CALL queryInterface( const Type & rType ) throw (::com::sun::star::uno::RuntimeException);
60     virtual void SAL_CALL acquire() throw ();
61     virtual void SAL_CALL release() throw ();
62 
63     // XTypeProvider
64     virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
65     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
66 
67     // XIdlMember
68     virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
69     virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
70     // XIdlField
71     virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
72     virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException);
73     virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
74     virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
75     // XIdlField2: getType, getAccessMode and get are equal to XIdlField
76     virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
77 };
78 
79 // XInterface
80 //__________________________________________________________________________________________________
81 Any IdlCompFieldImpl::queryInterface( const Type & rType )
82     throw(::com::sun::star::uno::RuntimeException)
83 {
84     Any aRet( ::cppu::queryInterface( rType,
85                                       static_cast< XIdlField * >( this ),
86                                       static_cast< XIdlField2 * >( this ) ) );
87     return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
88 }
89 //__________________________________________________________________________________________________
90 void IdlCompFieldImpl::acquire() throw()
91 {
92     IdlMemberImpl::acquire();
93 }
94 //__________________________________________________________________________________________________
95 void IdlCompFieldImpl::release() throw()
96 {
97     IdlMemberImpl::release();
98 }
99 
100 // XTypeProvider
101 //__________________________________________________________________________________________________
102 Sequence< Type > IdlCompFieldImpl::getTypes()
103     throw (::com::sun::star::uno::RuntimeException)
104 {
105     static OTypeCollection * s_pTypes = 0;
106     if (! s_pTypes)
107     {
108         MutexGuard aGuard( getMutexAccess() );
109         if (! s_pTypes)
110         {
111             static OTypeCollection s_aTypes(
112                 ::getCppuType( (const Reference< XIdlField2 > *)0 ),
113                 ::getCppuType( (const Reference< XIdlField > *)0 ),
114                 IdlMemberImpl::getTypes() );
115             s_pTypes = &s_aTypes;
116         }
117     }
118     return s_pTypes->getTypes();
119 }
120 //__________________________________________________________________________________________________
121 Sequence< sal_Int8 > IdlCompFieldImpl::getImplementationId()
122     throw (::com::sun::star::uno::RuntimeException)
123 {
124     static OImplementationId * s_pId = 0;
125     if (! s_pId)
126     {
127         MutexGuard aGuard( getMutexAccess() );
128         if (! s_pId)
129         {
130             static OImplementationId s_aId;
131             s_pId = &s_aId;
132         }
133     }
134     return s_pId->getImplementationId();
135 }
136 
137 // XIdlMember
138 //__________________________________________________________________________________________________
139 Reference< XIdlClass > IdlCompFieldImpl::getDeclaringClass()
140     throw(::com::sun::star::uno::RuntimeException)
141 {
142     if (! _xDeclClass.is())
143     {
144         MutexGuard aGuard( getMutexAccess() );
145         if (! _xDeclClass.is())
146         {
147             typelib_CompoundTypeDescription * pTD =
148                 (typelib_CompoundTypeDescription *)getDeclTypeDescr();
149             while (pTD)
150             {
151                 typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppTypeRefs;
152                 for ( sal_Int32 nPos = pTD->nMembers; nPos--; )
153                 {
154                     if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] ))
155                     {
156                         _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD );
157                         return _xDeclClass;
158                     }
159                 }
160                 pTD = pTD->pBaseTypeDescription;
161             }
162         }
163     }
164     return _xDeclClass;
165 }
166 //__________________________________________________________________________________________________
167 OUString IdlCompFieldImpl::getName()
168     throw(::com::sun::star::uno::RuntimeException)
169 {
170     return IdlMemberImpl::getName();
171 }
172 
173 // XIdlField
174 //__________________________________________________________________________________________________
175 Reference< XIdlClass > IdlCompFieldImpl::getType()
176     throw(::com::sun::star::uno::RuntimeException)
177 {
178     return getReflection()->forType( getTypeDescr() );
179 }
180 //__________________________________________________________________________________________________
181 FieldAccessMode IdlCompFieldImpl::getAccessMode()
182     throw(::com::sun::star::uno::RuntimeException)
183 {
184     return FieldAccessMode_READWRITE;
185 }
186 //__________________________________________________________________________________________________
187 Any IdlCompFieldImpl::get( const Any & rObj )
188     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
189 {
190     if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
191         rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
192     {
193         typelib_TypeDescription * pObjTD = 0;
194         TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
195 
196         typelib_TypeDescription * pTD = pObjTD;
197         typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
198         while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
199             pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
200 
201         OSL_ENSURE( pTD, "### illegal object type!" );
202         if (pTD)
203         {
204             TYPELIB_DANGER_RELEASE( pObjTD );
205             Any aRet;
206             uno_any_destruct(
207                 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
208             uno_any_construct(
209                 &aRet, (char *)rObj.getValue() + _nOffset, getTypeDescr(),
210                 reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
211             return aRet;
212         }
213         TYPELIB_DANGER_RELEASE( pObjTD );
214     }
215     throw IllegalArgumentException(
216         OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
217         (XWeak *)(OWeakObject *)this, 0 );
218 }
219 //__________________________________________________________________________________________________
220 void IdlCompFieldImpl::set( const Any & rObj, const Any & rValue )
221     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
222 {
223     if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
224         rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
225     {
226         typelib_TypeDescription * pObjTD = 0;
227         TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
228 
229         typelib_TypeDescription * pTD = pObjTD;
230         typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
231         while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
232             pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
233 
234         OSL_ENSURE( pTD, "### illegal object type!" );
235         if (pTD)
236         {
237             TYPELIB_DANGER_RELEASE( pObjTD );
238             if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
239             {
240                 return;
241             }
242             else
243             {
244                 throw IllegalArgumentException(
245                     OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
246                     (XWeak *)(OWeakObject *)this, 1 );
247             }
248         }
249         TYPELIB_DANGER_RELEASE( pObjTD );
250     }
251     throw IllegalArgumentException(
252         OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
253         (XWeak *)(OWeakObject *)this, 0 );
254 }
255 
256 //__________________________________________________________________________________________________
257 void IdlCompFieldImpl::set( Any & rObj, const Any & rValue )
258     throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
259 {
260     if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
261         rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
262     {
263         typelib_TypeDescription * pObjTD = 0;
264         TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
265 
266         typelib_TypeDescription * pTD = pObjTD;
267         typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
268         while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
269             pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
270 
271         OSL_ENSURE( pTD, "### illegal object type!" );
272         if (pTD)
273         {
274             TYPELIB_DANGER_RELEASE( pObjTD );
275             if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
276             {
277                 return;
278             }
279             else
280             {
281                 throw IllegalArgumentException(
282                     OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
283                     (XWeak *)(OWeakObject *)this, 1 );
284             }
285         }
286         TYPELIB_DANGER_RELEASE( pObjTD );
287     }
288     throw IllegalArgumentException(
289         OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
290         (XWeak *)(OWeakObject *)this, 0 );
291 }
292 
293 //##################################################################################################
294 //##################################################################################################
295 //##################################################################################################
296 
297 
298 //__________________________________________________________________________________________________
299 CompoundIdlClassImpl::~CompoundIdlClassImpl()
300 {
301     delete _pFields;
302 }
303 
304 //__________________________________________________________________________________________________
305 sal_Bool CompoundIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
306     throw(::com::sun::star::uno::RuntimeException)
307 {
308     if (xType.is())
309     {
310         TypeClass eTC = xType->getTypeClass();
311         if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION)
312         {
313             if (equals( xType ))
314                 return sal_True;
315             else
316             {
317                 const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses();
318                 if (rSeq.getLength())
319                 {
320                     OSL_ENSURE( rSeq.getLength() == 1, "### unexpected len of super classes!" );
321                     return isAssignableFrom( rSeq[0] );
322                 }
323             }
324         }
325     }
326     return sal_False;
327 }
328 //__________________________________________________________________________________________________
329 Sequence< Reference< XIdlClass > > CompoundIdlClassImpl::getSuperclasses()
330     throw(::com::sun::star::uno::RuntimeException)
331 {
332     if (! _xSuperClass.is())
333     {
334         MutexGuard aGuard( getMutexAccess() );
335         if (! _xSuperClass.is())
336         {
337             typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr()->pBaseTypeDescription;
338             if (pCompTypeDescr)
339                 _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pCompTypeDescr );
340         }
341     }
342     if (_xSuperClass.is())
343         return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 );
344     else
345         return Sequence< Reference< XIdlClass > >();
346 }
347 //__________________________________________________________________________________________________
348 Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName )
349     throw(::com::sun::star::uno::RuntimeException)
350 {
351     if (! _pFields)
352         getFields(); // init fields
353 
354     const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
355     if (iFind != _aName2Field.end())
356         return Reference< XIdlField >( (*iFind).second );
357     else
358         return Reference< XIdlField >();
359 }
360 //__________________________________________________________________________________________________
361 Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields()
362     throw(::com::sun::star::uno::RuntimeException)
363 {
364     MutexGuard aGuard( getMutexAccess() );
365     if (! _pFields)
366     {
367         sal_Int32 nAll = 0;
368         typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr();
369         for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
370             nAll += pCompTypeDescr->nMembers;
371 
372         Sequence< Reference< XIdlField > > * pFields =
373             new Sequence< Reference< XIdlField > >( nAll );
374         Reference< XIdlField > * pSeq = pFields->getArray();
375 
376         for ( pCompTypeDescr = getTypeDescr(); pCompTypeDescr;
377               pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
378         {
379             typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs;
380             rtl_uString ** ppNames                         = pCompTypeDescr->ppMemberNames;
381             sal_Int32 * pMemberOffsets                     = pCompTypeDescr->pMemberOffsets;
382 
383             for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; )
384             {
385                 typelib_TypeDescription * pTD = 0;
386                 TYPELIB_DANGER_GET( &pTD, ppTypeRefs[nPos] );
387                 OSL_ENSURE( pTD, "### cannot get field in struct!" );
388                 if (pTD)
389                 {
390                     OUString aName( ppNames[nPos] );
391                     _aName2Field[aName] = pSeq[--nAll] = new IdlCompFieldImpl(
392                         getReflection(), aName, pTD, IdlClassImpl::getTypeDescr(), pMemberOffsets[nPos] );
393                     TYPELIB_DANGER_RELEASE( pTD );
394                 }
395             }
396         }
397 
398         _pFields = pFields;
399     }
400     return *_pFields;
401 }
402 
403 }
404 
405 
406