merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / mozab / MDriver.cxx
blob340e6ed385423b14cc92c6c9c7e85223fe1df439
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MDriver.cxx,v $
10 * $Revision: 1.19.56.3 $
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"
33 #include "MDriver.hxx"
34 #include "MConnection.hxx"
35 #include "connectivity/dbexception.hxx"
36 #include "resource/mozab_res.hrc"
37 #include "resource/common_res.hrc"
39 #include <tools/solar.h>
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::lang;
42 using namespace com::sun::star::beans;
43 using namespace com::sun::star::sdbc;
44 using namespace connectivity::mozab;
46 namespace connectivity
48 namespace mozab
50 //------------------------------------------------------------------
51 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL MozabDriver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception )
53 return *(new MozabDriver( _rxFactory ));
57 // --------------------------------------------------------------------------------
58 MozabDriver::MozabDriver(
59 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
60 : ODriver_BASE(m_aMutex), m_xMSFactory( _rxFactory )
61 ,m_hModule(NULL)
62 ,m_pCreationFunc(NULL)
65 // -----------------------------------------------------------------------------
66 MozabDriver::~MozabDriver()
69 // --------------------------------------------------------------------------------
70 void MozabDriver::disposing()
72 ::osl::MutexGuard aGuard(m_aMutex);
74 // when driver will be destroied so all our connections have to be destroied as well
75 for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
77 Reference< XComponent > xComp(i->get(), UNO_QUERY);
78 if (xComp.is())
79 xComp->dispose();
81 m_xConnections.clear();
82 connectivity::OWeakRefArray().swap(m_xConnections); // this really clears
84 ODriver_BASE::disposing();
85 if(m_hModule)
87 m_pCreationFunc = NULL;
88 osl_unloadModule(m_hModule);
89 m_hModule = NULL;
93 // static ServiceInfo
94 //------------------------------------------------------------------------------
95 rtl::OUString MozabDriver::getImplementationName_Static( ) throw(RuntimeException)
97 return rtl::OUString::createFromAscii(MOZAB_DRIVER_IMPL_NAME);
98 // this name is referenced in the configuration and in the mozab.xml
99 // Please take care when changing it.
101 //------------------------------------------------------------------------------
102 Sequence< ::rtl::OUString > MozabDriver::getSupportedServiceNames_Static( ) throw (RuntimeException)
104 // which service is supported
105 // for more information @see com.sun.star.sdbc.Driver
106 Sequence< ::rtl::OUString > aSNS( 1 );
107 aSNS[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.Driver"));
108 return aSNS;
111 //------------------------------------------------------------------
112 ::rtl::OUString SAL_CALL MozabDriver::getImplementationName( ) throw(RuntimeException)
114 return getImplementationName_Static();
117 //------------------------------------------------------------------
118 sal_Bool SAL_CALL MozabDriver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
120 Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
121 const ::rtl::OUString* pSupported = aSupported.getConstArray();
122 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
123 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
126 return pSupported != pEnd;
129 //------------------------------------------------------------------
130 Sequence< ::rtl::OUString > SAL_CALL MozabDriver::getSupportedServiceNames( ) throw(RuntimeException)
132 return getSupportedServiceNames_Static();
135 // --------------------------------------------------------------------------------
136 Reference< XConnection > SAL_CALL MozabDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
138 if ( !ensureInit() )
139 return NULL;
141 if ( ! acceptsURL( url ) )
142 return NULL;
143 // create a new connection with the given properties and append it to our vector
144 Reference< XConnection > xCon;
145 if (m_pCreationFunc)
147 ::osl::MutexGuard aGuard(m_aMutex);
148 //We must make sure we create an com.sun.star.mozilla.MozillaBootstrap brfore call any mozilla codes
149 Reference<XInterface> xInstance = m_xMSFactory->createInstance(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) );
150 OSL_ENSURE( xInstance.is(), "failed to create instance" );
152 OConnection* pCon = reinterpret_cast<OConnection*>((*m_pCreationFunc)(this));
153 xCon = pCon; // important here because otherwise the connection could be deleted inside (refcount goes -> 0)
154 pCon->construct(url,info); // late constructor call which can throw exception and allows a correct dtor call when so
155 m_xConnections.push_back(WeakReferenceHelper(*pCon));
158 else
160 ::connectivity::SharedResources aResources;
161 const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
162 STR_COULD_NOT_LOAD_LIB,
163 "$libname$", ::rtl::OUString::createFromAscii( SVLIBRARY( "mozabdrv" ) )
164 ) );
166 ::dbtools::throwGenericSQLException(sError,*this);
169 return xCon;
171 // --------------------------------------------------------------------------------
172 sal_Bool SAL_CALL MozabDriver::acceptsURL( const ::rtl::OUString& url )
173 throw(SQLException, RuntimeException)
175 if ( !ensureInit() )
176 return sal_False;
178 // here we have to look if we support this url format
179 return impl_classifyURL(url) != Unknown;
181 // --------------------------------------------------------------------------------
182 Sequence< DriverPropertyInfo > SAL_CALL MozabDriver::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw(SQLException, RuntimeException)
184 if ( !ensureInit() )
185 return Sequence< DriverPropertyInfo >();
187 if ( acceptsURL(url) )
189 if ( impl_classifyURL(url) != LDAP )
190 return Sequence< DriverPropertyInfo >();
192 ::std::vector< DriverPropertyInfo > aDriverInfo;
193 aDriverInfo.push_back(DriverPropertyInfo(
194 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BaseDN"))
195 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Base DN."))
196 ,sal_False
197 ,::rtl::OUString()
198 ,Sequence< ::rtl::OUString >())
200 aDriverInfo.push_back(DriverPropertyInfo(
201 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MaxRowCount"))
202 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Records (max.)"))
203 ,sal_False
204 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("100"))
205 ,Sequence< ::rtl::OUString >())
207 return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
209 ::connectivity::SharedResources aResources;
210 const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
211 ::dbtools::throwGenericSQLException(sMessage ,*this);
212 // if you have somthing special to say return it here :-)
213 return Sequence< DriverPropertyInfo >();
215 // --------------------------------------------------------------------------------
216 sal_Int32 SAL_CALL MozabDriver::getMajorVersion( ) throw(RuntimeException)
218 return 1; // depends on you
220 // --------------------------------------------------------------------------------
221 sal_Int32 SAL_CALL MozabDriver::getMinorVersion( ) throw(RuntimeException)
223 return 0; // depends on you
225 // --------------------------------------------------------------------------------
226 EDriverType MozabDriver::impl_classifyURL( const ::rtl::OUString& url )
228 // Skip 'sdbc:mozab: part of URL
230 sal_Int32 nLen = url.indexOf(':');
231 nLen = url.indexOf(':',nLen+1);
232 ::rtl::OUString aAddrbookURI(url.copy(nLen+1));
233 // Get Scheme
234 nLen = aAddrbookURI.indexOf(':');
235 ::rtl::OUString aAddrbookScheme;
236 if ( nLen == -1 )
238 // There isn't any subschema: - but could be just subschema
239 if ( aAddrbookURI.getLength() > 0 )
240 aAddrbookScheme= aAddrbookURI;
241 else if(url == ::rtl::OUString::createFromAscii("sdbc:address:") )
242 return Unknown; // TODO check
243 else
244 return Unknown;
246 else
247 aAddrbookScheme = aAddrbookURI.copy(0, nLen);
249 struct __scheme_map
251 EDriverType eType;
252 const sal_Char* pScheme;
253 } aSchemeMap[] =
255 #if defined(WNT) || defined(WIN)
256 { Outlook, "outlook" },
257 { OutlookExpress, "outlookexp" },
258 #endif
259 { Mozilla, "mozilla" },
260 { ThunderBird, "thunderbird" },
261 { LDAP, "ldap" }
264 for ( size_t i=0; i < sizeof( aSchemeMap ) / sizeof( aSchemeMap[0] ); ++i )
266 if ( aAddrbookScheme.compareToAscii( aSchemeMap[i].pScheme ) == 0 )
267 return aSchemeMap[i].eType;
270 return Unknown;
273 // --------------------------------------------------------------------------------
274 namespace
276 template< typename FUNCTION >
277 void lcl_getFunctionFromModuleOrUnload( oslModule& _rModule, const sal_Char* _pAsciiSymbolName, FUNCTION& _rFunction )
279 _rFunction = NULL;
280 if ( _rModule )
282 const ::rtl::OUString sSymbolName = ::rtl::OUString::createFromAscii( _pAsciiSymbolName );
283 _rFunction = (FUNCTION)( osl_getFunctionSymbol( _rModule, sSymbolName.pData ) );
285 if ( !_rFunction )
286 { // did not find the symbol
287 OSL_ENSURE( false, ::rtl::OString( "lcl_getFunctionFromModuleOrUnload: could not find the symbol " ) + ::rtl::OString( _pAsciiSymbolName ) );
288 osl_unloadModule( _rModule );
289 _rModule = NULL;
295 // -----------------------------------------------------------------------------
296 extern "C" { static void SAL_CALL thisModule() {} }
298 bool MozabDriver::ensureInit()
300 if ( m_hModule )
301 return true;
303 OSL_ENSURE(NULL == m_pCreationFunc, "MozabDriver::ensureInit: inconsistence: already have a factory function!");
305 const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii(SVLIBRARY( "mozabdrv" ));
307 // load the mozabdrv library
308 m_hModule = osl_loadModuleRelative(&thisModule, sModuleName.pData, 0);
309 OSL_ENSURE(NULL != m_hModule, "MozabDriver::ensureInit: could not load the mozabdrv library!");
310 if ( !m_hModule )
311 return false;
313 OSetMozabServiceFactory pSetFactoryFunc( NULL );
315 lcl_getFunctionFromModuleOrUnload( m_hModule, "setMozabServiceFactory", pSetFactoryFunc );
316 lcl_getFunctionFromModuleOrUnload( m_hModule, "OMozabConnection_CreateInstance", m_pCreationFunc );
318 if ( !m_hModule )
319 // one of the symbols did not exist
320 return false;
322 if ( m_xMSFactory.is() )
324 // for purpose of transfer safety, the interface needs to be acuired once
325 // (will be release by the callee)
326 m_xMSFactory->acquire();
327 ( *pSetFactoryFunc )( m_xMSFactory.get() );
330 return true;
332 // -----------------------------------------------------------------------------