Update ooo320-m1
[ooovba.git] / connectivity / source / drivers / jdbc / Object.cxx
blobb8e8c87954fe519db827fcd95e73ecaefedb590e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Object.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
35 #ifndef _CONNECTIVITY_JAVA_LANG_OBJJECT_HXX_
36 #include "java/lang/Class.hxx"
37 #endif
38 #include "connectivity/CommonTools.hxx"
39 #include <com/sun/star/uno/Exception.hpp>
40 #include "java/tools.hxx"
41 #include "java/sql/SQLException.hxx"
42 #include <vos/process.hxx>
43 #include <vos/mutex.hxx>
44 #include <osl/thread.h>
45 #include <com/sun/star/uno/Sequence.hxx>
47 #include "resource/jdbc_log.hrc"
48 #include <rtl/logfile.hxx>
49 #include <comphelper/logging.hxx>
51 #include <memory>
53 using namespace connectivity;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::beans;
56 using namespace ::com::sun::star::sdbc;
57 using namespace ::com::sun::star::container;
58 using namespace ::com::sun::star::lang;
61 // -----------------------------------------------------------------------------
62 ::rtl::Reference< jvmaccess::VirtualMachine > getJavaVM2(const ::rtl::Reference< jvmaccess::VirtualMachine >& _rVM = ::rtl::Reference< jvmaccess::VirtualMachine >(),
63 sal_Bool _bSet = sal_False)
65 static ::rtl::Reference< jvmaccess::VirtualMachine > s_VM;
66 if ( _rVM.is() || _bSet )
67 s_VM = _rVM;
68 return s_VM;
70 // -----------------------------------------------------------------------------
71 ::rtl::Reference< jvmaccess::VirtualMachine > java_lang_Object::getVM(const Reference<XMultiServiceFactory >& _rxFactory)
73 ::rtl::Reference< jvmaccess::VirtualMachine > xVM = getJavaVM2();
74 if ( !xVM.is() && _rxFactory.is() )
75 xVM = getJavaVM2(::connectivity::getJavaVM(_rxFactory));
77 return xVM;
79 // -----------------------------------------------------------------------------
80 SDBThreadAttach::SDBThreadAttach()
81 : m_aGuard(java_lang_Object::getVM())
82 , pEnv(NULL)
84 pEnv = m_aGuard.getEnvironment();
85 OSL_ENSURE(pEnv,"Environment is nULL!");
87 // -----------------------------------------------------------------------------
88 SDBThreadAttach::~SDBThreadAttach()
91 // -----------------------------------------------------------------------------
92 oslInterlockedCount& getJavaVMRefCount()
94 static oslInterlockedCount s_nRefCount = 0;
95 return s_nRefCount;
97 // -----------------------------------------------------------------------------
98 void SDBThreadAttach::addRef()
100 osl_incrementInterlockedCount(&getJavaVMRefCount());
102 // -----------------------------------------------------------------------------
103 void SDBThreadAttach::releaseRef()
105 osl_decrementInterlockedCount(&getJavaVMRefCount());
106 if ( getJavaVMRefCount() == 0 )
108 getJavaVM2(::rtl::Reference< jvmaccess::VirtualMachine >(),sal_True);
111 // -----------------------------------------------------------------------------
112 // statische Variablen der Klasse:
113 jclass java_lang_Object::theClass = 0;
115 jclass java_lang_Object::getMyClass() const
117 if( !theClass )
118 theClass = findMyClass("java/lang/Object");
119 return theClass;
121 // der eigentliche Konstruktor
122 java_lang_Object::java_lang_Object(const Reference<XMultiServiceFactory >& _rxFactory)
123 : m_xFactory(_rxFactory),object( 0 )
125 SDBThreadAttach::addRef();
128 // der protected-Konstruktor fuer abgeleitete Klassen
129 java_lang_Object::java_lang_Object( JNIEnv * pXEnv, jobject myObj )
130 : object( NULL )
132 SDBThreadAttach::addRef();
133 if( pXEnv && myObj )
134 object = pXEnv->NewGlobalRef( myObj );
137 java_lang_Object::~java_lang_Object()
139 if( object )
141 SDBThreadAttach t;
142 clearObject(*t.pEnv);
144 SDBThreadAttach::releaseRef();
146 void java_lang_Object::clearObject(JNIEnv& rEnv)
148 if( object )
150 rEnv.DeleteGlobalRef( object );
151 object = NULL;
155 void java_lang_Object::clearObject()
157 if( object )
159 SDBThreadAttach t;
160 clearObject(*t.pEnv);
163 // der protected-Konstruktor fuer abgeleitete Klassen
164 void java_lang_Object::saveRef( JNIEnv * pXEnv, jobject myObj )
166 OSL_ENSURE( myObj, "object in c++ -> Java Wrapper" );
167 if( myObj )
168 object = pXEnv->NewGlobalRef( myObj );
172 java_lang_Class * java_lang_Object::getClass()
174 SDBThreadAttach t;
175 static jmethodID mID(NULL);
176 jobject out = callObjectMethod(t.pEnv,"getClass","()Ljava/lang/Class;", mID);
177 return out ? new java_lang_Class( t.pEnv, out ) : NULL;
180 ::rtl::OUString java_lang_Object::toString() const
182 static jmethodID mID(NULL);
183 return callStringMethod("toString",mID);
186 // --------------------------------------------------------------------------------
187 namespace
189 bool lcl_translateJNIExceptionToUNOException(
190 JNIEnv* _pEnvironment, const Reference< XInterface >& _rxContext, SQLException& _out_rException )
192 jthrowable jThrow = _pEnvironment ? _pEnvironment->ExceptionOccurred() : NULL;
193 if ( !jThrow )
194 return false;
196 _pEnvironment->ExceptionClear();
197 // we have to clear the exception here because we want to handle it itself
199 if ( _pEnvironment->IsInstanceOf( jThrow, java_sql_SQLException_BASE::st_getMyClass() ) )
201 ::std::auto_ptr< java_sql_SQLException_BASE > pException( new java_sql_SQLException_BASE( _pEnvironment, jThrow ) );
202 _out_rException = SQLException( pException->getMessage(), _rxContext,
203 pException->getSQLState(), pException->getErrorCode(), Any() );
204 return true;
206 else if ( _pEnvironment->IsInstanceOf( jThrow, java_lang_Throwable::st_getMyClass() ) )
208 ::std::auto_ptr< java_lang_Throwable > pThrow( new java_lang_Throwable( _pEnvironment, jThrow ) );
209 ::rtl::OUString sMessage = pThrow->getMessage();
210 if ( !sMessage.getLength() )
211 sMessage = pThrow->getLocalizedMessage();
212 if( !sMessage.getLength() )
213 sMessage = pThrow->toString();
214 _out_rException = SQLException( sMessage, _rxContext, ::rtl::OUString(), -1, Any() );
215 return true;
217 else
218 _pEnvironment->DeleteLocalRef( jThrow );
219 return false;
223 // --------------------------------------------------------------------------------
224 void java_lang_Object::ThrowLoggedSQLException( const ::comphelper::ResourceBasedEventLogger& _rLogger, JNIEnv* _pEnvironment,
225 const Reference< XInterface >& _rxContext )
227 SQLException aException;
228 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
230 _rLogger.log( ::com::sun::star::logging::LogLevel::SEVERE, STR_LOG_THROWING_EXCEPTION, aException.Message, aException.SQLState, aException.ErrorCode );
231 throw aException;
235 // --------------------------------------------------------------------------------
236 void java_lang_Object::ThrowSQLException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
238 SQLException aException;
239 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
240 throw aException;
242 // -----------------------------------------------------------------------------
243 void java_lang_Object::obtainMethodId(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
245 if ( !_inout_MethodID )
247 _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
248 OSL_ENSURE( _inout_MethodID, _pSignature );
249 if ( !_inout_MethodID )
250 throw SQLException();
251 } // if ( !_inout_MethodID )
253 // -----------------------------------------------------------------------------
254 sal_Bool java_lang_Object::callBooleanMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
256 jboolean out( sal_False );
258 SDBThreadAttach t;
259 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethod: no Java enviroment anymore!" );
260 obtainMethodId(t.pEnv, _pMethodName,"()Z", _inout_MethodID);
261 // call method
262 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID );
263 ThrowSQLException( t.pEnv, NULL );
265 return out;
267 // -----------------------------------------------------------------------------
268 sal_Bool java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
270 jboolean out( sal_False );
271 SDBThreadAttach t;
272 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethodWithIntArg: no Java enviroment anymore!" );
273 obtainMethodId(t.pEnv, _pMethodName,"(I)Z", _inout_MethodID);
274 // call method
275 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID, _nArgument );
276 ThrowSQLException( t.pEnv, NULL );
278 return out;
280 // -------------------------------------------------------------------------
281 jobject java_lang_Object::callResultSetMethod( JNIEnv& _rEnv,const char* _pMethodName, jmethodID& _inout_MethodID ) const
283 // call method
284 jobject out = callObjectMethod(&_rEnv,_pMethodName,"()Ljava/sql/ResultSet;", _inout_MethodID);
285 return out;
287 // -------------------------------------------------------------------------
288 sal_Int32 java_lang_Object::callIntMethod( const char* _pMethodName, jmethodID& _inout_MethodID,bool _bIgnoreException ) const
290 SDBThreadAttach t;
291 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
292 obtainMethodId(t.pEnv, _pMethodName,"()I", _inout_MethodID);
294 // call method
295 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
296 if ( _bIgnoreException )
297 isExceptionOccured(t.pEnv,sal_True);
298 else
299 ThrowSQLException( t.pEnv, NULL );
301 return (sal_Int32)out;
303 // -------------------------------------------------------------------------
304 sal_Int32 java_lang_Object::callIntMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
306 SDBThreadAttach t;
307 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
308 obtainMethodId(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
309 // call method
310 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
311 ThrowSQLException( t.pEnv, NULL );
313 return (sal_Int32)out;
315 // -------------------------------------------------------------------------
316 void java_lang_Object::callVoidMethod( const char* _pMethodName, jmethodID& _inout_MethodID) const
318 SDBThreadAttach t;
319 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
320 obtainMethodId(t.pEnv, _pMethodName,"()V", _inout_MethodID);
322 // call method
323 t.pEnv->CallVoidMethod( object, _inout_MethodID );
324 ThrowSQLException( t.pEnv, NULL );
326 // -------------------------------------------------------------------------
327 void java_lang_Object::callVoidMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument,bool _bIgnoreException ) const
329 SDBThreadAttach t;
330 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
331 obtainMethodId(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
333 // call method
334 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
335 if ( _bIgnoreException )
336 isExceptionOccured(t.pEnv,sal_True);
337 else
338 ThrowSQLException( t.pEnv, NULL );
340 // -------------------------------------------------------------------------
341 void java_lang_Object::callVoidMethodWithBoolArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument,bool _bIgnoreException ) const
343 SDBThreadAttach t;
344 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
345 obtainMethodId(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
346 // call method
347 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
348 if ( _bIgnoreException )
349 isExceptionOccured(t.pEnv,sal_True);
350 else
351 ThrowSQLException( t.pEnv, NULL );
353 // -----------------------------------------------------------------------------
354 ::rtl::OUString java_lang_Object::callStringMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
356 SDBThreadAttach t;
357 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java enviroment anymore!" );
359 // call method
360 jstring out = (jstring)callObjectMethod(t.pEnv,_pMethodName,"()Ljava/lang/String;", _inout_MethodID);
361 return JavaString2String( t.pEnv, out );
363 // -----------------------------------------------------------------------------
364 jobject java_lang_Object::callObjectMethod( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID ) const
366 // obtain method ID
367 obtainMethodId(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
368 // call method
369 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID);
370 ThrowSQLException( _pEnv, NULL );
371 return out;
374 // -----------------------------------------------------------------------------
375 jobject java_lang_Object::callObjectMethodWithIntArg( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
377 obtainMethodId(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
378 // call method
379 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID,_nArgument );
380 ThrowSQLException( _pEnv, NULL );
381 return out;
383 // -----------------------------------------------------------------------------
384 ::rtl::OUString java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
386 SDBThreadAttach t;
387 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java enviroment anymore!" );
388 jstring out = (jstring)callObjectMethodWithIntArg(t.pEnv,_pMethodName,"(I)Ljava/lang/String;",_inout_MethodID,_nArgument);
389 return JavaString2String( t.pEnv, out );
391 // -------------------------------------------------------------------------
392 void java_lang_Object::callVoidMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const ::rtl::OUString& _nArgument ) const
394 SDBThreadAttach t;
395 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
396 obtainMethodId(t.pEnv, _pMethodName,"(Ljava/lang/String;)V", _inout_MethodID);
398 jstring str = convertwchar_tToJavaString(t.pEnv,_nArgument);
399 // call method
400 t.pEnv->CallVoidMethod( object, _inout_MethodID , str);
401 t.pEnv->DeleteLocalRef(str);
402 ThrowSQLException( t.pEnv, NULL );
404 // -------------------------------------------------------------------------
405 sal_Int32 java_lang_Object::callIntMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const ::rtl::OUString& _nArgument ) const
407 SDBThreadAttach t;
408 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethodWithStringArg: no Java enviroment anymore!" );
409 obtainMethodId(t.pEnv, _pMethodName,"(Ljava/lang/String;)I", _inout_MethodID);
411 //TODO: Check if the code below is needed
412 //jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
414 // jdbc::ContextClassLoaderScope ccl( t.env(),
415 // m_pConnection ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
416 // m_aLogger,
417 // *this
418 // );
420 jstring str = convertwchar_tToJavaString(t.pEnv,_nArgument);
421 // call method
422 jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str);
423 t.pEnv->DeleteLocalRef(str);
424 ThrowSQLException( t.pEnv, NULL );
425 return (sal_Int32)out;
427 // -----------------------------------------------------------------------------
428 jclass java_lang_Object::findMyClass(const char* _pClassName)
430 // die Klasse muss nur einmal geholt werden, daher statisch
431 SDBThreadAttach t;
432 jclass tempClass = t.pEnv->FindClass(_pClassName); OSL_ENSURE(tempClass,"Java : FindClass nicht erfolgreich!");
433 if(!tempClass)
435 t.pEnv->ExceptionDescribe();
436 t.pEnv->ExceptionClear();
438 jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
439 t.pEnv->DeleteLocalRef( tempClass );
440 return globClass;