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 : * This Source Code Form is subject to the terms of the Mozilla Public
32 : * License, v. 2.0. If a copy of the MPL was not distributed with this
33 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
34 : *
35 : ************************************************************************/
36 :
37 : #include <stdio.h>
38 :
39 : #include <comphelper/processfactory.hxx>
40 : #include <cppuhelper/factory.hxx>
41 : #include <cppuhelper/compbase1.hxx>
42 : #include <cppuhelper/compbase2.hxx>
43 : #include <cppuhelper/implementationentry.hxx>
44 : #include <cppuhelper/supportsservice.hxx>
45 :
46 : #include "pq_driver.hxx"
47 :
48 : using osl::MutexGuard;
49 :
50 : using cppu::WeakComponentImplHelper2;
51 :
52 : using com::sun::star::lang::XSingleComponentFactory;
53 : using com::sun::star::lang::XServiceInfo;
54 : using com::sun::star::lang::XComponent;
55 :
56 : using com::sun::star::uno::RuntimeException;
57 : using com::sun::star::uno::Exception;
58 : using com::sun::star::uno::Sequence;
59 : using com::sun::star::uno::Reference;
60 : using com::sun::star::uno::XInterface;
61 : using com::sun::star::uno::UNO_QUERY;
62 : using com::sun::star::uno::XComponentContext;
63 : using com::sun::star::uno::Any;
64 :
65 : using com::sun::star::beans::PropertyValue;
66 :
67 : using com::sun::star::sdbc::XConnection;
68 : using com::sun::star::sdbc::SQLException;
69 : using com::sun::star::sdbc::DriverPropertyInfo;
70 :
71 : using com::sun::star::sdbcx::XTablesSupplier;
72 :
73 :
74 : namespace pq_sdbc_driver
75 : {
76 :
77 0 : OUString DriverGetImplementationName()
78 : {
79 : static OUString *p;
80 0 : if (! p )
81 : {
82 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
83 0 : static OUString instance( "org.openoffice.comp.connectivity.pq.Driver.noext" );
84 0 : p = &instance;
85 : }
86 0 : return *p;
87 : }
88 :
89 0 : Sequence< OUString > DriverGetSupportedServiceNames()
90 : {
91 : static Sequence< OUString > *p;
92 0 : if( ! p )
93 : {
94 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
95 0 : OUString tmp( "com.sun.star.sdbc.Driver" );
96 0 : static Sequence< OUString > instance( &tmp,1 );
97 0 : p = &instance;
98 : }
99 0 : return *p;
100 : }
101 :
102 0 : Reference< XConnection > Driver::connect(
103 : const OUString& url,const Sequence< PropertyValue >& info )
104 : throw (SQLException, RuntimeException, std::exception)
105 : {
106 0 : if( ! acceptsURL( url ) ) // XDriver spec tells me to do so ...
107 0 : return Reference< XConnection > ();
108 :
109 0 : Sequence< Any > seq ( 2 );
110 0 : seq[0] <<= url;
111 0 : seq[1] <<= info;
112 : return Reference< XConnection> (
113 0 : m_smgr->createInstanceWithArgumentsAndContext(
114 : OUString("org.openoffice.comp.connectivity.pq.Connection.noext" ),
115 0 : seq, m_ctx ),
116 0 : UNO_QUERY );
117 : }
118 :
119 0 : sal_Bool Driver::acceptsURL( const OUString& url )
120 : throw (SQLException, RuntimeException, std::exception)
121 : {
122 0 : return url.startsWith( "sdbc:postgresql:" );
123 : }
124 :
125 0 : Sequence< DriverPropertyInfo > Driver::getPropertyInfo(
126 : const OUString& url,const Sequence< PropertyValue >& info )
127 : throw (SQLException, RuntimeException, std::exception)
128 : {
129 : (void)url; (void)info;
130 0 : return Sequence< DriverPropertyInfo > ();
131 : }
132 :
133 0 : sal_Int32 Driver::getMajorVersion( ) throw (RuntimeException, std::exception)
134 : {
135 0 : return PQ_SDBC_MAJOR;
136 : }
137 :
138 :
139 0 : sal_Int32 Driver::getMinorVersion( ) throw (RuntimeException, std::exception)
140 : {
141 0 : return PQ_SDBC_MINOR;
142 : }
143 :
144 : // XServiceInfo
145 0 : OUString SAL_CALL Driver::getImplementationName()
146 : throw(::com::sun::star::uno::RuntimeException, std::exception)
147 : {
148 0 : return DriverGetImplementationName();
149 : }
150 :
151 0 : sal_Bool Driver::supportsService(const OUString& ServiceName)
152 : throw(::com::sun::star::uno::RuntimeException, std::exception)
153 : {
154 0 : return cppu::supportsService(this, ServiceName);
155 : }
156 :
157 0 : Sequence< OUString > Driver::getSupportedServiceNames(void)
158 : throw(::com::sun::star::uno::RuntimeException, std::exception)
159 : {
160 0 : return DriverGetSupportedServiceNames();
161 : }
162 :
163 : // XComponent
164 0 : void Driver::disposing()
165 : {
166 :
167 0 : }
168 :
169 :
170 0 : Reference< XTablesSupplier > Driver::getDataDefinitionByConnection(
171 : const Reference< XConnection >& connection )
172 : throw (SQLException, RuntimeException, std::exception)
173 : {
174 0 : return Reference< XTablesSupplier >( connection , UNO_QUERY );
175 : }
176 :
177 0 : Reference< XTablesSupplier > Driver::getDataDefinitionByURL(
178 : const OUString& url, const Sequence< PropertyValue >& info )
179 : throw (SQLException, RuntimeException, std::exception)
180 : {
181 0 : return Reference< XTablesSupplier > ( connect( url, info ), UNO_QUERY );
182 : }
183 :
184 :
185 0 : Reference< XInterface > DriverCreateInstance( const Reference < XComponentContext > & ctx )
186 : {
187 0 : Reference< XInterface > ret = * new Driver( ctx );
188 0 : return ret;
189 : }
190 :
191 :
192 :
193 :
194 0 : class OOneInstanceComponentFactory :
195 : public MutexHolder,
196 : public WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >
197 : {
198 : public:
199 0 : OOneInstanceComponentFactory(
200 : const OUString & rImplementationName_,
201 : cppu::ComponentFactoryFunc fptr,
202 : const Sequence< OUString > & serviceNames,
203 : const Reference< XComponentContext > & defaultContext) :
204 : WeakComponentImplHelper2< XSingleComponentFactory, XServiceInfo >( this->m_mutex ),
205 : m_create( fptr ),
206 : m_serviceNames( serviceNames ),
207 : m_implName( rImplementationName_ ),
208 0 : m_defaultContext( defaultContext )
209 : {
210 0 : }
211 :
212 : // XSingleComponentFactory
213 : virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
214 : Reference< XComponentContext > const & xContext )
215 : throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
216 : virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
217 : Sequence< Any > const & rArguments,
218 : Reference< XComponentContext > const & xContext )
219 : throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
220 :
221 : // XServiceInfo
222 0 : OUString SAL_CALL getImplementationName()
223 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
224 : {
225 0 : return m_implName;
226 : }
227 0 : sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
228 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
229 : {
230 0 : for( int i = 0 ; i < m_serviceNames.getLength() ; i ++ )
231 0 : if( m_serviceNames[i] == ServiceName )
232 0 : return sal_True;
233 0 : return sal_False;
234 : }
235 0 : Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
236 : throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
237 : {
238 0 : return m_serviceNames;
239 : }
240 :
241 : // XComponent
242 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
243 :
244 : private:
245 : cppu::ComponentFactoryFunc m_create;
246 : Sequence< OUString > m_serviceNames;
247 : OUString m_implName;
248 : Reference< XInterface > m_theInstance;
249 : Reference< XComponentContext > m_defaultContext;
250 : };
251 :
252 0 : Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithArgumentsAndContext(
253 : Sequence< Any > const &rArguments, const Reference< XComponentContext > & ctx )
254 : throw( RuntimeException, Exception, std::exception )
255 : {
256 : (void)rArguments;
257 0 : return createInstanceWithContext( ctx );
258 : }
259 :
260 0 : Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithContext(
261 : const Reference< XComponentContext > & ctx )
262 : throw( RuntimeException, Exception, std::exception )
263 : {
264 0 : if( ! m_theInstance.is() )
265 : {
266 : // work around the problem in sdbc
267 0 : Reference< XComponentContext > useCtx = ctx;
268 0 : if( ! useCtx.is() )
269 0 : useCtx = m_defaultContext;
270 0 : Reference< XInterface > theInstance = m_create( useCtx );
271 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
272 0 : if( ! m_theInstance.is () )
273 : {
274 0 : m_theInstance = theInstance;
275 0 : }
276 : }
277 0 : return m_theInstance;
278 : }
279 :
280 0 : void OOneInstanceComponentFactory::disposing()
281 : {
282 0 : Reference< XComponent > rComp;
283 : {
284 0 : MutexGuard guard( osl::Mutex::getGlobalMutex() );
285 0 : rComp = Reference< XComponent >( m_theInstance, UNO_QUERY );
286 0 : m_theInstance.clear();
287 : }
288 0 : if( rComp.is() )
289 0 : rComp->dispose();
290 0 : }
291 :
292 : // Reference< XSingleComponentFactory > createOneInstanceComponentFactory(
293 : // cppu::ComponentFactoryFunc fptr,
294 : // OUString const & rImplementationName,
295 : // ::com::sun::star::uno::Sequence< OUString > const & rServiceNames,
296 : // rtl_ModuleCount * pModCount = 0 )
297 : // SAL_THROW(())
298 : // {
299 : // return new OOneInstanceComponentFactory( rImplementationName, fptr , rServiceNames);
300 : // }
301 :
302 : }
303 :
304 : static const struct cppu::ImplementationEntry g_entries[] =
305 : {
306 : {
307 : pq_sdbc_driver::DriverCreateInstance, pq_sdbc_driver::DriverGetImplementationName,
308 : pq_sdbc_driver::DriverGetSupportedServiceNames, 0,
309 : 0 , 0
310 : },
311 : { 0, 0, 0, 0, 0, 0 }
312 : };
313 :
314 : extern "C"
315 : {
316 :
317 0 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL postgresql_sdbc_component_getFactory(
318 : const sal_Char * pImplName, void * pServiceManager, void * )
319 : {
320 : // need to extract the defaultcontext, because the way, sdbc
321 : // bypasses the servicemanager, does not allow to use the
322 : // XSingleComponentFactory interface ...
323 0 : void * pRet = 0;
324 0 : Reference< XSingleComponentFactory > xFactory;
325 : Reference< com::sun::star::lang::XMultiServiceFactory > xSmgr(
326 : static_cast< XInterface * >(pServiceManager),
327 0 : com::sun::star::uno::UNO_QUERY_THROW );
328 :
329 0 : for( sal_Int32 i = 0 ; g_entries[i].create ; i ++ )
330 : {
331 0 : OUString implName = g_entries[i].getImplementationName();
332 0 : if( implName.equalsAscii( pImplName ) )
333 : {
334 : Reference< XComponentContext > defaultContext(
335 0 : comphelper::getComponentContext( xSmgr ) );
336 0 : xFactory = new pq_sdbc_driver::OOneInstanceComponentFactory(
337 : implName,
338 : g_entries[i].create,
339 : g_entries[i].getSupportedServiceNames(),
340 0 : defaultContext );
341 : }
342 0 : }
343 :
344 0 : if( xFactory.is() )
345 : {
346 0 : xFactory->acquire();
347 0 : pRet = xFactory.get();
348 : }
349 0 : return pRet;
350 : }
351 :
352 : }
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|