| /************************************************************** |
| * |
| * 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 |