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: 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
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
)
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
);
81 m_xConnections
.clear();
82 connectivity::OWeakRefArray().swap(m_xConnections
); // this really clears
84 ODriver_BASE::disposing();
87 m_pCreationFunc
= NULL
;
88 osl_unloadModule(m_hModule
);
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"));
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
)
141 if ( ! acceptsURL( url
) )
143 // create a new connection with the given properties and append it to our vector
144 Reference
< XConnection
> xCon
;
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
));
160 ::connectivity::SharedResources aResources
;
161 const ::rtl::OUString
sError( aResources
.getResourceStringWithSubstitution(
162 STR_COULD_NOT_LOAD_LIB
,
163 "$libname$", ::rtl::OUString::createFromAscii( SVLIBRARY( "mozabdrv" ) )
166 ::dbtools::throwGenericSQLException(sError
,*this);
171 // --------------------------------------------------------------------------------
172 sal_Bool SAL_CALL
MozabDriver::acceptsURL( const ::rtl::OUString
& url
)
173 throw(SQLException
, RuntimeException
)
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
)
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."))
198 ,Sequence
< ::rtl::OUString
>())
200 aDriverInfo
.push_back(DriverPropertyInfo(
201 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MaxRowCount"))
202 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Records (max.)"))
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));
234 nLen
= aAddrbookURI
.indexOf(':');
235 ::rtl::OUString aAddrbookScheme
;
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
247 aAddrbookScheme
= aAddrbookURI
.copy(0, nLen
);
252 const sal_Char
* pScheme
;
255 #if defined(WNT) || defined(WIN)
256 { Outlook
, "outlook" },
257 { OutlookExpress
, "outlookexp" },
259 { Mozilla
, "mozilla" },
260 { ThunderBird
, "thunderbird" },
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
;
273 // --------------------------------------------------------------------------------
276 template< typename FUNCTION
>
277 void lcl_getFunctionFromModuleOrUnload( oslModule
& _rModule
, const sal_Char
* _pAsciiSymbolName
, FUNCTION
& _rFunction
)
282 const ::rtl::OUString sSymbolName
= ::rtl::OUString::createFromAscii( _pAsciiSymbolName
);
283 _rFunction
= (FUNCTION
)( osl_getFunctionSymbol( _rModule
, sSymbolName
.pData
) );
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
);
295 // -----------------------------------------------------------------------------
296 extern "C" { static void SAL_CALL
thisModule() {} }
298 bool MozabDriver::ensureInit()
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!");
313 OSetMozabServiceFactory
pSetFactoryFunc( NULL
);
315 lcl_getFunctionFromModuleOrUnload( m_hModule
, "setMozabServiceFactory", pSetFactoryFunc
);
316 lcl_getFunctionFromModuleOrUnload( m_hModule
, "OMozabConnection_CreateInstance", m_pCreationFunc
);
319 // one of the symbols did not exist
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() );
332 // -----------------------------------------------------------------------------