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