cid#1636677 Uninitialized scalar field
[LibreOffice.git] / connectivity / source / drivers / jdbc / Object.cxx
blob65d6680d745e5941293b687f01962c4e98ad41b3
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 using namespace connectivity;
33 using namespace ::com::sun::star::uno;
34 using namespace ::com::sun::star::sdbc;
35 using namespace ::com::sun::star::lang;
38 static ::rtl::Reference< jvmaccess::VirtualMachine > const & getJavaVM2(const ::rtl::Reference< jvmaccess::VirtualMachine >& _rVM = ::rtl::Reference< jvmaccess::VirtualMachine >(),
39 bool _bSet = false)
41 static ::rtl::Reference< jvmaccess::VirtualMachine > s_VM;
42 if ( _rVM.is() || _bSet )
43 s_VM = _rVM;
44 return s_VM;
47 ::rtl::Reference< jvmaccess::VirtualMachine > java_lang_Object::getVM(const Reference<XComponentContext >& _rxContext)
49 ::rtl::Reference< jvmaccess::VirtualMachine > xVM = getJavaVM2();
50 if ( !xVM.is() && _rxContext.is() )
51 xVM = getJavaVM2(::connectivity::getJavaVM(_rxContext));
53 return xVM;
56 SDBThreadAttach::SDBThreadAttach()
57 : m_aGuard(java_lang_Object::getVM())
58 , pEnv(nullptr)
60 pEnv = m_aGuard.getEnvironment();
61 OSL_ENSURE(pEnv,"Environment is nULL!");
64 SDBThreadAttach::~SDBThreadAttach()
68 static oslInterlockedCount& getJavaVMRefCount()
70 static oslInterlockedCount s_nRefCount = 0;
71 return s_nRefCount;
74 void SDBThreadAttach::addRef()
76 osl_atomic_increment(&getJavaVMRefCount());
79 void SDBThreadAttach::releaseRef()
81 osl_atomic_decrement(&getJavaVMRefCount());
82 if ( getJavaVMRefCount() == 0 )
84 getJavaVM2(::rtl::Reference< jvmaccess::VirtualMachine >(),true);
88 // static variables of the class
89 jclass java_lang_Object::theClass = nullptr;
91 jclass java_lang_Object::getMyClass() const
93 if( !theClass )
94 theClass = findMyClass("java/lang/Object");
95 return theClass;
97 // the actual constructor
98 java_lang_Object::java_lang_Object()
99 : object( nullptr )
101 SDBThreadAttach::addRef();
104 // the protected-constructor for the derived classes
105 java_lang_Object::java_lang_Object( JNIEnv * pXEnv, jobject myObj )
106 : object( nullptr )
108 SDBThreadAttach::addRef();
109 if( pXEnv && myObj )
110 object = pXEnv->NewGlobalRef( myObj );
113 java_lang_Object::~java_lang_Object() COVERITY_NOEXCEPT_FALSE
115 if( object )
117 SDBThreadAttach t;
118 clearObject(*t.pEnv);
120 SDBThreadAttach::releaseRef();
122 void java_lang_Object::clearObject(JNIEnv& rEnv)
124 if( object )
126 rEnv.DeleteGlobalRef( object );
127 object = nullptr;
131 void java_lang_Object::clearObject()
133 if( object )
135 SDBThreadAttach t;
136 clearObject(*t.pEnv);
139 // the protected-constructor for the derived classes
140 void java_lang_Object::saveRef( JNIEnv * pXEnv, jobject myObj )
142 OSL_ENSURE( myObj, "object in c++ -> Java Wrapper" );
143 if( myObj )
144 object = pXEnv->NewGlobalRef( myObj );
148 OUString java_lang_Object::toString() const
150 static jmethodID mID(nullptr);
151 return callStringMethod("toString",mID);
155 namespace
157 bool lcl_translateJNIExceptionToUNOException(
158 JNIEnv* _pEnvironment, const Reference< XInterface >& _rxContext, SQLException& _out_rException )
160 jthrowable jThrow = _pEnvironment ? _pEnvironment->ExceptionOccurred() : nullptr;
161 if ( !jThrow )
162 return false;
164 _pEnvironment->ExceptionClear();
165 // we have to clear the exception here because we want to handle it itself
167 if ( _pEnvironment->IsInstanceOf( jThrow, java_sql_SQLException_BASE::st_getMyClass() ) )
169 java_sql_SQLException_BASE aException( _pEnvironment, jThrow );
170 _out_rException = SQLException( aException.getMessage(), _rxContext,
171 aException.getSQLState(), aException.getErrorCode(), Any() );
172 return true;
174 else if ( _pEnvironment->IsInstanceOf( jThrow, java_lang_Throwable::st_getMyClass() ) )
176 java_lang_Throwable aThrow( _pEnvironment, jThrow );
177 #if OSL_DEBUG_LEVEL > 0
178 aThrow.printStackTrace();
179 #endif
180 OUString sMessage = aThrow.getMessage();
181 if ( sMessage.isEmpty() )
182 sMessage = aThrow.getLocalizedMessage();
183 if( sMessage.isEmpty() )
184 sMessage = aThrow.toString();
185 _out_rException = SQLException( sMessage, _rxContext, OUString(), -1, Any() );
186 return true;
188 else
189 _pEnvironment->DeleteLocalRef( jThrow );
190 return false;
195 void java_lang_Object::ThrowLoggedSQLException( const ::comphelper::EventLogger& _rLogger, JNIEnv* _pEnvironment,
196 const Reference< XInterface >& _rxContext )
198 SQLException aException;
199 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
201 _rLogger.log( css::logging::LogLevel::SEVERE, STR_LOG_THROWING_EXCEPTION, aException.Message, aException.SQLState, aException.ErrorCode );
202 throw aException;
206 void java_lang_Object::ThrowSQLException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
208 SQLException aException;
209 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
210 throw aException;
213 void java_lang_Object::ThrowRuntimeException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
217 ThrowSQLException(_pEnvironment, _rxContext);
219 catch (const SQLException& e)
221 css::uno::Any anyEx = cppu::getCaughtException();
222 throw css::lang::WrappedTargetRuntimeException( e.Message,
223 e.Context, anyEx );
227 void java_lang_Object::obtainMethodId_throwSQL(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
229 if ( !_inout_MethodID )
231 _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
232 OSL_ENSURE( _inout_MethodID, _pSignature );
233 if ( !_inout_MethodID )
234 throw SQLException();
235 } // if ( !_inout_MethodID )
238 void java_lang_Object::obtainMethodId_throwRuntime(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
240 if ( !_inout_MethodID )
242 _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
243 OSL_ENSURE( _inout_MethodID, _pSignature );
244 if ( !_inout_MethodID )
245 throw RuntimeException();
246 } // if ( !_inout_MethodID )
250 bool java_lang_Object::callBooleanMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
252 bool out( false );
254 SDBThreadAttach t;
255 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethod: no Java environment anymore!" );
256 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()Z", _inout_MethodID);
257 // call method
258 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID );
259 ThrowSQLException( t.pEnv, nullptr );
261 return out;
264 bool java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
266 bool out( false );
267 SDBThreadAttach t;
268 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethodWithIntArg: no Java environment anymore!" );
269 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)Z", _inout_MethodID);
270 // call method
271 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID, _nArgument );
272 ThrowSQLException( t.pEnv, nullptr );
274 return out;
277 jobject java_lang_Object::callResultSetMethod( JNIEnv& _rEnv,const char* _pMethodName, jmethodID& _inout_MethodID ) const
279 // call method
280 jobject out = callObjectMethod(&_rEnv,_pMethodName,"()Ljava/sql/ResultSet;", _inout_MethodID);
281 return out;
284 sal_Int32 java_lang_Object::callIntMethod_ThrowSQL(const char* _pMethodName, jmethodID& _inout_MethodID) const
286 SDBThreadAttach t;
287 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
288 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()I", _inout_MethodID);
289 // call method
290 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
291 ThrowSQLException( t.pEnv, nullptr );
292 return static_cast<sal_Int32>(out);
295 sal_Int32 java_lang_Object::callIntMethod_ThrowRuntime(const char* _pMethodName, jmethodID& _inout_MethodID) const
297 SDBThreadAttach t;
298 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
299 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"()I", _inout_MethodID);
300 // call method
301 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
302 ThrowRuntimeException(t.pEnv, nullptr);
303 return static_cast<sal_Int32>(out);
306 sal_Int32 java_lang_Object::callIntMethodWithIntArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
308 SDBThreadAttach t;
309 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
310 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
311 // call method
312 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
313 ThrowSQLException( t.pEnv, nullptr );
314 return static_cast<sal_Int32>(out);
317 sal_Int32 java_lang_Object::callIntMethodWithIntArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
319 SDBThreadAttach t;
320 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
321 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
322 // call method
323 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
324 ThrowRuntimeException(t.pEnv, nullptr);
325 return static_cast<sal_Int32>(out);
328 void java_lang_Object::callVoidMethod_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID) const
330 SDBThreadAttach t;
331 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
332 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()V", _inout_MethodID);
334 // call method
335 t.pEnv->CallVoidMethod( object, _inout_MethodID );
336 ThrowSQLException( t.pEnv, nullptr );
339 void java_lang_Object::callVoidMethod_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID) const
341 SDBThreadAttach t;
342 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
343 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"()V", _inout_MethodID);
345 // call method
346 t.pEnv->CallVoidMethod( object, _inout_MethodID );
347 ThrowRuntimeException(t.pEnv, nullptr);
350 void java_lang_Object::callVoidMethodWithIntArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
352 SDBThreadAttach t;
353 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
354 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
356 // call method
357 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
358 ThrowSQLException( t.pEnv, nullptr );
361 void java_lang_Object::callVoidMethodWithIntArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
363 SDBThreadAttach t;
364 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
365 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
367 // call method
368 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
369 ThrowRuntimeException(t.pEnv, nullptr);
372 void java_lang_Object::callVoidMethodWithBoolArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID, bool _nArgument ) const
374 SDBThreadAttach t;
375 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
376 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
377 // call method
378 t.pEnv->CallVoidMethod( object, _inout_MethodID,int(_nArgument) );
379 ThrowSQLException( t.pEnv, nullptr );
382 void java_lang_Object::callVoidMethodWithBoolArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID, bool _nArgument ) const
384 SDBThreadAttach t;
385 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
386 obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
387 // call method
388 t.pEnv->CallVoidMethod( object, _inout_MethodID,int(_nArgument) );
389 ThrowRuntimeException(t.pEnv, nullptr);
392 OUString java_lang_Object::callStringMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
394 SDBThreadAttach t;
395 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java environment anymore!" );
397 // call method
398 jstring out = static_cast<jstring>(callObjectMethod(t.pEnv,_pMethodName,"()Ljava/lang/String;", _inout_MethodID));
399 return JavaString2String( t.pEnv, out );
402 jobject java_lang_Object::callObjectMethod( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID ) const
404 // obtain method ID
405 obtainMethodId_throwSQL(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
406 // call method
407 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID);
408 ThrowSQLException( _pEnv, nullptr );
409 return out;
413 jobject java_lang_Object::callObjectMethodWithIntArg( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
415 obtainMethodId_throwSQL(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
416 // call method
417 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID,_nArgument );
418 ThrowSQLException( _pEnv, nullptr );
419 return out;
422 OUString java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
424 SDBThreadAttach t;
425 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java environment anymore!" );
426 jstring out = static_cast<jstring>(callObjectMethodWithIntArg(t.pEnv,_pMethodName,"(I)Ljava/lang/String;",_inout_MethodID,_nArgument));
427 return JavaString2String( t.pEnv, out );
430 void java_lang_Object::callVoidMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const OUString& _nArgument ) const
432 SDBThreadAttach t;
433 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
434 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Ljava/lang/String;)V", _inout_MethodID);
436 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
437 // call method
438 t.pEnv->CallVoidMethod( object, _inout_MethodID , str.get());
439 ThrowSQLException( t.pEnv, nullptr );
442 sal_Int32 java_lang_Object::callIntMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const OUString& _nArgument ) const
444 SDBThreadAttach t;
445 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethodWithStringArg: no Java environment anymore!" );
446 obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Ljava/lang/String;)I", _inout_MethodID);
448 //TODO: Check if the code below is needed
449 //jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
451 // jdbc::ContextClassLoaderScope ccl( t.env(),
452 // m_pConnection ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
453 // m_aLogger,
454 // *this
455 // );
457 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
458 // call method
459 jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str.get());
460 ThrowSQLException( t.pEnv, nullptr );
461 return static_cast<sal_Int32>(out);
464 jclass java_lang_Object::findMyClass(const char* _pClassName)
466 // the class must be fetched only once, therefore static
467 SDBThreadAttach t;
468 jclass tempClass = t.pEnv->FindClass(_pClassName); OSL_ENSURE(tempClass,"Java : FindClass not successful!");
469 if(!tempClass)
471 t.pEnv->ExceptionDescribe();
472 t.pEnv->ExceptionClear();
474 jclass globClass = static_cast<jclass>(t.pEnv->NewGlobalRef( tempClass ));
475 t.pEnv->DeleteLocalRef( tempClass );
476 return globClass;
479 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */