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