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