20#include <config_fuzzers.h>
23#include <com/sun/star/configuration/theDefaultProvider.hpp>
24#include <com/sun/star/sdbc/XDriver.hpp>
25#include <com/sun/star/container/XContentEnumerationAccess.hpp>
26#include <com/sun/star/container/ElementExistException.hpp>
27#include <com/sun/star/beans/NamedValue.hpp>
28#include <com/sun/star/logging/LogLevel.hpp>
34#include <osl/diagnose.h>
57 throw NoSuchElementException();
81 :m_aDrivers(
std::move(_rDriverSequence) )
82 ,m_aPos( m_aDrivers.
begin() )
111 explicit EnsureDriver(
const Reference< XComponentContext > &rxContext )
114 const DriverAccess& operator()(
const DriverAccess& _rDescriptor )
const
117 if (_rDescriptor.xDriver.is())
121 if (_rDescriptor.xComponentFactory.is())
123 DriverAccess& rDesc =
const_cast<DriverAccess&
>(_rDescriptor);
128 rDesc.xComponentFactory->createInstanceWithContext(
mxContext), css::uno::UNO_QUERY);
130 catch (
const Exception&)
133 rDesc.xComponentFactory.clear();
144 struct ExtractDriverFromAccess
146 const Reference<XDriver>& operator()(
const DriverAccess& _rAccess )
const
148 return _rAccess.xDriver;
152 struct ExtractDriverFromCollectionElement
154 const Reference<XDriver>& operator()(
const DriverCollection::value_type& _rElement )
const
156 return _rElement.second;
161 bool AcceptsURL(
const OUString& _rURL,
const Reference<XDriver>& _rDriver )
164 return _rDriver.is() && _rDriver->acceptsURL( _rURL );
168 sal_Int32 lcl_getDriverPrecedence(
const Reference<XComponentContext>& _rContext, Sequence< OUString >& _rPrecedence )
170 _rPrecedence.realloc( 0 );
174 Reference< XMultiServiceFactory > xConfigurationProvider(
175 css::configuration::theDefaultProvider::get( _rContext ) );
178 Sequence< Any > aCreationArgs{
Any(NamedValue(
179 "nodepath",
Any( OUString(
"org.openoffice.Office.DataAccess/DriverManager") ) )) };
182 Reference< XNameAccess > xDriverManagerNode(
183 xConfigurationProvider->createInstanceWithArguments(
"com.sun.star.configuration.ConfigurationAccess", aCreationArgs),
186 OSL_ENSURE(xDriverManagerNode.is(),
"lcl_getDriverPrecedence: could not open my configuration node!");
187 if (xDriverManagerNode.is())
190 Any aPreferences = xDriverManagerNode->getByName(
"DriverPrecedence");
191 bool bSuccess = aPreferences >>= _rPrecedence;
192 OSL_ENSURE(bSuccess || !aPreferences.hasValue(),
"lcl_getDriverPrecedence: invalid value for the preferences node (no string sequence but not NULL)!");
195 catch(
const Exception& )
200 return _rPrecedence.getLength();
205 struct CompareDriverAccessByName
208 bool operator()(
const DriverAccess& lhs,
const DriverAccess& rhs )
210 return lhs.sImplementationName < rhs.sImplementationName;
215 struct EqualDriverAccessToName
218 explicit EqualDriverAccessToName(OUString _sImplName) :
m_sImplName(
std::move(_sImplName)){}
220 bool operator()(
const DriverAccess& lhs)
230 ,m_aEventLogger( _rxContext,
"org.openoffice.logging.sdbc.DriverManager" )
248 Reference< XContentEnumerationAccess > xEnumAccess(
m_xContext->getServiceManager(), UNO_QUERY );
249 Reference< XEnumeration > xEnumDrivers;
250 if (xEnumAccess.is())
253 OSL_ENSURE( xEnumDrivers.is(),
"OSDBCDriverManager::bootstrapDrivers: no enumeration for the drivers available!" );
254 if (!xEnumDrivers.is())
257 Reference< XSingleComponentFactory >
xFactory;
258 Reference< XServiceInfo > xSI;
259 while (xEnumDrivers->hasMoreElements())
261 xFactory.set(xEnumDrivers->nextElement(), css::uno::UNO_QUERY);
262 OSL_ENSURE(
xFactory.is(),
"OSDBCDriverManager::bootstrapDrivers: no factory extracted" );
268 bool bValidDescriptor =
false;
271 xSI.set(
xFactory, css::uno::UNO_QUERY);
276 bValidDescriptor =
true;
279 "found SDBC driver $1$, no need to load it",
286 Reference< XDriver > xDriver(
xFactory->createInstanceWithContext(
m_xContext ), UNO_QUERY );
287 OSL_ENSURE( xDriver.is(),
"OSDBCDriverManager::bootstrapDrivers: a driver which is no driver?!" );
291 aDriverDescriptor.
xDriver = xDriver;
293 xSI.set(xDriver, css::uno::UNO_QUERY);
294 OSL_ENSURE( xSI.is(),
"OSDBCDriverManager::bootstrapDrivers: a driver without service info?" );
298 bValidDescriptor =
true;
301 "found SDBC driver $1$, needed to load it",
308 if ( bValidDescriptor )
327 Sequence< OUString > aDriverOrder;
328 if ( 0 == lcl_getDriverPrecedence(
m_xContext, aDriverOrder ) )
336 sal_Int32 nOrderedCount = aDriverOrder.getLength();
337 for ( sal_Int32
i=0;
i<nOrderedCount; ++
i )
339 "configuration's driver order: driver $1$ of $2$: $3$",
340 static_cast<sal_Int32
>(
i + 1), nOrderedCount, aDriverOrder[
i]
348 DriverAccessArray::iterator aNoPrefDriversStart =
m_aDriversBS.begin();
352 for (
const OUString& rDriverOrder : std::as_const(aDriverOrder) )
361 std::pair< DriverAccessArray::iterator, DriverAccessArray::iterator > aPos =
362 std::equal_range( aNoPrefDriversStart,
m_aDriversBS.end(), driver_order, CompareDriverAccessByName() );
364 if ( aPos.first != aPos.second )
367 OSL_ENSURE( std::distance( aPos.first, aPos.second ) == 1,
368 "OSDBCDriverManager::initializeDriverPrecedence: more than one driver with this impl name? How this?" );
371 if ( aPos.first != aNoPrefDriversStart )
375 std::rotate( aNoPrefDriversStart, aPos.second - 1, aPos.second );
379 ++aNoPrefDriversStart;
385 TOOLS_WARN_EXCEPTION(
"connectivity.hsqldb",
"OSDBCDriverManager::initializeDriverPrecedence: caught an exception while sorting the drivers!");
396 "connection requested for URL $1$",
400 Reference< XConnection > xConnection;
405 xConnection = xDriver->connect(_rURL, Sequence< PropertyValue >());
408 "connection retrieved for URL $1$",
422 "connection with info requested for URL $1$",
426 Reference< XConnection > xConnection;
431 xConnection = xDriver->connect(_rURL, _rInfo);
434 "connection with info retrieved for URL $1$",
470 std::back_inserter( aDrivers ),
471 ExtractDriverFromAccess()
478 std::back_inserter( aDrivers ),
479 ExtractDriverFromCollectionElement()
501 return "com.sun.star.comp.sdbc.OSDBCDriverManager";
512 return {
"com.sun.star.sdbc.DriverManager" };
519 DriverCollection::const_iterator aSearch =
m_aDriversRT.find(_rName);
523 return aSearch->second;
532 "attempt to register new driver for name $1$",
536 DriverCollection::const_iterator aSearch =
m_aDriversRT.find(_rName);
538 throw ElementExistException();
539 Reference< XDriver > xNewDriver(_rxObject, UNO_QUERY);
540 if (!xNewDriver.is())
541 throw IllegalArgumentException();
546 "new driver registered for name $1$",
557 "attempt to revoke driver for name $1$",
561 DriverCollection::iterator aSearch =
m_aDriversRT.find(_rName);
568 "driver revoked for name $1$",
577 "driver requested for URL $1$",
585 "driver obtained for URL $1$",
595 Reference< XDriver > xReturn;
600 EqualDriverAccessToName aEqual(sDriverFactoryName);
605 aFind = std::find_if(
608 [&_rURL,
this] (
const DriverAccessArray::value_type& driverAccess) {
610#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
611#pragma GCC diagnostic push
612#pragma GCC diagnostic ignored
"-Wdangling-reference"
614 const DriverAccess& ensuredAccess = EnsureDriver(m_xContext)(driverAccess);
615#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 13
616#pragma GCC diagnostic pop
618 const Reference<XDriver> driver = ExtractDriverFromAccess()(ensuredAccess);
619 return AcceptsURL(_rURL, driver);
629 if (
m_aDriversBS.end() != aFind && aFind->xDriver.is() && aFind->xDriver->acceptsURL(_rURL) )
630 xReturn = aFind->xDriver;
636 DriverCollection::const_iterator aPos = std::find_if(
639 [&_rURL] (
const DriverCollection::value_type& element) {
641 const Reference<XDriver> driver = ExtractDriverFromCollectionElement()(element);
642 return AcceptsURL(_rURL, driver);
646 xReturn = aPos->second;
654extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
656 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any>
const&)
Reference< XComponentContext > m_xContext
bool isLoggable(const sal_Int32 _nLogLevel) const
void log(const sal_Int32 _nLogLevel, const OUString &rMessage) const
OUString getDriverFactoryName(std::u16string_view _sUrl) const
mutable::osl::Mutex m_aMutex
css::uno::Type const & get()
virtual sal_Bool SAL_CALL hasMoreElements() override
DriverArray::const_iterator m_aPos
virtual Any SAL_CALL nextElement() override
ODriverEnumeration(DriverArray &&_rDriverSequence)
virtual ~ODriverEnumeration() override
std::vector< Reference< XDriver > > DriverArray
virtual css::uno::Reference< css::sdbc::XConnection > SAL_CALL getConnectionWithInfo(const OUString &url, const css::uno::Sequence< css::beans::PropertyValue > &info) override
DriverCollection m_aDriversRT
css::uno::Reference< css::sdbc::XDriver > implGetDriverForURL(const OUString &_rURL)
css::uno::Reference< css::uno::XComponentContext > m_xContext
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL setLoginTimeout(sal_Int32 seconds) override
::comphelper::EventLogger m_aEventLogger
void initializeDriverPrecedence()
retrieve the driver order preferences from the configuration and sort m_aDriversBS accordingly.
virtual sal_Bool SAL_CALL hasElements() override
virtual css::uno::Type SAL_CALL getElementType() override
::connectivity::DriversConfig m_aDriverConfig
virtual void SAL_CALL revokeObject(const OUString &Name) override
sal_Int32 m_nLoginTimeout
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual css::uno::Reference< css::sdbc::XConnection > SAL_CALL getConnection(const OUString &url) override
friend class ODriverEnumeration
virtual ~OSDBCDriverManager() override
virtual void SAL_CALL registerObject(const OUString &Name, const css::uno::Reference< css::uno::XInterface > &Object) override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Reference< css::sdbc::XDriver > SAL_CALL getDriverByURL(const OUString &url) override
OSDBCDriverManager(const css::uno::Reference< css::uno::XComponentContext > &_rxContext)
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getRegisteredObject(const OUString &Name) override
virtual sal_Int32 SAL_CALL getLoginTimeout() override
DriverAccessArray m_aDriversBS
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XSingleServiceFactory > xFactory
Reference< XComponentContext > mxContext
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * connectivity_OSDBCDriverManager_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
::cppu::WeakComponentImplHelper< css::sdbc::XDriverManager2, css::lang::XServiceInfo, css::uno::XNamingService > OSDBCDriverManager_Base
constexpr OUStringLiteral SERVICE_SDBC_DRIVER
static void throwNoSuchElementException()
enumrange< T >::Iterator begin(enumrange< T >)
css::uno::Reference< css::lang::XSingleComponentFactory > xComponentFactory
the driver itself
OUString sImplementationName
css::uno::Reference< css::sdbc::XDriver > xDriver
the implementation name of the driver