1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*9b5730f6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*9b5730f6SAndrew Rist * distributed with this work for additional information
6*9b5730f6SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*9b5730f6SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*9b5730f6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*9b5730f6SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist * KIND, either express or implied. See the License for the
17*9b5730f6SAndrew Rist * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*9b5730f6SAndrew Rist *************************************************************/
21*9b5730f6SAndrew Rist
22*9b5730f6SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "MacabDriver.hxx"
28cdf0e10cSrcweir #include "MacabConnection.hxx"
29cdf0e10cSrcweir
30cdf0e10cSrcweir /** === begin UNO includes === **/
31cdf0e10cSrcweir #include <com/sun/star/sdb/SQLContext.hpp>
32cdf0e10cSrcweir #include <com/sun/star/lang/NullPointerException.hpp>
33cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp>
34cdf0e10cSrcweir /** === end UNO includes === **/
35cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
36cdf0e10cSrcweir #include <tools/diagnose_ex.h>
37cdf0e10cSrcweir #include "resource/macab_res.hrc"
38cdf0e10cSrcweir
39cdf0e10cSrcweir using namespace com::sun::star::uno;
40cdf0e10cSrcweir using namespace com::sun::star::lang;
41cdf0e10cSrcweir using namespace com::sun::star::beans;
42cdf0e10cSrcweir using namespace com::sun::star::sdbc;
43cdf0e10cSrcweir using namespace com::sun::star::sdb;
44cdf0e10cSrcweir using namespace com::sun::star::frame;
45cdf0e10cSrcweir using namespace connectivity::macab;
46cdf0e10cSrcweir
47cdf0e10cSrcweir // =======================================================================
48cdf0e10cSrcweir // = MacabImplModule
49cdf0e10cSrcweir // =======================================================================
50cdf0e10cSrcweir // --------------------------------------------------------------------------------
MacabImplModule(const Reference<XMultiServiceFactory> & _rxFactory)51cdf0e10cSrcweir MacabImplModule::MacabImplModule( const Reference< XMultiServiceFactory >& _rxFactory )
52cdf0e10cSrcweir :m_xORB(_rxFactory)
53cdf0e10cSrcweir ,m_bAttemptedLoadModule(false)
54cdf0e10cSrcweir ,m_hConnectorModule(NULL)
55cdf0e10cSrcweir ,m_pConnectionFactoryFunc(NULL)
56cdf0e10cSrcweir {
57cdf0e10cSrcweir if ( !m_xORB.is() )
58cdf0e10cSrcweir throw NullPointerException();
59cdf0e10cSrcweir }
60cdf0e10cSrcweir
61cdf0e10cSrcweir // --------------------------------------------------------------------------------
isMacOSPresent()62cdf0e10cSrcweir bool MacabImplModule::isMacOSPresent()
63cdf0e10cSrcweir {
64cdf0e10cSrcweir return impl_loadModule();
65cdf0e10cSrcweir }
66cdf0e10cSrcweir
67cdf0e10cSrcweir // --------------------------------------------------------------------------------
68cdf0e10cSrcweir namespace
69cdf0e10cSrcweir {
70cdf0e10cSrcweir template< typename FUNCTION >
lcl_getFunctionFromModuleOrUnload(oslModule & _rModule,const sal_Char * _pAsciiSymbolName,FUNCTION & _rFunction)71cdf0e10cSrcweir void lcl_getFunctionFromModuleOrUnload( oslModule& _rModule, const sal_Char* _pAsciiSymbolName, FUNCTION& _rFunction )
72cdf0e10cSrcweir {
73cdf0e10cSrcweir _rFunction = NULL;
74cdf0e10cSrcweir if ( _rModule )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir //
77cdf0e10cSrcweir const ::rtl::OUString sSymbolName = ::rtl::OUString::createFromAscii( _pAsciiSymbolName );
78cdf0e10cSrcweir _rFunction = (FUNCTION)( osl_getSymbol( _rModule, sSymbolName.pData ) );
79cdf0e10cSrcweir
80cdf0e10cSrcweir if ( !_rFunction )
81cdf0e10cSrcweir { // did not find the symbol
82cdf0e10cSrcweir OSL_ENSURE( false, ::rtl::OString( "lcl_getFunctionFromModuleOrUnload: could not find the symbol " ) + ::rtl::OString( _pAsciiSymbolName ) );
83cdf0e10cSrcweir osl_unloadModule( _rModule );
84cdf0e10cSrcweir _rModule = NULL;
85cdf0e10cSrcweir }
86cdf0e10cSrcweir }
87cdf0e10cSrcweir }
88cdf0e10cSrcweir }
89cdf0e10cSrcweir
90cdf0e10cSrcweir // --------------------------------------------------------------------------------
thisModule()91cdf0e10cSrcweir extern "C" { static void SAL_CALL thisModule() {} }
92cdf0e10cSrcweir
impl_loadModule()93cdf0e10cSrcweir bool MacabImplModule::impl_loadModule()
94cdf0e10cSrcweir {
95cdf0e10cSrcweir if ( m_bAttemptedLoadModule )
96cdf0e10cSrcweir return ( m_hConnectorModule != NULL );
97cdf0e10cSrcweir m_bAttemptedLoadModule = true;
98cdf0e10cSrcweir
99cdf0e10cSrcweir OSL_ENSURE( !m_hConnectorModule && !m_pConnectionFactoryFunc,
100cdf0e10cSrcweir "MacabImplModule::impl_loadModule: inconsistence: inconsistency (never attempted load before, but some values already set)!");
101cdf0e10cSrcweir
102cdf0e10cSrcweir const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii( SAL_MODULENAME( "macabdrv1" ) );
103cdf0e10cSrcweir m_hConnectorModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, SAL_LOADMODULE_NOW ); // LAZY! #i61335#
104cdf0e10cSrcweir OSL_ENSURE( m_hConnectorModule, "MacabImplModule::impl_loadModule: could not load the implementation library!" );
105cdf0e10cSrcweir if ( !m_hConnectorModule )
106cdf0e10cSrcweir return false;
107cdf0e10cSrcweir
108cdf0e10cSrcweir lcl_getFunctionFromModuleOrUnload( m_hConnectorModule, "createMacabConnection", m_pConnectionFactoryFunc );
109cdf0e10cSrcweir
110cdf0e10cSrcweir if ( !m_hConnectorModule )
111cdf0e10cSrcweir // one of the symbols did not exist
112cdf0e10cSrcweir throw RuntimeException();
113cdf0e10cSrcweir
114cdf0e10cSrcweir return true;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir
117cdf0e10cSrcweir // --------------------------------------------------------------------------------
impl_unloadModule()118cdf0e10cSrcweir void MacabImplModule::impl_unloadModule()
119cdf0e10cSrcweir {
120cdf0e10cSrcweir OSL_PRECOND( m_hConnectorModule != NULL, "MacabImplModule::impl_unloadModule: no module!" );
121cdf0e10cSrcweir
122cdf0e10cSrcweir osl_unloadModule( m_hConnectorModule );
123cdf0e10cSrcweir m_hConnectorModule = NULL;
124cdf0e10cSrcweir
125cdf0e10cSrcweir m_pConnectionFactoryFunc = NULL;
126cdf0e10cSrcweir
127cdf0e10cSrcweir m_bAttemptedLoadModule = false;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir
130cdf0e10cSrcweir // --------------------------------------------------------------------------------
init()131cdf0e10cSrcweir void MacabImplModule::init()
132cdf0e10cSrcweir {
133cdf0e10cSrcweir if ( !impl_loadModule() )
134cdf0e10cSrcweir impl_throwNoMacOSException();
135cdf0e10cSrcweir
136cdf0e10cSrcweir }
137cdf0e10cSrcweir
138cdf0e10cSrcweir // --------------------------------------------------------------------------------
impl_throwNoMacOSException()139cdf0e10cSrcweir void MacabImplModule::impl_throwNoMacOSException()
140cdf0e10cSrcweir {
141cdf0e10cSrcweir ::connectivity::SharedResources aResources;
142cdf0e10cSrcweir const ::rtl::OUString sError( aResources.getResourceString(
143cdf0e10cSrcweir STR_NO_MAC_OS_FOUND
144cdf0e10cSrcweir ) );
145cdf0e10cSrcweir impl_throwGenericSQLException( sError );
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
148cdf0e10cSrcweir // --------------------------------------------------------------------------------
impl_throwGenericSQLException(const::rtl::OUString & _rMessage)149cdf0e10cSrcweir void MacabImplModule::impl_throwGenericSQLException( const ::rtl::OUString& _rMessage )
150cdf0e10cSrcweir {
151cdf0e10cSrcweir SQLException aError;
152cdf0e10cSrcweir aError.Message = _rMessage;
153cdf0e10cSrcweir aError.SQLState = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) );
154cdf0e10cSrcweir aError.ErrorCode = 0;
155cdf0e10cSrcweir throw aError;
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
158cdf0e10cSrcweir // --------------------------------------------------------------------------------
createConnection(MacabDriver * _pDriver) const159cdf0e10cSrcweir MacabConnection* MacabImplModule::createConnection( MacabDriver* _pDriver ) const
160cdf0e10cSrcweir {
161cdf0e10cSrcweir OSL_PRECOND( m_hConnectorModule, "MacabImplModule::createConnection: not initialized!" );
162cdf0e10cSrcweir
163cdf0e10cSrcweir void* pUntypedConnection = (*m_pConnectionFactoryFunc)( _pDriver );
164cdf0e10cSrcweir if ( !pUntypedConnection )
165cdf0e10cSrcweir throw RuntimeException();
166cdf0e10cSrcweir
167cdf0e10cSrcweir return static_cast< MacabConnection* >( pUntypedConnection );
168cdf0e10cSrcweir }
169cdf0e10cSrcweir
170cdf0e10cSrcweir // --------------------------------------------------------------------------------
shutdown()171cdf0e10cSrcweir void MacabImplModule::shutdown()
172cdf0e10cSrcweir {
173cdf0e10cSrcweir if ( !m_hConnectorModule )
174cdf0e10cSrcweir return;
175cdf0e10cSrcweir
176cdf0e10cSrcweir impl_unloadModule();
177cdf0e10cSrcweir }
178cdf0e10cSrcweir
179cdf0e10cSrcweir // =======================================================================
180cdf0e10cSrcweir // = MacabDriver
181cdf0e10cSrcweir // =======================================================================
MacabDriver(const Reference<::com::sun::star::lang::XMultiServiceFactory> & _rxFactory)182cdf0e10cSrcweir MacabDriver::MacabDriver(
183cdf0e10cSrcweir const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
184cdf0e10cSrcweir : MacabDriver_BASE(m_aMutex),
185cdf0e10cSrcweir m_xMSFactory(_rxFactory),
186cdf0e10cSrcweir m_aImplModule(_rxFactory)
187cdf0e10cSrcweir {
188cdf0e10cSrcweir if ( !m_xMSFactory.is() )
189cdf0e10cSrcweir throw NullPointerException();
190cdf0e10cSrcweir
191cdf0e10cSrcweir osl_incrementInterlockedCount( &m_refCount );
192cdf0e10cSrcweir try
193cdf0e10cSrcweir {
194cdf0e10cSrcweir Reference< XDesktop > xDesktop(
195cdf0e10cSrcweir m_xMSFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ),
196cdf0e10cSrcweir UNO_QUERY_THROW );
197cdf0e10cSrcweir xDesktop->addTerminateListener( this );
198cdf0e10cSrcweir }
199cdf0e10cSrcweir catch( const Exception& )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION();
202cdf0e10cSrcweir }
203cdf0e10cSrcweir osl_decrementInterlockedCount( &m_refCount );
204cdf0e10cSrcweir }
205cdf0e10cSrcweir // --------------------------------------------------------------------------------
disposing()206cdf0e10cSrcweir void MacabDriver::disposing()
207cdf0e10cSrcweir {
208cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex);
209cdf0e10cSrcweir
210cdf0e10cSrcweir // when driver will be destroied so all our connections have to be destroied as well
211cdf0e10cSrcweir for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir Reference< XComponent > xComp(i->get(), UNO_QUERY);
214cdf0e10cSrcweir if (xComp.is())
215cdf0e10cSrcweir xComp->dispose();
216cdf0e10cSrcweir }
217cdf0e10cSrcweir m_xConnections.clear();
218cdf0e10cSrcweir
219cdf0e10cSrcweir WeakComponentImplHelperBase::disposing();
220cdf0e10cSrcweir }
221cdf0e10cSrcweir // static ServiceInfo
222cdf0e10cSrcweir //------------------------------------------------------------------------------
getImplementationName_Static()223cdf0e10cSrcweir rtl::OUString MacabDriver::getImplementationName_Static( ) throw(RuntimeException)
224cdf0e10cSrcweir {
225cdf0e10cSrcweir return rtl::OUString::createFromAscii( impl_getAsciiImplementationName() );
226cdf0e10cSrcweir }
227cdf0e10cSrcweir //------------------------------------------------------------------------------
getSupportedServiceNames_Static()228cdf0e10cSrcweir Sequence< ::rtl::OUString > MacabDriver::getSupportedServiceNames_Static( ) throw (RuntimeException)
229cdf0e10cSrcweir {
230cdf0e10cSrcweir // which service is supported
231cdf0e10cSrcweir // for more information @see com.sun.star.sdbc.Driver
232cdf0e10cSrcweir Sequence< ::rtl::OUString > aSNS( 1 );
233cdf0e10cSrcweir aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
234cdf0e10cSrcweir
235cdf0e10cSrcweir return aSNS;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir //------------------------------------------------------------------
getImplementationName()238cdf0e10cSrcweir ::rtl::OUString SAL_CALL MacabDriver::getImplementationName( ) throw(RuntimeException)
239cdf0e10cSrcweir {
240cdf0e10cSrcweir return getImplementationName_Static();
241cdf0e10cSrcweir }
242cdf0e10cSrcweir //------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)243cdf0e10cSrcweir sal_Bool SAL_CALL MacabDriver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
244cdf0e10cSrcweir {
245cdf0e10cSrcweir Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
246cdf0e10cSrcweir const ::rtl::OUString* pSupported = aSupported.getConstArray();
247cdf0e10cSrcweir const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
248cdf0e10cSrcweir
249cdf0e10cSrcweir while (pSupported != pEnd && !pSupported->equals(_rServiceName))
250cdf0e10cSrcweir ++pSupported;
251cdf0e10cSrcweir return pSupported != pEnd;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir //------------------------------------------------------------------
getSupportedServiceNames()254cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL MacabDriver::getSupportedServiceNames( ) throw(RuntimeException)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir return getSupportedServiceNames_Static();
257cdf0e10cSrcweir }
258cdf0e10cSrcweir // --------------------------------------------------------------------------------
connect(const::rtl::OUString & url,const Sequence<PropertyValue> & info)259cdf0e10cSrcweir Reference< XConnection > SAL_CALL MacabDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
260cdf0e10cSrcweir {
261cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex);
262cdf0e10cSrcweir
263cdf0e10cSrcweir m_aImplModule.init();
264cdf0e10cSrcweir
265cdf0e10cSrcweir // create a new connection with the given properties and append it to our vector
266cdf0e10cSrcweir MacabConnection* pConnection = m_aImplModule.createConnection( this );
267cdf0e10cSrcweir OSL_POSTCOND( pConnection, "MacabDriver::connect: no connection has been created by the factory!" );
268cdf0e10cSrcweir
269cdf0e10cSrcweir // by definition, the factory function returned an object which was acquired once
270cdf0e10cSrcweir Reference< XConnection > xConnection = pConnection;
271cdf0e10cSrcweir pConnection->release();
272cdf0e10cSrcweir
273cdf0e10cSrcweir // late constructor call which can throw exception and allows a correct dtor call when so
274cdf0e10cSrcweir pConnection->construct( url, info );
275cdf0e10cSrcweir
276cdf0e10cSrcweir // remember it
277cdf0e10cSrcweir m_xConnections.push_back( WeakReferenceHelper( *pConnection ) );
278cdf0e10cSrcweir
279cdf0e10cSrcweir return xConnection;
280cdf0e10cSrcweir }
281cdf0e10cSrcweir // --------------------------------------------------------------------------------
acceptsURL(const::rtl::OUString & url)282cdf0e10cSrcweir sal_Bool SAL_CALL MacabDriver::acceptsURL( const ::rtl::OUString& url )
283cdf0e10cSrcweir throw(SQLException, RuntimeException)
284cdf0e10cSrcweir {
285cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex);
286cdf0e10cSrcweir
287cdf0e10cSrcweir if ( !m_aImplModule.isMacOSPresent() )
288cdf0e10cSrcweir return sal_False;
289cdf0e10cSrcweir
290cdf0e10cSrcweir // here we have to look whether we support this URL format
291cdf0e10cSrcweir return (!url.compareTo(::rtl::OUString::createFromAscii("sdbc:address:macab:"), 18));
292cdf0e10cSrcweir }
293cdf0e10cSrcweir // --------------------------------------------------------------------------------
getPropertyInfo(const::rtl::OUString &,const Sequence<PropertyValue> &)294cdf0e10cSrcweir Sequence< DriverPropertyInfo > SAL_CALL MacabDriver::getPropertyInfo( const ::rtl::OUString&, const Sequence< PropertyValue >& ) throw(SQLException, RuntimeException)
295cdf0e10cSrcweir {
296cdf0e10cSrcweir // if you have something special to say, return it here :-)
297cdf0e10cSrcweir return Sequence< DriverPropertyInfo >();
298cdf0e10cSrcweir }
299cdf0e10cSrcweir // --------------------------------------------------------------------------------
getMajorVersion()300cdf0e10cSrcweir sal_Int32 SAL_CALL MacabDriver::getMajorVersion( ) throw(RuntimeException)
301cdf0e10cSrcweir {
302cdf0e10cSrcweir return MACAB_DRIVER_VERSION_MAJOR;
303cdf0e10cSrcweir }
304cdf0e10cSrcweir // --------------------------------------------------------------------------------
getMinorVersion()305cdf0e10cSrcweir sal_Int32 SAL_CALL MacabDriver::getMinorVersion( ) throw(RuntimeException)
306cdf0e10cSrcweir {
307cdf0e10cSrcweir return MACAB_DRIVER_VERSION_MINOR;
308cdf0e10cSrcweir }
309cdf0e10cSrcweir // --------------------------------------------------------------------------------
queryTermination(const EventObject &)310cdf0e10cSrcweir void SAL_CALL MacabDriver::queryTermination( const EventObject& ) throw (TerminationVetoException, RuntimeException)
311cdf0e10cSrcweir {
312cdf0e10cSrcweir // nothing to do, nothing to veto
313cdf0e10cSrcweir }
314cdf0e10cSrcweir // --------------------------------------------------------------------------------
notifyTermination(const EventObject &)315cdf0e10cSrcweir void SAL_CALL MacabDriver::notifyTermination( const EventObject& ) throw (RuntimeException)
316cdf0e10cSrcweir {
317cdf0e10cSrcweir m_aImplModule.shutdown();
318cdf0e10cSrcweir }
319cdf0e10cSrcweir // --------------------------------------------------------------------------------
disposing(const EventObject &)320cdf0e10cSrcweir void SAL_CALL MacabDriver::disposing( const EventObject& ) throw (RuntimeException)
321cdf0e10cSrcweir {
322cdf0e10cSrcweir // not interested in (this is the disposing of the desktop, if any)
323cdf0e10cSrcweir }
324cdf0e10cSrcweir // --------------------------------------------------------------------------------
impl_getAsciiImplementationName()325cdf0e10cSrcweir const sal_Char* MacabDriver::impl_getAsciiImplementationName()
326cdf0e10cSrcweir {
327cdf0e10cSrcweir return "com.sun.star.comp.sdbc.macab.Driver";
328cdf0e10cSrcweir // this name is referenced in the configuration and in the macab.xml
329cdf0e10cSrcweir // Please be careful when changing it.
330cdf0e10cSrcweir }
331cdf0e10cSrcweir // --------------------------------------------------------------------------------
impl_getConfigurationSettingsPath()332cdf0e10cSrcweir ::rtl::OUString MacabDriver::impl_getConfigurationSettingsPath()
333cdf0e10cSrcweir {
334cdf0e10cSrcweir ::rtl::OUStringBuffer aPath;
335cdf0e10cSrcweir aPath.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" );
336cdf0e10cSrcweir aPath.appendAscii( "com.sun.star.comp.sdbc.macab.Driver" );
337cdf0e10cSrcweir return aPath.makeStringAndClear();
338cdf0e10cSrcweir }
339cdf0e10cSrcweir // --------------------------------------------------------------------------------
Create(const Reference<XMultiServiceFactory> & _rxFactory)340cdf0e10cSrcweir Reference< XInterface > SAL_CALL MacabDriver::Create( const Reference< XMultiServiceFactory >& _rxFactory ) throw( Exception )
341cdf0e10cSrcweir {
342cdf0e10cSrcweir return *(new MacabDriver(_rxFactory));
343cdf0e10cSrcweir }
344cdf0e10cSrcweir
345