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_sdbc2.hxx" 26 27 #include <stdio.h> 28 29 #include "mdrivermanager.hxx" 30 #include <com/sun/star/sdbc/XDriver.hpp> 31 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 32 #include <com/sun/star/container/ElementExistException.hpp> 33 #include <com/sun/star/beans/NamedValue.hpp> 34 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp> 35 36 #include <tools/diagnose_ex.h> 37 #include <comphelper/extract.hxx> 38 #include <comphelper/stl_types.hxx> 39 #include <cppuhelper/implbase1.hxx> 40 #include <cppuhelper/weakref.hxx> 41 #include <osl/diagnose.h> 42 43 #include <algorithm> 44 #include <functional> 45 #include <iterator> 46 47 namespace drivermanager 48 { 49 50 using namespace ::com::sun::star::uno; 51 using namespace ::com::sun::star::lang; 52 using namespace ::com::sun::star::sdbc; 53 using namespace ::com::sun::star::beans; 54 using namespace ::com::sun::star::container; 55 using namespace ::com::sun::star::logging; 56 using namespace ::osl; 57 58 #define SERVICE_SDBC_DRIVER ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver") 59 60 void throwNoSuchElementException() 61 { 62 throw NoSuchElementException(); 63 } 64 65 //========================================================================== 66 //= ODriverEnumeration 67 //========================================================================== 68 class ODriverEnumeration : public ::cppu::WeakImplHelper1< XEnumeration > 69 { 70 friend class OSDBCDriverManager; 71 72 DECLARE_STL_VECTOR( SdbcDriver, DriverArray ); 73 DriverArray m_aDrivers; 74 ConstDriverArrayIterator m_aPos; 75 // order matters! 76 77 protected: 78 virtual ~ODriverEnumeration(); 79 public: 80 ODriverEnumeration(const DriverArray& _rDriverSequence); 81 82 // XEnumeration 83 virtual sal_Bool SAL_CALL hasMoreElements( ); 84 virtual Any SAL_CALL nextElement( ); 85 }; 86 87 //-------------------------------------------------------------------------- 88 ODriverEnumeration::ODriverEnumeration(const DriverArray& _rDriverSequence) 89 :m_aDrivers( _rDriverSequence ) 90 ,m_aPos( m_aDrivers.begin() ) 91 { 92 } 93 94 //-------------------------------------------------------------------------- 95 ODriverEnumeration::~ODriverEnumeration() 96 { 97 } 98 99 //-------------------------------------------------------------------------- 100 sal_Bool SAL_CALL ODriverEnumeration::hasMoreElements( ) 101 { 102 return m_aPos != m_aDrivers.end(); 103 } 104 105 //-------------------------------------------------------------------------- 106 Any SAL_CALL ODriverEnumeration::nextElement( ) 107 { 108 if ( !hasMoreElements() ) 109 throwNoSuchElementException(); 110 111 return makeAny( *m_aPos++ ); 112 } 113 114 //===================================================================== 115 //= helper 116 //===================================================================== 117 //--------------------------------------------------------------------- 118 //--- 24.08.01 11:27:59 ----------------------------------------------- 119 120 /// an STL functor which ensures that a SdbcDriver described by a DriverAccess is loaded 121 struct EnsureDriver : public ::std::unary_function< DriverAccess, DriverAccess > 122 { 123 EnsureDriver( const Reference< XComponentContext > &rxContext ) 124 : mxContext( rxContext ) {} 125 126 const DriverAccess& operator()( const DriverAccess& _rDescriptor ) const 127 { 128 if ( !_rDescriptor.xDriver.is() ) 129 // we did not load this driver, yet 130 if ( _rDescriptor.xComponentFactory.is() ) 131 // we have a factory for it 132 const_cast< DriverAccess& >( _rDescriptor ).xDriver = _rDescriptor.xDriver.query( 133 _rDescriptor.xComponentFactory->createInstanceWithContext( mxContext ) ); 134 return _rDescriptor; 135 } 136 137 private: 138 Reference< XComponentContext > mxContext; 139 }; 140 141 //--------------------------------------------------------------------- 142 //--- 24.08.01 11:28:04 ----------------------------------------------- 143 144 /// an STL functor which extracts a SdbcDriver from a DriverAccess 145 struct ExtractDriverFromAccess : public ::std::unary_function< DriverAccess, SdbcDriver > 146 { 147 SdbcDriver operator()( const DriverAccess& _rAccess ) const 148 { 149 return _rAccess.xDriver; 150 } 151 }; 152 153 //--------------------------------------------------------------------- 154 //--- 24.08.01 12:37:50 ----------------------------------------------- 155 156 typedef ::std::unary_compose< ExtractDriverFromAccess, EnsureDriver > ExtractAfterLoad_BASE; 157 /// an STL functor which loads a driver described by a DriverAccess, and extracts the SdbcDriver 158 struct ExtractAfterLoad : public ExtractAfterLoad_BASE 159 { 160 ExtractAfterLoad( const Reference< XComponentContext > &rxContext ) 161 : ExtractAfterLoad_BASE( ExtractDriverFromAccess(), EnsureDriver( rxContext ) ) {} 162 }; 163 164 //--------------------------------------------------------------------- 165 //--- 24.08.01 11:42:36 ----------------------------------------------- 166 167 struct ExtractDriverFromCollectionElement : public ::std::unary_function< DriverCollection::value_type, SdbcDriver > 168 { 169 SdbcDriver operator()( const DriverCollection::value_type& _rElement ) const 170 { 171 return _rElement.second; 172 } 173 }; 174 175 //--------------------------------------------------------------------- 176 //--- 24.08.01 11:51:03 ----------------------------------------------- 177 178 // predicate for checking whether or not a driver accepts a given URL 179 class AcceptsURL : public ::std::unary_function< SdbcDriver, bool > 180 { 181 protected: 182 const ::rtl::OUString& m_rURL; 183 184 public: 185 // ctor 186 AcceptsURL( const ::rtl::OUString& _rURL ) : m_rURL( _rURL ) { } 187 188 //................................................................. 189 bool operator()( const SdbcDriver& _rDriver ) const 190 { 191 // ask the driver 192 if ( _rDriver.is() && _rDriver->acceptsURL( m_rURL ) ) 193 return true; 194 195 // does not accept ... 196 return false; 197 } 198 }; 199 200 //--------------------------------------------------------------------- 201 //--- 24.08.01 12:51:54 ----------------------------------------------- 202 203 static sal_Int32 lcl_getDriverPrecedence( const ::comphelper::ComponentContext& _rContext, Sequence< ::rtl::OUString >& _rPrecedence ) 204 { 205 _rPrecedence.realloc( 0 ); 206 try 207 { 208 // some strings we need 209 const ::rtl::OUString sConfigurationProviderServiceName = 210 ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"); 211 const ::rtl::OUString sDriverManagerConfigLocation = 212 ::rtl::OUString::createFromAscii("org.openoffice.Office.DataAccess/DriverManager"); 213 const ::rtl::OUString sDriverPreferenceLocation = 214 ::rtl::OUString::createFromAscii("DriverPrecedence"); 215 const ::rtl::OUString sNodePathArgumentName = 216 ::rtl::OUString::createFromAscii("nodepath"); 217 const ::rtl::OUString sNodeAccessServiceName = 218 ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"); 219 220 // create a configuration provider 221 Reference< XMultiServiceFactory > xConfigurationProvider; 222 if ( !_rContext.createComponent( sConfigurationProviderServiceName, xConfigurationProvider ) ) 223 throw ServiceNotRegisteredException( sConfigurationProviderServiceName, NULL ); 224 225 // one argument for creating the node access: the path to the configuration node 226 Sequence< Any > aCreationArgs(1); 227 aCreationArgs[0] <<= NamedValue( sNodePathArgumentName, makeAny( sDriverManagerConfigLocation ) ); 228 229 // create the node access 230 Reference< XNameAccess > xDriverManagerNode(xConfigurationProvider->createInstanceWithArguments(sNodeAccessServiceName, aCreationArgs), UNO_QUERY); 231 232 OSL_ENSURE(xDriverManagerNode.is(), "lcl_getDriverPrecedence: could not open my configuration node!"); 233 if (xDriverManagerNode.is()) 234 { 235 // obtain the preference list 236 Any aPreferences = xDriverManagerNode->getByName(sDriverPreferenceLocation); 237 #if OSL_DEBUG_LEVEL > 0 238 sal_Bool bSuccess = 239 #endif 240 aPreferences >>= _rPrecedence; 241 OSL_ENSURE(bSuccess || !aPreferences.hasValue(), "lcl_getDriverPrecedence: invalid value for the preferences node (no string sequence but not NULL)!"); 242 } 243 } 244 catch( const Exception& ) 245 { 246 DBG_UNHANDLED_EXCEPTION(); 247 } 248 249 return _rPrecedence.getLength(); 250 } 251 252 //--------------------------------------------------------------------- 253 //--- 24.08.01 13:01:56 ----------------------------------------------- 254 255 /// an STL argorithm compatible predicate comparing two DriverAccess instances by their implementation names 256 struct CompareDriverAccessByName : public ::std::binary_function< DriverAccess, DriverAccess, bool > 257 { 258 //................................................................. 259 bool operator()( const DriverAccess& lhs, const DriverAccess& rhs ) 260 { 261 return lhs.sImplementationName < rhs.sImplementationName ? true : false; 262 } 263 }; 264 265 //--------------------------------------------------------------------- 266 //--- 24.08.01 13:08:17 ----------------------------------------------- 267 268 /// and STL argorithm compatible predicate comparing a DriverAccess' impl name to a string 269 struct CompareDriverAccessToName : public ::std::binary_function< DriverAccess, ::rtl::OUString, bool > 270 { 271 //................................................................. 272 bool operator()( const DriverAccess& lhs, const ::rtl::OUString& rhs ) 273 { 274 return lhs.sImplementationName < rhs ? true : false; 275 } 276 //................................................................. 277 bool operator()( const ::rtl::OUString& lhs, const DriverAccess& rhs ) 278 { 279 return lhs < rhs.sImplementationName ? true : false; 280 } 281 }; 282 283 /// and STL argorithm compatible predicate comparing a DriverAccess' impl name to a string 284 struct EqualDriverAccessToName : public ::std::binary_function< DriverAccess, ::rtl::OUString, bool > 285 { 286 ::rtl::OUString m_sImplName; 287 EqualDriverAccessToName(const ::rtl::OUString& _sImplName) : m_sImplName(_sImplName){} 288 //................................................................. 289 bool operator()( const DriverAccess& lhs) 290 { 291 return lhs.sImplementationName.equals(m_sImplName); 292 } 293 }; 294 295 //========================================================================== 296 //= OSDBCDriverManager 297 //========================================================================== 298 //-------------------------------------------------------------------------- 299 OSDBCDriverManager::OSDBCDriverManager( const Reference< XComponentContext >& _rxContext ) 300 :m_aContext( _rxContext ) 301 ,m_aEventLogger( _rxContext, "org.openoffice.logging.sdbc.DriverManager" ) 302 ,m_aDriverConfig(m_aContext.getLegacyServiceFactory()) 303 ,m_nLoginTimeout(0) 304 { 305 // bootstrap all objects supporting the .sdb.Driver service 306 bootstrapDrivers(); 307 308 // initialize the drivers order 309 initializeDriverPrecedence(); 310 } 311 312 //--------------------------------------------------------------------- 313 OSDBCDriverManager::~OSDBCDriverManager() 314 { 315 } 316 317 //--------------------------------------------------------------------- 318 //--- 24.08.01 11:15:32 ----------------------------------------------- 319 320 void OSDBCDriverManager::bootstrapDrivers() 321 { 322 Reference< XContentEnumerationAccess > xEnumAccess( m_aContext.getLegacyServiceFactory(), UNO_QUERY ); 323 Reference< XEnumeration > xEnumDrivers; 324 if (xEnumAccess.is()) 325 xEnumDrivers = xEnumAccess->createContentEnumeration(SERVICE_SDBC_DRIVER); 326 327 OSL_ENSURE( xEnumDrivers.is(), "OSDBCDriverManager::bootstrapDrivers: no enumeration for the drivers available!" ); 328 if (xEnumDrivers.is()) 329 { 330 Reference< XSingleComponentFactory > xFactory; 331 Reference< XServiceInfo > xSI; 332 while (xEnumDrivers->hasMoreElements()) 333 { 334 ::cppu::extractInterface( xFactory, xEnumDrivers->nextElement() ); 335 OSL_ENSURE( xFactory.is(), "OSDBCDriverManager::bootstrapDrivers: no factory extracted" ); 336 337 if ( xFactory.is() ) 338 { 339 // we got a factory for the driver 340 DriverAccess aDriverDescriptor; 341 sal_Bool bValidDescriptor = sal_False; 342 343 // can it tell us something about the implementation name? 344 xSI = xSI.query( xFactory ); 345 if ( xSI.is() ) 346 { // yes -> no need to load the driver immediately (load it later when needed) 347 aDriverDescriptor.sImplementationName = xSI->getImplementationName(); 348 aDriverDescriptor.xComponentFactory = xFactory; 349 bValidDescriptor = sal_True; 350 351 m_aEventLogger.log( LogLevel::CONFIG, 352 "found SDBC driver $1$, no need to load it", 353 aDriverDescriptor.sImplementationName 354 ); 355 } 356 else 357 { 358 // no -> create the driver 359 Reference< XDriver > xDriver( xFactory->createInstanceWithContext( m_aContext.getUNOContext() ), UNO_QUERY ); 360 OSL_ENSURE( xDriver.is(), "OSDBCDriverManager::bootstrapDrivers: a driver which is no driver?!" ); 361 362 if ( xDriver.is() ) 363 { 364 aDriverDescriptor.xDriver = xDriver; 365 // and obtain it's implementation name 366 xSI = xSI.query( xDriver ); 367 OSL_ENSURE( xSI.is(), "OSDBCDriverManager::bootstrapDrivers: a driver without service info?" ); 368 if ( xSI.is() ) 369 { 370 aDriverDescriptor.sImplementationName = xSI->getImplementationName(); 371 bValidDescriptor = sal_True; 372 373 m_aEventLogger.log( LogLevel::CONFIG, 374 "found SDBC driver $1$, needed to load it", 375 aDriverDescriptor.sImplementationName 376 ); 377 } 378 } 379 } 380 381 if ( bValidDescriptor ) 382 { 383 m_aDriversBS.push_back( aDriverDescriptor ); 384 } 385 } 386 } 387 } 388 } 389 390 //-------------------------------------------------------------------------- 391 void OSDBCDriverManager::initializeDriverPrecedence() 392 { 393 if ( m_aDriversBS.empty() ) 394 // nothing to do 395 return; 396 397 try 398 { 399 // get the precedence of the drivers from the configuration 400 Sequence< ::rtl::OUString > aDriverOrder; 401 if ( 0 == lcl_getDriverPrecedence( m_aContext, aDriverOrder ) ) 402 // nothing to do 403 return; 404 405 // aDriverOrder now is the list of driver implementation names in the order they should be used 406 407 if ( m_aEventLogger.isLoggable( LogLevel::CONFIG ) ) 408 { 409 sal_Int32 nOrderedCount = aDriverOrder.getLength(); 410 for ( sal_Int32 i=0; i<nOrderedCount; ++i ) 411 m_aEventLogger.log( LogLevel::CONFIG, 412 "configuration's driver order: driver $1$ of $2$: $3$", 413 (sal_Int32)(i + 1), nOrderedCount, aDriverOrder[i] 414 ); 415 } 416 417 // sort our bootstrapped drivers 418 ::std::sort( m_aDriversBS.begin(), m_aDriversBS.end(), CompareDriverAccessByName() ); 419 420 // loop through the names in the precedence order 421 const ::rtl::OUString* pDriverOrder = aDriverOrder.getConstArray(); 422 const ::rtl::OUString* pDriverOrderEnd = pDriverOrder + aDriverOrder.getLength(); 423 424 // the first driver for which there is no preference 425 DriverAccessArrayIterator aNoPrefDriversStart = m_aDriversBS.begin(); 426 // at the moment this is the first of all drivers we know 427 428 for ( ; ( pDriverOrder < pDriverOrderEnd ) && ( aNoPrefDriversStart != m_aDriversBS.end() ); ++pDriverOrder ) 429 { 430 // look for the impl name in the DriverAccess array 431 ::std::pair< DriverAccessArrayIterator, DriverAccessArrayIterator > aPos = 432 ::std::equal_range( aNoPrefDriversStart, m_aDriversBS.end(), *pDriverOrder, CompareDriverAccessToName() ); 433 434 if ( aPos.first != aPos.second ) 435 { // we have a DriverAccess with this impl name 436 437 OSL_ENSURE( ::std::distance( aPos.first, aPos.second ) == 1, 438 "OSDBCDriverManager::initializeDriverPrecedence: more than one driver with this impl name? How this?" ); 439 // move the DriverAccess pointed to by aPos.first to the position pointed to by aNoPrefDriversStart 440 441 if ( aPos.first != aNoPrefDriversStart ) 442 { // if this does not hold, the DriverAccess alread has the correct position 443 444 // rotate the range [aNoPrefDriversStart, aPos.second) right 1 element 445 ::std::rotate( aNoPrefDriversStart, aPos.second - 1, aPos.second ); 446 } 447 448 // next round we start searching and pos right 449 ++aNoPrefDriversStart; 450 } 451 } 452 } 453 catch (Exception&) 454 { 455 OSL_ENSURE(sal_False, "OSDBCDriverManager::initializeDriverPrecedence: caught an exception while sorting the drivers!"); 456 } 457 } 458 459 //-------------------------------------------------------------------------- 460 Reference< XConnection > SAL_CALL OSDBCDriverManager::getConnection( const ::rtl::OUString& _rURL ) 461 { 462 MutexGuard aGuard(m_aMutex); 463 464 m_aEventLogger.log( LogLevel::INFO, 465 "connection requested for URL $1$", 466 _rURL 467 ); 468 469 Reference< XConnection > xConnection; 470 Reference< XDriver > xDriver = implGetDriverForURL(_rURL); 471 if (xDriver.is()) 472 { 473 // TODO : handle the login timeout 474 xConnection = xDriver->connect(_rURL, Sequence< PropertyValue >()); 475 // may throw an exception 476 m_aEventLogger.log( LogLevel::INFO, 477 "connection retrieved for URL $1$", 478 _rURL 479 ); 480 } 481 482 return xConnection; 483 } 484 485 //-------------------------------------------------------------------------- 486 Reference< XConnection > SAL_CALL OSDBCDriverManager::getConnectionWithInfo( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rInfo ) 487 { 488 MutexGuard aGuard(m_aMutex); 489 490 m_aEventLogger.log( LogLevel::INFO, 491 "connection with info requested for URL $1$", 492 _rURL 493 ); 494 495 Reference< XConnection > xConnection; 496 Reference< XDriver > xDriver = implGetDriverForURL(_rURL); 497 if (xDriver.is()) 498 { 499 // TODO : handle the login timeout 500 xConnection = xDriver->connect(_rURL, _rInfo); 501 // may throw an exception 502 m_aEventLogger.log( LogLevel::INFO, 503 "connection with info retrieved for URL $1$", 504 _rURL 505 ); 506 } 507 508 return xConnection; 509 } 510 511 //-------------------------------------------------------------------------- 512 void SAL_CALL OSDBCDriverManager::setLoginTimeout( sal_Int32 seconds ) 513 { 514 MutexGuard aGuard(m_aMutex); 515 m_nLoginTimeout = seconds; 516 } 517 518 //-------------------------------------------------------------------------- 519 sal_Int32 SAL_CALL OSDBCDriverManager::getLoginTimeout( ) 520 { 521 MutexGuard aGuard(m_aMutex); 522 return m_nLoginTimeout; 523 } 524 525 //-------------------------------------------------------------------------- 526 Reference< XEnumeration > SAL_CALL OSDBCDriverManager::createEnumeration( ) 527 { 528 MutexGuard aGuard(m_aMutex); 529 530 ODriverEnumeration::DriverArray aDrivers; 531 532 // ensure that all our bootstrapped drivers are insatntiated 533 ::std::for_each( m_aDriversBS.begin(), m_aDriversBS.end(), EnsureDriver( m_aContext.getUNOContext() ) ); 534 535 // copy the bootstrapped drivers 536 ::std::transform( 537 m_aDriversBS.begin(), // "copy from" start 538 m_aDriversBS.end(), // "copy from" end 539 ::std::back_inserter( aDrivers ), // insert into 540 ExtractDriverFromAccess() // transformation to apply (extract a driver from a driver access) 541 ); 542 543 // append the runtime drivers 544 ::std::transform( 545 m_aDriversRT.begin(), // "copy from" start 546 m_aDriversRT.end(), // "copy from" end 547 ::std::back_inserter( aDrivers ), // insert into 548 ExtractDriverFromCollectionElement() // transformation to apply (extract a driver from a driver access) 549 ); 550 551 return new ODriverEnumeration( aDrivers ); 552 } 553 554 //-------------------------------------------------------------------------- 555 ::com::sun::star::uno::Type SAL_CALL OSDBCDriverManager::getElementType( ) 556 { 557 return ::getCppuType(static_cast< Reference< XDriver >* >(NULL)); 558 } 559 560 //-------------------------------------------------------------------------- 561 sal_Bool SAL_CALL OSDBCDriverManager::hasElements( ) 562 { 563 MutexGuard aGuard(m_aMutex); 564 return !(m_aDriversBS.empty() && m_aDriversRT.empty()); 565 } 566 567 //-------------------------------------------------------------------------- 568 ::rtl::OUString SAL_CALL OSDBCDriverManager::getImplementationName( ) 569 { 570 return getImplementationName_static(); 571 } 572 573 //-------------------------------------------------------------------------- 574 sal_Bool SAL_CALL OSDBCDriverManager::supportsService( const ::rtl::OUString& _rServiceName ) 575 { 576 Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); 577 const ::rtl::OUString* pSupported = aSupported.getConstArray(); 578 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); 579 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported) 580 ; 581 582 return pSupported != pEnd; 583 } 584 585 //-------------------------------------------------------------------------- 586 Sequence< ::rtl::OUString > SAL_CALL OSDBCDriverManager::getSupportedServiceNames( ) 587 { 588 return getSupportedServiceNames_static(); 589 } 590 591 //-------------------------------------------------------------------------- 592 Reference< XInterface > SAL_CALL OSDBCDriverManager::Create( const Reference< XMultiServiceFactory >& _rxFactory ) 593 { 594 ::comphelper::ComponentContext aContext( _rxFactory ); 595 return *( new OSDBCDriverManager( aContext.getUNOContext() ) ); 596 } 597 598 //-------------------------------------------------------------------------- 599 ::rtl::OUString SAL_CALL OSDBCDriverManager::getImplementationName_static( ) 600 { 601 return ::rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.OSDBCDriverManager"); 602 } 603 604 //-------------------------------------------------------------------------- 605 Sequence< ::rtl::OUString > SAL_CALL OSDBCDriverManager::getSupportedServiceNames_static( ) 606 { 607 Sequence< ::rtl::OUString > aSupported(1); 608 aSupported[0] = getSingletonName_static(); 609 return aSupported; 610 } 611 612 //-------------------------------------------------------------------------- 613 ::rtl::OUString SAL_CALL OSDBCDriverManager::getSingletonName_static( ) 614 { 615 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.DriverManager" ) ); 616 } 617 618 //-------------------------------------------------------------------------- 619 Reference< XInterface > SAL_CALL OSDBCDriverManager::getRegisteredObject( const ::rtl::OUString& _rName ) 620 { 621 MutexGuard aGuard(m_aMutex); 622 ConstDriverCollectionIterator aSearch = m_aDriversRT.find(_rName); 623 if (aSearch == m_aDriversRT.end()) 624 throwNoSuchElementException(); 625 626 return aSearch->second.get(); 627 } 628 629 //-------------------------------------------------------------------------- 630 void SAL_CALL OSDBCDriverManager::registerObject( const ::rtl::OUString& _rName, const Reference< XInterface >& _rxObject ) 631 { 632 MutexGuard aGuard(m_aMutex); 633 634 m_aEventLogger.log( LogLevel::INFO, 635 "attempt to register new driver for name $1$", 636 _rName 637 ); 638 639 ConstDriverCollectionIterator aSearch = m_aDriversRT.find(_rName); 640 if (aSearch == m_aDriversRT.end()) 641 { 642 Reference< XDriver > xNewDriver(_rxObject, UNO_QUERY); 643 if (xNewDriver.is()) 644 m_aDriversRT.insert(DriverCollection::value_type(_rName, xNewDriver)); 645 else 646 throw IllegalArgumentException(); 647 } 648 else 649 throw ElementExistException(); 650 651 m_aEventLogger.log( LogLevel::INFO, 652 "new driver registered for name $1$", 653 _rName 654 ); 655 } 656 657 //-------------------------------------------------------------------------- 658 void SAL_CALL OSDBCDriverManager::revokeObject( const ::rtl::OUString& _rName ) 659 { 660 MutexGuard aGuard(m_aMutex); 661 662 m_aEventLogger.log( LogLevel::INFO, 663 "attempt to revoke driver for name $1$", 664 _rName 665 ); 666 667 DriverCollectionIterator aSearch = m_aDriversRT.find(_rName); 668 if (aSearch == m_aDriversRT.end()) 669 throwNoSuchElementException(); 670 671 m_aDriversRT.erase(aSearch); // we already have the iterator so we could use it 672 673 m_aEventLogger.log( LogLevel::INFO, 674 "driver revoked for name $1$", 675 _rName 676 ); 677 } 678 679 //-------------------------------------------------------------------------- 680 Reference< XDriver > SAL_CALL OSDBCDriverManager::getDriverByURL( const ::rtl::OUString& _rURL ) 681 { 682 m_aEventLogger.log( LogLevel::INFO, 683 "driver requested for URL $1$", 684 _rURL 685 ); 686 687 Reference< XDriver > xDriver( implGetDriverForURL( _rURL ) ); 688 689 if ( xDriver.is() ) 690 m_aEventLogger.log( LogLevel::INFO, 691 "driver obtained for URL $1$", 692 _rURL 693 ); 694 695 return xDriver; 696 } 697 698 //-------------------------------------------------------------------------- 699 Reference< XDriver > OSDBCDriverManager::implGetDriverForURL(const ::rtl::OUString& _rURL) 700 { 701 Reference< XDriver > xReturn; 702 703 { 704 const ::rtl::OUString sDriverFactoryName = m_aDriverConfig.getDriverFactoryName(_rURL); 705 706 EqualDriverAccessToName aEqual(sDriverFactoryName); 707 DriverAccessArray::iterator aFind = ::std::find_if(m_aDriversBS.begin(),m_aDriversBS.end(),aEqual); 708 if ( aFind == m_aDriversBS.end() ) 709 { 710 // search all bootstrapped drivers 711 aFind = ::std::find_if( 712 m_aDriversBS.begin(), // begin of search range 713 m_aDriversBS.end(), // end of search range 714 std::unary_compose< AcceptsURL, ExtractAfterLoad >( AcceptsURL( _rURL ), ExtractAfterLoad( m_aContext.getUNOContext() ) ) 715 // compose two functors: extract the driver from the access, then ask the resulting driver for acceptance 716 ); 717 } // if ( m_aDriversBS.find(sDriverFactoryName ) == m_aDriversBS.end() ) 718 else 719 { 720 EnsureDriver aEnsure( m_aContext.getUNOContext() ); 721 aEnsure(*aFind); 722 } 723 724 // found something? 725 if ( m_aDriversBS.end() != aFind && aFind->xDriver.is() && aFind->xDriver->acceptsURL(_rURL) ) 726 xReturn = aFind->xDriver; 727 } 728 729 if ( !xReturn.is() ) 730 { 731 // no -> search the runtime drivers 732 DriverCollectionIterator aPos = ::std::find_if( 733 m_aDriversRT.begin(), // begin of search range 734 m_aDriversRT.end(), // end of search range 735 std::unary_compose< AcceptsURL, ExtractDriverFromCollectionElement >( AcceptsURL( _rURL ), ExtractDriverFromCollectionElement() ) 736 // compose two functors: extract the driver from the access, then ask the resulting driver for acceptance 737 ); 738 739 if ( m_aDriversRT.end() != aPos ) 740 xReturn = aPos->second; 741 } 742 743 return xReturn; 744 } 745 746 } // namespace drivermanager 747