/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
Any SAL_CALL ODriverEnumeration::nextElement( )
{ if ( !hasMoreElements() ) throw NoSuchElementException();
return Any( *m_aPos++ );
}
namespace
{ /// an STL functor which ensures that a SdbcDriver described by a DriverAccess is loaded struct EnsureDriver
{ explicit EnsureDriver( const Reference< XComponentContext > &rxContext )
: mxContext( rxContext ) {}
const DriverAccess& operator()( const DriverAccess& _rDescriptor ) const
{ // we did not load this driver, yet if (_rDescriptor.xDriver.is()) return _rDescriptor;
// we have a factory for it if (_rDescriptor.xComponentFactory.is())
{
DriverAccess& rDesc = const_cast<DriverAccess&>(_rDescriptor); try
{ //load driver
rDesc.xDriver.set(
rDesc.xComponentFactory->createInstanceWithContext(mxContext), css::uno::UNO_QUERY);
} catch (const Exception&)
{ //failure, abandon driver
rDesc.xComponentFactory.clear();
}
} return _rDescriptor;
}
// predicate for checking whether or not a driver accepts a given URL bool AcceptsURL( const OUString& _rURL, const Reference<XDriver>& _rDriver )
{ // ask the driver return _rDriver.is() && _rDriver->acceptsURL( _rURL );
}
/// an STL algorithm compatible predicate comparing two DriverAccess instances by their implementation names struct CompareDriverAccessByName
{
/// and an STL algorithm compatible predicate comparing the impl name of a DriverAccess to a string struct EqualDriverAccessToName
{
OUString m_sImplName; explicit EqualDriverAccessToName(OUString _sImplName) : m_sImplName(std::move(_sImplName)){}
OSL_ENSURE( xEnumDrivers.is(), "OSDBCDriverManager::bootstrapDrivers: no enumeration for the drivers available!" ); if (!xEnumDrivers.is()) return;
Reference< XSingleComponentFactory > xFactory;
Reference< XServiceInfo > xSI; while (xEnumDrivers->hasMoreElements())
{
xFactory.set(xEnumDrivers->nextElement(), css::uno::UNO_QUERY);
OSL_ENSURE( xFactory.is(), "OSDBCDriverManager::bootstrapDrivers: no factory extracted" );
if ( xFactory.is() )
{ // we got a factory for the driver
DriverAccess aDriverDescriptor; bool bValidDescriptor = false;
// can it tell us something about the implementation name?
xSI.set(xFactory, css::uno::UNO_QUERY); if ( xSI.is() )
{ // yes -> no need to load the driver immediately (load it later when needed)
aDriverDescriptor.sImplementationName = xSI->getImplementationName();
aDriverDescriptor.xComponentFactory = xFactory;
bValidDescriptor = 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_xContext ), UNO_QUERY );
OSL_ENSURE( xDriver.is(), "OSDBCDriverManager::bootstrapDrivers: a driver which is no driver?!" );
if ( xDriver.is() )
{
aDriverDescriptor.xDriver = xDriver; // and obtain its implementation name
xSI.set(xDriver, css::uno::UNO_QUERY);
OSL_ENSURE( xSI.is(), "OSDBCDriverManager::bootstrapDrivers: a driver without service info?" ); if ( xSI.is() )
{
aDriverDescriptor.sImplementationName = xSI->getImplementationName();
bValidDescriptor = true;
void OSDBCDriverManager::initializeDriverPrecedence()
{ #if !ENABLE_FUZZERS if ( m_aDriversBS.empty() ) // nothing to do return;
try
{ // get the precedence of the drivers from the configuration
Sequence< OUString > aDriverOrder = officecfg::Office::DataAccess::DriverManager::DriverPrecedence::get(); if ( 0 == aDriverOrder.getLength() ) // nothing to do return;
// aDriverOrder now is the list of driver implementation names in the order they should be used
// the first driver for which there is no preference
DriverAccessArray::iterator aNoPrefDriversStart = m_aDriversBS.begin(); // at the moment this is the first of all drivers we know
// loop through the names in the precedence order for (const OUString& rDriverOrder : aDriverOrder)
{ if (aNoPrefDriversStart == m_aDriversBS.end()) break;
// look for the impl name in the DriverAccess array
std::pair< DriverAccessArray::iterator, DriverAccessArray::iterator > aPos =
std::equal_range( aNoPrefDriversStart, m_aDriversBS.end(), driver_order, CompareDriverAccessByName() );
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 already 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&)
{
TOOLS_WARN_EXCEPTION( "connectivity.hsqldb", "OSDBCDriverManager::initializeDriverPrecedence: caught an exception while sorting the drivers!");
} #endif
}
// ensure that all our bootstrapped drivers are instantiated
std::for_each( m_aDriversBS.begin(), m_aDriversBS.end(), EnsureDriver( m_xContext ) );
// 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)
);
DriverAccessArray::const_iterator aFind = std::find_if(m_aDriversBS.begin(), m_aDriversBS.end(),
EqualDriverAccessToName(sDriverFactoryName)); 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
[&_rURL, this] (const DriverAccessArray::value_type& driverAccess) { // extract the driver from the access, then ask the resulting driver for acceptance #ifdefined __GNUC__ && !defined __clang__ && __GNUC__ >= 13 && __GNUC__ <= 16 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdangling-reference" #endif const DriverAccess& ensuredAccess = EnsureDriver(m_xContext)(driverAccess); #ifdefined __GNUC__ && !defined __clang__ && __GNUC__ >= 13 && __GNUC__ <= 16 #pragma GCC diagnostic pop #endif const Reference<XDriver> driver = ExtractDriverFromAccess()(ensuredAccess); return AcceptsURL(_rURL, driver);
});
} // if ( m_aDriversBS.find(sDriverFactoryName ) == m_aDriversBS.end() ) else
{
EnsureDriver aEnsure( m_xContext );
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
DriverCollection::const_iterator aPos = std::find_if(
m_aDriversRT.begin(), // begin of search range
m_aDriversRT.end(), // end of search range
[&_rURL] (const DriverCollection::value_type& element) { // extract the driver from the collection element, then ask the resulting driver for acceptance const Reference<XDriver> driver = ExtractDriverFromCollectionElement()(element); return AcceptsURL(_rURL, driver);
});
if ( m_aDriversRT.end() != aPos )
xReturn = aPos->second;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.