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