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
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
)
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
);
78 m_xConnections
.clear();
79 connectivity::OWeakRefArray().swap(m_xConnections
); // this really clears
81 ODriver_BASE::disposing();
84 m_pCreationFunc
= NULL
;
85 osl_unloadModule(m_hModule
);
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");
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
)
138 if ( ! acceptsURL( url
) )
140 // create a new connection with the given properties and append it to our vector
141 Reference
< XConnection
> xCon
;
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
));
157 ::connectivity::SharedResources aResources
;
158 const ::rtl::OUString
sError( aResources
.getResourceStringWithSubstitution(
159 STR_COULD_NOT_LOAD_LIB
,
160 "$libname$", ::rtl::OUString( SVLIBRARY( "mozabdrv" ) )
163 ::dbtools::throwGenericSQLException(sError
,*this);
168 // --------------------------------------------------------------------------------
169 sal_Bool SAL_CALL
MozabDriver::acceptsURL( const ::rtl::OUString
& url
)
170 throw(SQLException
, RuntimeException
)
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
)
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.")
195 ,Sequence
< ::rtl::OUString
>())
197 aDriverInfo
.push_back(DriverPropertyInfo(
198 ::rtl::OUString("MaxRowCount")
199 ,::rtl::OUString("Records (max.)")
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));
231 nLen
= aAddrbookURI
.indexOf(':');
232 ::rtl::OUString aAddrbookScheme
;
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
244 aAddrbookScheme
= aAddrbookURI
.copy(0, nLen
);
249 const sal_Char
* pScheme
;
253 { Outlook
, "outlook" },
254 { OutlookExpress
, "outlookexp" },
256 { Mozilla
, "mozilla" },
257 { ThunderBird
, "thunderbird" },
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
;
270 // --------------------------------------------------------------------------------
273 template< typename FUNCTION
>
274 void lcl_getFunctionFromModuleOrUnload( oslModule
& _rModule
, const sal_Char
* _pAsciiSymbolName
, FUNCTION
& _rFunction
)
279 const ::rtl::OUString sSymbolName
= ::rtl::OUString::createFromAscii( _pAsciiSymbolName
);
280 _rFunction
= (FUNCTION
)( osl_getFunctionSymbol( _rModule
, sSymbolName
.pData
) );
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
);
292 // -----------------------------------------------------------------------------
293 extern "C" { static void SAL_CALL
thisModule() {} }
295 bool MozabDriver::ensureInit()
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!");
310 OSetMozabServiceFactory
pSetFactoryFunc( NULL
);
312 lcl_getFunctionFromModuleOrUnload( m_hModule
, "setMozabServiceFactory", pSetFactoryFunc
);
313 lcl_getFunctionFromModuleOrUnload( m_hModule
, "OMozabConnection_CreateInstance", m_pCreationFunc
);
316 // one of the symbols did not exist
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() );
329 // -----------------------------------------------------------------------------
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */