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 <osl/mutex.hxx> 28 #include <uno/dispatcher.h> 29 #include <uno/mapping.hxx> 30 #include <cppuhelper/factory.hxx> 31 #include <cppuhelper/compbase4.hxx> 32 #include <cppuhelper/implbase2.hxx> 33 #include <cppuhelper/typeprovider.hxx> 34 35 #include <cppuhelper/weakref.hxx> 36 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 #include <com/sun/star/lang/XComponent.hpp> 39 #include <com/sun/star/lang/XTypeProvider.hpp> 40 #include <com/sun/star/lang/XInitialization.hpp> 41 #include <com/sun/star/registry/XSimpleRegistry.hpp> 42 #include <com/sun/star/registry/XRegistryKey.hpp> 43 #include <com/sun/star/beans/XPropertySet.hpp> 44 #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp> 45 #include "com/sun/star/uno/RuntimeException.hpp" 46 47 #include "registry/reader.hxx" 48 #include "registry/version.h" 49 #include "base.hxx" 50 #include "rdbtdp_tdenumeration.hxx" 51 #include "structtypedescription.hxx" 52 53 #define SERVICENAME "com.sun.star.reflection.TypeDescriptionProvider" 54 #define IMPLNAME "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider" 55 56 using namespace com::sun::star; 57 using namespace com::sun::star::beans; 58 using namespace com::sun::star::registry; 59 60 extern rtl_StandardModuleCount g_moduleCount; 61 62 namespace stoc_bootstrap 63 { 64 uno::Sequence< OUString > rdbtdp_getSupportedServiceNames() 65 { 66 static Sequence < OUString > *pNames = 0; 67 if( ! pNames ) 68 { 69 MutexGuard guard( Mutex::getGlobalMutex() ); 70 if( !pNames ) 71 { 72 static Sequence< OUString > seqNames(1); 73 seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME)); 74 pNames = &seqNames; 75 } 76 } 77 return *pNames; 78 } 79 80 OUString rdbtdp_getImplementationName() 81 { 82 static OUString *pImplName = 0; 83 if( ! pImplName ) 84 { 85 MutexGuard guard( Mutex::getGlobalMutex() ); 86 if( ! pImplName ) 87 { 88 static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) ); 89 pImplName = &implName; 90 } 91 } 92 return *pImplName; 93 } 94 } 95 96 namespace stoc_rdbtdp 97 { 98 struct MutexHolder 99 { 100 Mutex _aComponentMutex; 101 }; 102 //================================================================================================== 103 class ProviderImpl 104 : public MutexHolder 105 , public WeakComponentImplHelper4< XServiceInfo, 106 XHierarchicalNameAccess, 107 XTypeDescriptionEnumerationAccess, 108 XInitialization > 109 { 110 // XHierarchicalNameAccess + XTypeDescriptionEnumerationAccess wrapper 111 // first asking the tdmgr instance, then looking up locally 112 class TypeDescriptionManagerWrapper 113 : public ::cppu::WeakImplHelper2< 114 container::XHierarchicalNameAccess, 115 reflection::XTypeDescriptionEnumerationAccess> 116 { 117 com::sun::star::uno::Reference<container::XHierarchicalNameAccess> 118 m_xTDMgr; 119 com::sun::star::uno::Reference<container::XHierarchicalNameAccess> 120 m_xThisProvider; 121 public: 122 TypeDescriptionManagerWrapper( ProviderImpl * pProvider ) 123 : m_xTDMgr( pProvider->_xContext->getValueByName( 124 OUString( RTL_CONSTASCII_USTRINGPARAM( 125 "/singletons/com.sun.star.reflection." 126 "theTypeDescriptionManager") ) ), 127 UNO_QUERY_THROW ), 128 m_xThisProvider( pProvider ) 129 {} 130 // XHierarchicalNameAccess 131 virtual Any SAL_CALL getByHierarchicalName( OUString const & name ) 132 throw (container::NoSuchElementException, RuntimeException); 133 virtual sal_Bool SAL_CALL hasByHierarchicalName( OUString const & name ) 134 throw (RuntimeException); 135 136 // XTypeDescriptionEnumerationAccess 137 virtual uno::Reference< 138 reflection::XTypeDescriptionEnumeration > SAL_CALL 139 createTypeDescriptionEnumeration( 140 const ::rtl::OUString& moduleName, 141 const uno::Sequence< uno::TypeClass >& types, 142 reflection::TypeDescriptionSearchDepth depth ) 143 throw ( reflection::NoSuchTypeNameException, 144 reflection::InvalidTypeNameException, 145 uno::RuntimeException ); 146 }; 147 friend class TypeDescriptionManagerWrapper; 148 149 com::sun::star::uno::Reference< XComponentContext > _xContext; 150 com::sun::star::uno::WeakReference<XHierarchicalNameAccess> _xTDMgr; 151 com::sun::star::uno::Reference< XHierarchicalNameAccess > getTDMgr() SAL_THROW( () ); 152 153 RegistryKeyList _aBaseKeys; 154 155 protected: 156 virtual void SAL_CALL disposing(); 157 158 public: 159 ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext ); 160 virtual ~ProviderImpl(); 161 162 // XInitialization 163 virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException); 164 165 // XServiceInfo 166 virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); 167 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException); 168 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); 169 170 // XHierarchicalNameAccess 171 Any getByHierarchicalNameImpl( const OUString & rName ); 172 173 virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); 174 virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException); 175 176 // XTypeDescriptionEnumerationAccess 177 virtual ::com::sun::star::uno::Reference< 178 ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL 179 createTypeDescriptionEnumeration( 180 const ::rtl::OUString& moduleName, 181 const ::com::sun::star::uno::Sequence< 182 ::com::sun::star::uno::TypeClass >& types, 183 ::com::sun::star::reflection::TypeDescriptionSearchDepth depth ) 184 throw ( ::com::sun::star::reflection::NoSuchTypeNameException, 185 ::com::sun::star::reflection::InvalidTypeNameException, 186 ::com::sun::star::uno::RuntimeException ); 187 }; 188 //__________________________________________________________________________________________________ 189 ProviderImpl::ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext ) 190 : WeakComponentImplHelper4< 191 XServiceInfo, XHierarchicalNameAccess, 192 XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex ) 193 , _xContext( xContext ) 194 { 195 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 196 } 197 //__________________________________________________________________________________________________ 198 ProviderImpl::~ProviderImpl() 199 { 200 g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 201 } 202 203 //______________________________________________________________________________ 204 Any ProviderImpl::TypeDescriptionManagerWrapper::getByHierarchicalName( 205 OUString const & name ) throw (container::NoSuchElementException, 206 RuntimeException) 207 { 208 try 209 { 210 // first try tdmgr: 211 return m_xTDMgr->getByHierarchicalName( name ); 212 } 213 catch (container::NoSuchElementException &) 214 { 215 // then lookup locally: 216 return m_xThisProvider->getByHierarchicalName( name ); 217 } 218 } 219 220 //______________________________________________________________________________ 221 sal_Bool ProviderImpl::TypeDescriptionManagerWrapper::hasByHierarchicalName( 222 OUString const & name ) throw (RuntimeException) 223 { 224 return m_xTDMgr->hasByHierarchicalName( name ) || m_xThisProvider->hasByHierarchicalName( name ); 225 } 226 227 //______________________________________________________________________________ 228 uno::Reference< reflection::XTypeDescriptionEnumeration > SAL_CALL 229 ProviderImpl::TypeDescriptionManagerWrapper::createTypeDescriptionEnumeration( 230 const ::rtl::OUString& moduleName, 231 const uno::Sequence< uno::TypeClass >& types, 232 reflection::TypeDescriptionSearchDepth depth ) 233 throw ( reflection::NoSuchTypeNameException, 234 reflection::InvalidTypeNameException, 235 uno::RuntimeException ) 236 { 237 try 238 { 239 // first try tdmgr: 240 uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA( 241 m_xTDMgr, uno::UNO_QUERY_THROW ); 242 return 243 xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth ); 244 } 245 catch (reflection::NoSuchTypeNameException &) 246 { 247 // then lookup locally: 248 uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA( 249 m_xThisProvider, uno::UNO_QUERY_THROW ); 250 return 251 xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth ); 252 } 253 } 254 255 //__________________________________________________________________________________________________ 256 com::sun::star::uno::Reference< XHierarchicalNameAccess > ProviderImpl::getTDMgr() 257 SAL_THROW( () ) 258 { 259 // harden weak reference: 260 com::sun::star::uno::Reference<container::XHierarchicalNameAccess> xTDMgr( 261 _xTDMgr ); 262 if (! xTDMgr.is()) 263 { 264 xTDMgr.set( new TypeDescriptionManagerWrapper(this) ); 265 { 266 MutexGuard guard( _aComponentMutex ); 267 _xTDMgr = xTDMgr; 268 } 269 } 270 return xTDMgr; 271 } 272 273 //__________________________________________________________________________________________________ 274 void ProviderImpl::disposing() 275 { 276 _xContext.clear(); 277 278 for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() ); 279 iPos != _aBaseKeys.end(); ++iPos ) 280 { 281 (*iPos)->closeKey(); 282 } 283 _aBaseKeys.clear(); 284 } 285 286 // XInitialization 287 //__________________________________________________________________________________________________ 288 void ProviderImpl::initialize( 289 const Sequence< Any > & args ) 290 throw (Exception, RuntimeException) 291 { 292 // registries to read from 293 Any const * pRegistries = args.getConstArray(); 294 for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos ) 295 { 296 com::sun::star::uno::Reference< XSimpleRegistry > xRegistry( pRegistries[ nPos ], UNO_QUERY ); 297 if (xRegistry.is() && xRegistry->isValid()) 298 { 299 com::sun::star::uno::Reference< XRegistryKey > xKey( xRegistry->getRootKey()->openKey( 300 OUString( RTL_CONSTASCII_USTRINGPARAM("/UCR") ) ) ); 301 if (xKey.is() && xKey->isValid()) 302 { 303 _aBaseKeys.push_back( xKey ); 304 } 305 } 306 } 307 } 308 309 // XServiceInfo 310 //__________________________________________________________________________________________________ 311 OUString ProviderImpl::getImplementationName() 312 throw(::com::sun::star::uno::RuntimeException) 313 { 314 return stoc_bootstrap::rdbtdp_getImplementationName(); 315 } 316 //__________________________________________________________________________________________________ 317 sal_Bool ProviderImpl::supportsService( const OUString & rServiceName ) 318 throw(::com::sun::star::uno::RuntimeException) 319 { 320 const Sequence< OUString > & rSNL = getSupportedServiceNames(); 321 const OUString * pArray = rSNL.getConstArray(); 322 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) 323 { 324 if (pArray[nPos] == rServiceName) 325 return sal_True; 326 } 327 return sal_False; 328 } 329 //__________________________________________________________________________________________________ 330 Sequence< OUString > ProviderImpl::getSupportedServiceNames() 331 throw(::com::sun::star::uno::RuntimeException) 332 { 333 return stoc_bootstrap::rdbtdp_getSupportedServiceNames(); 334 } 335 336 // XHierarchicalNameAccess 337 //__________________________________________________________________________________________________ 338 Any ProviderImpl::getByHierarchicalNameImpl( const OUString & rName ) 339 { 340 Any aRet; 341 342 // read from registry 343 OUString aKey( rName.replace( '.', '/' ) ); 344 for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() ); 345 !aRet.hasValue() && iPos != _aBaseKeys.end(); ++iPos ) 346 { 347 try 348 { 349 com::sun::star::uno::Reference< XRegistryKey > xBaseKey( *iPos ); 350 com::sun::star::uno::Reference< XRegistryKey > xKey( xBaseKey->openKey( aKey ) ); 351 if (xKey.is()) 352 { 353 // closes key in it's dtor (which is 354 // called even in case of exceptions). 355 RegistryKeyCloser aCloser( xKey ); 356 357 if ( xKey->isValid() ) 358 { 359 if (xKey->getValueType() == RegistryValueType_BINARY) 360 { 361 Sequence< sal_Int8 > aBytes( xKey->getBinaryValue() ); 362 com::sun::star::uno::Reference< XTypeDescription > xTD( 363 createTypeDescription( aBytes, 364 getTDMgr(), 365 true ) ); 366 if ( xTD.is() ) 367 aRet <<= xTD; 368 } 369 } 370 } 371 else // might be a constant 372 { 373 sal_Int32 nIndex = aKey.lastIndexOf( '/' ); 374 if (nIndex > 0) 375 { 376 // open module 377 com::sun::star::uno::Reference< XRegistryKey > xKey2( xBaseKey->openKey( aKey.copy( 0, nIndex ) ) ); 378 if (xKey2.is()) 379 { 380 // closes key in it's dtor (which is 381 // called even in case of exceptions). 382 RegistryKeyCloser aCloser( xKey2 ); 383 384 if ( xKey2->isValid() ) 385 { 386 if (xKey2->getValueType() == RegistryValueType_BINARY) 387 { 388 Sequence< sal_Int8 > aBytes( xKey2->getBinaryValue() ); 389 typereg::Reader aReader( 390 aBytes.getConstArray(), aBytes.getLength(), 391 false, TYPEREG_VERSION_1); 392 393 if (aReader.getTypeClass() == RT_TYPE_MODULE || 394 aReader.getTypeClass() == RT_TYPE_CONSTANTS || 395 aReader.getTypeClass() == RT_TYPE_ENUM) 396 { 397 OUString aFieldName( aKey.copy( nIndex+1, aKey.getLength() - nIndex -1 ) ); 398 sal_Int16 nPos = aReader.getFieldCount(); 399 while (nPos--) 400 { 401 if (aFieldName.equals( 402 aReader.getFieldName(nPos))) 403 break; 404 } 405 if (nPos >= 0) 406 aRet = getRTValue( 407 aReader.getFieldValue(nPos)); 408 } 409 } 410 } 411 } 412 } 413 } 414 } 415 catch ( InvalidRegistryException const & ) 416 { 417 OSL_ENSURE( sal_False, 418 "ProviderImpl::getByHierarchicalName " 419 "- Caught InvalidRegistryException!" ); 420 421 // openKey, closeKey, getValueType, getBinaryValue, isValid 422 423 // Don't stop iteration in this case. 424 } 425 catch ( NoSuchElementException const & ) 426 { 427 } 428 } 429 return aRet; 430 } 431 432 Any SAL_CALL ProviderImpl::getByHierarchicalName( const OUString & rName ) 433 throw(::com::sun::star::uno::RuntimeException, com::sun::star::container::NoSuchElementException) 434 { 435 Any aRet( getByHierarchicalNameImpl( rName ) ); 436 437 if ( !aRet.hasValue() ) 438 throw NoSuchElementException( 439 rName, static_cast< cppu::OWeakObject * >( this ) ); 440 441 return aRet; 442 } 443 444 //__________________________________________________________________________________________________ 445 sal_Bool ProviderImpl::hasByHierarchicalName( const OUString & rName ) 446 throw(::com::sun::star::uno::RuntimeException) 447 { 448 return getByHierarchicalNameImpl( rName ).hasValue(); 449 } 450 451 // XTypeDescriptionEnumerationAccess 452 //__________________________________________________________________________________________________ 453 // virtual 454 com::sun::star::uno::Reference< XTypeDescriptionEnumeration > SAL_CALL 455 ProviderImpl::createTypeDescriptionEnumeration( 456 const OUString & moduleName, 457 const Sequence< TypeClass > & types, 458 TypeDescriptionSearchDepth depth ) 459 throw ( NoSuchTypeNameException, 460 InvalidTypeNameException, 461 RuntimeException ) 462 { 463 return com::sun::star::uno::Reference< XTypeDescriptionEnumeration >( 464 TypeDescriptionEnumerationImpl::createInstance( getTDMgr(), 465 moduleName, 466 types, 467 depth, 468 _aBaseKeys ).get() ); 469 } 470 471 //__________________________________________________________________________________________________ 472 // global helper function 473 474 com::sun::star::uno::Reference< XTypeDescription > resolveTypedefs( 475 com::sun::star::uno::Reference< XTypeDescription > const & type) 476 { 477 com::sun::star::uno::Reference< XTypeDescription > resolved(type); 478 while (resolved->getTypeClass() == TypeClass_TYPEDEF) { 479 resolved = com::sun::star::uno::Reference< XIndirectTypeDescription >( 480 resolved, UNO_QUERY_THROW)->getReferencedType(); 481 } 482 return resolved; 483 } 484 485 com::sun::star::uno::Reference< XTypeDescription > createTypeDescription( 486 const Sequence< sal_Int8 > & rData, 487 const com::sun::star::uno::Reference< XHierarchicalNameAccess > & xNameAccess, 488 bool bReturnEmptyRefForUnknownType ) 489 { 490 typereg::Reader aReader( 491 rData.getConstArray(), rData.getLength(), false, TYPEREG_VERSION_1); 492 493 OUString aName( aReader.getTypeName().replace( '/', '.' ) ); 494 495 switch (aReader.getTypeClass()) 496 { 497 case RT_TYPE_INTERFACE: 498 { 499 sal_uInt16 n = aReader.getSuperTypeCount(); 500 com::sun::star::uno::Sequence< rtl::OUString > aBaseTypeNames(n); 501 {for (sal_uInt16 i = 0; i < n; ++i) { 502 aBaseTypeNames[i] = aReader.getSuperTypeName(i).replace( 503 '/', '.'); 504 }} 505 sal_uInt16 n2 = aReader.getReferenceCount(); 506 com::sun::star::uno::Sequence< rtl::OUString > 507 aOptionalBaseTypeNames(n2); 508 {for (sal_uInt16 i = 0; i < n2; ++i) { 509 OSL_ASSERT( 510 aReader.getReferenceSort(i) == RT_REF_SUPPORTS 511 && aReader.getReferenceFlags(i) == RT_ACCESS_OPTIONAL); 512 aOptionalBaseTypeNames[i] = aReader.getReferenceTypeName(i); 513 }} 514 return com::sun::star::uno::Reference< XTypeDescription >( 515 new InterfaceTypeDescriptionImpl( xNameAccess, 516 aName, 517 aBaseTypeNames, 518 aOptionalBaseTypeNames, 519 rData, 520 aReader.isPublished() ) ); 521 } 522 523 case RT_TYPE_MODULE: 524 { 525 com::sun::star::uno::Reference< 526 XTypeDescriptionEnumerationAccess > xTDEA( 527 xNameAccess, UNO_QUERY ); 528 529 OSL_ENSURE( xTDEA.is(), 530 "No XTypeDescriptionEnumerationAccess!" ); 531 532 return com::sun::star::uno::Reference< XTypeDescription >( 533 new ModuleTypeDescriptionImpl( xTDEA, aName ) ); 534 } 535 536 case RT_TYPE_STRUCT: 537 { 538 rtl::OUString superTypeName; 539 if (aReader.getSuperTypeCount() == 1) { 540 superTypeName = aReader.getSuperTypeName(0).replace( 541 '/', '.'); 542 } 543 return com::sun::star::uno::Reference< XTypeDescription >( 544 new stoc::registry_tdprovider::StructTypeDescription( 545 xNameAccess, aName, superTypeName, rData, 546 aReader.isPublished())); 547 } 548 549 case RT_TYPE_ENUM: 550 return com::sun::star::uno::Reference< XTypeDescription >( 551 new EnumTypeDescriptionImpl( xNameAccess, 552 aName, 553 getRTValueAsInt32( 554 aReader.getFieldValue( 0 ) ), 555 rData, aReader.isPublished() ) ); 556 557 case RT_TYPE_EXCEPTION: 558 { 559 rtl::OUString superTypeName; 560 if (aReader.getSuperTypeCount() == 1) { 561 superTypeName = aReader.getSuperTypeName(0).replace( 562 '/', '.'); 563 } 564 return com::sun::star::uno::Reference< XTypeDescription >( 565 new CompoundTypeDescriptionImpl( 566 xNameAccess, TypeClass_EXCEPTION, aName, superTypeName, 567 rData, aReader.isPublished())); 568 } 569 570 case RT_TYPE_TYPEDEF: 571 return com::sun::star::uno::Reference< XTypeDescription >( 572 new TypedefTypeDescriptionImpl( xNameAccess, 573 aName, 574 aReader.getSuperTypeName(0) 575 .replace( '/', '.' ), 576 aReader.isPublished() ) ); 577 case RT_TYPE_SERVICE: 578 return com::sun::star::uno::Reference< XTypeDescription >( 579 new ServiceTypeDescriptionImpl( 580 xNameAccess, aName, rData, aReader.isPublished() ) ); 581 582 case RT_TYPE_CONSTANTS: 583 return com::sun::star::uno::Reference< XTypeDescription >( 584 new ConstantsTypeDescriptionImpl( 585 aName, rData, aReader.isPublished() ) ); 586 587 case RT_TYPE_SINGLETON: 588 return com::sun::star::uno::Reference< XTypeDescription >( 589 new SingletonTypeDescriptionImpl( xNameAccess, 590 aName, 591 aReader.getSuperTypeName(0) 592 .replace( '/', '.' ), 593 aReader.isPublished() ) ); 594 case RT_TYPE_INVALID: 595 case RT_TYPE_OBJECT: // deprecated and not used 596 case RT_TYPE_UNION: // deprecated and not used 597 OSL_ENSURE( sal_False, "createTypeDescription - Unsupported Type!" ); 598 break; 599 600 default: 601 OSL_ENSURE( sal_False, "createTypeDescription - Unknown Type!" ); 602 break; 603 } 604 605 // Unknown type. 606 607 if ( bReturnEmptyRefForUnknownType ) 608 return com::sun::star::uno::Reference< XTypeDescription >(); 609 610 return com::sun::star::uno::Reference< XTypeDescription >( 611 new TypeDescriptionImpl( TypeClass_UNKNOWN, aName ) ); 612 } 613 614 } 615 616 namespace stoc_bootstrap 617 { 618 //================================================================================================== 619 com::sun::star::uno::Reference< XInterface > SAL_CALL ProviderImpl_create( 620 com::sun::star::uno::Reference< XComponentContext > const & xContext ) 621 throw(::com::sun::star::uno::Exception) 622 { 623 return com::sun::star::uno::Reference< XInterface >( *new stoc_rdbtdp::ProviderImpl( xContext ) ); 624 } 625 } 626