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