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