/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#include <stdio.h>

#include "mdrivermanager.hxx"
#include <com/sun/star/sdbc/XDriver.hpp>
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#include <com/sun/star/container/ElementExistException.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>

#include <tools/diagnose_ex.h>
#include <comphelper/extract.hxx>
#include <comphelper/stl_types.hxx>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/weakref.hxx>
#include <osl/diagnose.h>

#include <algorithm>
#include <functional>

namespace drivermanager
{

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::logging;
using namespace ::osl;

#define SERVICE_SDBC_DRIVER		::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver")

void throwNoSuchElementException() throw(NoSuchElementException)
{
	throw NoSuchElementException();
}

//==========================================================================
//= ODriverEnumeration
//==========================================================================
class ODriverEnumeration : public ::cppu::WeakImplHelper1< XEnumeration >
{
	friend class OSDBCDriverManager;

	DECLARE_STL_VECTOR( SdbcDriver, DriverArray );
	DriverArray					m_aDrivers;
	ConstDriverArrayIterator	m_aPos;
	// order matters!

protected:
	virtual ~ODriverEnumeration();
public:
	ODriverEnumeration(const DriverArray& _rDriverSequence);

// XEnumeration
	virtual sal_Bool SAL_CALL hasMoreElements( ) throw(RuntimeException);
    virtual Any SAL_CALL nextElement( ) throw(NoSuchElementException, WrappedTargetException, RuntimeException);
};

//--------------------------------------------------------------------------
ODriverEnumeration::ODriverEnumeration(const DriverArray& _rDriverSequence)
	:m_aDrivers( _rDriverSequence )
	,m_aPos( m_aDrivers.begin() )
{
}

//--------------------------------------------------------------------------
ODriverEnumeration::~ODriverEnumeration()
{
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL ODriverEnumeration::hasMoreElements(  ) throw(RuntimeException)
{
	return m_aPos != m_aDrivers.end();
}

//--------------------------------------------------------------------------
Any SAL_CALL ODriverEnumeration::nextElement(  ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	if ( !hasMoreElements() )
		throwNoSuchElementException();

	return makeAny( *m_aPos++ );
}

	//=====================================================================
	//= helper
	//=====================================================================
	//---------------------------------------------------------------------
	//--- 24.08.01 11:27:59 -----------------------------------------------

	/// an STL functor which ensures that a SdbcDriver described by a DriverAccess is loaded
	struct EnsureDriver : public ::std::unary_function< DriverAccess, DriverAccess >
	{
        EnsureDriver( const Reference< XComponentContext > &rxContext )
            : mxContext( rxContext ) {}

		const DriverAccess& operator()( const DriverAccess& _rDescriptor ) const
		{
			if ( !_rDescriptor.xDriver.is() )
				// we did not load this driver, yet
				if ( _rDescriptor.xComponentFactory.is() )
					// we have a factory for it
					const_cast< DriverAccess& >( _rDescriptor ).xDriver = _rDescriptor.xDriver.query(
                        _rDescriptor.xComponentFactory->createInstanceWithContext( mxContext ) );
			return _rDescriptor;
		}

    private:
        Reference< XComponentContext > mxContext;
	};

	//---------------------------------------------------------------------
	//--- 24.08.01 11:28:04 -----------------------------------------------

	/// an STL functor which extracts a SdbcDriver from a DriverAccess
	struct ExtractDriverFromAccess : public ::std::unary_function< DriverAccess, SdbcDriver >
	{
		SdbcDriver operator()( const DriverAccess& _rAccess ) const
		{
			return _rAccess.xDriver;
		}
	};

	//---------------------------------------------------------------------
	//--- 24.08.01 12:37:50 -----------------------------------------------

	typedef ::std::unary_compose< ExtractDriverFromAccess, EnsureDriver > ExtractAfterLoad_BASE;
	/// an STL functor which loads a driver described by a DriverAccess, and extracts the SdbcDriver
	struct ExtractAfterLoad : public ExtractAfterLoad_BASE
	{
        ExtractAfterLoad( const Reference< XComponentContext > &rxContext )
            : ExtractAfterLoad_BASE( ExtractDriverFromAccess(), EnsureDriver( rxContext ) ) {}
	};

	//---------------------------------------------------------------------
	//--- 24.08.01 11:42:36 -----------------------------------------------

	struct ExtractDriverFromCollectionElement : public ::std::unary_function< DriverCollection::value_type, SdbcDriver >
	{
		SdbcDriver operator()( const DriverCollection::value_type& _rElement ) const
		{
			return _rElement.second;
		}
	};

	//---------------------------------------------------------------------
	//--- 24.08.01 11:51:03 -----------------------------------------------

	// predicate for checking whether or not a driver accepts a given URL
	class AcceptsURL : public ::std::unary_function< SdbcDriver, bool >
	{
	protected:
		const ::rtl::OUString& m_rURL;

	public:
		// ctor
		AcceptsURL( const ::rtl::OUString& _rURL ) : m_rURL( _rURL ) { }

		//.................................................................
		bool operator()( const SdbcDriver& _rDriver ) const
		{
			// ask the driver
			if ( _rDriver.is() && _rDriver->acceptsURL( m_rURL ) )
				return true;

			// does not accept ...
			return false;
		}
	};

	//---------------------------------------------------------------------
	//--- 24.08.01 12:51:54 -----------------------------------------------

    static sal_Int32 lcl_getDriverPrecedence( const ::comphelper::ComponentContext& _rContext, Sequence< ::rtl::OUString >& _rPrecedence )
	{
		_rPrecedence.realloc( 0 );
		try
		{
			// some strings we need
			const ::rtl::OUString sConfigurationProviderServiceName =
				::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
			const ::rtl::OUString sDriverManagerConfigLocation =
				::rtl::OUString::createFromAscii("org.openoffice.Office.DataAccess/DriverManager");
			const ::rtl::OUString sDriverPreferenceLocation =
				::rtl::OUString::createFromAscii("DriverPrecedence");
			const ::rtl::OUString sNodePathArgumentName =
				::rtl::OUString::createFromAscii("nodepath");
			const ::rtl::OUString sNodeAccessServiceName =
				::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");

			// create a configuration provider
			Reference< XMultiServiceFactory > xConfigurationProvider;
            if ( !_rContext.createComponent( sConfigurationProviderServiceName, xConfigurationProvider ) )
                throw ServiceNotRegisteredException( sConfigurationProviderServiceName, NULL );

            // one argument for creating the node access: the path to the configuration node
			Sequence< Any > aCreationArgs(1);
			aCreationArgs[0] <<= NamedValue( sNodePathArgumentName, makeAny( sDriverManagerConfigLocation ) );

			// create the node access
			Reference< XNameAccess > xDriverManagerNode(xConfigurationProvider->createInstanceWithArguments(sNodeAccessServiceName, aCreationArgs), UNO_QUERY);

			OSL_ENSURE(xDriverManagerNode.is(), "lcl_getDriverPrecedence: could not open my configuration node!");
			if (xDriverManagerNode.is())
			{
				// obtain the preference list
				Any aPreferences = xDriverManagerNode->getByName(sDriverPreferenceLocation);
#if OSL_DEBUG_LEVEL > 0
				sal_Bool bSuccess =
#endif
				aPreferences >>= _rPrecedence;
				OSL_ENSURE(bSuccess || !aPreferences.hasValue(), "lcl_getDriverPrecedence: invalid value for the preferences node (no string sequence but not NULL)!");
			}
		}
		catch( const Exception& )
		{
            DBG_UNHANDLED_EXCEPTION();
		}

		return _rPrecedence.getLength();
	}

	//---------------------------------------------------------------------
	//--- 24.08.01 13:01:56 -----------------------------------------------

	/// an STL argorithm compatible predicate comparing two DriverAccess instances by their implementation names
	struct CompareDriverAccessByName : public ::std::binary_function< DriverAccess, DriverAccess, bool >
	{
		//.................................................................
		bool operator()( const DriverAccess& lhs, const DriverAccess& rhs )
		{
			return lhs.sImplementationName < rhs.sImplementationName ? true : false;
		}
	};

	//---------------------------------------------------------------------
	//--- 24.08.01 13:08:17 -----------------------------------------------

	/// and STL argorithm compatible predicate comparing a DriverAccess' impl name to a string
	struct CompareDriverAccessToName : public ::std::binary_function< DriverAccess, ::rtl::OUString, bool >
	{
		//.................................................................
		bool operator()( const DriverAccess& lhs, const ::rtl::OUString& rhs )
		{
			return lhs.sImplementationName < rhs ? true : false;
		}
		//.................................................................
		bool operator()( const ::rtl::OUString& lhs, const DriverAccess& rhs )
		{
			return lhs < rhs.sImplementationName ? true : false;
		}
	};

    /// and STL argorithm compatible predicate comparing a DriverAccess' impl name to a string
	struct EqualDriverAccessToName : public ::std::binary_function< DriverAccess, ::rtl::OUString, bool >
	{
        ::rtl::OUString m_sImplName;
        EqualDriverAccessToName(const ::rtl::OUString& _sImplName) : m_sImplName(_sImplName){}
		//.................................................................
		bool operator()( const DriverAccess& lhs)
		{
			return lhs.sImplementationName.equals(m_sImplName);
		}
    };

//==========================================================================
//= OSDBCDriverManager
//==========================================================================
//--------------------------------------------------------------------------
OSDBCDriverManager::OSDBCDriverManager( const Reference< XComponentContext >& _rxContext )
	:m_aContext( _rxContext )
    ,m_aEventLogger( _rxContext, "org.openoffice.logging.sdbc.DriverManager" )
    ,m_aDriverConfig(m_aContext.getLegacyServiceFactory())
	,m_nLoginTimeout(0)
{
	// bootstrap all objects supporting the .sdb.Driver service
	bootstrapDrivers();

	// initialize the drivers order
	initializeDriverPrecedence();
}

//---------------------------------------------------------------------
OSDBCDriverManager::~OSDBCDriverManager()
{
}

//---------------------------------------------------------------------
//--- 24.08.01 11:15:32 -----------------------------------------------

void OSDBCDriverManager::bootstrapDrivers()
{
	Reference< XContentEnumerationAccess > xEnumAccess( m_aContext.getLegacyServiceFactory(), UNO_QUERY );
	Reference< XEnumeration > xEnumDrivers;
	if (xEnumAccess.is())
		xEnumDrivers = xEnumAccess->createContentEnumeration(SERVICE_SDBC_DRIVER);

	OSL_ENSURE( xEnumDrivers.is(), "OSDBCDriverManager::bootstrapDrivers: no enumeration for the drivers available!" );
	if (xEnumDrivers.is())
	{
		Reference< XSingleComponentFactory > xFactory;
		Reference< XServiceInfo > xSI;
		while (xEnumDrivers->hasMoreElements())
		{
			::cppu::extractInterface( xFactory, xEnumDrivers->nextElement() );
			OSL_ENSURE( xFactory.is(), "OSDBCDriverManager::bootstrapDrivers: no factory extracted" );

			if ( xFactory.is() )
			{
				// we got a factory for the driver
				DriverAccess aDriverDescriptor;
				sal_Bool bValidDescriptor = sal_False;

				// can it tell us something about the implementation name?
				xSI = xSI.query( xFactory );
				if ( xSI.is() )
				{	// yes -> no need to load the driver immediately (load it later when needed)
					aDriverDescriptor.sImplementationName = xSI->getImplementationName();
					aDriverDescriptor.xComponentFactory = xFactory;
					bValidDescriptor = sal_True;

                    m_aEventLogger.log( LogLevel::CONFIG,
                        "found SDBC driver $1$, no need to load it",
                        aDriverDescriptor.sImplementationName
                    );
				}
				else
				{
					// no -> create the driver
					Reference< XDriver > xDriver( xFactory->createInstanceWithContext( m_aContext.getUNOContext() ), UNO_QUERY );
					OSL_ENSURE( xDriver.is(), "OSDBCDriverManager::bootstrapDrivers: a driver which is no driver?!" );

					if ( xDriver.is() )
					{
						aDriverDescriptor.xDriver = xDriver;
						// and obtain it's implementation name
						xSI = xSI.query( xDriver );
						OSL_ENSURE( xSI.is(), "OSDBCDriverManager::bootstrapDrivers: a driver without service info?" );
						if ( xSI.is() )
						{
							aDriverDescriptor.sImplementationName = xSI->getImplementationName();
							bValidDescriptor = sal_True;

                            m_aEventLogger.log( LogLevel::CONFIG,
                                "found SDBC driver $1$, needed to load it",
                                aDriverDescriptor.sImplementationName
                            );
						}
					}
				}

				if ( bValidDescriptor )
				{
					m_aDriversBS.push_back( aDriverDescriptor );
				}
			}
		}
	}
}

//--------------------------------------------------------------------------
void OSDBCDriverManager::initializeDriverPrecedence()
{
	if ( m_aDriversBS.empty() )
		// nothing to do
		return;

	try
	{
		// get the precedence of the drivers from the configuration
		Sequence< ::rtl::OUString > aDriverOrder;
		if ( 0 == lcl_getDriverPrecedence( m_aContext, aDriverOrder ) )
			// nothing to do
			return;

		// aDriverOrder now is the list of driver implementation names in the order they should be used

        if ( m_aEventLogger.isLoggable( LogLevel::CONFIG ) )
        {
            sal_Int32 nOrderedCount = aDriverOrder.getLength();
            for ( sal_Int32 i=0; i<nOrderedCount; ++i )
            m_aEventLogger.log( LogLevel::CONFIG,
                "configuration's driver order: driver $1$ of $2$: $3$",
                (sal_Int32)(i + 1), nOrderedCount, aDriverOrder[i]
            );
        }

		// sort our bootstrapped drivers
		::std::sort( m_aDriversBS.begin(), m_aDriversBS.end(), CompareDriverAccessByName() );

		// loop through the names in the precedence order
		const ::rtl::OUString* pDriverOrder		=					aDriverOrder.getConstArray();
		const ::rtl::OUString* pDriverOrderEnd	=	pDriverOrder +	aDriverOrder.getLength();

		// the first driver for which there is no preference
		DriverAccessArrayIterator aNoPrefDriversStart = m_aDriversBS.begin();
			// at the moment this is the first of all drivers we know

		for ( ; ( pDriverOrder < pDriverOrderEnd ) && ( aNoPrefDriversStart != m_aDriversBS.end() ); ++pDriverOrder )
		{
			// look for the impl name in the DriverAccess array
			::std::pair< DriverAccessArrayIterator, DriverAccessArrayIterator > aPos =
				::std::equal_range( aNoPrefDriversStart, m_aDriversBS.end(), *pDriverOrder, CompareDriverAccessToName() );

			if ( aPos.first != aPos.second )
			{	// we have a DriverAccess with this impl name

				OSL_ENSURE( ::std::distance( aPos.first, aPos.second ) == 1,
					"OSDBCDriverManager::initializeDriverPrecedence: more than one driver with this impl name? How this?" );
				// move the DriverAccess pointed to by aPos.first to the position pointed to by aNoPrefDriversStart

				if ( aPos.first != aNoPrefDriversStart )
				{	// if this does not hold, the DriverAccess alread has the correct position

					// rotate the range [aNoPrefDriversStart, aPos.second) right 1 element
					::std::rotate( aNoPrefDriversStart, aPos.second - 1, aPos.second );
				}

				// next round we start searching and pos right
				++aNoPrefDriversStart;
			}
		}
	}
	catch (Exception&)
	{
		OSL_ENSURE(sal_False, "OSDBCDriverManager::initializeDriverPrecedence: caught an exception while sorting the drivers!");
	}
}

//--------------------------------------------------------------------------
Reference< XConnection > SAL_CALL OSDBCDriverManager::getConnection( const ::rtl::OUString& _rURL ) throw(SQLException, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

    m_aEventLogger.log( LogLevel::INFO,
        "connection requested for URL $1$",
        _rURL
    );

	Reference< XConnection > xConnection;
	Reference< XDriver > xDriver = implGetDriverForURL(_rURL);
	if (xDriver.is())
    {
		// TODO : handle the login timeout
		xConnection = xDriver->connect(_rURL, Sequence< PropertyValue >());
		// may throw an exception
        m_aEventLogger.log( LogLevel::INFO,
            "connection retrieved for URL $1$",
            _rURL
        );
    }

	return xConnection;
}

//--------------------------------------------------------------------------
Reference< XConnection > SAL_CALL OSDBCDriverManager::getConnectionWithInfo( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rInfo ) throw(SQLException, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

    m_aEventLogger.log( LogLevel::INFO,
        "connection with info requested for URL $1$",
        _rURL
    );

    Reference< XConnection > xConnection;
	Reference< XDriver > xDriver = implGetDriverForURL(_rURL);
	if (xDriver.is())
    {
		// TODO : handle the login timeout
		xConnection = xDriver->connect(_rURL, _rInfo);
		// may throw an exception
        m_aEventLogger.log( LogLevel::INFO,
            "connection with info retrieved for URL $1$",
            _rURL
        );
    }

	return xConnection;
}

//--------------------------------------------------------------------------
void SAL_CALL OSDBCDriverManager::setLoginTimeout( sal_Int32 seconds ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	m_nLoginTimeout = seconds;
}

//--------------------------------------------------------------------------
sal_Int32 SAL_CALL OSDBCDriverManager::getLoginTimeout(  ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	return m_nLoginTimeout;
}

//--------------------------------------------------------------------------
Reference< XEnumeration > SAL_CALL OSDBCDriverManager::createEnumeration(  ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

	ODriverEnumeration::DriverArray aDrivers;

	// ensure that all our bootstrapped drivers are insatntiated
	::std::for_each( m_aDriversBS.begin(), m_aDriversBS.end(), EnsureDriver( m_aContext.getUNOContext() ) );

	// copy the bootstrapped drivers
	::std::transform(
		m_aDriversBS.begin(),				// "copy from" start
		m_aDriversBS.end(),					// "copy from" end
		::std::back_inserter( aDrivers ),	// insert into
		ExtractDriverFromAccess()			// transformation to apply (extract a driver from a driver access)
	);

	// append the runtime drivers
	::std::transform(
		m_aDriversRT.begin(),					// "copy from" start
		m_aDriversRT.end(),						// "copy from" end
		::std::back_inserter( aDrivers ),		// insert into
		ExtractDriverFromCollectionElement()	// transformation to apply (extract a driver from a driver access)
	);

	return new ODriverEnumeration( aDrivers );
}

//--------------------------------------------------------------------------
::com::sun::star::uno::Type SAL_CALL OSDBCDriverManager::getElementType(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return ::getCppuType(static_cast< Reference< XDriver >* >(NULL));
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL OSDBCDriverManager::hasElements(  ) throw(::com::sun::star::uno::RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	return !(m_aDriversBS.empty() && m_aDriversRT.empty());
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSDBCDriverManager::getImplementationName(  ) throw(RuntimeException)
{
	return getImplementationName_static();
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL OSDBCDriverManager::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
{
	Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
	const ::rtl::OUString* pSupported = aSupported.getConstArray();
	const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
	for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
		;

	return pSupported != pEnd;
}

//--------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL OSDBCDriverManager::getSupportedServiceNames(  ) throw(RuntimeException)
{
	return getSupportedServiceNames_static();
}

//--------------------------------------------------------------------------
Reference< XInterface > SAL_CALL OSDBCDriverManager::Create( const Reference< XMultiServiceFactory >& _rxFactory )
{
    ::comphelper::ComponentContext aContext( _rxFactory );
    return *( new OSDBCDriverManager( aContext.getUNOContext() ) );
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSDBCDriverManager::getImplementationName_static(  ) throw(RuntimeException)
{
	return ::rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.OSDBCDriverManager");
}

//--------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL OSDBCDriverManager::getSupportedServiceNames_static(  ) throw(RuntimeException)
{
	Sequence< ::rtl::OUString > aSupported(1);
	aSupported[0] = getSingletonName_static();
	return aSupported;
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OSDBCDriverManager::getSingletonName_static(  ) throw(RuntimeException)
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.DriverManager" ) );
}

//--------------------------------------------------------------------------
Reference< XInterface > SAL_CALL OSDBCDriverManager::getRegisteredObject( const ::rtl::OUString& _rName ) throw(Exception, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	ConstDriverCollectionIterator aSearch = m_aDriversRT.find(_rName);
	if (aSearch == m_aDriversRT.end())
		throwNoSuchElementException();

	return aSearch->second.get();
}

//--------------------------------------------------------------------------
void SAL_CALL OSDBCDriverManager::registerObject( const ::rtl::OUString& _rName, const Reference< XInterface >& _rxObject ) throw(Exception, RuntimeException)
{
    MutexGuard aGuard(m_aMutex);

    m_aEventLogger.log( LogLevel::INFO,
        "attempt to register new driver for name $1$",
        _rName
    );

	ConstDriverCollectionIterator aSearch = m_aDriversRT.find(_rName);
	if (aSearch == m_aDriversRT.end())
	{
		Reference< XDriver > xNewDriver(_rxObject, UNO_QUERY);
		if (xNewDriver.is())
			m_aDriversRT.insert(DriverCollection::value_type(_rName, xNewDriver));
		else
			throw IllegalArgumentException();
	}
	else
		throw ElementExistException();

    m_aEventLogger.log( LogLevel::INFO,
        "new driver registered for name $1$",
        _rName
    );
}

//--------------------------------------------------------------------------
void SAL_CALL OSDBCDriverManager::revokeObject( const ::rtl::OUString& _rName ) throw(Exception, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

    m_aEventLogger.log( LogLevel::INFO,
        "attempt to revoke driver for name $1$",
        _rName
    );

    DriverCollectionIterator aSearch = m_aDriversRT.find(_rName);
	if (aSearch == m_aDriversRT.end())
		throwNoSuchElementException();

	m_aDriversRT.erase(aSearch); // we already have the iterator so we could use it

    m_aEventLogger.log( LogLevel::INFO,
        "driver revoked for name $1$",
        _rName
    );
}

//--------------------------------------------------------------------------
Reference< XDriver > SAL_CALL OSDBCDriverManager::getDriverByURL( const ::rtl::OUString& _rURL ) throw(RuntimeException)
{
    m_aEventLogger.log( LogLevel::INFO,
        "driver requested for URL $1$",
        _rURL
    );

    Reference< XDriver > xDriver( implGetDriverForURL( _rURL ) );

    if ( xDriver.is() )
        m_aEventLogger.log( LogLevel::INFO,
            "driver obtained for URL $1$",
            _rURL
        );

    return xDriver;
}

//--------------------------------------------------------------------------
Reference< XDriver > OSDBCDriverManager::implGetDriverForURL(const ::rtl::OUString& _rURL)
{
	Reference< XDriver > xReturn;

	{
        const ::rtl::OUString sDriverFactoryName = m_aDriverConfig.getDriverFactoryName(_rURL);

        EqualDriverAccessToName aEqual(sDriverFactoryName);
        DriverAccessArray::iterator aFind = ::std::find_if(m_aDriversBS.begin(),m_aDriversBS.end(),aEqual);
        if ( aFind == m_aDriversBS.end() )
        {
		    // search all bootstrapped drivers
		    aFind = ::std::find_if(
			    m_aDriversBS.begin(),		// begin of search range
			    m_aDriversBS.end(),			// end of search range
			    std::unary_compose< AcceptsURL, ExtractAfterLoad >( AcceptsURL( _rURL ), ExtractAfterLoad( m_aContext.getUNOContext() ) )
										    // compose two functors: extract the driver from the access, then ask the resulting driver for acceptance
		    );
        } // if ( m_aDriversBS.find(sDriverFactoryName ) == m_aDriversBS.end() )
        else
        {
            EnsureDriver aEnsure( m_aContext.getUNOContext() );
            aEnsure(*aFind);
        }

		// found something?
		if ( m_aDriversBS.end() != aFind && aFind->xDriver.is() && aFind->xDriver->acceptsURL(_rURL) )
			xReturn = aFind->xDriver;
	}

	if ( !xReturn.is() )
	{
		// no -> search the runtime drivers
		DriverCollectionIterator aPos = ::std::find_if(
			m_aDriversRT.begin(),		// begin of search range
			m_aDriversRT.end(),			// end of search range
			std::unary_compose< AcceptsURL, ExtractDriverFromCollectionElement >( AcceptsURL( _rURL ), ExtractDriverFromCollectionElement() )
										// compose two functors: extract the driver from the access, then ask the resulting driver for acceptance
		);

		if ( m_aDriversRT.end() != aPos )
			xReturn = aPos->second;
	}

	return xReturn;
}

}	// namespace drivermanager
