1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: crcomp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
33 #include <rtl/strbuf.hxx>
35 #include <com/sun/star/reflection/XIdlField.hpp>
36 #include <com/sun/star/reflection/XIdlField2.hpp>
37 #include "com/sun/star/uno/TypeClass.hpp"
45 //==================================================================================================
46 class IdlCompFieldImpl
47 : public IdlMemberImpl
54 IdlCompFieldImpl( IdlReflectionServiceImpl
* pReflection
, const OUString
& rName
,
55 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
,
57 : IdlMemberImpl( pReflection
, rName
, pTypeDescr
, pDeclTypeDescr
)
62 virtual Any SAL_CALL
queryInterface( const Type
& rType
) throw (::com::sun::star::uno::RuntimeException
);
63 virtual void SAL_CALL
acquire() throw ();
64 virtual void SAL_CALL
release() throw ();
67 virtual Sequence
< Type
> SAL_CALL
getTypes() throw (::com::sun::star::uno::RuntimeException
);
68 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId() throw (::com::sun::star::uno::RuntimeException
);
71 virtual Reference
< XIdlClass
> SAL_CALL
getDeclaringClass() throw(::com::sun::star::uno::RuntimeException
);
72 virtual OUString SAL_CALL
getName() throw(::com::sun::star::uno::RuntimeException
);
74 virtual Reference
< XIdlClass
> SAL_CALL
getType() throw(::com::sun::star::uno::RuntimeException
);
75 virtual FieldAccessMode SAL_CALL
getAccessMode() throw(::com::sun::star::uno::RuntimeException
);
76 virtual Any SAL_CALL
get( const Any
& rObj
) throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
);
77 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
);
78 // XIdlField2: getType, getAccessMode and get are equal to XIdlField
79 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
);
83 //__________________________________________________________________________________________________
84 Any
IdlCompFieldImpl::queryInterface( const Type
& rType
)
85 throw(::com::sun::star::uno::RuntimeException
)
87 Any
aRet( ::cppu::queryInterface( rType
,
88 static_cast< XIdlField
* >( this ),
89 static_cast< XIdlField2
* >( this ) ) );
90 return (aRet
.hasValue() ? aRet
: IdlMemberImpl::queryInterface( rType
));
92 //__________________________________________________________________________________________________
93 void IdlCompFieldImpl::acquire() throw()
95 IdlMemberImpl::acquire();
97 //__________________________________________________________________________________________________
98 void IdlCompFieldImpl::release() throw()
100 IdlMemberImpl::release();
104 //__________________________________________________________________________________________________
105 Sequence
< Type
> IdlCompFieldImpl::getTypes()
106 throw (::com::sun::star::uno::RuntimeException
)
108 static OTypeCollection
* s_pTypes
= 0;
111 MutexGuard
aGuard( getMutexAccess() );
114 static OTypeCollection
s_aTypes(
115 ::getCppuType( (const Reference
< XIdlField2
> *)0 ),
116 ::getCppuType( (const Reference
< XIdlField
> *)0 ),
117 IdlMemberImpl::getTypes() );
118 s_pTypes
= &s_aTypes
;
121 return s_pTypes
->getTypes();
123 //__________________________________________________________________________________________________
124 Sequence
< sal_Int8
> IdlCompFieldImpl::getImplementationId()
125 throw (::com::sun::star::uno::RuntimeException
)
127 static OImplementationId
* s_pId
= 0;
130 MutexGuard
aGuard( getMutexAccess() );
133 static OImplementationId s_aId
;
137 return s_pId
->getImplementationId();
141 //__________________________________________________________________________________________________
142 Reference
< XIdlClass
> IdlCompFieldImpl::getDeclaringClass()
143 throw(::com::sun::star::uno::RuntimeException
)
145 if (! _xDeclClass
.is())
147 MutexGuard
aGuard( getMutexAccess() );
148 if (! _xDeclClass
.is())
150 typelib_CompoundTypeDescription
* pTD
=
151 (typelib_CompoundTypeDescription
*)getDeclTypeDescr();
154 typelib_TypeDescriptionReference
** ppTypeRefs
= pTD
->ppTypeRefs
;
155 for ( sal_Int32 nPos
= pTD
->nMembers
; nPos
--; )
157 if (td_equals( (typelib_TypeDescription
*)getTypeDescr(), ppTypeRefs
[nPos
] ))
159 _xDeclClass
= getReflection()->forType( (typelib_TypeDescription
*)pTD
);
163 pTD
= pTD
->pBaseTypeDescription
;
169 //__________________________________________________________________________________________________
170 OUString
IdlCompFieldImpl::getName()
171 throw(::com::sun::star::uno::RuntimeException
)
173 return IdlMemberImpl::getName();
177 //__________________________________________________________________________________________________
178 Reference
< XIdlClass
> IdlCompFieldImpl::getType()
179 throw(::com::sun::star::uno::RuntimeException
)
181 return getReflection()->forType( getTypeDescr() );
183 //__________________________________________________________________________________________________
184 FieldAccessMode
IdlCompFieldImpl::getAccessMode()
185 throw(::com::sun::star::uno::RuntimeException
)
187 return FieldAccessMode_READWRITE
;
189 //__________________________________________________________________________________________________
190 Any
IdlCompFieldImpl::get( const Any
& rObj
)
191 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::uno::RuntimeException
)
193 if (rObj
.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT
||
194 rObj
.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION
)
196 typelib_TypeDescription
* pObjTD
= 0;
197 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
199 typelib_TypeDescription
* pTD
= pObjTD
;
200 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
201 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
202 pTD
= (typelib_TypeDescription
*)((typelib_CompoundTypeDescription
*)pTD
)->pBaseTypeDescription
;
204 OSL_ENSURE( pTD
, "### illegal object type!" );
207 TYPELIB_DANGER_RELEASE( pObjTD
);
210 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
212 &aRet
, (char *)rObj
.getValue() + _nOffset
, getTypeDescr(),
213 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
216 TYPELIB_DANGER_RELEASE( pObjTD
);
218 throw IllegalArgumentException(
219 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
220 (XWeak
*)(OWeakObject
*)this, 0 );
222 //__________________________________________________________________________________________________
223 void IdlCompFieldImpl::set( const Any
& rObj
, const Any
& rValue
)
224 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::IllegalAccessException
, ::com::sun::star::uno::RuntimeException
)
226 if (rObj
.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT
||
227 rObj
.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION
)
229 typelib_TypeDescription
* pObjTD
= 0;
230 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
232 typelib_TypeDescription
* pTD
= pObjTD
;
233 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
234 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
235 pTD
= (typelib_TypeDescription
*)((typelib_CompoundTypeDescription
*)pTD
)->pBaseTypeDescription
;
237 OSL_ENSURE( pTD
, "### illegal object type!" );
240 TYPELIB_DANGER_RELEASE( pObjTD
);
241 if (coerce_assign( (char *)rObj
.getValue() + _nOffset
, getTypeDescr(), rValue
, getReflection() ))
247 throw IllegalArgumentException(
248 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
249 (XWeak
*)(OWeakObject
*)this, 1 );
252 TYPELIB_DANGER_RELEASE( pObjTD
);
254 throw IllegalArgumentException(
255 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
256 (XWeak
*)(OWeakObject
*)this, 0 );
259 //__________________________________________________________________________________________________
260 void IdlCompFieldImpl::set( Any
& rObj
, const Any
& rValue
)
261 throw(::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::IllegalAccessException
, ::com::sun::star::uno::RuntimeException
)
263 if (rObj
.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT
||
264 rObj
.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION
)
266 typelib_TypeDescription
* pObjTD
= 0;
267 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
269 typelib_TypeDescription
* pTD
= pObjTD
;
270 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
271 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
272 pTD
= (typelib_TypeDescription
*)((typelib_CompoundTypeDescription
*)pTD
)->pBaseTypeDescription
;
274 OSL_ENSURE( pTD
, "### illegal object type!" );
277 TYPELIB_DANGER_RELEASE( pObjTD
);
278 if (coerce_assign( (char *)rObj
.getValue() + _nOffset
, getTypeDescr(), rValue
, getReflection() ))
284 throw IllegalArgumentException(
285 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
286 (XWeak
*)(OWeakObject
*)this, 1 );
289 TYPELIB_DANGER_RELEASE( pObjTD
);
291 throw IllegalArgumentException(
292 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
293 (XWeak
*)(OWeakObject
*)this, 0 );
296 //##################################################################################################
297 //##################################################################################################
298 //##################################################################################################
301 //__________________________________________________________________________________________________
302 CompoundIdlClassImpl::~CompoundIdlClassImpl()
307 //__________________________________________________________________________________________________
308 sal_Bool
CompoundIdlClassImpl::isAssignableFrom( const Reference
< XIdlClass
> & xType
)
309 throw(::com::sun::star::uno::RuntimeException
)
313 TypeClass eTC
= xType
->getTypeClass();
314 if (eTC
== TypeClass_STRUCT
|| eTC
== TypeClass_EXCEPTION
)
320 const Sequence
< Reference
< XIdlClass
> > & rSeq
= xType
->getSuperclasses();
321 if (rSeq
.getLength())
323 OSL_ENSURE( rSeq
.getLength() == 1, "### unexpected len of super classes!" );
324 return isAssignableFrom( rSeq
[0] );
331 //__________________________________________________________________________________________________
332 Sequence
< Reference
< XIdlClass
> > CompoundIdlClassImpl::getSuperclasses()
333 throw(::com::sun::star::uno::RuntimeException
)
335 if (! _xSuperClass
.is())
337 MutexGuard
aGuard( getMutexAccess() );
338 if (! _xSuperClass
.is())
340 typelib_CompoundTypeDescription
* pCompTypeDescr
= getTypeDescr()->pBaseTypeDescription
;
342 _xSuperClass
= getReflection()->forType( (typelib_TypeDescription
*)pCompTypeDescr
);
345 if (_xSuperClass
.is())
346 return Sequence
< Reference
< XIdlClass
> >( &_xSuperClass
, 1 );
348 return Sequence
< Reference
< XIdlClass
> >();
350 //__________________________________________________________________________________________________
351 Reference
< XIdlField
> CompoundIdlClassImpl::getField( const OUString
& rName
)
352 throw(::com::sun::star::uno::RuntimeException
)
355 getFields(); // init fields
357 const OUString2Field::const_iterator
iFind( _aName2Field
.find( rName
) );
358 if (iFind
!= _aName2Field
.end())
359 return Reference
< XIdlField
>( (*iFind
).second
);
361 return Reference
< XIdlField
>();
363 //__________________________________________________________________________________________________
364 Sequence
< Reference
< XIdlField
> > CompoundIdlClassImpl::getFields()
365 throw(::com::sun::star::uno::RuntimeException
)
367 MutexGuard
aGuard( getMutexAccess() );
371 typelib_CompoundTypeDescription
* pCompTypeDescr
= getTypeDescr();
372 for ( ; pCompTypeDescr
; pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
373 nAll
+= pCompTypeDescr
->nMembers
;
375 Sequence
< Reference
< XIdlField
> > * pFields
=
376 new Sequence
< Reference
< XIdlField
> >( nAll
);
377 Reference
< XIdlField
> * pSeq
= pFields
->getArray();
379 for ( pCompTypeDescr
= getTypeDescr(); pCompTypeDescr
;
380 pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
382 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompTypeDescr
->ppTypeRefs
;
383 rtl_uString
** ppNames
= pCompTypeDescr
->ppMemberNames
;
384 sal_Int32
* pMemberOffsets
= pCompTypeDescr
->pMemberOffsets
;
386 for ( sal_Int32 nPos
= pCompTypeDescr
->nMembers
; nPos
--; )
388 typelib_TypeDescription
* pTD
= 0;
389 TYPELIB_DANGER_GET( &pTD
, ppTypeRefs
[nPos
] );
390 OSL_ENSURE( pTD
, "### cannot get field in struct!" );
393 OUString
aName( ppNames
[nPos
] );
394 _aName2Field
[aName
] = pSeq
[--nAll
] = new IdlCompFieldImpl(
395 getReflection(), aName
, pTD
, IdlClassImpl::getTypeDescr(), pMemberOffsets
[nPos
] );
396 TYPELIB_DANGER_RELEASE( pTD
);