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 <com/sun/star/beans/PropertyAttribute.hpp> 29 #include "com/sun/star/uno/RuntimeException.hpp" 30 31 #include "registry/reader.hxx" 32 #include "registry/version.h" 33 #include "base.hxx" 34 #include "methoddescription.hxx" 35 36 #include <memory> 37 38 using namespace com::sun::star; 39 40 namespace { 41 42 class Constructor: 43 public cppu::WeakImplHelper1< XServiceConstructorDescription > 44 { 45 public: 46 Constructor( 47 Reference< XHierarchicalNameAccess > const & manager, 48 rtl::OUString const & name, Sequence< sal_Int8 > const & bytes, 49 sal_uInt16 index): 50 m_desc(manager, name, bytes, index) {} 51 52 virtual ~Constructor() {} 53 54 virtual sal_Bool SAL_CALL isDefaultConstructor() throw (RuntimeException) 55 { return m_desc.getName().getLength() == 0; } 56 57 virtual rtl::OUString SAL_CALL getName() throw (RuntimeException) 58 { return m_desc.getName(); } 59 60 virtual Sequence< Reference< XParameter > > SAL_CALL getParameters() 61 throw (RuntimeException) 62 { return m_desc.getParameters(); } 63 64 virtual Sequence< Reference<XCompoundTypeDescription > > SAL_CALL 65 getExceptions() throw (RuntimeException) 66 { return m_desc.getExceptions(); } 67 68 private: 69 Constructor(Constructor &); // not implemented 70 void operator =(Constructor); // not implemented 71 72 stoc::registry_tdprovider::MethodDescription m_desc; 73 }; 74 75 } 76 77 namespace stoc_rdbtdp 78 { 79 80 //================================================================================================== 81 // 82 // class PropertyTypeDescriptionImpl 83 // 84 //================================================================================================== 85 class PropertyTypeDescriptionImpl : public WeakImplHelper1< XPropertyTypeDescription > 86 { 87 OUString _aName; 88 Reference< XTypeDescription > _xTD; 89 sal_Int16 _nFlags; 90 91 public: 92 PropertyTypeDescriptionImpl( const OUString & rName, 93 const Reference< XTypeDescription > & xTD, 94 sal_Int16 nFlags ) 95 : _aName( rName ), _xTD( xTD ), _nFlags( nFlags ) 96 { 97 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 98 } 99 virtual ~PropertyTypeDescriptionImpl(); 100 101 // XTypeDescription 102 virtual TypeClass SAL_CALL getTypeClass() 103 throw( RuntimeException ); 104 virtual OUString SAL_CALL getName() 105 throw( RuntimeException ); 106 107 // XPropertyTypeDescription 108 virtual sal_Int16 SAL_CALL getPropertyFlags() 109 throw ( RuntimeException ); 110 virtual Reference< XTypeDescription > SAL_CALL getPropertyTypeDescription() 111 throw ( RuntimeException ); 112 }; 113 114 //__________________________________________________________________________________________________ 115 // virtual 116 PropertyTypeDescriptionImpl::~PropertyTypeDescriptionImpl() 117 { 118 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 119 } 120 121 // XTypeDescription 122 //__________________________________________________________________________________________________ 123 // virtual 124 TypeClass PropertyTypeDescriptionImpl::getTypeClass() 125 throw ( RuntimeException ) 126 { 127 return TypeClass_PROPERTY; 128 } 129 //__________________________________________________________________________________________________ 130 // virtual 131 OUString PropertyTypeDescriptionImpl::getName() 132 throw ( RuntimeException ) 133 { 134 return _aName; 135 } 136 137 // XPropertyTypeDescription 138 //__________________________________________________________________________________________________ 139 // virtual 140 sal_Int16 SAL_CALL PropertyTypeDescriptionImpl::getPropertyFlags() 141 throw ( RuntimeException ) 142 { 143 return _nFlags; 144 } 145 146 //__________________________________________________________________________________________________ 147 // virtual 148 Reference< XTypeDescription > SAL_CALL 149 PropertyTypeDescriptionImpl::getPropertyTypeDescription() 150 throw ( RuntimeException ) 151 { 152 return _xTD; 153 } 154 155 //================================================================================================== 156 // 157 // ServiceTypeDescriptionImpl implementation 158 // 159 //================================================================================================== 160 161 //__________________________________________________________________________________________________ 162 // virtual 163 ServiceTypeDescriptionImpl::~ServiceTypeDescriptionImpl() 164 { 165 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 166 } 167 168 // XTypeDescription 169 //__________________________________________________________________________________________________ 170 // virtual 171 TypeClass ServiceTypeDescriptionImpl::getTypeClass() 172 throw(::com::sun::star::uno::RuntimeException) 173 { 174 return TypeClass_SERVICE; 175 } 176 //__________________________________________________________________________________________________ 177 // virtual 178 OUString ServiceTypeDescriptionImpl::getName() 179 throw(::com::sun::star::uno::RuntimeException) 180 { 181 return _aName; 182 } 183 184 // XServiceTypeDescription 185 //__________________________________________________________________________________________________ 186 // virtual 187 Sequence< Reference< XServiceTypeDescription > > SAL_CALL 188 ServiceTypeDescriptionImpl::getMandatoryServices() 189 throw ( RuntimeException ) 190 { 191 getReferences(); 192 return _aMandatoryServices; 193 } 194 195 //__________________________________________________________________________________________________ 196 // virtual 197 Sequence< Reference< XServiceTypeDescription > > SAL_CALL 198 ServiceTypeDescriptionImpl::getOptionalServices() 199 throw ( RuntimeException ) 200 { 201 getReferences(); 202 return _aOptionalServices; 203 } 204 205 //__________________________________________________________________________________________________ 206 // virtual 207 Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL 208 ServiceTypeDescriptionImpl::getMandatoryInterfaces() 209 throw ( RuntimeException ) 210 { 211 getReferences(); 212 return _aMandatoryInterfaces; 213 } 214 215 //__________________________________________________________________________________________________ 216 // virtual 217 Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL 218 ServiceTypeDescriptionImpl::getOptionalInterfaces() 219 throw ( RuntimeException ) 220 { 221 getReferences(); 222 return _aOptionalInterfaces; 223 } 224 225 //__________________________________________________________________________________________________ 226 // virtual 227 Sequence< Reference< XPropertyTypeDescription > > SAL_CALL 228 ServiceTypeDescriptionImpl::getProperties() 229 throw ( RuntimeException ) 230 { 231 { 232 MutexGuard guard(getMutex()); 233 if (_pProps.get() != 0) { 234 return *_pProps; 235 } 236 } 237 238 typereg::Reader aReader( 239 _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1); 240 241 sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount(); 242 std::auto_ptr< Sequence< Reference< XPropertyTypeDescription > > > 243 pTempProps( 244 new Sequence< Reference< XPropertyTypeDescription > >(nFields)); 245 Reference< XPropertyTypeDescription > * pProps = pTempProps->getArray(); 246 247 while ( nFields-- ) 248 { 249 // name 250 OUStringBuffer aName( _aName ); 251 aName.appendAscii( "." ); 252 aName.append( aReader.getFieldName( nFields ) ); 253 254 // type description 255 Reference< XTypeDescription > xTD; 256 try 257 { 258 _xTDMgr->getByHierarchicalName( 259 aReader.getFieldTypeName( nFields ).replace( '/', '.' ) ) 260 >>= xTD; 261 } 262 catch ( NoSuchElementException const & ) 263 { 264 } 265 OSL_ENSURE( xTD.is(), "### no type description for property!" ); 266 267 // flags 268 RTFieldAccess nFlags = aReader.getFieldFlags( nFields ); 269 270 sal_Int16 nAttribs = 0; 271 if ( nFlags & RT_ACCESS_READONLY ) 272 nAttribs |= beans::PropertyAttribute::READONLY; 273 if ( nFlags & RT_ACCESS_OPTIONAL ) 274 nAttribs |= beans::PropertyAttribute::OPTIONAL; 275 if ( nFlags & RT_ACCESS_MAYBEVOID ) 276 nAttribs |= beans::PropertyAttribute::MAYBEVOID; 277 if ( nFlags & RT_ACCESS_BOUND ) 278 nAttribs |= beans::PropertyAttribute::BOUND; 279 if ( nFlags & RT_ACCESS_CONSTRAINED ) 280 nAttribs |= beans::PropertyAttribute::CONSTRAINED; 281 if ( nFlags & RT_ACCESS_TRANSIENT ) 282 nAttribs |= beans::PropertyAttribute::TRANSIENT; 283 if ( nFlags & RT_ACCESS_MAYBEAMBIGUOUS ) 284 nAttribs |= beans::PropertyAttribute::MAYBEAMBIGUOUS; 285 if ( nFlags & RT_ACCESS_MAYBEDEFAULT ) 286 nAttribs |= beans::PropertyAttribute::MAYBEDEFAULT; 287 if ( nFlags & RT_ACCESS_REMOVEABLE ) 288 nAttribs |= beans::PropertyAttribute::REMOVEABLE; 289 290 OSL_ENSURE( !(nFlags & RT_ACCESS_PROPERTY), 291 "### RT_ACCESS_PROPERTY is unexpected here!" ); 292 OSL_ENSURE( !(nFlags & RT_ACCESS_ATTRIBUTE), 293 "### RT_ACCESS_ATTRIBUTE is unexpected here!" ); 294 OSL_ENSURE( !(nFlags & RT_ACCESS_CONST), 295 "### RT_ACCESS_CONST is unexpected here!" ); 296 // always set, unless RT_ACCESS_READONLY is set. 297 //OSL_ENSURE( !(nFlags & RT_ACCESS_READWRITE), 298 // "### RT_ACCESS_READWRITE is unexpected here" ); 299 OSL_ENSURE( !(nFlags & RT_ACCESS_DEFAULT), 300 "### RT_ACCESS_DEAFAULT is unexpected here" ); 301 302 pProps[ nFields ] 303 = new PropertyTypeDescriptionImpl( aName.makeStringAndClear(), 304 xTD, 305 nAttribs ); 306 } 307 308 MutexGuard guard(getMutex()); 309 if (_pProps.get() == 0) { 310 _pProps = pTempProps; 311 } 312 return *_pProps; 313 } 314 315 sal_Bool ServiceTypeDescriptionImpl::isSingleInterfaceBased() 316 throw (RuntimeException) 317 { 318 getReferences(); 319 return _xInterfaceTD.is(); 320 } 321 322 Reference< XTypeDescription > ServiceTypeDescriptionImpl::getInterface() 323 throw (RuntimeException) 324 { 325 getReferences(); 326 return _xInterfaceTD; 327 } 328 329 Sequence< Reference< XServiceConstructorDescription > > 330 ServiceTypeDescriptionImpl::getConstructors() throw (RuntimeException) { 331 MutexGuard guard(getMutex()); 332 if (_pCtors.get() == 0) { 333 typereg::Reader reader( 334 _aBytes.getConstArray(), _aBytes.getLength(), false, 335 TYPEREG_VERSION_1); 336 sal_uInt16 ctorCount = reader.getMethodCount(); 337 std::auto_ptr< Sequence< Reference< XServiceConstructorDescription > > > 338 ctors( 339 new Sequence< Reference< XServiceConstructorDescription > >( 340 ctorCount)); 341 for (sal_uInt16 i = 0; i < ctorCount; ++i) { 342 rtl::OUString name(reader.getMethodName(i)); 343 if (reader.getMethodFlags(i) != RT_MODE_TWOWAY 344 || (!reader.getMethodReturnTypeName(i).equalsAsciiL( 345 RTL_CONSTASCII_STRINGPARAM("void"))) 346 || (name.getLength() == 0 347 && (ctorCount != 1 || reader.getMethodParameterCount(i) != 0 348 || reader.getMethodExceptionCount(i) != 0))) 349 { 350 throw RuntimeException( 351 rtl::OUString( 352 RTL_CONSTASCII_USTRINGPARAM( 353 "Service has bad constructors")), 354 static_cast< OWeakObject * >(this)); 355 } 356 (*ctors)[i] = new Constructor( 357 _xTDMgr, reader.getMethodName(i), _aBytes, i); 358 } 359 _pCtors = ctors; 360 } 361 return *_pCtors; 362 } 363 364 //__________________________________________________________________________________________________ 365 void ServiceTypeDescriptionImpl::getReferences() 366 throw ( RuntimeException ) 367 { 368 { 369 MutexGuard guard(getMutex()); 370 if (_bInitReferences) { 371 return; 372 } 373 } 374 typereg::Reader aReader( 375 _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1); 376 sal_uInt16 superTypes = aReader.getSuperTypeCount(); 377 if (superTypes > 1) { 378 throw RuntimeException( 379 rtl::OUString( 380 RTL_CONSTASCII_USTRINGPARAM( 381 "Service has more than one supertype")), 382 static_cast< OWeakObject * >(this)); 383 } 384 if (superTypes == 1) { 385 OUString aBaseName( aReader.getSuperTypeName(0).replace( '/', '.' ) ); 386 if ( aReader.getReferenceCount() != 0 387 || aReader.getFieldCount() != 0 ) 388 throw RuntimeException( 389 OUString( 390 RTL_CONSTASCII_USTRINGPARAM( 391 "Service is single-interface--based but also has" 392 " references and/or properties" ) ), 393 static_cast< OWeakObject * >( this ) ); 394 Reference< XTypeDescription > ifc; 395 try 396 { 397 _xTDMgr->getByHierarchicalName( aBaseName ) >>= ifc; 398 } 399 catch ( NoSuchElementException const & e ) 400 { 401 throw RuntimeException( 402 OUString( 403 RTL_CONSTASCII_USTRINGPARAM( 404 "com.sun.star.container.NoSuchElementException: " ) ) 405 + e.Message, 406 static_cast< OWeakObject * >( this ) ); 407 } 408 OSL_ASSERT(ifc.is()); 409 if (resolveTypedefs(ifc)->getTypeClass() != TypeClass_INTERFACE) { 410 throw RuntimeException( 411 OUString( 412 RTL_CONSTASCII_USTRINGPARAM( 413 "Single-interface--based service is not based on" 414 " interface type" ) ), 415 static_cast< OWeakObject * >( this ) ); 416 } 417 MutexGuard guard(getMutex()); 418 if (!_bInitReferences) { 419 _xInterfaceTD = ifc; 420 _bInitReferences = true; 421 } 422 } 423 else 424 { 425 sal_uInt16 nRefs = aReader.getReferenceCount(); 426 Sequence< Reference< XServiceTypeDescription > > aMandatoryServices( 427 nRefs); 428 Sequence< Reference< XServiceTypeDescription > > aOptionalServices( 429 nRefs); 430 Sequence< Reference< XInterfaceTypeDescription > > aMandatoryInterfaces( 431 nRefs); 432 Sequence< Reference< XInterfaceTypeDescription > > aOptionalInterfaces( 433 nRefs); 434 sal_uInt32 nMS = 0; 435 sal_uInt32 nOS = 0; 436 sal_uInt32 nMI = 0; 437 sal_uInt32 nOI = 0; 438 439 for ( sal_uInt16 nPos = 0; nPos < nRefs; ++nPos ) 440 { 441 RTReferenceType eType = aReader.getReferenceSort( nPos ); 442 switch ( eType ) 443 { 444 case RT_REF_EXPORTS: // service 445 { 446 uno::Any aTypeDesc; 447 try 448 { 449 aTypeDesc = _xTDMgr->getByHierarchicalName( 450 aReader.getReferenceTypeName( nPos ).replace( 451 '/', '.' ) ); 452 } 453 catch ( NoSuchElementException const & e ) 454 { 455 throw RuntimeException( 456 OUString( 457 RTL_CONSTASCII_USTRINGPARAM( 458 "com.sun.star.container." 459 "NoSuchElementException: " ) ) 460 + e.Message, 461 static_cast< OWeakObject * >( this ) ); 462 } 463 464 RTFieldAccess nAccess = aReader.getReferenceFlags( nPos ); 465 if ( nAccess & RT_ACCESS_OPTIONAL ) 466 { 467 // optional service 468 if ( !( aTypeDesc >>= aOptionalServices[ nOS ] ) ) 469 throw RuntimeException( 470 OUString( 471 RTL_CONSTASCII_USTRINGPARAM( 472 "Service 'export' is not a service" ) ), 473 static_cast< OWeakObject * >( this ) ); 474 nOS++; 475 } 476 else 477 { 478 // mandatory service 479 if ( !( aTypeDesc >>= aMandatoryServices[ nMS ] ) ) 480 throw RuntimeException( 481 OUString( 482 RTL_CONSTASCII_USTRINGPARAM( 483 "Service 'export' is not a service" ) ), 484 static_cast< OWeakObject * >( this ) ); 485 nMS++; 486 } 487 break; 488 } 489 case RT_REF_SUPPORTS: // interface 490 { 491 uno::Any aTypeDesc; 492 try 493 { 494 aTypeDesc = _xTDMgr->getByHierarchicalName( 495 aReader.getReferenceTypeName( nPos ).replace( 496 '/', '.' ) ); 497 } 498 catch ( NoSuchElementException const & e ) 499 { 500 throw RuntimeException( 501 OUString( 502 RTL_CONSTASCII_USTRINGPARAM( 503 "com.sun.star.container." 504 "NoSuchElementException: " ) ) 505 + e.Message, 506 static_cast< OWeakObject * >( this ) ); 507 } 508 509 RTFieldAccess nAccess = aReader.getReferenceFlags( nPos ); 510 if ( nAccess & RT_ACCESS_OPTIONAL ) 511 { 512 // optional interface 513 if ( !( aTypeDesc >>= aOptionalInterfaces[ nOI ] ) ) 514 throw RuntimeException( 515 OUString( 516 RTL_CONSTASCII_USTRINGPARAM( 517 "Service 'supports' is not an" 518 " interface" ) ), 519 static_cast< OWeakObject * >( this ) ); 520 nOI++; 521 } 522 else 523 { 524 // mandatory interface 525 if ( !( aTypeDesc >>= aMandatoryInterfaces[ nMI ] ) ) 526 throw RuntimeException( 527 OUString( 528 RTL_CONSTASCII_USTRINGPARAM( 529 "Service 'supports' is not an" 530 " interface" ) ), 531 static_cast< OWeakObject * >( this ) ); 532 nMI++; 533 } 534 break; 535 } 536 case RT_REF_OBSERVES: 537 case RT_REF_NEEDS: 538 break; 539 default: 540 OSL_ENSURE( sal_False, "### unsupported reference type!" ); 541 break; 542 } 543 } 544 aMandatoryServices.realloc( nMS ); 545 aOptionalServices.realloc( nOS ); 546 aMandatoryInterfaces.realloc( nMI ); 547 aOptionalInterfaces.realloc( nOI ); 548 549 MutexGuard guard(getMutex()); 550 if (!_bInitReferences) { 551 _aMandatoryServices = aMandatoryServices; 552 _aOptionalServices = aOptionalServices; 553 _aMandatoryInterfaces = aMandatoryInterfaces; 554 _aOptionalInterfaces = aOptionalInterfaces; 555 _bInitReferences = true; 556 } 557 } 558 } 559 560 561 } 562