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 <osl/diagnose.h> 31 #include <rtl/ustrbuf.hxx> 32 #include "registry/reader.hxx" 33 #include "registry/version.h" 34 35 #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp> 36 #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp> 37 #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> 38 #include <com/sun/star/reflection/XMethodParameter.hpp> 39 #include <com/sun/star/reflection/XParameter.hpp> 40 #include "com/sun/star/uno/RuntimeException.hpp" 41 #include "base.hxx" 42 #include "functiondescription.hxx" 43 #include "methoddescription.hxx" 44 45 #include <memory> 46 #include <set> 47 48 namespace stoc_rdbtdp 49 { 50 51 //================================================================================================== 52 class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription > 53 { 54 stoc::registry_tdprovider::MethodDescription _desc; 55 56 Reference< XHierarchicalNameAccess > _xTDMgr; 57 58 OUString _aTypeName; 59 60 OUString _aReturnType; 61 Reference< XTypeDescription > _xReturnTD; 62 63 sal_Bool _bIsOneWay; 64 sal_Int32 _nPosition; 65 66 public: 67 InterfaceMethodImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, 68 const OUString & rTypeName, 69 const OUString & rMemberName, 70 const OUString & rReturnType, 71 const Sequence< sal_Int8 > & rBytes, 72 sal_uInt16 nMethodIndex, 73 sal_Bool bIsOneWay, 74 sal_Int32 nPosition ) 75 : _desc(xTDMgr, rMemberName, rBytes, nMethodIndex) 76 , _xTDMgr( xTDMgr ) 77 , _aTypeName( rTypeName ) 78 , _aReturnType( rReturnType ) 79 , _bIsOneWay( bIsOneWay ) 80 , _nPosition( nPosition ) 81 { 82 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 83 } 84 virtual ~InterfaceMethodImpl(); 85 86 // XTypeDescription 87 virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); 88 virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); 89 90 // XInterfaceMemberTypeDescription 91 virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException) 92 { return _desc.getName(); } 93 virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); 94 95 // XInterfaceMethodTypeDescription 96 virtual Reference< XTypeDescription > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException); 97 virtual sal_Bool SAL_CALL isOneway() throw(::com::sun::star::uno::RuntimeException); 98 virtual Sequence< Reference< XMethodParameter > > SAL_CALL getParameters() throw(::com::sun::star::uno::RuntimeException); 99 virtual Sequence< Reference< XTypeDescription > > SAL_CALL getExceptions() throw(::com::sun::star::uno::RuntimeException); 100 }; 101 //__________________________________________________________________________________________________ 102 InterfaceMethodImpl::~InterfaceMethodImpl() 103 { 104 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 105 } 106 107 // XTypeDescription 108 //__________________________________________________________________________________________________ 109 TypeClass InterfaceMethodImpl::getTypeClass() 110 throw(::com::sun::star::uno::RuntimeException) 111 { 112 return TypeClass_INTERFACE_METHOD; 113 } 114 //__________________________________________________________________________________________________ 115 OUString InterfaceMethodImpl::getName() 116 throw(::com::sun::star::uno::RuntimeException) 117 { 118 return _aTypeName; 119 } 120 121 // XInterfaceMemberTypeDescription 122 //__________________________________________________________________________________________________ 123 sal_Int32 InterfaceMethodImpl::getPosition() 124 throw(::com::sun::star::uno::RuntimeException) 125 { 126 return _nPosition; 127 } 128 129 // XInterfaceMethodTypeDescription 130 //__________________________________________________________________________________________________ 131 Reference<XTypeDescription > InterfaceMethodImpl::getReturnType() 132 throw(::com::sun::star::uno::RuntimeException) 133 { 134 if (!_xReturnTD.is() && _aReturnType.getLength()) 135 { 136 try 137 { 138 Reference< XTypeDescription > xReturnTD; 139 if (_xTDMgr->getByHierarchicalName( _aReturnType ) >>= xReturnTD) 140 { 141 MutexGuard aGuard( getMutex() ); 142 if (! _xReturnTD.is()) 143 _xReturnTD = xReturnTD; 144 return _xReturnTD; 145 } 146 } 147 catch (NoSuchElementException &) 148 { 149 } 150 // never try again, if no td was found 151 _aReturnType = OUString(); 152 } 153 return _xReturnTD; 154 } 155 //__________________________________________________________________________________________________ 156 sal_Bool InterfaceMethodImpl::isOneway() 157 throw(::com::sun::star::uno::RuntimeException) 158 { 159 return _bIsOneWay; 160 } 161 //__________________________________________________________________________________________________ 162 Sequence<Reference<XMethodParameter > > InterfaceMethodImpl::getParameters() 163 throw(::com::sun::star::uno::RuntimeException) 164 { 165 Sequence< Reference< XParameter > > s1(_desc.getParameters()); 166 Sequence< Reference< XMethodParameter > > s2(s1.getLength()); 167 for (sal_Int32 i = 0; i < s1.getLength(); ++i) { 168 s2[i] = s1[i].get(); 169 } 170 return s2; 171 } 172 //__________________________________________________________________________________________________ 173 Sequence<Reference<XTypeDescription > > InterfaceMethodImpl::getExceptions() 174 throw(::com::sun::star::uno::RuntimeException) 175 { 176 Sequence< Reference< XCompoundTypeDescription > > s1( 177 _desc.getExceptions()); 178 Sequence< Reference< XTypeDescription > > s2(s1.getLength()); 179 for (sal_Int32 i = 0; i < s1.getLength(); ++i) { 180 s2[i] = s1[i].get(); 181 } 182 return s2; 183 } 184 185 186 //################################################################################################## 187 //################################################################################################## 188 //################################################################################################## 189 190 191 //================================================================================================== 192 class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription2 > 193 { 194 Reference< XHierarchicalNameAccess > _xTDMgr; 195 196 OUString _aTypeName; 197 OUString _aMemberName; 198 199 OUString _aMemberTypeName; 200 Reference< XTypeDescription > _xMemberTD; 201 202 sal_Bool _bReadOnly; 203 sal_Bool _bBound; 204 sal_Int32 _nPosition; 205 206 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _getter; 207 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _setter; 208 209 public: 210 InterfaceAttributeImpl( 211 const Reference< XHierarchicalNameAccess > & xTDMgr, 212 const OUString & rTypeName, 213 const OUString & rMemberName, 214 const OUString & rMemberTypeName, 215 sal_Bool bReadOnly, 216 sal_Bool bBound, 217 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > & 218 getter, 219 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > & 220 setter, 221 sal_Int32 nPosition ) 222 : _xTDMgr( xTDMgr ) 223 , _aTypeName( rTypeName ) 224 , _aMemberName( rMemberName ) 225 , _aMemberTypeName( rMemberTypeName ) 226 , _bReadOnly( bReadOnly ) 227 , _bBound( bBound ) 228 , _nPosition( nPosition ) 229 , _getter( getter ) 230 , _setter( setter ) 231 { 232 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 233 } 234 virtual ~InterfaceAttributeImpl(); 235 236 // XTypeDescription 237 virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); 238 virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); 239 240 // XInterfaceMemberTypeDescription 241 virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException); 242 virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); 243 244 // XInterfaceAttributeTypeDescription2 245 virtual sal_Bool SAL_CALL isReadOnly() throw(::com::sun::star::uno::RuntimeException); 246 virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); 247 248 virtual sal_Bool SAL_CALL isBound() throw (RuntimeException) 249 { return _bBound; } 250 251 virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL 252 getGetExceptions() throw (RuntimeException) 253 { 254 if (_getter.get() != 0) { 255 return _getter->getExceptions(); 256 } else { 257 return Sequence< Reference< XCompoundTypeDescription > >(); 258 } 259 } 260 261 virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL 262 getSetExceptions() throw (RuntimeException) 263 { 264 if (_setter.get() != 0) { 265 return _setter->getExceptions(); 266 } else { 267 return Sequence< Reference< XCompoundTypeDescription > >(); 268 } 269 } 270 }; 271 272 InterfaceAttributeImpl::~InterfaceAttributeImpl() 273 { 274 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 275 } 276 // XTypeDescription 277 //__________________________________________________________________________________________________ 278 TypeClass InterfaceAttributeImpl::getTypeClass() 279 throw(::com::sun::star::uno::RuntimeException) 280 { 281 return TypeClass_INTERFACE_ATTRIBUTE; 282 } 283 //__________________________________________________________________________________________________ 284 OUString InterfaceAttributeImpl::getName() 285 throw(::com::sun::star::uno::RuntimeException) 286 { 287 return _aTypeName; 288 } 289 290 // XInterfaceMemberTypeDescription 291 //__________________________________________________________________________________________________ 292 OUString InterfaceAttributeImpl::getMemberName() 293 throw(::com::sun::star::uno::RuntimeException) 294 { 295 return _aMemberName; 296 } 297 //__________________________________________________________________________________________________ 298 sal_Int32 InterfaceAttributeImpl::getPosition() 299 throw(::com::sun::star::uno::RuntimeException) 300 { 301 return _nPosition; 302 } 303 304 // XInterfaceAttributeTypeDescription2 305 //__________________________________________________________________________________________________ 306 sal_Bool InterfaceAttributeImpl::isReadOnly() 307 throw(::com::sun::star::uno::RuntimeException) 308 { 309 return _bReadOnly; 310 } 311 //__________________________________________________________________________________________________ 312 Reference<XTypeDescription > InterfaceAttributeImpl::getType() 313 throw(::com::sun::star::uno::RuntimeException) 314 { 315 if (!_xMemberTD.is() && _aMemberTypeName.getLength()) 316 { 317 try 318 { 319 Reference< XTypeDescription > xMemberTD; 320 if (_xTDMgr->getByHierarchicalName( _aMemberTypeName ) >>= xMemberTD) 321 { 322 MutexGuard aGuard( getMutex() ); 323 if (! _xMemberTD.is()) 324 _xMemberTD = xMemberTD; 325 return _xMemberTD; 326 } 327 } 328 catch (NoSuchElementException &) 329 { 330 } 331 // never try again, if no td was found 332 _aMemberTypeName = OUString(); 333 } 334 return _xMemberTD; 335 } 336 337 338 //################################################################################################## 339 //################################################################################################## 340 //################################################################################################## 341 342 void InterfaceTypeDescriptionImpl::checkInterfaceType( 343 Reference< XTypeDescription > const & type) 344 { 345 if (resolveTypedefs(type)->getTypeClass() != TypeClass_INTERFACE) { 346 throw RuntimeException( 347 OUString( 348 RTL_CONSTASCII_USTRINGPARAM( 349 "Interface base is not an interface type")), 350 static_cast< OWeakObject * >(this)); 351 } 352 } 353 354 namespace { 355 356 class BaseOffset { 357 public: 358 BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc); 359 360 sal_Int32 get() const { return offset; } 361 362 private: 363 void calculateBases(Reference< XInterfaceTypeDescription2 > const & desc); 364 365 void calculate(Reference< XInterfaceTypeDescription2 > const & desc); 366 367 std::set< rtl::OUString > set; 368 sal_Int32 offset; 369 }; 370 371 BaseOffset::BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc) { 372 offset = 0; 373 calculateBases(desc); 374 } 375 376 void BaseOffset::calculateBases( 377 Reference< XInterfaceTypeDescription2 > const & desc) 378 { 379 Sequence< Reference < XTypeDescription > > bases(desc->getBaseTypes()); 380 for (sal_Int32 i = 0; i < bases.getLength(); ++i) { 381 calculate( 382 Reference< XInterfaceTypeDescription2 >( 383 resolveTypedefs(bases[i]), UNO_QUERY_THROW)); 384 } 385 } 386 387 void BaseOffset::calculate(Reference< XInterfaceTypeDescription2 > const & desc) 388 { 389 if (set.insert(desc->getName()).second) { 390 calculateBases(desc); 391 offset += desc->getMembers().getLength(); 392 } 393 } 394 395 } 396 397 //__________________________________________________________________________________________________ 398 InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl( 399 const Reference< XHierarchicalNameAccess > & xTDMgr, 400 const OUString & rName, const Sequence< OUString > & rBaseTypes, 401 const Sequence< OUString > & rOptionalBaseTypes, 402 const Sequence< sal_Int8 > & rBytes, bool published ) 403 : _xTDMgr( xTDMgr ) 404 , _aBytes( rBytes ) 405 , _aName( rName ) 406 , _aBaseTypes( rBaseTypes ) 407 , _aOptionalBaseTypes( rOptionalBaseTypes ) 408 , _membersInit( false ) 409 , _published( published ) 410 { 411 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 412 } 413 //__________________________________________________________________________________________________ 414 InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl() 415 { 416 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 417 } 418 419 // XTypeDescription 420 //__________________________________________________________________________________________________ 421 TypeClass InterfaceTypeDescriptionImpl::getTypeClass() 422 throw(::com::sun::star::uno::RuntimeException) 423 { 424 return TypeClass_INTERFACE; 425 } 426 //__________________________________________________________________________________________________ 427 OUString InterfaceTypeDescriptionImpl::getName() 428 throw(::com::sun::star::uno::RuntimeException) 429 { 430 return _aName; 431 } 432 433 // XInterfaceTypeDescription2 434 //__________________________________________________________________________________________________ 435 Reference< XTypeDescription > InterfaceTypeDescriptionImpl::getBaseType() 436 throw(::com::sun::star::uno::RuntimeException) 437 { 438 Sequence< Reference< XTypeDescription > > aBaseTypes(getBaseTypes()); 439 return aBaseTypes.getLength() >= 1 ? aBaseTypes[0] : 0; 440 } 441 //__________________________________________________________________________________________________ 442 Uik SAL_CALL InterfaceTypeDescriptionImpl::getUik() 443 throw(::com::sun::star::uno::RuntimeException) 444 { 445 return Uik(); 446 } 447 //__________________________________________________________________________________________________ 448 Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers() 449 throw(::com::sun::star::uno::RuntimeException) 450 { 451 osl::MutexGuard guard(getMutex()); 452 if (!_membersInit) { 453 _nBaseOffset = BaseOffset(this).get(); 454 typereg::Reader reader( 455 _aBytes.getConstArray(), _aBytes.getLength(), false, 456 TYPEREG_VERSION_1); 457 sal_Int32 count = 0; 458 sal_uInt16 methodCount = reader.getMethodCount(); 459 {for (sal_uInt16 i = 0; i < methodCount; ++i) { 460 RTMethodMode flags = reader.getMethodFlags(i); 461 if (flags != RT_MODE_ATTRIBUTE_GET 462 && flags != RT_MODE_ATTRIBUTE_SET) 463 { 464 ++count; 465 } 466 }} 467 sal_uInt16 fieldCount = reader.getFieldCount(); 468 count += fieldCount; 469 _members.realloc(count); 470 sal_Int32 index = 0; 471 {for (sal_uInt16 i = 0; i < fieldCount; ++i) { 472 rtl::OUString name(reader.getFieldName(i)); 473 rtl::OUStringBuffer typeName(getName()); 474 typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::")); 475 typeName.append(name); 476 RTFieldAccess flags = reader.getFieldFlags(i); 477 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > 478 getter; 479 std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > 480 setter; 481 for (sal_uInt16 j = 0; j < methodCount; ++j) { 482 if (reader.getMethodName(j) == name) { 483 switch (reader.getMethodFlags(j)) { 484 case RT_MODE_ATTRIBUTE_GET: 485 OSL_ASSERT(getter.get() == 0); 486 getter.reset( 487 new stoc::registry_tdprovider::FunctionDescription( 488 _xTDMgr, _aBytes, j)); 489 break; 490 491 case RT_MODE_ATTRIBUTE_SET: 492 OSL_ASSERT(setter.get() == 0); 493 setter.reset( 494 new stoc::registry_tdprovider::FunctionDescription( 495 _xTDMgr, _aBytes, j)); 496 break; 497 498 default: 499 OSL_ASSERT(false); 500 break; 501 } 502 } 503 } 504 _members[index] = new InterfaceAttributeImpl( 505 _xTDMgr, typeName.makeStringAndClear(), name, 506 reader.getFieldTypeName(i).replace('/', '.'), 507 (flags & RT_ACCESS_READONLY) != 0, 508 (flags & RT_ACCESS_BOUND) != 0, getter, setter, 509 _nBaseOffset + index); 510 ++index; 511 }} 512 {for (sal_uInt16 i = 0; i < methodCount; ++i) { 513 RTMethodMode flags = reader.getMethodFlags(i); 514 if (flags != RT_MODE_ATTRIBUTE_GET 515 && flags != RT_MODE_ATTRIBUTE_SET) 516 { 517 rtl::OUString name(reader.getMethodName(i)); 518 rtl::OUStringBuffer typeName(getName()); 519 typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::")); 520 typeName.append(name); 521 _members[index] = new InterfaceMethodImpl( 522 _xTDMgr, typeName.makeStringAndClear(), name, 523 reader.getMethodReturnTypeName(i).replace('/', '.'), 524 _aBytes, i, flags == RT_MODE_ONEWAY, _nBaseOffset + index); 525 ++index; 526 } 527 }} 528 _membersInit = true; 529 } 530 return _members; 531 } 532 533 Sequence< Reference< XTypeDescription > > 534 InterfaceTypeDescriptionImpl::getBaseTypes() throw (RuntimeException) { 535 MutexGuard guard(getMutex()); 536 if (_xBaseTDs.getLength() == 0 && _aBaseTypes.getLength() != 0) { 537 Sequence< Reference< XTypeDescription > > tds(_aBaseTypes.getLength()); 538 for (sal_Int32 i = 0; i < _aBaseTypes.getLength(); ++i) { 539 try { 540 _xTDMgr->getByHierarchicalName(_aBaseTypes[i]) >>= tds[i]; 541 } catch (NoSuchElementException & e) { 542 throw RuntimeException( 543 (OUString( 544 RTL_CONSTASCII_USTRINGPARAM( 545 "com.sun.star.container.NoSuchElementException: ")) 546 + e.Message), 547 static_cast< OWeakObject * >(this)); 548 } 549 OSL_ASSERT(tds[i].is()); 550 checkInterfaceType(tds[i]); 551 } 552 _xBaseTDs = tds; 553 } 554 return _xBaseTDs; 555 } 556 557 Sequence< Reference< XTypeDescription > > 558 InterfaceTypeDescriptionImpl::getOptionalBaseTypes() throw (RuntimeException) { 559 MutexGuard guard(getMutex()); 560 if (_xOptionalBaseTDs.getLength() == 0 561 && _aOptionalBaseTypes.getLength() != 0) 562 { 563 Sequence< Reference< XTypeDescription > > tds( 564 _aOptionalBaseTypes.getLength()); 565 for (sal_Int32 i = 0; i < _aOptionalBaseTypes.getLength(); ++i) { 566 try { 567 _xTDMgr->getByHierarchicalName(_aOptionalBaseTypes[i]) 568 >>= tds[i]; 569 } catch (NoSuchElementException & e) { 570 throw RuntimeException( 571 (OUString( 572 RTL_CONSTASCII_USTRINGPARAM( 573 "com.sun.star.container.NoSuchElementException: ")) 574 + e.Message), 575 static_cast< OWeakObject * >(this)); 576 } 577 OSL_ASSERT(tds[i].is()); 578 checkInterfaceType(tds[i]); 579 } 580 _xOptionalBaseTDs = tds; 581 } 582 return _xOptionalBaseTDs; 583 } 584 585 } 586