Branch data 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 <cppuhelper/factory.hxx>
61 : : #include <cppuhelper/compbase1.hxx>
62 : : #include <cppuhelper/compbase2.hxx>
63 : : #include <cppuhelper/implementationentry.hxx>
64 : :
65 : : #include <com/sun/star/beans/XPropertySet.hpp>
66 : :
67 : : #include "pq_driver.hxx"
68 : :
69 : : using rtl::OUString;
70 : : using rtl::OUStringToOString;
71 : : using osl::MutexGuard;
72 : :
73 : : using cppu::WeakComponentImplHelper2;
74 : :
75 : : using com::sun::star::lang::XSingleComponentFactory;
76 : : using com::sun::star::lang::XServiceInfo;
77 : : using com::sun::star::lang::XComponent;
78 : :
79 : : using com::sun::star::uno::RuntimeException;
80 : : using com::sun::star::uno::Exception;
81 : : using com::sun::star::uno::Sequence;
82 : : using com::sun::star::uno::Reference;
83 : : using com::sun::star::uno::XInterface;
84 : : using com::sun::star::uno::UNO_QUERY;
85 : : using com::sun::star::uno::XComponentContext;
86 : : using com::sun::star::uno::Any;
87 : :
88 : : using com::sun::star::beans::PropertyValue;
89 : : using com::sun::star::beans::XPropertySet;
90 : :
91 : : using com::sun::star::sdbc::XConnection;
92 : : using com::sun::star::sdbc::SQLException;
93 : : using com::sun::star::sdbc::DriverPropertyInfo;
94 : :
95 : : using com::sun::star::sdbcx::XTablesSupplier;
96 : :
97 : :
98 : : namespace pq_sdbc_driver
99 : : {
100 : : #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
101 : :
102 : 0 : OUString DriverGetImplementationName()
103 : : {
104 : : static OUString *p;
105 : 0 : if (! p )
106 : : {
107 : 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
108 : : static OUString instance(
109 : 0 : RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.connectivity.pq.Driver.noext" ) );
110 : 0 : p = &instance;
111 : : }
112 : 0 : return *p;
113 : : }
114 : :
115 : 0 : Sequence< OUString > DriverGetSupportedServiceNames()
116 : : {
117 : : static Sequence< OUString > *p;
118 : 0 : if( ! p )
119 : : {
120 : 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
121 : 0 : OUString tmp( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Driver" ) );
122 : 0 : static Sequence< OUString > instance( &tmp,1 );
123 : 0 : p = &instance;
124 : : }
125 : 0 : return *p;
126 : : }
127 : :
128 : 0 : Reference< XConnection > Driver::connect(
129 : : const OUString& url,const Sequence< PropertyValue >& info )
130 : : throw (SQLException, RuntimeException)
131 : : {
132 : 0 : if( ! acceptsURL( url ) ) // XDriver spec tells me to do so ...
133 : 0 : return Reference< XConnection > ();
134 : :
135 : 0 : Sequence< Any > seq ( 2 );
136 : 0 : seq[0] <<= url;
137 : 0 : seq[1] <<= info;
138 : : return Reference< XConnection> (
139 : 0 : m_smgr->createInstanceWithArgumentsAndContext(
140 : : OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.connectivity.pq.Connection.noext" ) ),
141 : 0 : seq, m_ctx ),
142 : 0 : UNO_QUERY );
143 : : }
144 : :
145 : 0 : sal_Bool Driver::acceptsURL( const ::rtl::OUString& url )
146 : : throw (SQLException, RuntimeException)
147 : : {
148 : 0 : return url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:postgresql:" ) );
149 : : }
150 : :
151 : 0 : Sequence< DriverPropertyInfo > Driver::getPropertyInfo(
152 : : const OUString& url,const Sequence< PropertyValue >& info )
153 : : throw (SQLException, RuntimeException)
154 : : {
155 : : (void)url; (void)info;
156 : 0 : return Sequence< DriverPropertyInfo > ();
157 : : }
158 : :
159 : 0 : sal_Int32 Driver::getMajorVersion( ) throw (RuntimeException)
160 : : {
161 : 0 : return PQ_SDBC_MAJOR;
162 : : }
163 : :
164 : :
165 : 0 : sal_Int32 Driver::getMinorVersion( ) throw (RuntimeException)
166 : : {
167 : 0 : return PQ_SDBC_MINOR;
168 : : }
169 : :
170 : : // XServiceInfo
171 : 0 : OUString SAL_CALL Driver::getImplementationName()
172 : : throw(::com::sun::star::uno::RuntimeException)
173 : : {
174 : 0 : return DriverGetImplementationName();
175 : : }
176 : :
177 : 0 : sal_Bool Driver::supportsService(const OUString& ServiceName)
178 : : throw(::com::sun::star::uno::RuntimeException)
179 : : {
180 : 0 : Sequence< OUString > serviceNames = DriverGetSupportedServiceNames();
181 : 0 : for( int i = 0 ; i < serviceNames.getLength() ; i ++ )
182 : 0 : if( serviceNames[i] == ServiceName )
183 : 0 : return sal_True;
184 : 0 : return sal_False;
185 : : }
186 : :
187 : 0 : Sequence< OUString > Driver::getSupportedServiceNames(void)
188 : : throw(::com::sun::star::uno::RuntimeException)
189 : : {
190 : 0 : return DriverGetSupportedServiceNames();
191 : : }
192 : :
193 : : // XComponent
194 : 0 : void Driver::disposing()
195 : : {
196 : :
197 : 0 : }
198 : :
199 : :
200 : 0 : Reference< XTablesSupplier > Driver::getDataDefinitionByConnection(
201 : : const Reference< XConnection >& connection )
202 : : throw (SQLException, RuntimeException)
203 : : {
204 : 0 : return Reference< XTablesSupplier >( connection , UNO_QUERY );
205 : : }
206 : :
207 : 0 : Reference< XTablesSupplier > Driver::getDataDefinitionByURL(
208 : : const ::rtl::OUString& url, const Sequence< PropertyValue >& info )
209 : : throw (SQLException, RuntimeException)
210 : : {
211 : 0 : return Reference< XTablesSupplier > ( connect( url, info ), UNO_QUERY );
212 : : }
213 : :
214 : :
215 : 0 : Reference< XInterface > DriverCreateInstance( const Reference < XComponentContext > & ctx )
216 : : {
217 : 0 : Reference< XInterface > ret = * new Driver( ctx );
218 : 0 : return ret;
219 : : }
220 : :
221 : :
222 : :
223 : :
224 : 0 : class OOneInstanceComponentFactory :
225 : : public MutexHolder,
226 : : public WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >
227 : : {
228 : : public:
229 : 0 : OOneInstanceComponentFactory(
230 : : const OUString & rImplementationName_,
231 : : cppu::ComponentFactoryFunc fptr,
232 : : const Sequence< OUString > & serviceNames,
233 : : const Reference< XComponentContext > & defaultContext) :
234 : : WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >( this->m_mutex ),
235 : : m_create( fptr ),
236 : : m_serviceNames( serviceNames ),
237 : : m_implName( rImplementationName_ ),
238 : 0 : m_defaultContext( defaultContext )
239 : : {
240 : 0 : }
241 : :
242 : : // XSingleComponentFactory
243 : : virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
244 : : Reference< XComponentContext > const & xContext )
245 : : throw (Exception, RuntimeException);
246 : : virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
247 : : Sequence< Any > const & rArguments,
248 : : Reference< XComponentContext > const & xContext )
249 : : throw (Exception, RuntimeException);
250 : :
251 : : // XServiceInfo
252 : 0 : OUString SAL_CALL getImplementationName()
253 : : throw(::com::sun::star::uno::RuntimeException)
254 : : {
255 : 0 : return m_implName;
256 : : }
257 : 0 : sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
258 : : throw(::com::sun::star::uno::RuntimeException)
259 : : {
260 : 0 : for( int i = 0 ; i < m_serviceNames.getLength() ; i ++ )
261 : 0 : if( m_serviceNames[i] == ServiceName )
262 : 0 : return sal_True;
263 : 0 : return sal_False;
264 : : }
265 : 0 : Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
266 : : throw(::com::sun::star::uno::RuntimeException)
267 : : {
268 : 0 : return m_serviceNames;
269 : : }
270 : :
271 : : // XComponent
272 : : virtual void SAL_CALL disposing();
273 : :
274 : : private:
275 : : cppu::ComponentFactoryFunc m_create;
276 : : Sequence< OUString > m_serviceNames;
277 : : OUString m_implName;
278 : : Reference< XInterface > m_theInstance;
279 : : Reference< XComponentContext > m_defaultContext;
280 : : };
281 : :
282 : 0 : Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithArgumentsAndContext(
283 : : Sequence< Any > const &rArguments, const Reference< XComponentContext > & ctx )
284 : : throw( RuntimeException, Exception )
285 : : {
286 : : (void)rArguments;
287 : 0 : return createInstanceWithContext( ctx );
288 : : }
289 : :
290 : 0 : Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithContext(
291 : : const Reference< XComponentContext > & ctx )
292 : : throw( RuntimeException, Exception )
293 : : {
294 : 0 : if( ! m_theInstance.is() )
295 : : {
296 : : // work around the problem in sdbc
297 : 0 : Reference< XComponentContext > useCtx = ctx;
298 : 0 : if( ! useCtx.is() )
299 : 0 : useCtx = m_defaultContext;
300 : 0 : Reference< XInterface > theInstance = m_create( useCtx );
301 : 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
302 : 0 : if( ! m_theInstance.is () )
303 : : {
304 : 0 : m_theInstance = theInstance;
305 : 0 : }
306 : : }
307 : 0 : return m_theInstance;
308 : : }
309 : :
310 : 0 : void OOneInstanceComponentFactory::disposing()
311 : : {
312 : 0 : Reference< XComponent > rComp;
313 : : {
314 : 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
315 : 0 : rComp = Reference< XComponent >( m_theInstance, UNO_QUERY );
316 : 0 : m_theInstance.clear();
317 : : }
318 : 0 : if( rComp.is() )
319 : 0 : rComp->dispose();
320 : 0 : }
321 : :
322 : : // Reference< XSingleComponentFactory > createOneInstanceComponentFactory(
323 : : // cppu::ComponentFactoryFunc fptr,
324 : : // ::rtl::OUString const & rImplementationName,
325 : : // ::com::sun::star::uno::Sequence< ::rtl::OUString > const & rServiceNames,
326 : : // rtl_ModuleCount * pModCount = 0 )
327 : : // SAL_THROW(())
328 : : // {
329 : : // return new OOneInstanceComponentFactory( rImplementationName, fptr , rServiceNames);
330 : : // }
331 : :
332 : : }
333 : :
334 : : static struct cppu::ImplementationEntry g_entries[] =
335 : : {
336 : : {
337 : : pq_sdbc_driver::DriverCreateInstance, pq_sdbc_driver::DriverGetImplementationName,
338 : : pq_sdbc_driver::DriverGetSupportedServiceNames, 0,
339 : : 0 , 0
340 : : },
341 : : { 0, 0, 0, 0, 0, 0 }
342 : : };
343 : :
344 : : extern "C"
345 : : {
346 : :
347 : 0 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
348 : : const sal_Char * pImplName, void * pServiceManager, void * )
349 : : {
350 : : // need to extract the defaultcontext, because the way, sdbc
351 : : // bypasses the servicemanager, does not allow to use the
352 : : // XSingleComponentFactory interface ...
353 : 0 : void * pRet = 0;
354 : 0 : Reference< XSingleComponentFactory > xFactory;
355 : 0 : Reference< XInterface > xSmgr( (XInterface * ) pServiceManager );
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 : 0 : Reference< XComponentContext > defaultContext;
363 : 0 : Reference< XPropertySet > propSet( xSmgr, UNO_QUERY );
364 : 0 : if( propSet.is() )
365 : : {
366 : : try
367 : : {
368 : 0 : propSet->getPropertyValue( ASCII_STR( "DefaultContext" ) ) >>= defaultContext;
369 : : }
370 : 0 : catch( com::sun::star::uno::Exception & )
371 : : {
372 : : // if there is no default context, ignore it
373 : : }
374 : : }
375 : : xFactory = new pq_sdbc_driver::OOneInstanceComponentFactory(
376 : : implName,
377 : : g_entries[i].create,
378 : : g_entries[i].getSupportedServiceNames(),
379 : 0 : defaultContext );
380 : : }
381 : 0 : }
382 : :
383 : 0 : if( xFactory.is() )
384 : : {
385 : 0 : xFactory->acquire();
386 : 0 : pRet = xFactory.get();
387 : : }
388 : 0 : return pRet;
389 : : }
390 : :
391 : : }
|