Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * Effective License of whole file:
5 : *
6 : * This library is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public
8 : * License version 2.1, as published by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * Lesser General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public
16 : * License along with this library; if not, write to the Free Software
17 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 : * MA 02111-1307 USA
19 : *
20 : * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011:
21 : *
22 : * The Contents of this file are made available subject to the terms of
23 : * the GNU Lesser General Public License Version 2.1
24 : *
25 : * Copyright: 2000 by Sun Microsystems, Inc.
26 : *
27 : * Contributor(s): Joerg Budischewski
28 : *
29 : * All parts contributed on or after August 2011:
30 : *
31 : * Version: MPL 1.1 / GPLv3+ / LGPLv2.1+
32 : *
33 : * The contents of this file are subject to the Mozilla Public License Version
34 : * 1.1 (the "License"); you may not use this file except in compliance with
35 : * the License or as specified alternatively below. You may obtain a copy of
36 : * the License at http://www.mozilla.org/MPL/
37 : *
38 : * Software distributed under the License is distributed on an "AS IS" basis,
39 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
40 : * for the specific language governing rights and limitations under the
41 : * License.
42 : *
43 : * Major Contributor(s):
44 : * [ Copyright (C) 2011 Lionel Elie Mamane <lionel@mamane.lu> ]
45 : *
46 : * All Rights Reserved.
47 : *
48 : * For minor contributions see the git repository.
49 : *
50 : * Alternatively, the contents of this file may be used under the terms of
51 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
52 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPLv2.1+"),
53 : * in which case the provisions of the GPLv3+ or the LGPLv2.1+ are applicable
54 : * instead of those above.
55 : *
56 : ************************************************************************/
57 :
58 : #include <stdio.h>
59 :
60 : #include <comphelper/processfactory.hxx>
61 : #include <cppuhelper/factory.hxx>
62 : #include <cppuhelper/compbase1.hxx>
63 : #include <cppuhelper/compbase2.hxx>
64 : #include <cppuhelper/implementationentry.hxx>
65 :
66 : #include "pq_driver.hxx"
67 :
68 : using rtl::OUString;
69 : using rtl::OUStringToOString;
70 : using osl::MutexGuard;
71 :
72 : using cppu::WeakComponentImplHelper2;
73 :
74 : using com::sun::star::lang::XSingleComponentFactory;
75 : using com::sun::star::lang::XServiceInfo;
76 : using com::sun::star::lang::XComponent;
77 :
78 : using com::sun::star::uno::RuntimeException;
79 : using com::sun::star::uno::Exception;
80 : using com::sun::star::uno::Sequence;
81 : using com::sun::star::uno::Reference;
82 : using com::sun::star::uno::XInterface;
83 : using com::sun::star::uno::UNO_QUERY;
84 : using com::sun::star::uno::XComponentContext;
85 : using com::sun::star::uno::Any;
86 :
87 : using com::sun::star::beans::PropertyValue;
88 :
89 : using com::sun::star::sdbc::XConnection;
90 : using com::sun::star::sdbc::SQLException;
91 : using com::sun::star::sdbc::DriverPropertyInfo;
92 :
93 : using com::sun::star::sdbcx::XTablesSupplier;
94 :
95 :
96 : namespace pq_sdbc_driver
97 : {
98 : #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
99 :
100 0 : OUString DriverGetImplementationName()
101 : {
102 : static OUString *p;
103 0 : if (! p )
104 : {
105 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
106 : static OUString instance(
107 0 : RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.connectivity.pq.Driver.noext" ) );
108 0 : p = &instance;
109 : }
110 0 : return *p;
111 : }
112 :
113 0 : Sequence< OUString > DriverGetSupportedServiceNames()
114 : {
115 : static Sequence< OUString > *p;
116 0 : if( ! p )
117 : {
118 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
119 0 : OUString tmp( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Driver" ) );
120 0 : static Sequence< OUString > instance( &tmp,1 );
121 0 : p = &instance;
122 : }
123 0 : return *p;
124 : }
125 :
126 0 : Reference< XConnection > Driver::connect(
127 : const OUString& url,const Sequence< PropertyValue >& info )
128 : throw (SQLException, RuntimeException)
129 : {
130 0 : if( ! acceptsURL( url ) ) // XDriver spec tells me to do so ...
131 0 : return Reference< XConnection > ();
132 :
133 0 : Sequence< Any > seq ( 2 );
134 0 : seq[0] <<= url;
135 0 : seq[1] <<= info;
136 : return Reference< XConnection> (
137 0 : m_smgr->createInstanceWithArgumentsAndContext(
138 : OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.connectivity.pq.Connection.noext" ) ),
139 0 : seq, m_ctx ),
140 0 : UNO_QUERY );
141 : }
142 :
143 0 : sal_Bool Driver::acceptsURL( const ::rtl::OUString& url )
144 : throw (SQLException, RuntimeException)
145 : {
146 0 : return url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:postgresql:" ) );
147 : }
148 :
149 0 : Sequence< DriverPropertyInfo > Driver::getPropertyInfo(
150 : const OUString& url,const Sequence< PropertyValue >& info )
151 : throw (SQLException, RuntimeException)
152 : {
153 : (void)url; (void)info;
154 0 : return Sequence< DriverPropertyInfo > ();
155 : }
156 :
157 0 : sal_Int32 Driver::getMajorVersion( ) throw (RuntimeException)
158 : {
159 0 : return PQ_SDBC_MAJOR;
160 : }
161 :
162 :
163 0 : sal_Int32 Driver::getMinorVersion( ) throw (RuntimeException)
164 : {
165 0 : return PQ_SDBC_MINOR;
166 : }
167 :
168 : // XServiceInfo
169 0 : OUString SAL_CALL Driver::getImplementationName()
170 : throw(::com::sun::star::uno::RuntimeException)
171 : {
172 0 : return DriverGetImplementationName();
173 : }
174 :
175 0 : sal_Bool Driver::supportsService(const OUString& ServiceName)
176 : throw(::com::sun::star::uno::RuntimeException)
177 : {
178 0 : Sequence< OUString > serviceNames = DriverGetSupportedServiceNames();
179 0 : for( int i = 0 ; i < serviceNames.getLength() ; i ++ )
180 0 : if( serviceNames[i] == ServiceName )
181 0 : return sal_True;
182 0 : return sal_False;
183 : }
184 :
185 0 : Sequence< OUString > Driver::getSupportedServiceNames(void)
186 : throw(::com::sun::star::uno::RuntimeException)
187 : {
188 0 : return DriverGetSupportedServiceNames();
189 : }
190 :
191 : // XComponent
192 0 : void Driver::disposing()
193 : {
194 :
195 0 : }
196 :
197 :
198 0 : Reference< XTablesSupplier > Driver::getDataDefinitionByConnection(
199 : const Reference< XConnection >& connection )
200 : throw (SQLException, RuntimeException)
201 : {
202 0 : return Reference< XTablesSupplier >( connection , UNO_QUERY );
203 : }
204 :
205 0 : Reference< XTablesSupplier > Driver::getDataDefinitionByURL(
206 : const ::rtl::OUString& url, const Sequence< PropertyValue >& info )
207 : throw (SQLException, RuntimeException)
208 : {
209 0 : return Reference< XTablesSupplier > ( connect( url, info ), UNO_QUERY );
210 : }
211 :
212 :
213 0 : Reference< XInterface > DriverCreateInstance( const Reference < XComponentContext > & ctx )
214 : {
215 0 : Reference< XInterface > ret = * new Driver( ctx );
216 0 : return ret;
217 : }
218 :
219 :
220 :
221 :
222 0 : class OOneInstanceComponentFactory :
223 : public MutexHolder,
224 : public WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >
225 : {
226 : public:
227 0 : OOneInstanceComponentFactory(
228 : const OUString & rImplementationName_,
229 : cppu::ComponentFactoryFunc fptr,
230 : const Sequence< OUString > & serviceNames,
231 : const Reference< XComponentContext > & defaultContext) :
232 : WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >( this->m_mutex ),
233 : m_create( fptr ),
234 : m_serviceNames( serviceNames ),
235 : m_implName( rImplementationName_ ),
236 0 : m_defaultContext( defaultContext )
237 : {
238 0 : }
239 :
240 : // XSingleComponentFactory
241 : virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
242 : Reference< XComponentContext > const & xContext )
243 : throw (Exception, RuntimeException);
244 : virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
245 : Sequence< Any > const & rArguments,
246 : Reference< XComponentContext > const & xContext )
247 : throw (Exception, RuntimeException);
248 :
249 : // XServiceInfo
250 0 : OUString SAL_CALL getImplementationName()
251 : throw(::com::sun::star::uno::RuntimeException)
252 : {
253 0 : return m_implName;
254 : }
255 0 : sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
256 : throw(::com::sun::star::uno::RuntimeException)
257 : {
258 0 : for( int i = 0 ; i < m_serviceNames.getLength() ; i ++ )
259 0 : if( m_serviceNames[i] == ServiceName )
260 0 : return sal_True;
261 0 : return sal_False;
262 : }
263 0 : Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
264 : throw(::com::sun::star::uno::RuntimeException)
265 : {
266 0 : return m_serviceNames;
267 : }
268 :
269 : // XComponent
270 : virtual void SAL_CALL disposing();
271 :
272 : private:
273 : cppu::ComponentFactoryFunc m_create;
274 : Sequence< OUString > m_serviceNames;
275 : OUString m_implName;
276 : Reference< XInterface > m_theInstance;
277 : Reference< XComponentContext > m_defaultContext;
278 : };
279 :
280 0 : Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithArgumentsAndContext(
281 : Sequence< Any > const &rArguments, const Reference< XComponentContext > & ctx )
282 : throw( RuntimeException, Exception )
283 : {
284 : (void)rArguments;
285 0 : return createInstanceWithContext( ctx );
286 : }
287 :
288 0 : Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithContext(
289 : const Reference< XComponentContext > & ctx )
290 : throw( RuntimeException, Exception )
291 : {
292 0 : if( ! m_theInstance.is() )
293 : {
294 : // work around the problem in sdbc
295 0 : Reference< XComponentContext > useCtx = ctx;
296 0 : if( ! useCtx.is() )
297 0 : useCtx = m_defaultContext;
298 0 : Reference< XInterface > theInstance = m_create( useCtx );
299 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
300 0 : if( ! m_theInstance.is () )
301 : {
302 0 : m_theInstance = theInstance;
303 0 : }
304 : }
305 0 : return m_theInstance;
306 : }
307 :
308 0 : void OOneInstanceComponentFactory::disposing()
309 : {
310 0 : Reference< XComponent > rComp;
311 : {
312 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
313 0 : rComp = Reference< XComponent >( m_theInstance, UNO_QUERY );
314 0 : m_theInstance.clear();
315 : }
316 0 : if( rComp.is() )
317 0 : rComp->dispose();
318 0 : }
319 :
320 : // Reference< XSingleComponentFactory > createOneInstanceComponentFactory(
321 : // cppu::ComponentFactoryFunc fptr,
322 : // ::rtl::OUString const & rImplementationName,
323 : // ::com::sun::star::uno::Sequence< ::rtl::OUString > const & rServiceNames,
324 : // rtl_ModuleCount * pModCount = 0 )
325 : // SAL_THROW(())
326 : // {
327 : // return new OOneInstanceComponentFactory( rImplementationName, fptr , rServiceNames);
328 : // }
329 :
330 : }
331 :
332 : static struct cppu::ImplementationEntry g_entries[] =
333 : {
334 : {
335 : pq_sdbc_driver::DriverCreateInstance, pq_sdbc_driver::DriverGetImplementationName,
336 : pq_sdbc_driver::DriverGetSupportedServiceNames, 0,
337 : 0 , 0
338 : },
339 : { 0, 0, 0, 0, 0, 0 }
340 : };
341 :
342 : extern "C"
343 : {
344 :
345 0 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL postgresql_sdbc_component_getFactory(
346 : const sal_Char * pImplName, void * pServiceManager, void * )
347 : {
348 : // need to extract the defaultcontext, because the way, sdbc
349 : // bypasses the servicemanager, does not allow to use the
350 : // XSingleComponentFactory interface ...
351 0 : void * pRet = 0;
352 0 : Reference< XSingleComponentFactory > xFactory;
353 : Reference< com::sun::star::lang::XMultiServiceFactory > xSmgr(
354 : static_cast< XInterface * >(pServiceManager),
355 0 : com::sun::star::uno::UNO_QUERY_THROW );
356 :
357 0 : for( sal_Int32 i = 0 ; g_entries[i].create ; i ++ )
358 : {
359 0 : OUString implName = g_entries[i].getImplementationName();
360 0 : if( 0 == implName.compareToAscii( pImplName ) )
361 : {
362 : Reference< XComponentContext > defaultContext(
363 0 : comphelper::getComponentContext( xSmgr ) );
364 : xFactory = new pq_sdbc_driver::OOneInstanceComponentFactory(
365 : implName,
366 : g_entries[i].create,
367 : g_entries[i].getSupportedServiceNames(),
368 0 : defaultContext );
369 : }
370 0 : }
371 :
372 0 : if( xFactory.is() )
373 : {
374 0 : xFactory->acquire();
375 0 : pRet = xFactory.get();
376 : }
377 0 : return pRet;
378 : }
379 :
380 : }
|