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