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