| /************************************************************** |
| * |
| * 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 "MacabDriver.hxx" |
| #include "MacabConnection.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/sdb/SQLContext.hpp> |
| #include <com/sun/star/lang/NullPointerException.hpp> |
| #include <com/sun/star/frame/XDesktop.hpp> |
| /** === end UNO includes === **/ |
| #include <rtl/ustrbuf.hxx> |
| #include <tools/diagnose_ex.h> |
| #include "resource/macab_res.hrc" |
| |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::beans; |
| using namespace com::sun::star::sdbc; |
| using namespace com::sun::star::sdb; |
| using namespace com::sun::star::frame; |
| using namespace connectivity::macab; |
| |
| // ======================================================================= |
| // = MacabImplModule |
| // ======================================================================= |
| // -------------------------------------------------------------------------------- |
| MacabImplModule::MacabImplModule( const Reference< XMultiServiceFactory >& _rxFactory ) |
| :m_xORB(_rxFactory) |
| ,m_bAttemptedLoadModule(false) |
| ,m_hConnectorModule(NULL) |
| ,m_pConnectionFactoryFunc(NULL) |
| { |
| if ( !m_xORB.is() ) |
| throw NullPointerException(); |
| } |
| |
| // -------------------------------------------------------------------------------- |
| bool MacabImplModule::isMacOSPresent() |
| { |
| return impl_loadModule(); |
| } |
| |
| // -------------------------------------------------------------------------------- |
| namespace |
| { |
| template< typename FUNCTION > |
| void lcl_getFunctionFromModuleOrUnload( oslModule& _rModule, const sal_Char* _pAsciiSymbolName, FUNCTION& _rFunction ) |
| { |
| _rFunction = NULL; |
| if ( _rModule ) |
| { |
| // |
| const ::rtl::OUString sSymbolName = ::rtl::OUString::createFromAscii( _pAsciiSymbolName ); |
| _rFunction = (FUNCTION)( osl_getSymbol( _rModule, sSymbolName.pData ) ); |
| |
| if ( !_rFunction ) |
| { // did not find the symbol |
| OSL_ENSURE( false, ::rtl::OString( "lcl_getFunctionFromModuleOrUnload: could not find the symbol " ) + ::rtl::OString( _pAsciiSymbolName ) ); |
| osl_unloadModule( _rModule ); |
| _rModule = NULL; |
| } |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------------------- |
| extern "C" { static void SAL_CALL thisModule() {} } |
| |
| bool MacabImplModule::impl_loadModule() |
| { |
| if ( m_bAttemptedLoadModule ) |
| return ( m_hConnectorModule != NULL ); |
| m_bAttemptedLoadModule = true; |
| |
| OSL_ENSURE( !m_hConnectorModule && !m_pConnectionFactoryFunc, |
| "MacabImplModule::impl_loadModule: inconsistence: inconsistency (never attempted load before, but some values already set)!"); |
| |
| const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii( SAL_MODULENAME( "macabdrv1" ) ); |
| m_hConnectorModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, SAL_LOADMODULE_NOW ); // LAZY! #i61335# |
| OSL_ENSURE( m_hConnectorModule, "MacabImplModule::impl_loadModule: could not load the implementation library!" ); |
| if ( !m_hConnectorModule ) |
| return false; |
| |
| lcl_getFunctionFromModuleOrUnload( m_hConnectorModule, "createMacabConnection", m_pConnectionFactoryFunc ); |
| |
| if ( !m_hConnectorModule ) |
| // one of the symbols did not exist |
| throw RuntimeException(); |
| |
| return true; |
| } |
| |
| // -------------------------------------------------------------------------------- |
| void MacabImplModule::impl_unloadModule() |
| { |
| OSL_PRECOND( m_hConnectorModule != NULL, "MacabImplModule::impl_unloadModule: no module!" ); |
| |
| osl_unloadModule( m_hConnectorModule ); |
| m_hConnectorModule = NULL; |
| |
| m_pConnectionFactoryFunc = NULL; |
| |
| m_bAttemptedLoadModule = false; |
| } |
| |
| // -------------------------------------------------------------------------------- |
| void MacabImplModule::init() |
| { |
| if ( !impl_loadModule() ) |
| impl_throwNoMacOSException(); |
| |
| } |
| |
| // -------------------------------------------------------------------------------- |
| void MacabImplModule::impl_throwNoMacOSException() |
| { |
| ::connectivity::SharedResources aResources; |
| const ::rtl::OUString sError( aResources.getResourceString( |
| STR_NO_MAC_OS_FOUND |
| ) ); |
| impl_throwGenericSQLException( sError ); |
| } |
| |
| // -------------------------------------------------------------------------------- |
| void MacabImplModule::impl_throwGenericSQLException( const ::rtl::OUString& _rMessage ) |
| { |
| SQLException aError; |
| aError.Message = _rMessage; |
| aError.SQLState = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ); |
| aError.ErrorCode = 0; |
| throw aError; |
| } |
| |
| // -------------------------------------------------------------------------------- |
| MacabConnection* MacabImplModule::createConnection( MacabDriver* _pDriver ) const |
| { |
| OSL_PRECOND( m_hConnectorModule, "MacabImplModule::createConnection: not initialized!" ); |
| |
| void* pUntypedConnection = (*m_pConnectionFactoryFunc)( _pDriver ); |
| if ( !pUntypedConnection ) |
| throw RuntimeException(); |
| |
| return static_cast< MacabConnection* >( pUntypedConnection ); |
| } |
| |
| // -------------------------------------------------------------------------------- |
| void MacabImplModule::shutdown() |
| { |
| if ( !m_hConnectorModule ) |
| return; |
| |
| impl_unloadModule(); |
| } |
| |
| // ======================================================================= |
| // = MacabDriver |
| // ======================================================================= |
| MacabDriver::MacabDriver( |
| const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) |
| : MacabDriver_BASE(m_aMutex), |
| m_xMSFactory(_rxFactory), |
| m_aImplModule(_rxFactory) |
| { |
| if ( !m_xMSFactory.is() ) |
| throw NullPointerException(); |
| |
| osl_incrementInterlockedCount( &m_refCount ); |
| try |
| { |
| Reference< XDesktop > xDesktop( |
| m_xMSFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ), |
| UNO_QUERY_THROW ); |
| xDesktop->addTerminateListener( this ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| osl_decrementInterlockedCount( &m_refCount ); |
| } |
| // -------------------------------------------------------------------------------- |
| void MacabDriver::disposing() |
| { |
| ::osl::MutexGuard aGuard(m_aMutex); |
| |
| // when driver will be destroied so all our connections have to be destroied as well |
| for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i) |
| { |
| Reference< XComponent > xComp(i->get(), UNO_QUERY); |
| if (xComp.is()) |
| xComp->dispose(); |
| } |
| m_xConnections.clear(); |
| |
| WeakComponentImplHelperBase::disposing(); |
| } |
| // static ServiceInfo |
| //------------------------------------------------------------------------------ |
| rtl::OUString MacabDriver::getImplementationName_Static( ) throw(RuntimeException) |
| { |
| return rtl::OUString::createFromAscii( impl_getAsciiImplementationName() ); |
| } |
| //------------------------------------------------------------------------------ |
| Sequence< ::rtl::OUString > MacabDriver::getSupportedServiceNames_Static( ) throw (RuntimeException) |
| { |
| // which service is supported |
| // for more information @see com.sun.star.sdbc.Driver |
| Sequence< ::rtl::OUString > aSNS( 1 ); |
| aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver"); |
| |
| return aSNS; |
| } |
| //------------------------------------------------------------------ |
| ::rtl::OUString SAL_CALL MacabDriver::getImplementationName( ) throw(RuntimeException) |
| { |
| return getImplementationName_Static(); |
| } |
| //------------------------------------------------------------------ |
| sal_Bool SAL_CALL MacabDriver::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(); |
| |
| while (pSupported != pEnd && !pSupported->equals(_rServiceName)) |
| ++pSupported; |
| return pSupported != pEnd; |
| } |
| //------------------------------------------------------------------ |
| Sequence< ::rtl::OUString > SAL_CALL MacabDriver::getSupportedServiceNames( ) throw(RuntimeException) |
| { |
| return getSupportedServiceNames_Static(); |
| } |
| // -------------------------------------------------------------------------------- |
| Reference< XConnection > SAL_CALL MacabDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException) |
| { |
| ::osl::MutexGuard aGuard(m_aMutex); |
| |
| m_aImplModule.init(); |
| |
| // create a new connection with the given properties and append it to our vector |
| MacabConnection* pConnection = m_aImplModule.createConnection( this ); |
| OSL_POSTCOND( pConnection, "MacabDriver::connect: no connection has been created by the factory!" ); |
| |
| // by definition, the factory function returned an object which was acquired once |
| Reference< XConnection > xConnection = pConnection; |
| pConnection->release(); |
| |
| // late constructor call which can throw exception and allows a correct dtor call when so |
| pConnection->construct( url, info ); |
| |
| // remember it |
| m_xConnections.push_back( WeakReferenceHelper( *pConnection ) ); |
| |
| return xConnection; |
| } |
| // -------------------------------------------------------------------------------- |
| sal_Bool SAL_CALL MacabDriver::acceptsURL( const ::rtl::OUString& url ) |
| throw(SQLException, RuntimeException) |
| { |
| ::osl::MutexGuard aGuard(m_aMutex); |
| |
| if ( !m_aImplModule.isMacOSPresent() ) |
| return sal_False; |
| |
| // here we have to look whether we support this URL format |
| return (!url.compareTo(::rtl::OUString::createFromAscii("sdbc:address:macab:"), 18)); |
| } |
| // -------------------------------------------------------------------------------- |
| Sequence< DriverPropertyInfo > SAL_CALL MacabDriver::getPropertyInfo( const ::rtl::OUString&, const Sequence< PropertyValue >& ) throw(SQLException, RuntimeException) |
| { |
| // if you have something special to say, return it here :-) |
| return Sequence< DriverPropertyInfo >(); |
| } |
| // -------------------------------------------------------------------------------- |
| sal_Int32 SAL_CALL MacabDriver::getMajorVersion( ) throw(RuntimeException) |
| { |
| return MACAB_DRIVER_VERSION_MAJOR; |
| } |
| // -------------------------------------------------------------------------------- |
| sal_Int32 SAL_CALL MacabDriver::getMinorVersion( ) throw(RuntimeException) |
| { |
| return MACAB_DRIVER_VERSION_MINOR; |
| } |
| // -------------------------------------------------------------------------------- |
| void SAL_CALL MacabDriver::queryTermination( const EventObject& ) throw (TerminationVetoException, RuntimeException) |
| { |
| // nothing to do, nothing to veto |
| } |
| // -------------------------------------------------------------------------------- |
| void SAL_CALL MacabDriver::notifyTermination( const EventObject& ) throw (RuntimeException) |
| { |
| m_aImplModule.shutdown(); |
| } |
| // -------------------------------------------------------------------------------- |
| void SAL_CALL MacabDriver::disposing( const EventObject& ) throw (RuntimeException) |
| { |
| // not interested in (this is the disposing of the desktop, if any) |
| } |
| // -------------------------------------------------------------------------------- |
| const sal_Char* MacabDriver::impl_getAsciiImplementationName() |
| { |
| return "com.sun.star.comp.sdbc.macab.Driver"; |
| // this name is referenced in the configuration and in the macab.xml |
| // Please be careful when changing it. |
| } |
| // -------------------------------------------------------------------------------- |
| ::rtl::OUString MacabDriver::impl_getConfigurationSettingsPath() |
| { |
| ::rtl::OUStringBuffer aPath; |
| aPath.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" ); |
| aPath.appendAscii( "com.sun.star.comp.sdbc.macab.Driver" ); |
| return aPath.makeStringAndClear(); |
| } |
| // -------------------------------------------------------------------------------- |
| Reference< XInterface > SAL_CALL MacabDriver::Create( const Reference< XMultiServiceFactory >& _rxFactory ) throw( Exception ) |
| { |
| return *(new MacabDriver(_rxFactory)); |
| } |
| |