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