bump product version to 7.2.5.1
[LibreOffice.git] / connectivity / source / drivers / jdbc / Object.cxx
blobb2dd83168e5e0b3e8f8b7ae02d3b3bbc66681945
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <connectivity/CommonTools.hxx>
21 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
22 #include <com/sun/star/logging/LogLevel.hpp>
23 #include <java/tools.hxx>
24 #include <java/sql/SQLException.hxx>
25 #include <osl/diagnose.h>
26 #include <java/LocalRef.hxx>
27 #include <strings.hxx>
29 #include <comphelper/logging.hxx>
30 #include <cppuhelper/exc_hlp.hxx>
32 #include <memory>
34 using namespace connectivity;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::beans;
37 using namespace ::com::sun::star::sdbc;
38 using namespace ::com::sun::star::container;
39 using namespace ::com::sun::star::lang;
42 static ::rtl::Reference< jvmaccess::VirtualMachine > const & getJavaVM2(const ::rtl::Reference< jvmaccess::VirtualMachine >& _rVM = ::rtl::Reference< jvmaccess::VirtualMachine >(),
43 bool _bSet = false)
45 static ::rtl::Reference< jvmaccess::VirtualMachine > s_VM;
46 if ( _rVM.is() || _bSet )
47 s_VM = _rVM;
48 return s_VM;
51 ::rtl::Reference< jvmaccess::VirtualMachine > java_lang_Object::getVM(const Reference<XComponentContext >& _rxContext)
53 ::rtl::Reference< jvmaccess::VirtualMachine > xVM = getJavaVM2();
54 if ( !xVM.is() && _rxContext.is() )
55 xVM = getJavaVM2(::connectivity::getJavaVM(_rxContext));
57 return xVM;
60 SDBThreadAttach::SDBThreadAttach()
61 : m_aGuard(java_lang_Object::getVM())
62 , pEnv(nullptr)
64 pEnv = m_aGuard.getEnvironment();
65 OSL_ENSURE(pEnv,"Environment is nULL!");
68 SDBThreadAttach::~SDBThreadAttach()
72 static oslInterlockedCount& getJavaVMRefCount()
74 static oslInterlockedCount s_nRefCount = 0;
75 return s_nRefCount;
78 void SDBThreadAttach::addRef()
80 osl_atomic_increment(&getJavaVMRefCount());
83 void SDBThreadAttach::releaseRef()
85 osl_atomic_decrement(&getJavaVMRefCount());
86 if ( getJavaVMRefCount() == 0 )
88 getJavaVM2(::rtl::Reference< jvmaccess::VirtualMachine >(),true);
92 // static variables of the class
93 jclass java_lang_Object::theClass = nullptr;
95 jclass java_lang_Object::getMyClass() const
97 if( !theClass )
98 theClass = findMyClass("java/lang/Object");
99 return theClass;
101 // the actual constructor
102 java_lang_Object::java_lang_Object()
103 : object( nullptr )
105 SDBThreadAttach::addRef();
108 // the protected-constructor for the derived classes
109 java_lang_Object::java_lang_Object( JNIEnv * pXEnv, jobject myObj )
110 : object( nullptr )
112 SDBThreadAttach::addRef();
113 if( pXEnv && myObj )
114 object = pXEnv->NewGlobalRef( myObj );
117 java_lang_Object::~java_lang_Object() COVERITY_NOEXCEPT_FALSE
119 if( object )
121 SDBThreadAttach t;
122 clearObject(*t.pEnv);
124 SDBThreadAttach::releaseRef();
126 void java_lang_Object::clearObject(JNIEnv& rEnv)
128 if( object )
130 rEnv.DeleteGlobalRef( object );
131 object = nullptr;
135 void java_lang_Object::clearObject()
137 if( object )
139 SDBThreadAttach t;
140 clearObject(*t.pEnv);
143 // the protected-constructor for the derived classes
144 void java_lang_Object::saveRef( JNIEnv * pXEnv, jobject myObj )
146 OSL_ENSURE( myObj, "object in c++ -> Java Wrapper" );
147 if( myObj )
148 object = pXEnv->NewGlobalRef( myObj );
152 OUString java_lang_Object::toString() const
154 static jmethodID mID(nullptr);
155 return callStringMethod("toString",mID);
159 namespace
161 bool lcl_translateJNIExceptionToUNOException(
162 JNIEnv* _pEnvironment, const Reference< XInterface >& _rxContext, SQLException& _out_rException )
164 jthrowable jThrow = _pEnvironment ? _pEnvironment->ExceptionOccurred() : nullptr;
165 if ( !jThrow )
166 return false;
168 _pEnvironment->ExceptionClear();
169 // we have to clear the exception here because we want to handle it itself
171 if ( _pEnvironment->IsInstanceOf( jThrow, java_sql_SQLException_BASE::st_getMyClass() ) )
173 java_sql_SQLException_BASE aException( _pEnvironment, jThrow );
174 _out_rException = SQLException( aException.getMessage(), _rxContext,
175 aException.getSQLState(), aException.getErrorCode(), Any() );
176 return true;
178 else if ( _pEnvironment->IsInstanceOf( jThrow, java_lang_Throwable::st_getMyClass() ) )
180 java_lang_Throwable aThrow( _pEnvironment, jThrow );
181 #if OSL_DEBUG_LEVEL > 0
182 aThrow.printStackTrace();
183 #endif
184 OUString sMessage = aThrow.getMessage();
185 if ( sMessage.isEmpty() )
186 sMessage = aThrow.getLocalizedMessage();
187 if( sMessage.isEmpty() )
188 sMessage = aThrow.toString();
189 _out_rException = SQLException( sMessage, _rxContext, OUString(), -1, Any() );
190 return true;
192 else
193 _pEnvironment->DeleteLocalRef( jThrow );
194 return false;
199 void java_lang_Object::ThrowLoggedSQLException( const ::comphelper::EventLogger& _rLogger, JNIEnv* _pEnvironment,
200 const Reference< XInterface >& _rxContext )
202 SQLException aException;
203 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
205 _rLogger.log( css::logging::LogLevel::SEVERE, STR_LOG_THROWING_EXCEPTION, aException.Message, aException.SQLState, aException.ErrorCode );
206 throw aException;
210 void java_lang_Object::ThrowSQLException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
212 SQLException aException;
213 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
214 throw aException;
217 void java_lang_Object::ThrowRuntimeException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
221 ThrowSQLException(_pEnvironment, _rxContext);
223 catch (const SQLException& e)
225 css::uno::Any anyEx = cppu::getCaughtException();
226 throw css::lang::WrappedTargetRuntimeException( e.Message,
227 e.Context, anyEx );
231 void java_lang_Object::obtainMethodId_throwSQL(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
233 if ( !_inout_MethodID )
235 _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
236 OSL_ENSURE( _inout_MethodID, _pSignature );
237 if ( !_inout_MethodID )
238 throw SQLException();
239 } // if ( !_inout_MethodID )
242 void java_lang_Object::obtainMethodId_throwRuntime(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
244 if ( !_inout_MethodID )
246 _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
247 OSL_ENSURE( _inout_MethodID, _pSignature );
248 if ( !_inout_MethodID )
249 throw RuntimeException();
250 } // if ( !_inout_MethodID )
254 bool java_lang_Object::callBooleanMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
256 bool out( false );
258 SDBThreadAttach t;
259 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethod: no Java environment anymore!" );
260 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()Z", _inout_MethodID);
261 // call method
262 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID );
263 ThrowSQLException( t.pEnv, nullptr );
265 return out;
268 bool java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
270 bool out( false );
271 SDBThreadAttach t;
272 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethodWithIntArg: no Java environment anymore!" );
273 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)Z", _inout_MethodID);
274 // call method
275 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID, _nArgument );
276 ThrowSQLException( t.pEnv, nullptr );
278 return out;
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;
288 sal_Int32 java_lang_Object::callIntMethod_ThrowSQL(const char* _pMethodName, jmethodID& _inout_MethodID) const
290 SDBThreadAttach t;
291 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
292 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()I", _inout_MethodID);
293 // call method
294 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
295 ThrowSQLException( t.pEnv, nullptr );
296 return static_cast<sal_Int32>(out);
299 sal_Int32 java_lang_Object::callIntMethod_ThrowRuntime(const char* _pMethodName, jmethodID& _inout_MethodID) const
301 SDBThreadAttach t;
302 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
303 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"()I", _inout_MethodID);
304 // call method
305 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
306 ThrowRuntimeException(t.pEnv, nullptr);
307 return static_cast<sal_Int32>(out);
310 sal_Int32 java_lang_Object::callIntMethodWithIntArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
312 SDBThreadAttach t;
313 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
314 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
315 // call method
316 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
317 ThrowSQLException( t.pEnv, nullptr );
318 return static_cast<sal_Int32>(out);
321 sal_Int32 java_lang_Object::callIntMethodWithIntArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
323 SDBThreadAttach t;
324 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
325 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
326 // call method
327 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
328 ThrowRuntimeException(t.pEnv, nullptr);
329 return static_cast<sal_Int32>(out);
332 void java_lang_Object::callVoidMethod_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID) const
334 SDBThreadAttach t;
335 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
336 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()V", _inout_MethodID);
338 // call method
339 t.pEnv->CallVoidMethod( object, _inout_MethodID );
340 ThrowSQLException( t.pEnv, nullptr );
343 void java_lang_Object::callVoidMethod_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID) const
345 SDBThreadAttach t;
346 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
347 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"()V", _inout_MethodID);
349 // call method
350 t.pEnv->CallVoidMethod( object, _inout_MethodID );
351 ThrowRuntimeException(t.pEnv, nullptr);
354 void java_lang_Object::callVoidMethodWithIntArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
356 SDBThreadAttach t;
357 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
358 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
360 // call method
361 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
362 ThrowSQLException( t.pEnv, nullptr );
365 void java_lang_Object::callVoidMethodWithIntArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
367 SDBThreadAttach t;
368 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
369 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
371 // call method
372 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
373 ThrowRuntimeException(t.pEnv, nullptr);
376 void java_lang_Object::callVoidMethodWithBoolArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID, bool _nArgument ) const
378 SDBThreadAttach t;
379 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
380 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
381 // call method
382 t.pEnv->CallVoidMethod( object, _inout_MethodID,int(_nArgument) );
383 ThrowSQLException( t.pEnv, nullptr );
386 void java_lang_Object::callVoidMethodWithBoolArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID, bool _nArgument ) const
388 SDBThreadAttach t;
389 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
390 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
391 // call method
392 t.pEnv->CallVoidMethod( object, _inout_MethodID,int(_nArgument) );
393 ThrowRuntimeException(t.pEnv, nullptr);
396 OUString java_lang_Object::callStringMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
398 SDBThreadAttach t;
399 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java environment anymore!" );
401 // call method
402 jstring out = static_cast<jstring>(callObjectMethod(t.pEnv,_pMethodName,"()Ljava/lang/String;", _inout_MethodID));
403 return JavaString2String( t.pEnv, out );
406 jobject java_lang_Object::callObjectMethod( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID ) const
408 // obtain method ID
409 obtainMethodId_throwSQL(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
410 // call method
411 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID);
412 ThrowSQLException( _pEnv, nullptr );
413 return out;
417 jobject java_lang_Object::callObjectMethodWithIntArg( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
419 obtainMethodId_throwSQL(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
420 // call method
421 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID,_nArgument );
422 ThrowSQLException( _pEnv, nullptr );
423 return out;
426 OUString java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
428 SDBThreadAttach t;
429 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java environment anymore!" );
430 jstring out = static_cast<jstring>(callObjectMethodWithIntArg(t.pEnv,_pMethodName,"(I)Ljava/lang/String;",_inout_MethodID,_nArgument));
431 return JavaString2String( t.pEnv, out );
434 void java_lang_Object::callVoidMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const OUString& _nArgument ) const
436 SDBThreadAttach t;
437 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
438 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Ljava/lang/String;)V", _inout_MethodID);
440 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
441 // call method
442 t.pEnv->CallVoidMethod( object, _inout_MethodID , str.get());
443 ThrowSQLException( t.pEnv, nullptr );
446 sal_Int32 java_lang_Object::callIntMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const OUString& _nArgument ) const
448 SDBThreadAttach t;
449 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethodWithStringArg: no Java environment anymore!" );
450 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Ljava/lang/String;)I", _inout_MethodID);
452 //TODO: Check if the code below is needed
453 //jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
455 // jdbc::ContextClassLoaderScope ccl( t.env(),
456 // m_pConnection ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
457 // m_aLogger,
458 // *this
459 // );
461 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
462 // call method
463 jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str.get());
464 ThrowSQLException( t.pEnv, nullptr );
465 return static_cast<sal_Int32>(out);
468 jclass java_lang_Object::findMyClass(const char* _pClassName)
470 // the class must be fetched only once, therefore static
471 SDBThreadAttach t;
472 jclass tempClass = t.pEnv->FindClass(_pClassName); OSL_ENSURE(tempClass,"Java : FindClass not successful!");
473 if(!tempClass)
475 t.pEnv->ExceptionDescribe();
476 t.pEnv->ExceptionClear();
478 jclass globClass = static_cast<jclass>(t.pEnv->NewGlobalRef( tempClass ));
479 t.pEnv->DeleteLocalRef( tempClass );
480 return globClass;
483 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */