xref: /AOO41X/main/connectivity/source/drivers/jdbc/JConnection.cxx (revision 9b5730f6ddef7eb82608ca4d31dc0d7678e652cf)
1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9b5730f6SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9b5730f6SAndrew Rist  * distributed with this work for additional information
6*9b5730f6SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9b5730f6SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist  * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*9b5730f6SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*9b5730f6SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist  * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9b5730f6SAndrew Rist  * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*9b5730f6SAndrew Rist  *************************************************************/
21*9b5730f6SAndrew Rist 
22*9b5730f6SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "java/sql/Connection.hxx"
28cdf0e10cSrcweir #include "java/lang/Class.hxx"
29cdf0e10cSrcweir #include "java/tools.hxx"
30cdf0e10cSrcweir #include "java/ContextClassLoader.hxx"
31cdf0e10cSrcweir #include "java/sql/DatabaseMetaData.hxx"
32cdf0e10cSrcweir #include "java/sql/JStatement.hxx"
33cdf0e10cSrcweir #include "java/sql/Driver.hxx"
34cdf0e10cSrcweir #include "java/sql/PreparedStatement.hxx"
35cdf0e10cSrcweir #include "java/sql/CallableStatement.hxx"
36cdf0e10cSrcweir #include "java/sql/SQLWarning.hxx"
37cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sdbc/SQLWarning.hpp>
39cdf0e10cSrcweir #include <com/sun/star/sdbc/SQLWarning.hpp>
40cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
41cdf0e10cSrcweir #include "connectivity/sqlparse.hxx"
42cdf0e10cSrcweir #include "connectivity/dbexception.hxx"
43cdf0e10cSrcweir #include "java/util/Property.hxx"
44cdf0e10cSrcweir #include "java/LocalRef.hxx"
45cdf0e10cSrcweir #include "resource/jdbc_log.hrc"
46cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
47cdf0e10cSrcweir #include "jvmaccess/classpath.hxx"
48cdf0e10cSrcweir #include <comphelper/namedvaluecollection.hxx>
49cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
50cdf0e10cSrcweir #include <jni.h>
51cdf0e10cSrcweir #include "resource/common_res.hrc"
52cdf0e10cSrcweir #include <unotools/confignode.hxx>
53cdf0e10cSrcweir 
54cdf0e10cSrcweir #include <list>
55cdf0e10cSrcweir #include <memory>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir using namespace connectivity;
58cdf0e10cSrcweir using namespace connectivity::jdbc;
59cdf0e10cSrcweir using namespace ::com::sun::star::uno;
60cdf0e10cSrcweir using namespace ::com::sun::star::beans;
61cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
62cdf0e10cSrcweir using namespace ::com::sun::star::container;
63cdf0e10cSrcweir using namespace ::com::sun::star::lang;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir namespace {
66cdf0e10cSrcweir 
67cdf0e10cSrcweir struct ClassMapEntry {
ClassMapEntry__anon56d046570111::ClassMapEntry68cdf0e10cSrcweir     ClassMapEntry(
69cdf0e10cSrcweir         rtl::OUString const & theClassPath, rtl::OUString const & theClassName):
70cdf0e10cSrcweir         classPath(theClassPath), className(theClassName), classLoader(NULL),
71cdf0e10cSrcweir         classObject(NULL) {}
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     rtl::OUString classPath;
74cdf0e10cSrcweir     rtl::OUString className;
75cdf0e10cSrcweir     jweak classLoader;
76cdf0e10cSrcweir     jweak classObject;
77cdf0e10cSrcweir };
78cdf0e10cSrcweir 
79cdf0e10cSrcweir typedef std::list< ClassMapEntry > ClassMap;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir struct ClassMapData {
82cdf0e10cSrcweir     osl::Mutex mutex;
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     ClassMap map;
85cdf0e10cSrcweir };
86cdf0e10cSrcweir 
87cdf0e10cSrcweir struct ClassMapDataInit {
operator ()__anon56d046570111::ClassMapDataInit88cdf0e10cSrcweir     ClassMapData * operator()() {
89cdf0e10cSrcweir         static ClassMapData instance;
90cdf0e10cSrcweir         return &instance;
91cdf0e10cSrcweir     }
92cdf0e10cSrcweir };
93cdf0e10cSrcweir 
94cdf0e10cSrcweir template < typename T >
getLocalFromWeakRef(jweak & _weak,LocalRef<T> & _inout_local)95cdf0e10cSrcweir bool getLocalFromWeakRef( jweak& _weak, LocalRef< T >& _inout_local )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir     _inout_local.set( static_cast< T >( _inout_local.env().NewLocalRef( _weak ) ) );
98cdf0e10cSrcweir 
99cdf0e10cSrcweir     if ( !_inout_local.is() )
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         if ( _inout_local.env().ExceptionCheck())
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             return false;
104cdf0e10cSrcweir         }
105cdf0e10cSrcweir         else if ( _weak != NULL )
106cdf0e10cSrcweir         {
107cdf0e10cSrcweir             _inout_local.env().DeleteWeakGlobalRef( _weak );
108cdf0e10cSrcweir             _weak = NULL;
109cdf0e10cSrcweir         }
110cdf0e10cSrcweir     }
111cdf0e10cSrcweir     return true;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir // Load a class.  A map from pairs of (classPath, name) to pairs of weak Java
115cdf0e10cSrcweir // references to (ClassLoader, Class) is maintained, so that a class is only
116cdf0e10cSrcweir // loaded once.
117cdf0e10cSrcweir //
118cdf0e10cSrcweir // It may happen that the weak reference to the ClassLoader becomes null while
119cdf0e10cSrcweir // the reference to the Class remains non-null (in case the Class was actually
120cdf0e10cSrcweir // loaded by some parent of the ClassLoader), in which case the ClassLoader is
121cdf0e10cSrcweir // resurrected (which cannot cause any classes to be loaded multiple times, as
122cdf0e10cSrcweir // the ClassLoader is no longer reachable, so no classes it has ever loaded are
123cdf0e10cSrcweir // still reachable).
124cdf0e10cSrcweir //
125cdf0e10cSrcweir // Similarly, it may happen that the weak reference to the Class becomes null
126cdf0e10cSrcweir // while the reference to the ClassLoader remains non-null, in which case the
127cdf0e10cSrcweir // Class is simply re-loaded.
128cdf0e10cSrcweir //
129cdf0e10cSrcweir // This code is close to the implementation of jvmaccess::ClassPath::loadClass
130cdf0e10cSrcweir // in jvmaccess/classpath.hxx, but not close enough to avoid the duplication.
131cdf0e10cSrcweir //
132cdf0e10cSrcweir // If false is returned, a (still pending) JNI exception occurred.
loadClass(Reference<XComponentContext> const & context,JNIEnv & environment,rtl::OUString const & classPath,rtl::OUString const & name,LocalRef<jobject> * classLoaderPtr,LocalRef<jclass> * classPtr)133cdf0e10cSrcweir bool loadClass(
134cdf0e10cSrcweir     Reference< XComponentContext > const & context, JNIEnv& environment,
135cdf0e10cSrcweir     rtl::OUString const & classPath, rtl::OUString const & name,
136cdf0e10cSrcweir     LocalRef< jobject > * classLoaderPtr, LocalRef< jclass > * classPtr)
137cdf0e10cSrcweir {
138cdf0e10cSrcweir     OSL_ASSERT(classLoaderPtr != NULL);
139cdf0e10cSrcweir     // For any jweak entries still present in the map upon destruction,
140cdf0e10cSrcweir     // DeleteWeakGlobalRef is not called (which is a leak):
141cdf0e10cSrcweir     ClassMapData * d =
142cdf0e10cSrcweir         rtl_Instance< ClassMapData, ClassMapDataInit, osl::MutexGuard,
143cdf0e10cSrcweir         osl::GetGlobalMutex >::create(
144cdf0e10cSrcweir             ClassMapDataInit(), osl::GetGlobalMutex());
145cdf0e10cSrcweir     osl::MutexGuard g(d->mutex);
146cdf0e10cSrcweir     ClassMap::iterator i(d->map.begin());
147cdf0e10cSrcweir     LocalRef< jobject > cloader(environment);
148cdf0e10cSrcweir     LocalRef< jclass > cl(environment);
149cdf0e10cSrcweir     // Prune dangling weak references from the list while searching for a match,
150cdf0e10cSrcweir     // so that the list cannot grow unbounded:
151cdf0e10cSrcweir     for (; i != d->map.end();)
152cdf0e10cSrcweir     {
153cdf0e10cSrcweir         LocalRef< jobject > classLoader( environment );
154cdf0e10cSrcweir         if ( !getLocalFromWeakRef( i->classLoader, classLoader ) )
155cdf0e10cSrcweir             return false;
156cdf0e10cSrcweir 
157cdf0e10cSrcweir         LocalRef< jclass > classObject( environment );
158cdf0e10cSrcweir         if ( !getLocalFromWeakRef( i->classObject, classObject ) )
159cdf0e10cSrcweir             return false;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir         if ( !classLoader.is() && !classObject.is() )
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir             i = d->map.erase(i);
164cdf0e10cSrcweir         }
165cdf0e10cSrcweir         else if ( i->classPath == classPath && i->className == name )
166cdf0e10cSrcweir         {
167cdf0e10cSrcweir             cloader.set( classLoader.release() );
168cdf0e10cSrcweir             cl.set( classObject.release() );
169cdf0e10cSrcweir             break;
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir         else
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir             ++i;
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     if ( !cloader.is() || !cl.is() )
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir         if ( i == d->map.end() )
179cdf0e10cSrcweir         {
180cdf0e10cSrcweir             // Push a new ClassMapEntry (which can potentially fail) before
181cdf0e10cSrcweir             // loading the class, so that it never happens that a class is
182cdf0e10cSrcweir             // loaded but not added to the map (which could have effects on the
183cdf0e10cSrcweir             // JVM that are not easily undone).  If the pushed ClassMapEntry is
184cdf0e10cSrcweir             // not used after all (return false, etc.) it will be pruned on next
185cdf0e10cSrcweir             // call because its classLoader/classObject are null:
186cdf0e10cSrcweir             d->map.push_front( ClassMapEntry( classPath, name ) );
187cdf0e10cSrcweir             i = d->map.begin();
188cdf0e10cSrcweir         }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         LocalRef< jclass > clClass( environment );
191cdf0e10cSrcweir         clClass.set( environment.FindClass( "java/net/URLClassLoader" ) );
192cdf0e10cSrcweir         if ( !clClass.is() )
193cdf0e10cSrcweir             return false;
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         jweak wcloader = NULL;
196cdf0e10cSrcweir         if (!cloader.is())
197cdf0e10cSrcweir         {
198cdf0e10cSrcweir             jmethodID ctorLoader( environment.GetMethodID( clClass.get(), "<init>", "([Ljava/net/URL;)V" ) );
199cdf0e10cSrcweir             if (ctorLoader == NULL)
200cdf0e10cSrcweir                 return false;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir             LocalRef< jobjectArray > arr( environment );
203cdf0e10cSrcweir             arr.set( jvmaccess::ClassPath::translateToUrls( context, &environment, classPath ) );
204cdf0e10cSrcweir             if ( !arr.is() )
205cdf0e10cSrcweir                 return false;
206cdf0e10cSrcweir 
207cdf0e10cSrcweir             jvalue arg;
208cdf0e10cSrcweir             arg.l = arr.get();
209cdf0e10cSrcweir             cloader.set( environment.NewObjectA( clClass.get(), ctorLoader, &arg ) );
210cdf0e10cSrcweir             if ( !cloader.is() )
211cdf0e10cSrcweir                 return false;
212cdf0e10cSrcweir 
213cdf0e10cSrcweir             wcloader = environment.NewWeakGlobalRef( cloader.get() );
214cdf0e10cSrcweir             if ( wcloader == NULL )
215cdf0e10cSrcweir                 return false;
216cdf0e10cSrcweir         }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir         jweak wcl = NULL;
219cdf0e10cSrcweir         if ( !cl.is() )
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir             jmethodID methLoadClass( environment.GetMethodID( clClass.get(), "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;" ) );
222cdf0e10cSrcweir             if ( methLoadClass == NULL )
223cdf0e10cSrcweir                 return false;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir             LocalRef< jstring > str( environment );
226cdf0e10cSrcweir             str.set( convertwchar_tToJavaString( &environment, name ) );
227cdf0e10cSrcweir             if ( !str.is() )
228cdf0e10cSrcweir                 return false;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir             jvalue arg;
231cdf0e10cSrcweir             arg.l = str.get();
232cdf0e10cSrcweir             cl.set( static_cast< jclass >( environment.CallObjectMethodA( cloader.get(), methLoadClass, &arg ) ) );
233cdf0e10cSrcweir             if ( !cl.is() )
234cdf0e10cSrcweir                 return false;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir             wcl = environment.NewWeakGlobalRef( cl.get() );
237cdf0e10cSrcweir             if ( wcl == NULL )
238cdf0e10cSrcweir                 return false;
239cdf0e10cSrcweir         }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir         if ( wcloader != NULL)
242cdf0e10cSrcweir         {
243cdf0e10cSrcweir             i->classLoader = wcloader;
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir         if ( wcl != NULL )
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             i->classObject = wcl;
248cdf0e10cSrcweir         }
249cdf0e10cSrcweir     }
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     classLoaderPtr->set( cloader.release() );
252cdf0e10cSrcweir     classPtr->set( cl.release() );
253cdf0e10cSrcweir     return true;
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir //------------------------------------------------------------------------------
259cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO(java_sql_Connection,"com.sun.star.sdbcx.JConnection","com.sun.star.sdbc.Connection");
260cdf0e10cSrcweir //------------------------------------------------------------------------------
261cdf0e10cSrcweir //**************************************************************
262cdf0e10cSrcweir //************ Class: java.sql.Connection
263cdf0e10cSrcweir //**************************************************************
264cdf0e10cSrcweir jclass java_sql_Connection::theClass = 0;
265cdf0e10cSrcweir 
java_sql_Connection(const java_sql_Driver & _rDriver)266cdf0e10cSrcweir java_sql_Connection::java_sql_Connection( const java_sql_Driver& _rDriver )
267cdf0e10cSrcweir     :java_lang_Object( _rDriver.getContext().getLegacyServiceFactory() )
268cdf0e10cSrcweir     ,OSubComponent<java_sql_Connection, java_sql_Connection_BASE>((::cppu::OWeakObject*)(&_rDriver), this)
269cdf0e10cSrcweir     ,m_pDriver( &_rDriver )
270cdf0e10cSrcweir     ,m_pDriverobject(NULL)
271cdf0e10cSrcweir     ,m_pDriverClassLoader()
272cdf0e10cSrcweir     ,m_Driver_theClass(NULL)
273cdf0e10cSrcweir     ,m_aLogger( _rDriver.getLogger() )
274cdf0e10cSrcweir     ,m_bParameterSubstitution(sal_False)
275cdf0e10cSrcweir     ,m_bIgnoreDriverPrivileges(sal_True)
276cdf0e10cSrcweir     ,m_bIgnoreCurrency(sal_False)
277cdf0e10cSrcweir {
278cdf0e10cSrcweir }
279cdf0e10cSrcweir // -----------------------------------------------------------------------------
~java_sql_Connection()280cdf0e10cSrcweir java_sql_Connection::~java_sql_Connection()
281cdf0e10cSrcweir {
282cdf0e10cSrcweir 	::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM();
283cdf0e10cSrcweir 	if ( xTest.is() )
284cdf0e10cSrcweir 	{
285cdf0e10cSrcweir 		SDBThreadAttach t;
286cdf0e10cSrcweir         clearObject(*t.pEnv);
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 		{
289cdf0e10cSrcweir 			if ( m_pDriverobject )
290cdf0e10cSrcweir 				t.pEnv->DeleteGlobalRef( m_pDriverobject );
291cdf0e10cSrcweir 			m_pDriverobject = NULL;
292cdf0e10cSrcweir 			if ( m_Driver_theClass )
293cdf0e10cSrcweir 				t.pEnv->DeleteGlobalRef( m_Driver_theClass );
294cdf0e10cSrcweir 			m_Driver_theClass = NULL;
295cdf0e10cSrcweir 		}
296cdf0e10cSrcweir 		t.releaseRef();
297cdf0e10cSrcweir 	}
298cdf0e10cSrcweir }
299cdf0e10cSrcweir //-----------------------------------------------------------------------------
release()300cdf0e10cSrcweir void SAL_CALL java_sql_Connection::release() throw()
301cdf0e10cSrcweir {
302cdf0e10cSrcweir 	relase_ChildImpl();
303cdf0e10cSrcweir }
304cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing()305cdf0e10cSrcweir void java_sql_Connection::disposing()
306cdf0e10cSrcweir {
307cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_aMutex);
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     m_aLogger.log( LogLevel::INFO, STR_LOG_SHUTDOWN_CONNECTION );
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     dispose_ChildImpl();
312cdf0e10cSrcweir 	java_sql_Connection_BASE::disposing();
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 	if ( object )
315cdf0e10cSrcweir 	{
316cdf0e10cSrcweir         static jmethodID mID(NULL);
317cdf0e10cSrcweir         callVoidMethod("close",mID);
318cdf0e10cSrcweir 	}
319cdf0e10cSrcweir }
320cdf0e10cSrcweir // -------------------------------------------------------------------------
getMyClass() const321cdf0e10cSrcweir jclass java_sql_Connection::getMyClass() const
322cdf0e10cSrcweir {
323cdf0e10cSrcweir 	// die Klasse muss nur einmal geholt werden, daher statisch
324cdf0e10cSrcweir 	if( !theClass )
325cdf0e10cSrcweir         theClass = findMyClass("java/sql/Connection");
326cdf0e10cSrcweir 	return theClass;
327cdf0e10cSrcweir }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir // -------------------------------------------------------------------------
getCatalog()330cdf0e10cSrcweir ::rtl::OUString SAL_CALL java_sql_Connection::getCatalog(  ) throw(SQLException, RuntimeException)
331cdf0e10cSrcweir {
332cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
333cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     static jmethodID mID(NULL);
336cdf0e10cSrcweir     return callStringMethod("getCatalog",mID);
337cdf0e10cSrcweir }
338cdf0e10cSrcweir // -------------------------------------------------------------------------
getMetaData()339cdf0e10cSrcweir Reference< XDatabaseMetaData > SAL_CALL java_sql_Connection::getMetaData(  ) throw(SQLException, RuntimeException)
340cdf0e10cSrcweir {
341cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
342cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 	Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
346cdf0e10cSrcweir 	if(!xMetaData.is())
347cdf0e10cSrcweir 	{
348cdf0e10cSrcweir         SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
349cdf0e10cSrcweir         static jmethodID mID(NULL);
350cdf0e10cSrcweir         jobject out = callObjectMethod(t.pEnv,"getMetaData","()Ljava/sql/DatabaseMetaData;", mID);
351cdf0e10cSrcweir 		if(out)
352cdf0e10cSrcweir 		{
353cdf0e10cSrcweir 			xMetaData = new java_sql_DatabaseMetaData( t.pEnv, out, *this );
354cdf0e10cSrcweir 			m_xMetaData = xMetaData;
355cdf0e10cSrcweir 		}
356cdf0e10cSrcweir 	}
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 	return xMetaData;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir // -------------------------------------------------------------------------
close()361cdf0e10cSrcweir void SAL_CALL java_sql_Connection::close(  ) throw(SQLException, RuntimeException)
362cdf0e10cSrcweir {
363cdf0e10cSrcweir 	dispose();
364cdf0e10cSrcweir }
365cdf0e10cSrcweir // -------------------------------------------------------------------------
commit()366cdf0e10cSrcweir void SAL_CALL java_sql_Connection::commit(  ) throw(SQLException, RuntimeException)
367cdf0e10cSrcweir {
368cdf0e10cSrcweir     static jmethodID mID(NULL);
369cdf0e10cSrcweir     callVoidMethod("commit",mID);
370cdf0e10cSrcweir }
371cdf0e10cSrcweir // -------------------------------------------------------------------------
isClosed()372cdf0e10cSrcweir sal_Bool SAL_CALL java_sql_Connection::isClosed(  ) throw(SQLException, RuntimeException)
373cdf0e10cSrcweir {
374cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
375cdf0e10cSrcweir 
376cdf0e10cSrcweir     static jmethodID mID(NULL);
377cdf0e10cSrcweir     return callBooleanMethod( "isClosed", mID ) && java_sql_Connection_BASE::rBHelper.bDisposed;
378cdf0e10cSrcweir }
379cdf0e10cSrcweir // -------------------------------------------------------------------------
isReadOnly()380cdf0e10cSrcweir sal_Bool SAL_CALL java_sql_Connection::isReadOnly(  ) throw(SQLException, RuntimeException)
381cdf0e10cSrcweir {
382cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
383cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
384cdf0e10cSrcweir     static jmethodID mID(NULL);
385cdf0e10cSrcweir     return callBooleanMethod( "isReadOnly", mID );
386cdf0e10cSrcweir }
387cdf0e10cSrcweir // -------------------------------------------------------------------------
setCatalog(const::rtl::OUString & catalog)388cdf0e10cSrcweir void SAL_CALL java_sql_Connection::setCatalog( const ::rtl::OUString& catalog ) throw(SQLException, RuntimeException)
389cdf0e10cSrcweir {
390cdf0e10cSrcweir     static jmethodID mID(NULL);
391cdf0e10cSrcweir     callVoidMethodWithStringArg("setCatalog",mID,catalog);
392cdf0e10cSrcweir }
393cdf0e10cSrcweir // -------------------------------------------------------------------------
rollback()394cdf0e10cSrcweir void SAL_CALL java_sql_Connection::rollback(  ) throw(SQLException, RuntimeException)
395cdf0e10cSrcweir {
396cdf0e10cSrcweir     static jmethodID mID(NULL);
397cdf0e10cSrcweir     callVoidMethod("rollback",mID);
398cdf0e10cSrcweir }
399cdf0e10cSrcweir // -------------------------------------------------------------------------
getAutoCommit()400cdf0e10cSrcweir sal_Bool SAL_CALL java_sql_Connection::getAutoCommit(  ) throw(SQLException, RuntimeException)
401cdf0e10cSrcweir {
402cdf0e10cSrcweir     static jmethodID mID(NULL);
403cdf0e10cSrcweir     return callBooleanMethod( "getAutoCommit", mID );
404cdf0e10cSrcweir }
405cdf0e10cSrcweir // -------------------------------------------------------------------------
setReadOnly(sal_Bool readOnly)406cdf0e10cSrcweir void SAL_CALL java_sql_Connection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException)
407cdf0e10cSrcweir {
408cdf0e10cSrcweir     static jmethodID mID(NULL);
409cdf0e10cSrcweir     callVoidMethodWithBoolArg("setReadOnly",mID,readOnly);
410cdf0e10cSrcweir }
411cdf0e10cSrcweir // -------------------------------------------------------------------------
setAutoCommit(sal_Bool autoCommit)412cdf0e10cSrcweir void SAL_CALL java_sql_Connection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException)
413cdf0e10cSrcweir {
414cdf0e10cSrcweir     static jmethodID mID(NULL);
415cdf0e10cSrcweir     callVoidMethodWithBoolArg("setAutoCommit",mID,autoCommit);
416cdf0e10cSrcweir }
417cdf0e10cSrcweir // -------------------------------------------------------------------------
getTypeMap()418cdf0e10cSrcweir Reference< ::com::sun::star::container::XNameAccess > SAL_CALL java_sql_Connection::getTypeMap(  ) throw(SQLException, RuntimeException)
419cdf0e10cSrcweir {
420cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
421cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
424cdf0e10cSrcweir     static jmethodID mID(NULL);
425cdf0e10cSrcweir     /*jobject out = */callObjectMethod(t.pEnv,"getTypeMap","()Ljava/util/Map;", mID);
426cdf0e10cSrcweir 	// ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
427cdf0e10cSrcweir 	return 0;// ? 0 : Map2XNameAccess( t.pEnv, out );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir // -------------------------------------------------------------------------
setTypeMap(const Reference<::com::sun::star::container::XNameAccess> &)430cdf0e10cSrcweir void SAL_CALL java_sql_Connection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
431cdf0e10cSrcweir {
432cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
433cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
434cdf0e10cSrcweir 
435cdf0e10cSrcweir     ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
436cdf0e10cSrcweir }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir // -------------------------------------------------------------------------
getTransactionIsolation()439cdf0e10cSrcweir sal_Int32 SAL_CALL java_sql_Connection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
440cdf0e10cSrcweir {
441cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
442cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     static jmethodID mID(NULL);
445cdf0e10cSrcweir 	return callIntMethod("getTransactionIsolation",mID);
446cdf0e10cSrcweir }
447cdf0e10cSrcweir // -------------------------------------------------------------------------
setTransactionIsolation(sal_Int32 level)448cdf0e10cSrcweir void SAL_CALL java_sql_Connection::setTransactionIsolation( sal_Int32 level ) throw(SQLException, RuntimeException)
449cdf0e10cSrcweir {
450cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
451cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     static jmethodID mID(NULL);
454cdf0e10cSrcweir     callVoidMethodWithIntArg("setTransactionIsolation",mID,level);
455cdf0e10cSrcweir }
456cdf0e10cSrcweir // -------------------------------------------------------------------------
createStatement()457cdf0e10cSrcweir Reference< XStatement > SAL_CALL java_sql_Connection::createStatement(  ) throw(SQLException, RuntimeException)
458cdf0e10cSrcweir {
459cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
460cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
461cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINE, STR_LOG_CREATE_STATEMENT );
462cdf0e10cSrcweir 
463cdf0e10cSrcweir 	SDBThreadAttach t;
464cdf0e10cSrcweir     java_sql_Statement* pStatement = new java_sql_Statement( t.pEnv, *this );
465cdf0e10cSrcweir 	Reference< XStatement > xStmt = pStatement;
466cdf0e10cSrcweir 	m_aStatements.push_back( WeakReferenceHelper( xStmt ) );
467cdf0e10cSrcweir 
468cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINE, STR_LOG_CREATED_STATEMENT_ID, pStatement->getStatementObjectID() );
469cdf0e10cSrcweir     return xStmt;
470cdf0e10cSrcweir }
471cdf0e10cSrcweir // -----------------------------------------------------------------------------
transFormPreparedStatement(const::rtl::OUString & _sSQL)472cdf0e10cSrcweir ::rtl::OUString java_sql_Connection::transFormPreparedStatement(const ::rtl::OUString& _sSQL)
473cdf0e10cSrcweir {
474cdf0e10cSrcweir 	::rtl::OUString sSqlStatement = _sSQL;
475cdf0e10cSrcweir 	if ( m_bParameterSubstitution )
476cdf0e10cSrcweir 	{
477cdf0e10cSrcweir 		try
478cdf0e10cSrcweir 		{
479cdf0e10cSrcweir 			OSQLParser aParser( m_pDriver->getContext().getLegacyServiceFactory() );
480cdf0e10cSrcweir 			::rtl::OUString sErrorMessage;
481cdf0e10cSrcweir 			::rtl::OUString sNewSql;
482cdf0e10cSrcweir 			OSQLParseNode* pNode = aParser.parseTree(sErrorMessage,_sSQL);
483cdf0e10cSrcweir 			if(pNode)
484cdf0e10cSrcweir 			{	// special handling for parameters
485cdf0e10cSrcweir 				OSQLParseNode::substituteParameterNames(pNode);
486cdf0e10cSrcweir 				pNode->parseNodeToStr( sNewSql, this );
487cdf0e10cSrcweir 				delete pNode;
488cdf0e10cSrcweir 				sSqlStatement = sNewSql;
489cdf0e10cSrcweir 			}
490cdf0e10cSrcweir 		}
491cdf0e10cSrcweir 		catch(const Exception&)
492cdf0e10cSrcweir 		{
493cdf0e10cSrcweir 		}
494cdf0e10cSrcweir 	}
495cdf0e10cSrcweir 	return sSqlStatement;
496cdf0e10cSrcweir }
497cdf0e10cSrcweir // -------------------------------------------------------------------------
prepareStatement(const::rtl::OUString & sql)498cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
499cdf0e10cSrcweir {
500cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
501cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
502cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_STATEMENT, sql );
503cdf0e10cSrcweir 
504cdf0e10cSrcweir     SDBThreadAttach t;
505cdf0e10cSrcweir 	::rtl::OUString sSqlStatement = sql;
506cdf0e10cSrcweir 	sSqlStatement = transFormPreparedStatement( sSqlStatement );
507cdf0e10cSrcweir 
508cdf0e10cSrcweir     java_sql_PreparedStatement* pStatement = new java_sql_PreparedStatement( t.pEnv, *this, sSqlStatement );
509cdf0e10cSrcweir 	Reference< XPreparedStatement > xReturn( pStatement );
510cdf0e10cSrcweir 	m_aStatements.push_back(WeakReferenceHelper(xReturn));
511cdf0e10cSrcweir 
512cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_STATEMENT_ID, pStatement->getStatementObjectID() );
513cdf0e10cSrcweir 	return xReturn;
514cdf0e10cSrcweir }
515cdf0e10cSrcweir // -------------------------------------------------------------------------
prepareCall(const::rtl::OUString & sql)516cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareCall( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
519cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
520cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_CALL, sql );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir 	SDBThreadAttach t;
523cdf0e10cSrcweir 	::rtl::OUString sSqlStatement = sql;
524cdf0e10cSrcweir 	sSqlStatement = transFormPreparedStatement( sSqlStatement );
525cdf0e10cSrcweir 
526cdf0e10cSrcweir     java_sql_CallableStatement* pStatement = new java_sql_CallableStatement( t.pEnv, *this, sSqlStatement );
527cdf0e10cSrcweir 	Reference< XPreparedStatement > xStmt( pStatement );
528cdf0e10cSrcweir 	m_aStatements.push_back(WeakReferenceHelper(xStmt));
529cdf0e10cSrcweir 
530cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_CALL_ID, pStatement->getStatementObjectID() );
531cdf0e10cSrcweir     return xStmt;
532cdf0e10cSrcweir }
533cdf0e10cSrcweir // -------------------------------------------------------------------------
nativeSQL(const::rtl::OUString & sql)534cdf0e10cSrcweir ::rtl::OUString SAL_CALL java_sql_Connection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
535cdf0e10cSrcweir {
536cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
537cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 	::rtl::OUString aStr;
540cdf0e10cSrcweir     SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!");
541cdf0e10cSrcweir 	{
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 		// temporaere Variable initialisieren
544cdf0e10cSrcweir 		static const char * cSignature = "(Ljava/lang/String;)Ljava/lang/String;";
545cdf0e10cSrcweir 		static const char * cMethodName = "nativeSQL";
546cdf0e10cSrcweir 		// Java-Call absetzen
547cdf0e10cSrcweir 		static jmethodID mID(NULL);
548cdf0e10cSrcweir         obtainMethodId(t.pEnv, cMethodName,cSignature, mID);
549cdf0e10cSrcweir 		// Parameter konvertieren
550cdf0e10cSrcweir 		jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,sql));
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 		jobject out = t.pEnv->CallObjectMethod( object, mID, str.get() );
553cdf0e10cSrcweir 		aStr = JavaString2String(t.pEnv, (jstring)out );
554cdf0e10cSrcweir 		ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
555cdf0e10cSrcweir 	} //t.pEnv
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     m_aLogger.log( LogLevel::FINER, STR_LOG_NATIVE_SQL, sql, aStr );
558cdf0e10cSrcweir 
559cdf0e10cSrcweir 	return aStr;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir // -------------------------------------------------------------------------
clearWarnings()562cdf0e10cSrcweir void SAL_CALL java_sql_Connection::clearWarnings(  ) throw(SQLException, RuntimeException)
563cdf0e10cSrcweir {
564cdf0e10cSrcweir     static jmethodID mID(NULL);
565cdf0e10cSrcweir     callVoidMethod("clearWarnings",mID);
566cdf0e10cSrcweir }
567cdf0e10cSrcweir // -------------------------------------------------------------------------
getWarnings()568cdf0e10cSrcweir Any SAL_CALL java_sql_Connection::getWarnings(  ) throw(SQLException, RuntimeException)
569cdf0e10cSrcweir {
570cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
571cdf0e10cSrcweir 	checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
572cdf0e10cSrcweir 
573cdf0e10cSrcweir 	SDBThreadAttach t;
574cdf0e10cSrcweir     static jmethodID mID(NULL);
575cdf0e10cSrcweir     jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID);
576cdf0e10cSrcweir 	// ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!!
577cdf0e10cSrcweir 	if( out )
578cdf0e10cSrcweir 	{
579cdf0e10cSrcweir 		java_sql_SQLWarning_BASE		warn_base(t.pEnv, out);
580cdf0e10cSrcweir         SQLException aAsException( static_cast< starsdbc::SQLException >( java_sql_SQLWarning( warn_base, *this ) ) );
581cdf0e10cSrcweir 
582cdf0e10cSrcweir         // translate to warning
583cdf0e10cSrcweir         SQLWarning aWarning;
584cdf0e10cSrcweir         aWarning.Context = aAsException.Context;
585cdf0e10cSrcweir         aWarning.Message = aAsException.Message;
586cdf0e10cSrcweir         aWarning.SQLState = aAsException.SQLState;
587cdf0e10cSrcweir         aWarning.ErrorCode = aAsException.ErrorCode;
588cdf0e10cSrcweir         aWarning.NextException = aAsException.NextException;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 		return makeAny( aWarning );
591cdf0e10cSrcweir 	}
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 	return Any();
594cdf0e10cSrcweir }
595cdf0e10cSrcweir 
596cdf0e10cSrcweir // -----------------------------------------------------------------------------
597cdf0e10cSrcweir namespace
598cdf0e10cSrcweir {
lcl_getDriverLoadErrorMessage(const::connectivity::SharedResources & _aResource,const::rtl::OUString & _rDriverClass,const::rtl::OUString & _rDriverClassPath)599cdf0e10cSrcweir     ::rtl::OUString lcl_getDriverLoadErrorMessage( const ::connectivity::SharedResources& _aResource,const ::rtl::OUString& _rDriverClass, const ::rtl::OUString& _rDriverClassPath )
600cdf0e10cSrcweir     {
601cdf0e10cSrcweir         ::rtl::OUString sError1( _aResource.getResourceStringWithSubstitution(
602cdf0e10cSrcweir                 STR_NO_CLASSNAME,
603cdf0e10cSrcweir                 "$classname$", _rDriverClass
604cdf0e10cSrcweir              ) );
605cdf0e10cSrcweir         if ( _rDriverClassPath.getLength() )
606cdf0e10cSrcweir         {
607cdf0e10cSrcweir             const ::rtl::OUString sError2( _aResource.getResourceStringWithSubstitution(
608cdf0e10cSrcweir                 STR_NO_CLASSNAME_PATH,
609cdf0e10cSrcweir                 "$classpath$", _rDriverClassPath
610cdf0e10cSrcweir              ) );
611cdf0e10cSrcweir             sError1 += sError2;
612cdf0e10cSrcweir         } // if ( _rDriverClassPath.getLength() )
613cdf0e10cSrcweir         return sError1;
614cdf0e10cSrcweir     }
615cdf0e10cSrcweir }
616cdf0e10cSrcweir 
617cdf0e10cSrcweir // -----------------------------------------------------------------------------
618cdf0e10cSrcweir namespace
619cdf0e10cSrcweir {
lcl_setSystemProperties_nothrow(const java::sql::ConnectionLog & _rLogger,JNIEnv & _rEnv,const Sequence<NamedValue> & _rSystemProperties)620cdf0e10cSrcweir     bool lcl_setSystemProperties_nothrow( const java::sql::ConnectionLog& _rLogger,
621cdf0e10cSrcweir         JNIEnv& _rEnv, const Sequence< NamedValue >& _rSystemProperties )
622cdf0e10cSrcweir     {
623cdf0e10cSrcweir         if ( _rSystemProperties.getLength() == 0 )
624cdf0e10cSrcweir             // nothing to do
625cdf0e10cSrcweir             return true;
626cdf0e10cSrcweir 
627cdf0e10cSrcweir         LocalRef< jclass > systemClass( _rEnv );
628cdf0e10cSrcweir         jmethodID nSetPropertyMethodID = 0;
629cdf0e10cSrcweir         // retrieve the java.lang.System class
630cdf0e10cSrcweir         systemClass.set( _rEnv.FindClass( "java/lang/System" ) );
631cdf0e10cSrcweir         if ( systemClass.is() )
632cdf0e10cSrcweir         {
633cdf0e10cSrcweir             nSetPropertyMethodID = _rEnv.GetStaticMethodID(
634cdf0e10cSrcweir                 systemClass.get(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" );
635cdf0e10cSrcweir         }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir         if ( nSetPropertyMethodID == 0 )
638cdf0e10cSrcweir             return false;
639cdf0e10cSrcweir 
640cdf0e10cSrcweir         for (   const NamedValue* pSystemProp = _rSystemProperties.getConstArray();
641cdf0e10cSrcweir                 pSystemProp != _rSystemProperties.getConstArray() + _rSystemProperties.getLength();
642cdf0e10cSrcweir                 ++pSystemProp
643cdf0e10cSrcweir             )
644cdf0e10cSrcweir         {
645cdf0e10cSrcweir             ::rtl::OUString sValue;
646cdf0e10cSrcweir             OSL_VERIFY( pSystemProp->Value >>= sValue );
647cdf0e10cSrcweir 
648cdf0e10cSrcweir             _rLogger.log( LogLevel::FINER, STR_LOG_SETTING_SYSTEM_PROPERTY, pSystemProp->Name, sValue );
649cdf0e10cSrcweir 
650cdf0e10cSrcweir             LocalRef< jstring > jName( _rEnv, convertwchar_tToJavaString( &_rEnv, pSystemProp->Name ) );
651cdf0e10cSrcweir             LocalRef< jstring > jValue( _rEnv, convertwchar_tToJavaString( &_rEnv, sValue ) );
652cdf0e10cSrcweir 
653cdf0e10cSrcweir             _rEnv.CallStaticObjectMethod( systemClass.get(), nSetPropertyMethodID, jName.get(), jValue.get() );
654cdf0e10cSrcweir             LocalRef< jthrowable > throwable( _rEnv, _rEnv.ExceptionOccurred() );
655cdf0e10cSrcweir             if ( throwable.is() )
656cdf0e10cSrcweir                 return false;
657cdf0e10cSrcweir         }
658cdf0e10cSrcweir 
659cdf0e10cSrcweir         return true;
660cdf0e10cSrcweir     }
661cdf0e10cSrcweir }
662cdf0e10cSrcweir 
663cdf0e10cSrcweir // -----------------------------------------------------------------------------
loadDriverFromProperties(const::rtl::OUString & _sDriverClass,const::rtl::OUString & _sDriverClassPath,const Sequence<NamedValue> & _rSystemProperties)664cdf0e10cSrcweir void java_sql_Connection::loadDriverFromProperties( const ::rtl::OUString& _sDriverClass, const ::rtl::OUString& _sDriverClassPath,
665cdf0e10cSrcweir     const Sequence< NamedValue >& _rSystemProperties )
666cdf0e10cSrcweir {
667cdf0e10cSrcweir     // contains the statement which should be used when query for automatically generated values
668cdf0e10cSrcweir 	::rtl::OUString		sGeneratedValueStatement;
669cdf0e10cSrcweir     // set to <TRUE/> when we should allow to query for generated values
670cdf0e10cSrcweir 	sal_Bool			bAutoRetrievingEnabled = sal_False;
671cdf0e10cSrcweir 
672cdf0e10cSrcweir     // first try if the jdbc driver is alraedy registered at the driver manager
673cdf0e10cSrcweir     SDBThreadAttach t;
674cdf0e10cSrcweir 	try
675cdf0e10cSrcweir 	{
676cdf0e10cSrcweir         if ( !object )
677cdf0e10cSrcweir         {
678cdf0e10cSrcweir             if ( !lcl_setSystemProperties_nothrow( getLogger(), *t.pEnv, _rSystemProperties ) )
679cdf0e10cSrcweir                 ThrowLoggedSQLException( getLogger(), t.pEnv, *this );
680cdf0e10cSrcweir 
681cdf0e10cSrcweir             m_pDriverClassLoader.reset();
682cdf0e10cSrcweir 
683cdf0e10cSrcweir             // here I try to find the class for jdbc driver
684cdf0e10cSrcweir             java_sql_SQLException_BASE::st_getMyClass();
685cdf0e10cSrcweir             java_lang_Throwable::st_getMyClass();
686cdf0e10cSrcweir 
687cdf0e10cSrcweir             if ( !_sDriverClass.getLength() )
688cdf0e10cSrcweir             {
689cdf0e10cSrcweir                 m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_DRIVER_CLASS );
690cdf0e10cSrcweir                 ::dbtools::throwGenericSQLException(
691cdf0e10cSrcweir                     lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
692cdf0e10cSrcweir                     *this
693cdf0e10cSrcweir                 );
694cdf0e10cSrcweir             }
695cdf0e10cSrcweir             else
696cdf0e10cSrcweir             {
697cdf0e10cSrcweir                 m_aLogger.log( LogLevel::INFO, STR_LOG_LOADING_DRIVER, _sDriverClass );
698cdf0e10cSrcweir                 // the driver manager holds the class of the driver for later use
699cdf0e10cSrcweir                 ::std::auto_ptr< java_lang_Class > pDrvClass;
700cdf0e10cSrcweir                 if ( !_sDriverClassPath.getLength() )
701cdf0e10cSrcweir                 {
702cdf0e10cSrcweir 					// if forName didn't find the class it will throw an exception
703cdf0e10cSrcweir 					pDrvClass = ::std::auto_ptr< java_lang_Class >(java_lang_Class::forName(_sDriverClass));
704cdf0e10cSrcweir                 }
705cdf0e10cSrcweir                 else
706cdf0e10cSrcweir                 {
707cdf0e10cSrcweir                     LocalRef< jclass > driverClass(t.env());
708cdf0e10cSrcweir                     LocalRef< jobject > driverClassLoader(t.env());
709cdf0e10cSrcweir 
710cdf0e10cSrcweir                     loadClass(
711cdf0e10cSrcweir                         m_pDriver->getContext().getUNOContext(),
712cdf0e10cSrcweir                         t.env(), _sDriverClassPath, _sDriverClass, &driverClassLoader, &driverClass );
713cdf0e10cSrcweir 
714cdf0e10cSrcweir                     m_pDriverClassLoader.set( driverClassLoader );
715cdf0e10cSrcweir                     pDrvClass.reset( new java_lang_Class( t.pEnv, driverClass.release() ) );
716cdf0e10cSrcweir 
717cdf0e10cSrcweir                     ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
718cdf0e10cSrcweir                 }
719cdf0e10cSrcweir                 if ( pDrvClass.get() )
720cdf0e10cSrcweir                 {
721cdf0e10cSrcweir                     LocalRef< jobject > driverObject( t.env() );
722cdf0e10cSrcweir                     driverObject.set( pDrvClass->newInstanceObject() );
723cdf0e10cSrcweir                     ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
724cdf0e10cSrcweir                     m_pDriverobject = driverObject.release();
725cdf0e10cSrcweir 
726cdf0e10cSrcweir                     if( t.pEnv && m_pDriverobject )
727cdf0e10cSrcweir                         m_pDriverobject = t.pEnv->NewGlobalRef( m_pDriverobject );
728cdf0e10cSrcweir 
729cdf0e10cSrcweir                     {
730cdf0e10cSrcweir                         jclass tempClass = t.pEnv->GetObjectClass(m_pDriverobject);
731cdf0e10cSrcweir                         if ( m_pDriverobject )
732cdf0e10cSrcweir                         {
733cdf0e10cSrcweir                             m_Driver_theClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
734cdf0e10cSrcweir                             t.pEnv->DeleteLocalRef( tempClass );
735cdf0e10cSrcweir                         }
736cdf0e10cSrcweir                     }
737cdf0e10cSrcweir                 }
738cdf0e10cSrcweir                 m_aLogger.log( LogLevel::INFO, STR_LOG_CONN_SUCCESS );
739cdf0e10cSrcweir             }
740cdf0e10cSrcweir         }
741cdf0e10cSrcweir 	}
742cdf0e10cSrcweir     catch( const SQLException& e )
743cdf0e10cSrcweir 	{
744cdf0e10cSrcweir 		throw SQLException(
745cdf0e10cSrcweir             lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
746cdf0e10cSrcweir             *this,
747cdf0e10cSrcweir             ::rtl::OUString(),
748cdf0e10cSrcweir             1000,
749cdf0e10cSrcweir             makeAny(e)
750cdf0e10cSrcweir         );
751cdf0e10cSrcweir 	}
752cdf0e10cSrcweir 	catch( Exception& )
753cdf0e10cSrcweir 	{
754cdf0e10cSrcweir 		::dbtools::throwGenericSQLException(
755cdf0e10cSrcweir             lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
756cdf0e10cSrcweir             *this
757cdf0e10cSrcweir         );
758cdf0e10cSrcweir 	}
759cdf0e10cSrcweir 
760cdf0e10cSrcweir 	enableAutoRetrievingEnabled( bAutoRetrievingEnabled );
761cdf0e10cSrcweir 	setAutoRetrievingStatement( sGeneratedValueStatement );
762cdf0e10cSrcweir }
763cdf0e10cSrcweir // -----------------------------------------------------------------------------
impl_getJavaDriverClassPath_nothrow(const::rtl::OUString & _sDriverClass)764cdf0e10cSrcweir ::rtl::OUString java_sql_Connection::impl_getJavaDriverClassPath_nothrow(const ::rtl::OUString& _sDriverClass)
765cdf0e10cSrcweir {
766cdf0e10cSrcweir     static const ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/JDBC/DriverClassPaths"));
767cdf0e10cSrcweir     ::utl::OConfigurationTreeRoot aNamesRoot = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
768cdf0e10cSrcweir         m_pDriver->getContext().getLegacyServiceFactory(), s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
769cdf0e10cSrcweir     ::rtl::OUString sURL;
770cdf0e10cSrcweir     if ( aNamesRoot.isValid() && aNamesRoot.hasByName( _sDriverClass ) )
771cdf0e10cSrcweir     {
772cdf0e10cSrcweir         ::utl::OConfigurationNode aRegisterObj = aNamesRoot.openNode( _sDriverClass );
773cdf0e10cSrcweir         OSL_VERIFY( aRegisterObj.getNodeValue( "Path" ) >>= sURL );
774cdf0e10cSrcweir     }
775cdf0e10cSrcweir     return sURL;
776cdf0e10cSrcweir }
777cdf0e10cSrcweir // -----------------------------------------------------------------------------
construct(const::rtl::OUString & url,const Sequence<PropertyValue> & info)778cdf0e10cSrcweir sal_Bool java_sql_Connection::construct(const ::rtl::OUString& url,
779cdf0e10cSrcweir 									const Sequence< PropertyValue >& info)
780cdf0e10cSrcweir {
781cdf0e10cSrcweir 	{ // initialize the java vm
782cdf0e10cSrcweir 		::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM(getORB());
783cdf0e10cSrcweir 		if ( !xTest.is() )
784cdf0e10cSrcweir             throwGenericSQLException(STR_NO_JAVA,*this);
785cdf0e10cSrcweir 	}
786cdf0e10cSrcweir 	SDBThreadAttach t;
787cdf0e10cSrcweir 	t.addRef();		 // will be released in dtor
788cdf0e10cSrcweir 	if ( !t.pEnv )
789cdf0e10cSrcweir 		throwGenericSQLException(STR_NO_JAVA,*this);
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 	::rtl::OUString		sGeneratedValueStatement; // contains the statement which should be used when query for automatically generated values
792cdf0e10cSrcweir 	sal_Bool			bAutoRetrievingEnabled = sal_False; // set to <TRUE/> when we should allow to query for generated values
793cdf0e10cSrcweir     ::rtl::OUString sDriverClassPath,sDriverClass;
794cdf0e10cSrcweir     Sequence< NamedValue > aSystemProperties;
795cdf0e10cSrcweir 
796cdf0e10cSrcweir     ::comphelper::NamedValueCollection aSettings( info );
797cdf0e10cSrcweir     sDriverClass = aSettings.getOrDefault( "JavaDriverClass", sDriverClass );
798cdf0e10cSrcweir     sDriverClassPath = aSettings.getOrDefault( "JavaDriverClassPath", sDriverClassPath);
799cdf0e10cSrcweir     if ( !sDriverClassPath.getLength() )
800cdf0e10cSrcweir         sDriverClassPath = impl_getJavaDriverClassPath_nothrow(sDriverClass);
801cdf0e10cSrcweir     bAutoRetrievingEnabled = aSettings.getOrDefault( "IsAutoRetrievingEnabled", bAutoRetrievingEnabled );
802cdf0e10cSrcweir     sGeneratedValueStatement = aSettings.getOrDefault( "AutoRetrievingStatement", sGeneratedValueStatement );
803cdf0e10cSrcweir     m_bParameterSubstitution = aSettings.getOrDefault( "ParameterNameSubstitution", m_bParameterSubstitution );
804cdf0e10cSrcweir     m_bIgnoreDriverPrivileges = aSettings.getOrDefault( "IgnoreDriverPrivileges", m_bIgnoreDriverPrivileges );
805cdf0e10cSrcweir     m_bIgnoreCurrency = aSettings.getOrDefault( "IgnoreCurrency", m_bIgnoreCurrency );
806cdf0e10cSrcweir     aSystemProperties = aSettings.getOrDefault( "SystemProperties", aSystemProperties );
807cdf0e10cSrcweir     m_aCatalogRestriction = aSettings.getOrDefault( "ImplicitCatalogRestriction", Any() );
808cdf0e10cSrcweir     m_aSchemaRestriction = aSettings.getOrDefault( "ImplicitSchemaRestriction", Any() );
809cdf0e10cSrcweir 
810cdf0e10cSrcweir     loadDriverFromProperties( sDriverClass, sDriverClassPath, aSystemProperties );
811cdf0e10cSrcweir 
812cdf0e10cSrcweir 	enableAutoRetrievingEnabled(bAutoRetrievingEnabled);
813cdf0e10cSrcweir 	setAutoRetrievingStatement(sGeneratedValueStatement);
814cdf0e10cSrcweir 
815cdf0e10cSrcweir 	if ( t.pEnv && m_Driver_theClass && m_pDriverobject )
816cdf0e10cSrcweir 	{
817cdf0e10cSrcweir 		// temporaere Variable initialisieren
818cdf0e10cSrcweir 		static const char * cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
819cdf0e10cSrcweir 		static const char * cMethodName = "connect";
820cdf0e10cSrcweir 		// Java-Call absetzen
821cdf0e10cSrcweir 		jmethodID mID = NULL;
822cdf0e10cSrcweir         if ( !mID  )
823cdf0e10cSrcweir             mID  = t.pEnv->GetMethodID( m_Driver_theClass, cMethodName, cSignature );
824cdf0e10cSrcweir         if ( mID )
825cdf0e10cSrcweir 		{
826cdf0e10cSrcweir 			jvalue args[2];
827cdf0e10cSrcweir 			// Parameter konvertieren
828cdf0e10cSrcweir 			args[0].l = convertwchar_tToJavaString(t.pEnv,url);
829cdf0e10cSrcweir 			java_util_Properties* pProps = createStringPropertyArray(info);
830cdf0e10cSrcweir 			args[1].l = pProps->getJavaObject();
831cdf0e10cSrcweir 
832cdf0e10cSrcweir             LocalRef< jobject > ensureDelete( t.env(), args[0].l );
833cdf0e10cSrcweir 
834cdf0e10cSrcweir             jobject out = NULL;
835cdf0e10cSrcweir             // In some cases (e.g.,
836cdf0e10cSrcweir             // connectivity/source/drivers/hsqldb/HDriver.cxx:1.24
837cdf0e10cSrcweir             // l. 249) the JavaDriverClassPath contains multiple jars,
838cdf0e10cSrcweir             // as creating the JavaDriverClass instance requires
839cdf0e10cSrcweir             // (reflective) access to those other jars.  Now, if the
840cdf0e10cSrcweir             // JavaDriverClass is actually loaded by some parent class
841cdf0e10cSrcweir             // loader (e.g., because its jar is also on the global
842cdf0e10cSrcweir             // class path), it would still not have access to the
843cdf0e10cSrcweir             // additional jars on the JavaDriverClassPath.  Hence, the
844cdf0e10cSrcweir             // JavaDriverClassPath class loader is pushed as context
845cdf0e10cSrcweir             // class loader around the JavaDriverClass instance
846cdf0e10cSrcweir             // creation:
847cdf0e10cSrcweir             // #i82222# / 2007-10-15
848cdf0e10cSrcweir             {
849cdf0e10cSrcweir                 ContextClassLoaderScope ccl( t.env(), getDriverClassLoader(), getLogger(), *this );
850cdf0e10cSrcweir                 out = t.pEnv->CallObjectMethod( m_pDriverobject, mID, args[0].l,args[1].l );
851cdf0e10cSrcweir                 delete pProps, pProps = NULL;
852cdf0e10cSrcweir                 ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
853cdf0e10cSrcweir             }
854cdf0e10cSrcweir 
855cdf0e10cSrcweir             if ( !out )
856cdf0e10cSrcweir                 m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_SYSTEM_CONNECTION );
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 			if ( out )
859cdf0e10cSrcweir 				object = t.pEnv->NewGlobalRef( out );
860cdf0e10cSrcweir 
861cdf0e10cSrcweir             if ( object )
862cdf0e10cSrcweir                 m_aLogger.log( LogLevel::INFO, STR_LOG_GOT_JDBC_CONNECTION, url );
863cdf0e10cSrcweir 
864cdf0e10cSrcweir             m_aConnectionInfo = info;
865cdf0e10cSrcweir 		} //mID
866cdf0e10cSrcweir 	} //t.pEnv
867cdf0e10cSrcweir 	 return object != NULL;
868cdf0e10cSrcweir }
869cdf0e10cSrcweir // -----------------------------------------------------------------------------
870