summaryrefslogtreecommitdiffstats
path: root/connectivity/source/drivers/macab/MacabDriver.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /connectivity/source/drivers/macab/MacabDriver.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--connectivity/source/drivers/macab/MacabDriver.cxx310
1 files changed, 310 insertions, 0 deletions
diff --git a/connectivity/source/drivers/macab/MacabDriver.cxx b/connectivity/source/drivers/macab/MacabDriver.cxx
new file mode 100644
index 000000000..4667c690a
--- /dev/null
+++ b/connectivity/source/drivers/macab/MacabDriver.cxx
@@ -0,0 +1,310 @@
+/* -*- 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 .
+ */
+
+
+#include "MacabDriver.hxx"
+#include "MacabConnection.hxx"
+
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+#include <strings.hrc>
+#include <cppuhelper/supportsservice.hxx>
+
+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;
+
+namespace {
+
+/** throws a generic SQL exception with SQLState S1000 and error code 0
+ */
+void throwGenericSQLException( const OUString& _rMessage )
+{
+ SQLException aError;
+ aError.Message = _rMessage;
+ aError.SQLState = "S1000";
+ aError.ErrorCode = 0;
+ throw aError;
+}
+
+/** throws an SQLException saying that no Mac OS installation was found
+ */
+void throwNoMacOSException()
+{
+ ::connectivity::SharedResources aResources;
+ const OUString sError( aResources.getResourceString(
+ STR_NO_MAC_OS_FOUND
+ ) );
+ throwGenericSQLException( sError );
+}
+
+
+}
+
+// = MacabImplModule
+
+
+MacabImplModule::MacabImplModule()
+ :m_bAttemptedLoadModule(false)
+ ,m_hConnectorModule(nullptr)
+ ,m_pConnectionFactoryFunc(nullptr)
+{
+}
+
+
+bool MacabImplModule::isMacOSPresent()
+{
+ return impl_loadModule();
+}
+
+
+namespace
+{
+ template< typename FUNCTION >
+ void lcl_getFunctionFromModuleOrUnload( oslModule& _rModule, const char* _pAsciiSymbolName, FUNCTION& _rFunction )
+ {
+ _rFunction = nullptr;
+ if ( _rModule )
+ {
+
+ const OUString sSymbolName = OUString::createFromAscii( _pAsciiSymbolName );
+ _rFunction = reinterpret_cast<FUNCTION>( osl_getSymbol( _rModule, sSymbolName.pData ) );
+
+ if ( !_rFunction )
+ { // did not find the symbol
+ SAL_WARN( "connectivity.macab", "lcl_getFunctionFromModuleOrUnload: could not find the symbol " << _pAsciiSymbolName );
+ osl_unloadModule( _rModule );
+ _rModule = nullptr;
+ }
+ }
+ }
+}
+
+
+extern "C" { static void thisModule() {} }
+
+bool MacabImplModule::impl_loadModule()
+{
+ if ( m_bAttemptedLoadModule )
+ return ( m_hConnectorModule != nullptr );
+ m_bAttemptedLoadModule = true;
+
+ OSL_ENSURE( !m_hConnectorModule && !m_pConnectionFactoryFunc,
+ "MacabImplModule::impl_loadModule: inconsistence: inconsistency (never attempted load before, but some values already set)!");
+
+ const OUString sModuleName( 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 != nullptr, "MacabImplModule::impl_unloadModule: no module!" );
+
+ osl_unloadModule( m_hConnectorModule );
+ m_hConnectorModule = nullptr;
+
+ m_pConnectionFactoryFunc = nullptr;
+
+ m_bAttemptedLoadModule = false;
+}
+
+
+void MacabImplModule::init()
+{
+ if ( !impl_loadModule() )
+ throwNoMacOSException();
+
+}
+
+
+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< css::uno::XComponentContext >& _rxContext)
+ : MacabDriver_BASE(m_aMutex),
+ m_xContext(_rxContext),
+ m_aImplModule()
+{
+ if ( !m_xContext.is() )
+ throw NullPointerException();
+
+ osl_atomic_increment( &m_refCount );
+ try
+ {
+ Reference< XDesktop2 > xDesktop = Desktop::create( m_xContext );
+ xDesktop->addTerminateListener( this );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("connectivity.macab");
+ }
+ osl_atomic_decrement( &m_refCount );
+}
+
+void MacabDriver::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ // when driver will be destroyed so all our connections have to be destroyed as well
+ for (auto& rxConnection : m_xConnections)
+ {
+ Reference< XComponent > xComp(rxConnection.get(), UNO_QUERY);
+ if (xComp.is())
+ xComp->dispose();
+ }
+ m_xConnections.clear();
+
+ WeakComponentImplHelperBase::disposing();
+}
+
+OUString SAL_CALL MacabDriver::getImplementationName( )
+{
+ return "com.sun.star.comp.sdbc.macab.Driver";
+}
+
+sal_Bool SAL_CALL MacabDriver::supportsService( const OUString& _rServiceName )
+{
+ return cppu::supportsService(this, _rServiceName);
+}
+
+Sequence< OUString > SAL_CALL MacabDriver::getSupportedServiceNames( )
+{
+ // which service is supported
+ // for more information @see com.sun.star.sdbc.Driver
+ return { "com.sun.star.sdbc.Driver" };
+}
+
+Reference< XConnection > SAL_CALL MacabDriver::connect( const OUString& url, const Sequence< PropertyValue >& info )
+{
+ ::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 );
+ SAL_WARN_IF( !pConnection, "connectivity.macab", "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 OUString& url )
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if ( !m_aImplModule.isMacOSPresent() )
+ return false;
+
+ // here we have to look whether we support this URL format
+ return url == "sdbc:address:macab";
+}
+
+Sequence< DriverPropertyInfo > SAL_CALL MacabDriver::getPropertyInfo( const OUString&, const Sequence< PropertyValue >& )
+{
+ // if you have something special to say, return it here :-)
+ return Sequence< DriverPropertyInfo >();
+}
+
+sal_Int32 SAL_CALL MacabDriver::getMajorVersion( )
+{
+ return MACAB_DRIVER_VERSION_MAJOR;
+}
+
+sal_Int32 SAL_CALL MacabDriver::getMinorVersion( )
+{
+ return MACAB_DRIVER_VERSION_MINOR;
+}
+
+void SAL_CALL MacabDriver::queryTermination( const EventObject& )
+{
+ // nothing to do, nothing to veto
+}
+
+void SAL_CALL MacabDriver::notifyTermination( const EventObject& )
+{
+ m_aImplModule.shutdown();
+}
+
+void SAL_CALL MacabDriver::disposing( const EventObject& )
+{
+ // not interested in (this is the disposing of the desktop, if any)
+}
+
+OUString MacabDriver::impl_getConfigurationSettingsPath()
+{
+ return "/org.openoffice.Office.DataAccess/DriverSettings/com.sun.star.comp.sdbc.macab.Driver";
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+connectivity_MacabDriver_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new MacabDriver(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */