1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _CONNECTIVITY_KAB_DRIVER_HXX_
29 #define _CONNECTIVITY_KAB_DRIVER_HXX_
30 
31 /** === begin UNO includes === **/
32 #include <com/sun/star/sdbc/XDriver.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/frame/XTerminateListener.hpp>
35 /** === end UNO includes === **/
36 #include <cppuhelper/compbase3.hxx>
37 #include <osl/module.h>
38 
39 namespace connectivity
40 {
41 	namespace kab
42 	{
43         class KabConnection;
44         class KabDriver;
45 
46         typedef void*   (SAL_CALL * ConnectionFactoryFunction)( void* _pDriver );
47         typedef void    (SAL_CALL * ApplicationInitFunction)( void );
48         typedef void    (SAL_CALL * ApplicationShutdownFunction)( void );
49         typedef int     (SAL_CALL * KDEVersionCheckFunction)( void );
50 
51         typedef std::vector< ::com::sun::star::uno::WeakReferenceHelper > OWeakRefArray;
52 
53         // ===============================================================
54         // = KabImplModule
55         // ===============================================================
56         class KabImplModule
57         {
58         private:
59 			::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
60 										m_xORB;
61 
62             /// Did we already attempt to load the module and to retrieve the symbols?
63             bool    m_bAttemptedLoadModule;
64             /// Did we already check the KDE version and initialize the impl module (or at least attempted to)?
65             bool    m_bAttemptedInitialize;
66 
67             oslModule                   m_hConnectorModule;
68             ConnectionFactoryFunction   m_pConnectionFactoryFunc;
69             ApplicationInitFunction     m_pApplicationInitFunc;
70             ApplicationShutdownFunction m_pApplicationShutdownFunc;
71             KDEVersionCheckFunction     m_pKDEVersionCheckFunc;
72 
73         public:
74             KabImplModule( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory );
75 
76             /** determines whether there is a KDE present in the environment
77             */
78             bool isKDEPresent();
79 
80             enum KDEVersionType
81             {
82                 eTooOld,
83                 eSupported,
84                 eToNew
85             };
86             /** checks whether the KDE version we're running against is supported
87                 @precond
88                     the module is loaded, i.e impl_loadModule has successfully been called
89             */
90             KDEVersionType matchKDEVersion();
91 
92             /** initializes the implementation module.
93 
94                 @raises ::com::sun::star::uno::RuntimeException
95                     if the module could be loaded, but required symbols are missing
96                 @raises ::com::sun::star::sdbc::SQLException
97                     if the KDE version we're running against is not supported, or no KDE was found at all
98             */
99             void init();
100 
101             /** shuts down the impl module (and the KDE application, if we own it)
102             */
103             void shutdown();
104 
105             /** creates a new connection
106                 @precond
107                     <member>init</member> has been called before
108                 @raises ::com::sun::star::uno::RuntimeException
109                     if no connection object could be created (which is a severe error, normally impossible)
110             */
111             KabConnection*  createConnection( KabDriver* _pDriver ) const;
112 
113         private:
114             /** loads the implementation module and retrieves the needed symbols
115 
116                 Save against being called multiple times.
117 
118                 @return <TRUE/> if the module could be loaded successfully.
119 
120                 @raises ::com::sun::star::uno::RuntimeException
121                     if the module could be loaded, but required symbols are missing
122             */
123             bool    impl_loadModule();
124 
125             /** unloads the implementation module, and resets all function pointers to <NULL/>
126                 @precond m_hConnectorModule is not <NULL/>
127             */
128             void    impl_unloadModule();
129 
130             /** throws an SQLException saying than no KDE installation was found
131             */
132             void    impl_throwNoKdeException();
133 
134             /** throws an SQLException saying that the found KDE version is too old
135             */
136             void    impl_throwKdeTooOldException();
137 
138             /** throws an SQLException saying that the found KDE version is too new
139             */
140             void    impl_throwKdeTooNewException();
141 
142             /** throws a generic SQL exception with SQLState S1000 and error code 0
143             */
144             void    impl_throwGenericSQLException( const ::rtl::OUString& _rMessage );
145 
146             /** determines whether it's allowed to run on a too-new (not confirmed to work) version
147             */
148             bool    impl_doAllowNewKDEVersion();
149         };
150 
151         // ===============================================================
152         // = KabDriver
153         // ===============================================================
154 		typedef ::cppu::WeakComponentImplHelper3<   ::com::sun::star::sdbc::XDriver,
155 													::com::sun::star::lang::XServiceInfo,
156                                                     ::com::sun::star::frame::XTerminateListener > KDriver_BASE;
157 		class KabDriver : public KDriver_BASE
158 		{
159 		protected:
160 			::osl::Mutex				m_aMutex;			// mutex is need to control member access
161 			OWeakRefArray				m_xConnections;		// vector containing a list of all the
162 															//  KabConnection objects for this Driver
163 			::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
164 										m_xMSFactory;		// the multi-service factory
165             KabImplModule               m_aImplModule;
166 
167         public:
168             static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );
169 
170             // XServiceInfo - static versions
171             static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
172             static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);
173 
174             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
175                     getMSFactory() const { return m_xMSFactory; }
176 
177             /** returns the driver's implementation name (being pure ASCII) for reference in various places
178             */
179             static const sal_Char*  impl_getAsciiImplementationName();
180 
181             /** returns the path of our configuration settings
182             */
183             static ::rtl::OUString  impl_getConfigurationSettingsPath();
184 
185         protected:
186 			KabDriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory);
187 
188 			// OComponentHelper
189 			virtual void SAL_CALL disposing(void);
190 
191 			// XServiceInfo
192 			virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
193 			virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
194 			virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
195 
196 			// XDriver
197 			virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
198 			virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
199 			virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
200 			virtual sal_Int32 SAL_CALL getMajorVersion() throw(::com::sun::star::uno::RuntimeException);
201 			virtual sal_Int32 SAL_CALL getMinorVersion() throw(::com::sun::star::uno::RuntimeException);
202 
203             // XTerminateListener
204             virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
205             virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
206 
207             // XEventListener
208             virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
209 
210         private:
211             /** shuts down the library which contains the real implementations
212 
213                 This method is safe against being called multiple times
214 
215                 @precond our mutex is locked
216             */
217             void impl_shutdownImplementationModule();
218 		};
219 	}
220 
221 }
222 
223 #endif // _CONNECTIVITY_KAB_DRIVER_HXX_
224