1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "MacabDriver.hxx"
22 #include "MacabConnection.hxx"
24 #include <com/sun/star/sdb/SQLContext.hpp>
25 #include <com/sun/star/lang/NullPointerException.hpp>
26 #include <com/sun/star/frame/Desktop.hpp>
27 #include <sal/log.hxx>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <strings.hrc>
30 #include <cppuhelper/supportsservice.hxx>
32 using namespace com::sun::star::uno
;
33 using namespace com::sun::star::lang
;
34 using namespace com::sun::star::beans
;
35 using namespace com::sun::star::sdbc
;
36 using namespace com::sun::star::sdb
;
37 using namespace com::sun::star::frame
;
38 using namespace connectivity::macab
;
42 /** throws a generic SQL exception with SQLState S1000 and error code 0
44 void throwGenericSQLException( const OUString
& _rMessage
)
47 aError
.Message
= _rMessage
;
48 aError
.SQLState
= "S1000";
53 /** throws an SQLException saying that no Mac OS installation was found
55 void throwNoMacOSException()
57 ::connectivity::SharedResources aResources
;
58 const OUString
sError( aResources
.getResourceString(
61 throwGenericSQLException( sError
);
70 MacabImplModule::MacabImplModule()
71 :m_bAttemptedLoadModule(false)
72 ,m_hConnectorModule(nullptr)
73 ,m_pConnectionFactoryFunc(nullptr)
78 bool MacabImplModule::isMacOSPresent()
80 return impl_loadModule();
86 template< typename FUNCTION
>
87 void lcl_getFunctionFromModuleOrUnload( oslModule
& _rModule
, const char* _pAsciiSymbolName
, FUNCTION
& _rFunction
)
93 const OUString sSymbolName
= OUString::createFromAscii( _pAsciiSymbolName
);
94 _rFunction
= reinterpret_cast<FUNCTION
>( osl_getSymbol( _rModule
, sSymbolName
.pData
) );
97 { // did not find the symbol
98 SAL_WARN( "connectivity.macab", "lcl_getFunctionFromModuleOrUnload: could not find the symbol " << _pAsciiSymbolName
);
99 osl_unloadModule( _rModule
);
107 extern "C" { static void thisModule() {} }
109 bool MacabImplModule::impl_loadModule()
111 if ( m_bAttemptedLoadModule
)
112 return ( m_hConnectorModule
!= nullptr );
113 m_bAttemptedLoadModule
= true;
115 OSL_ENSURE( !m_hConnectorModule
&& !m_pConnectionFactoryFunc
,
116 "MacabImplModule::impl_loadModule: inconsistence: inconsistency (never attempted load before, but some values already set)!");
118 static constexpr OUString
sModuleName( u
"" SAL_MODULENAME( "macabdrv1" ) ""_ustr
);
119 m_hConnectorModule
= osl_loadModuleRelative( &thisModule
, sModuleName
.pData
, SAL_LOADMODULE_NOW
); // LAZY! #i61335#
120 OSL_ENSURE( m_hConnectorModule
, "MacabImplModule::impl_loadModule: could not load the implementation library!" );
121 if ( !m_hConnectorModule
)
124 lcl_getFunctionFromModuleOrUnload( m_hConnectorModule
, "createMacabConnection", m_pConnectionFactoryFunc
);
126 if ( !m_hConnectorModule
)
127 // one of the symbols did not exist
128 throw RuntimeException();
134 void MacabImplModule::impl_unloadModule()
136 OSL_PRECOND( m_hConnectorModule
!= nullptr, "MacabImplModule::impl_unloadModule: no module!" );
138 osl_unloadModule( m_hConnectorModule
);
139 m_hConnectorModule
= nullptr;
141 m_pConnectionFactoryFunc
= nullptr;
143 m_bAttemptedLoadModule
= false;
147 void MacabImplModule::init()
149 if ( !impl_loadModule() )
150 throwNoMacOSException();
155 MacabConnection
* MacabImplModule::createConnection( MacabDriver
* _pDriver
) const
157 OSL_PRECOND( m_hConnectorModule
, "MacabImplModule::createConnection: not initialized!" );
159 void* pUntypedConnection
= (*m_pConnectionFactoryFunc
)( _pDriver
);
160 if ( !pUntypedConnection
)
161 throw RuntimeException();
163 return static_cast< MacabConnection
* >( pUntypedConnection
);
167 void MacabImplModule::shutdown()
169 if ( !m_hConnectorModule
)
178 MacabDriver::MacabDriver(
179 const Reference
< css::uno::XComponentContext
>& _rxContext
)
180 : MacabDriver_BASE(m_aMutex
),
181 m_xContext(_rxContext
),
184 if ( !m_xContext
.is() )
185 throw NullPointerException();
187 osl_atomic_increment( &m_refCount
);
190 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_xContext
);
191 xDesktop
->addTerminateListener( this );
193 catch( const Exception
& )
195 DBG_UNHANDLED_EXCEPTION("connectivity.macab");
197 osl_atomic_decrement( &m_refCount
);
200 void MacabDriver::disposing()
202 ::osl::MutexGuard
aGuard(m_aMutex
);
204 // when driver will be destroyed so all our connections have to be destroyed as well
205 for (auto& rxConnection
: m_xConnections
)
207 Reference
< XComponent
> xComp(rxConnection
.get(), UNO_QUERY
);
211 m_xConnections
.clear();
213 WeakComponentImplHelperBase::disposing();
216 OUString SAL_CALL
MacabDriver::getImplementationName( )
218 return "com.sun.star.comp.sdbc.macab.Driver";
221 sal_Bool SAL_CALL
MacabDriver::supportsService( const OUString
& _rServiceName
)
223 return cppu::supportsService(this, _rServiceName
);
226 Sequence
< OUString
> SAL_CALL
MacabDriver::getSupportedServiceNames( )
228 // which service is supported
229 // for more information @see com.sun.star.sdbc.Driver
230 return { "com.sun.star.sdbc.Driver" };
233 Reference
< XConnection
> SAL_CALL
MacabDriver::connect( const OUString
& url
, const Sequence
< PropertyValue
>& info
)
235 ::osl::MutexGuard
aGuard(m_aMutex
);
237 m_aImplModule
.init();
239 // create a new connection with the given properties and append it to our vector
240 MacabConnection
* pConnection
= m_aImplModule
.createConnection( this );
241 SAL_WARN_IF( !pConnection
, "connectivity.macab", "MacabDriver::connect: no connection has been created by the factory!" );
243 // by definition, the factory function returned an object which was acquired once
244 Reference
< XConnection
> xConnection
= pConnection
;
245 pConnection
->release();
247 // late constructor call which can throw exception and allows a correct dtor call when so
248 pConnection
->construct( url
, info
);
251 m_xConnections
.push_back( WeakReferenceHelper( *pConnection
) );
256 sal_Bool SAL_CALL
MacabDriver::acceptsURL( const OUString
& url
)
258 ::osl::MutexGuard
aGuard(m_aMutex
);
260 if ( !m_aImplModule
.isMacOSPresent() )
263 // here we have to look whether we support this URL format
264 return url
== "sdbc:address:macab";
267 Sequence
< DriverPropertyInfo
> SAL_CALL
MacabDriver::getPropertyInfo( const OUString
&, const Sequence
< PropertyValue
>& )
269 // if you have something special to say, return it here :-)
270 return Sequence
< DriverPropertyInfo
>();
273 sal_Int32 SAL_CALL
MacabDriver::getMajorVersion( )
275 return MACAB_DRIVER_VERSION_MAJOR
;
278 sal_Int32 SAL_CALL
MacabDriver::getMinorVersion( )
280 return MACAB_DRIVER_VERSION_MINOR
;
283 void SAL_CALL
MacabDriver::queryTermination( const EventObject
& )
285 // nothing to do, nothing to veto
288 void SAL_CALL
MacabDriver::notifyTermination( const EventObject
& )
290 m_aImplModule
.shutdown();
293 void SAL_CALL
MacabDriver::disposing( const EventObject
& )
295 // not interested in (this is the disposing of the desktop, if any)
298 OUString
MacabDriver::impl_getConfigurationSettingsPath()
300 return "/org.openoffice.Office.DataAccess/DriverSettings/com.sun.star.comp.sdbc.macab.Driver";
303 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
304 connectivity_MacabDriver_get_implementation(
305 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
307 return cppu::acquire(new MacabDriver(context
));
310 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */