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