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