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