Bump for 3.6-28
[LibreOffice.git] / connectivity / source / drivers / mozab / MDriver.cxx
blob89bb2dec8fcc91328c83028a785e95cbc94154b6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <sal/macros.h>
30 #include "MDriver.hxx"
31 #include "MConnection.hxx"
32 #include "connectivity/dbexception.hxx"
33 #include "resource/mozab_res.hrc"
34 #include "resource/common_res.hrc"
36 #include <tools/solar.h>
37 using namespace com::sun::star::uno;
38 using namespace com::sun::star::lang;
39 using namespace com::sun::star::beans;
40 using namespace com::sun::star::sdbc;
41 using namespace connectivity::mozab;
43 namespace connectivity
45 namespace mozab
47 //------------------------------------------------------------------
48 ::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 )
50 return *(new MozabDriver( _rxFactory ));
54 // --------------------------------------------------------------------------------
55 MozabDriver::MozabDriver(
56 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
57 : ODriver_BASE(m_aMutex), m_xMSFactory( _rxFactory )
58 ,m_hModule(NULL)
59 ,m_pCreationFunc(NULL)
62 // -----------------------------------------------------------------------------
63 MozabDriver::~MozabDriver()
66 // --------------------------------------------------------------------------------
67 void MozabDriver::disposing()
69 ::osl::MutexGuard aGuard(m_aMutex);
71 // when driver will be destroied so all our connections have to be destroied as well
72 for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
74 Reference< XComponent > xComp(i->get(), UNO_QUERY);
75 if (xComp.is())
76 xComp->dispose();
78 m_xConnections.clear();
79 connectivity::OWeakRefArray().swap(m_xConnections); // this really clears
81 ODriver_BASE::disposing();
82 if(m_hModule)
84 m_pCreationFunc = NULL;
85 osl_unloadModule(m_hModule);
86 m_hModule = NULL;
90 // static ServiceInfo
91 //------------------------------------------------------------------------------
92 rtl::OUString MozabDriver::getImplementationName_Static( ) throw(RuntimeException)
94 return rtl::OUString(MOZAB_DRIVER_IMPL_NAME);
95 // this name is referenced in the configuration and in the mozab.xml
96 // Please take care when changing it.
98 //------------------------------------------------------------------------------
99 Sequence< ::rtl::OUString > MozabDriver::getSupportedServiceNames_Static( ) throw (RuntimeException)
101 // which service is supported
102 // for more information @see com.sun.star.sdbc.Driver
103 Sequence< ::rtl::OUString > aSNS( 1 );
104 aSNS[0] = ::rtl::OUString( "com.sun.star.sdbc.Driver");
105 return aSNS;
108 //------------------------------------------------------------------
109 ::rtl::OUString SAL_CALL MozabDriver::getImplementationName( ) throw(RuntimeException)
111 return getImplementationName_Static();
114 //------------------------------------------------------------------
115 sal_Bool SAL_CALL MozabDriver::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
117 Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
118 const ::rtl::OUString* pSupported = aSupported.getConstArray();
119 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
120 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
123 return pSupported != pEnd;
126 //------------------------------------------------------------------
127 Sequence< ::rtl::OUString > SAL_CALL MozabDriver::getSupportedServiceNames( ) throw(RuntimeException)
129 return getSupportedServiceNames_Static();
132 // --------------------------------------------------------------------------------
133 Reference< XConnection > SAL_CALL MozabDriver::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException)
135 if ( !ensureInit() )
136 return NULL;
138 if ( ! acceptsURL( url ) )
139 return NULL;
140 // create a new connection with the given properties and append it to our vector
141 Reference< XConnection > xCon;
142 if (m_pCreationFunc)
144 ::osl::MutexGuard aGuard(m_aMutex);
145 //We must make sure we create an com.sun.star.mozilla.MozillaBootstrap brfore call any mozilla codes
146 Reference<XInterface> xInstance = m_xMSFactory->createInstance(::rtl::OUString( "com.sun.star.mozilla.MozillaBootstrap") );
147 OSL_ENSURE( xInstance.is(), "failed to create instance" );
149 OConnection* pCon = reinterpret_cast<OConnection*>((*m_pCreationFunc)(this));
150 xCon = pCon; // important here because otherwise the connection could be deleted inside (refcount goes -> 0)
151 pCon->construct(url,info); // late constructor call which can throw exception and allows a correct dtor call when so
152 m_xConnections.push_back(WeakReferenceHelper(*pCon));
155 else
157 ::connectivity::SharedResources aResources;
158 const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
159 STR_COULD_NOT_LOAD_LIB,
160 "$libname$", ::rtl::OUString( SVLIBRARY( "mozabdrv" ) )
161 ) );
163 ::dbtools::throwGenericSQLException(sError,*this);
166 return xCon;
168 // --------------------------------------------------------------------------------
169 sal_Bool SAL_CALL MozabDriver::acceptsURL( const ::rtl::OUString& url )
170 throw(SQLException, RuntimeException)
172 if ( !ensureInit() )
173 return sal_False;
175 // here we have to look if we support this url format
176 return impl_classifyURL(url) != Unknown;
178 // --------------------------------------------------------------------------------
179 Sequence< DriverPropertyInfo > SAL_CALL MozabDriver::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw(SQLException, RuntimeException)
181 if ( !ensureInit() )
182 return Sequence< DriverPropertyInfo >();
184 if ( acceptsURL(url) )
186 if ( impl_classifyURL(url) != LDAP )
187 return Sequence< DriverPropertyInfo >();
189 ::std::vector< DriverPropertyInfo > aDriverInfo;
190 aDriverInfo.push_back(DriverPropertyInfo(
191 ::rtl::OUString("BaseDN")
192 ,::rtl::OUString("Base DN.")
193 ,sal_False
194 ,::rtl::OUString()
195 ,Sequence< ::rtl::OUString >())
197 aDriverInfo.push_back(DriverPropertyInfo(
198 ::rtl::OUString("MaxRowCount")
199 ,::rtl::OUString("Records (max.)")
200 ,sal_False
201 ,::rtl::OUString("100")
202 ,Sequence< ::rtl::OUString >())
204 return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
206 ::connectivity::SharedResources aResources;
207 const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
208 ::dbtools::throwGenericSQLException(sMessage ,*this);
209 // if you have somthing special to say return it here :-)
210 return Sequence< DriverPropertyInfo >();
212 // --------------------------------------------------------------------------------
213 sal_Int32 SAL_CALL MozabDriver::getMajorVersion( ) throw(RuntimeException)
215 return 1; // depends on you
217 // --------------------------------------------------------------------------------
218 sal_Int32 SAL_CALL MozabDriver::getMinorVersion( ) throw(RuntimeException)
220 return 0; // depends on you
222 // --------------------------------------------------------------------------------
223 EDriverType MozabDriver::impl_classifyURL( const ::rtl::OUString& url )
225 // Skip 'sdbc:mozab: part of URL
227 sal_Int32 nLen = url.indexOf(':');
228 nLen = url.indexOf(':',nLen+1);
229 ::rtl::OUString aAddrbookURI(url.copy(nLen+1));
230 // Get Scheme
231 nLen = aAddrbookURI.indexOf(':');
232 ::rtl::OUString aAddrbookScheme;
233 if ( nLen == -1 )
235 // There isn't any subschema: - but could be just subschema
236 if ( !aAddrbookURI.isEmpty() )
237 aAddrbookScheme= aAddrbookURI;
238 else if(url == ::rtl::OUString("sdbc:address:") )
239 return Unknown; // TODO check
240 else
241 return Unknown;
243 else
244 aAddrbookScheme = aAddrbookURI.copy(0, nLen);
246 struct __scheme_map
248 EDriverType eType;
249 const sal_Char* pScheme;
250 } aSchemeMap[] =
252 #if defined(WNT)
253 { Outlook, "outlook" },
254 { OutlookExpress, "outlookexp" },
255 #endif
256 { Mozilla, "mozilla" },
257 { ThunderBird, "thunderbird" },
258 { LDAP, "ldap" }
261 for ( size_t i=0; i < sizeof( aSchemeMap ) / sizeof( aSchemeMap[0] ); ++i )
263 if ( aAddrbookScheme.compareToAscii( aSchemeMap[i].pScheme ) == 0 )
264 return aSchemeMap[i].eType;
267 return Unknown;
270 // --------------------------------------------------------------------------------
271 namespace
273 template< typename FUNCTION >
274 void lcl_getFunctionFromModuleOrUnload( oslModule& _rModule, const sal_Char* _pAsciiSymbolName, FUNCTION& _rFunction )
276 _rFunction = NULL;
277 if ( _rModule )
279 const ::rtl::OUString sSymbolName = ::rtl::OUString::createFromAscii( _pAsciiSymbolName );
280 _rFunction = (FUNCTION)( osl_getFunctionSymbol( _rModule, sSymbolName.pData ) );
282 if ( !_rFunction )
283 { // did not find the symbol
284 OSL_FAIL( ( ::rtl::OString( "lcl_getFunctionFromModuleOrUnload: could not find the symbol " ) + ::rtl::OString( _pAsciiSymbolName ) ).getStr() );
285 osl_unloadModule( _rModule );
286 _rModule = NULL;
292 // -----------------------------------------------------------------------------
293 extern "C" { static void SAL_CALL thisModule() {} }
295 bool MozabDriver::ensureInit()
297 if ( m_hModule )
298 return true;
300 OSL_ENSURE(NULL == m_pCreationFunc, "MozabDriver::ensureInit: inconsistence: already have a factory function!");
302 const ::rtl::OUString sModuleName(SVLIBRARY( "mozabdrv" ));
304 // load the mozabdrv library
305 m_hModule = osl_loadModuleRelative(&thisModule, sModuleName.pData, 0);
306 OSL_ENSURE(NULL != m_hModule, "MozabDriver::ensureInit: could not load the mozabdrv library!");
307 if ( !m_hModule )
308 return false;
310 OSetMozabServiceFactory pSetFactoryFunc( NULL );
312 lcl_getFunctionFromModuleOrUnload( m_hModule, "setMozabServiceFactory", pSetFactoryFunc );
313 lcl_getFunctionFromModuleOrUnload( m_hModule, "OMozabConnection_CreateInstance", m_pCreationFunc );
315 if ( !m_hModule )
316 // one of the symbols did not exist
317 return false;
319 if ( m_xMSFactory.is() )
321 // for purpose of transfer safety, the interface needs to be acuired once
322 // (will be release by the callee)
323 m_xMSFactory->acquire();
324 ( *pSetFactoryFunc )( m_xMSFactory.get() );
327 return true;
329 // -----------------------------------------------------------------------------
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */