1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MacabDriver.cxx,v $
10 * $Revision: 1.4.56.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include "MacabDriver.hxx"
35 #include "MacabConnection.hxx"
37 /** === begin UNO includes === **/
38 #include <com/sun/star/sdb/SQLContext.hpp>
39 #include <com/sun/star/lang/NullPointerException.hpp>
40 #include <com/sun/star/frame/XDesktop.hpp>
41 /** === end UNO includes === **/
42 #include <rtl/ustrbuf.hxx>
43 #include <tools/diagnose_ex.h>
44 #include "resource/macab_res.hrc"
46 using namespace com::sun::star::uno
;
47 using namespace com::sun::star::lang
;
48 using namespace com::sun::star::beans
;
49 using namespace com::sun::star::sdbc
;
50 using namespace com::sun::star::sdb
;
51 using namespace com::sun::star::frame
;
52 using namespace connectivity::macab
;
54 // =======================================================================
56 // =======================================================================
57 // --------------------------------------------------------------------------------
58 MacabImplModule::MacabImplModule( const Reference
< XMultiServiceFactory
>& _rxFactory
)
60 ,m_bAttemptedLoadModule(false)
61 ,m_hConnectorModule(NULL
)
62 ,m_pConnectionFactoryFunc(NULL
)
65 throw NullPointerException();
68 // --------------------------------------------------------------------------------
69 bool MacabImplModule::isMacOSPresent()
71 return impl_loadModule();
74 // --------------------------------------------------------------------------------
77 template< typename FUNCTION
>
78 void lcl_getFunctionFromModuleOrUnload( oslModule
& _rModule
, const sal_Char
* _pAsciiSymbolName
, FUNCTION
& _rFunction
)
84 const ::rtl::OUString sSymbolName
= ::rtl::OUString::createFromAscii( _pAsciiSymbolName
);
85 _rFunction
= (FUNCTION
)( osl_getSymbol( _rModule
, sSymbolName
.pData
) );
88 { // did not find the symbol
89 OSL_ENSURE( false, ::rtl::OString( "lcl_getFunctionFromModuleOrUnload: could not find the symbol " ) + ::rtl::OString( _pAsciiSymbolName
) );
90 osl_unloadModule( _rModule
);
97 // --------------------------------------------------------------------------------
98 extern "C" { static void SAL_CALL
thisModule() {} }
100 bool MacabImplModule::impl_loadModule()
102 if ( m_bAttemptedLoadModule
)
103 return ( m_hConnectorModule
!= NULL
);
104 m_bAttemptedLoadModule
= true;
106 OSL_ENSURE( !m_hConnectorModule
&& !m_pConnectionFactoryFunc
,
107 "MacabImplModule::impl_loadModule: inconsistence: inconsistency (never attempted load before, but some values already set)!");
109 const ::rtl::OUString sModuleName
= ::rtl::OUString::createFromAscii( SAL_MODULENAME( "macabdrv1" ) );
110 m_hConnectorModule
= osl_loadModuleRelative( &thisModule
, sModuleName
.pData
, SAL_LOADMODULE_NOW
); // LAZY! #i61335#
111 OSL_ENSURE( m_hConnectorModule
, "MacabImplModule::impl_loadModule: could not load the implementation library!" );
112 if ( !m_hConnectorModule
)
115 lcl_getFunctionFromModuleOrUnload( m_hConnectorModule
, "createMacabConnection", m_pConnectionFactoryFunc
);
117 if ( !m_hConnectorModule
)
118 // one of the symbols did not exist
119 throw RuntimeException();
124 // --------------------------------------------------------------------------------
125 void MacabImplModule::impl_unloadModule()
127 OSL_PRECOND( m_hConnectorModule
!= NULL
, "MacabImplModule::impl_unloadModule: no module!" );
129 osl_unloadModule( m_hConnectorModule
);
130 m_hConnectorModule
= NULL
;
132 m_pConnectionFactoryFunc
= NULL
;
134 m_bAttemptedLoadModule
= false;
137 // --------------------------------------------------------------------------------
138 void MacabImplModule::init()
140 if ( !impl_loadModule() )
141 impl_throwNoMacOSException();
145 // --------------------------------------------------------------------------------
146 void MacabImplModule::impl_throwNoMacOSException()
148 ::connectivity::SharedResources aResources
;
149 const ::rtl::OUString
sError( aResources
.getResourceString(
152 impl_throwGenericSQLException( sError
);
155 // --------------------------------------------------------------------------------
156 void MacabImplModule::impl_throwGenericSQLException( const ::rtl::OUString
& _rMessage
)
159 aError
.Message
= _rMessage
;
160 aError
.SQLState
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) );
161 aError
.ErrorCode
= 0;
165 // --------------------------------------------------------------------------------
166 MacabConnection
* MacabImplModule::createConnection( MacabDriver
* _pDriver
) const
168 OSL_PRECOND( m_hConnectorModule
, "MacabImplModule::createConnection: not initialized!" );
170 void* pUntypedConnection
= (*m_pConnectionFactoryFunc
)( _pDriver
);
171 if ( !pUntypedConnection
)
172 throw RuntimeException();
174 return static_cast< MacabConnection
* >( pUntypedConnection
);
177 // --------------------------------------------------------------------------------
178 void MacabImplModule::shutdown()
180 if ( !m_hConnectorModule
)
186 // =======================================================================
188 // =======================================================================
189 MacabDriver::MacabDriver(
190 const Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& _rxFactory
)
191 : MacabDriver_BASE(m_aMutex
),
192 m_xMSFactory(_rxFactory
),
193 m_aImplModule(_rxFactory
)
195 if ( !m_xMSFactory
.is() )
196 throw NullPointerException();
198 osl_incrementInterlockedCount( &m_refCount
);
201 Reference
< XDesktop
> xDesktop(
202 m_xMSFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ),
204 xDesktop
->addTerminateListener( this );
206 catch( const Exception
& )
208 DBG_UNHANDLED_EXCEPTION();
210 osl_decrementInterlockedCount( &m_refCount
);
212 // --------------------------------------------------------------------------------
213 void MacabDriver::disposing()
215 ::osl::MutexGuard
aGuard(m_aMutex
);
217 // when driver will be destroied so all our connections have to be destroied as well
218 for (OWeakRefArray::iterator i
= m_xConnections
.begin(); m_xConnections
.end() != i
; ++i
)
220 Reference
< XComponent
> xComp(i
->get(), UNO_QUERY
);
224 m_xConnections
.clear();
226 WeakComponentImplHelperBase::disposing();
228 // static ServiceInfo
229 //------------------------------------------------------------------------------
230 rtl::OUString
MacabDriver::getImplementationName_Static( ) throw(RuntimeException
)
232 return rtl::OUString::createFromAscii( impl_getAsciiImplementationName() );
234 //------------------------------------------------------------------------------
235 Sequence
< ::rtl::OUString
> MacabDriver::getSupportedServiceNames_Static( ) throw (RuntimeException
)
237 // which service is supported
238 // for more information @see com.sun.star.sdbc.Driver
239 Sequence
< ::rtl::OUString
> aSNS( 1 );
240 aSNS
[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
244 //------------------------------------------------------------------
245 ::rtl::OUString SAL_CALL
MacabDriver::getImplementationName( ) throw(RuntimeException
)
247 return getImplementationName_Static();
249 //------------------------------------------------------------------
250 sal_Bool SAL_CALL
MacabDriver::supportsService( const ::rtl::OUString
& _rServiceName
) throw(RuntimeException
)
252 Sequence
< ::rtl::OUString
> aSupported(getSupportedServiceNames());
253 const ::rtl::OUString
* pSupported
= aSupported
.getConstArray();
254 const ::rtl::OUString
* pEnd
= pSupported
+ aSupported
.getLength();
256 while (pSupported
!= pEnd
&& !pSupported
->equals(_rServiceName
))
258 return pSupported
!= pEnd
;
260 //------------------------------------------------------------------
261 Sequence
< ::rtl::OUString
> SAL_CALL
MacabDriver::getSupportedServiceNames( ) throw(RuntimeException
)
263 return getSupportedServiceNames_Static();
265 // --------------------------------------------------------------------------------
266 Reference
< XConnection
> SAL_CALL
MacabDriver::connect( const ::rtl::OUString
& url
, const Sequence
< PropertyValue
>& info
) throw(SQLException
, RuntimeException
)
268 ::osl::MutexGuard
aGuard(m_aMutex
);
270 m_aImplModule
.init();
272 // create a new connection with the given properties and append it to our vector
273 MacabConnection
* pConnection
= m_aImplModule
.createConnection( this );
274 OSL_POSTCOND( pConnection
, "MacabDriver::connect: no connection has been created by the factory!" );
276 // by definition, the factory function returned an object which was acquired once
277 Reference
< XConnection
> xConnection
= pConnection
;
278 pConnection
->release();
280 // late constructor call which can throw exception and allows a correct dtor call when so
281 pConnection
->construct( url
, info
);
284 m_xConnections
.push_back( WeakReferenceHelper( *pConnection
) );
288 // --------------------------------------------------------------------------------
289 sal_Bool SAL_CALL
MacabDriver::acceptsURL( const ::rtl::OUString
& url
)
290 throw(SQLException
, RuntimeException
)
292 ::osl::MutexGuard
aGuard(m_aMutex
);
294 if ( !m_aImplModule
.isMacOSPresent() )
297 // here we have to look whether we support this URL format
298 return (!url
.compareTo(::rtl::OUString::createFromAscii("sdbc:address:macab:"), 18));
300 // --------------------------------------------------------------------------------
301 Sequence
< DriverPropertyInfo
> SAL_CALL
MacabDriver::getPropertyInfo( const ::rtl::OUString
&, const Sequence
< PropertyValue
>& ) throw(SQLException
, RuntimeException
)
303 // if you have something special to say, return it here :-)
304 return Sequence
< DriverPropertyInfo
>();
306 // --------------------------------------------------------------------------------
307 sal_Int32 SAL_CALL
MacabDriver::getMajorVersion( ) throw(RuntimeException
)
309 return MACAB_DRIVER_VERSION_MAJOR
;
311 // --------------------------------------------------------------------------------
312 sal_Int32 SAL_CALL
MacabDriver::getMinorVersion( ) throw(RuntimeException
)
314 return MACAB_DRIVER_VERSION_MINOR
;
316 // --------------------------------------------------------------------------------
317 void SAL_CALL
MacabDriver::queryTermination( const EventObject
& ) throw (TerminationVetoException
, RuntimeException
)
319 // nothing to do, nothing to veto
321 // --------------------------------------------------------------------------------
322 void SAL_CALL
MacabDriver::notifyTermination( const EventObject
& ) throw (RuntimeException
)
324 m_aImplModule
.shutdown();
326 // --------------------------------------------------------------------------------
327 void SAL_CALL
MacabDriver::disposing( const EventObject
& ) throw (RuntimeException
)
329 // not interested in (this is the disposing of the desktop, if any)
331 // --------------------------------------------------------------------------------
332 const sal_Char
* MacabDriver::impl_getAsciiImplementationName()
334 return "com.sun.star.comp.sdbc.macab.Driver";
335 // this name is referenced in the configuration and in the macab.xml
336 // Please be careful when changing it.
338 // --------------------------------------------------------------------------------
339 ::rtl::OUString
MacabDriver::impl_getConfigurationSettingsPath()
341 ::rtl::OUStringBuffer aPath
;
342 aPath
.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" );
343 aPath
.appendAscii( "com.sun.star.comp.sdbc.macab.Driver" );
344 return aPath
.makeStringAndClear();
346 // --------------------------------------------------------------------------------
347 Reference
< XInterface
> SAL_CALL
MacabDriver::Create( const Reference
< XMultiServiceFactory
>& _rxFactory
) throw( Exception
)
349 return *(new MacabDriver(_rxFactory
));