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