Bump for 3.6-28
[LibreOffice.git] / connectivity / source / drivers / jdbc / Object.cxx
blob4cace9ac636a450877556d7365e632b546d91c7d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include "java/lang/Class.hxx"
32 #include "connectivity/CommonTools.hxx"
33 #include <com/sun/star/uno/Exception.hpp>
34 #include "java/tools.hxx"
35 #include "java/sql/SQLException.hxx"
36 #include <osl/mutex.hxx>
37 #include <osl/thread.h>
38 #include <com/sun/star/uno/Sequence.hxx>
39 #include "java/LocalRef.hxx"
40 #include "resource/jdbc_log.hrc"
41 #include <rtl/logfile.hxx>
42 #include <comphelper/logging.hxx>
44 #include <memory>
46 using namespace connectivity;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::sdbc;
50 using namespace ::com::sun::star::container;
51 using namespace ::com::sun::star::lang;
54 // -----------------------------------------------------------------------------
55 ::rtl::Reference< jvmaccess::VirtualMachine > getJavaVM2(const ::rtl::Reference< jvmaccess::VirtualMachine >& _rVM = ::rtl::Reference< jvmaccess::VirtualMachine >(),
56 sal_Bool _bSet = sal_False)
58 static ::rtl::Reference< jvmaccess::VirtualMachine > s_VM;
59 if ( _rVM.is() || _bSet )
60 s_VM = _rVM;
61 return s_VM;
63 // -----------------------------------------------------------------------------
64 ::rtl::Reference< jvmaccess::VirtualMachine > java_lang_Object::getVM(const Reference<XMultiServiceFactory >& _rxFactory)
66 ::rtl::Reference< jvmaccess::VirtualMachine > xVM = getJavaVM2();
67 if ( !xVM.is() && _rxFactory.is() )
68 xVM = getJavaVM2(::connectivity::getJavaVM(_rxFactory));
70 return xVM;
72 // -----------------------------------------------------------------------------
73 SDBThreadAttach::SDBThreadAttach()
74 : m_aGuard(java_lang_Object::getVM())
75 , pEnv(NULL)
77 pEnv = m_aGuard.getEnvironment();
78 OSL_ENSURE(pEnv,"Environment is nULL!");
80 // -----------------------------------------------------------------------------
81 SDBThreadAttach::~SDBThreadAttach()
84 // -----------------------------------------------------------------------------
85 oslInterlockedCount& getJavaVMRefCount()
87 static oslInterlockedCount s_nRefCount = 0;
88 return s_nRefCount;
90 // -----------------------------------------------------------------------------
91 void SDBThreadAttach::addRef()
93 osl_incrementInterlockedCount(&getJavaVMRefCount());
95 // -----------------------------------------------------------------------------
96 void SDBThreadAttach::releaseRef()
98 osl_decrementInterlockedCount(&getJavaVMRefCount());
99 if ( getJavaVMRefCount() == 0 )
101 getJavaVM2(::rtl::Reference< jvmaccess::VirtualMachine >(),sal_True);
104 // -----------------------------------------------------------------------------
105 // static variables of the class
106 jclass java_lang_Object::theClass = 0;
108 jclass java_lang_Object::getMyClass() const
110 if( !theClass )
111 theClass = findMyClass("java/lang/Object");
112 return theClass;
114 // the actual constructor
115 java_lang_Object::java_lang_Object(const Reference<XMultiServiceFactory >& _rxFactory)
116 : m_xFactory(_rxFactory),object( 0 )
118 SDBThreadAttach::addRef();
121 // the protected-constructor for the derived classes
122 java_lang_Object::java_lang_Object( JNIEnv * pXEnv, jobject myObj )
123 : object( NULL )
125 SDBThreadAttach::addRef();
126 if( pXEnv && myObj )
127 object = pXEnv->NewGlobalRef( myObj );
130 java_lang_Object::~java_lang_Object()
132 if( object )
134 SDBThreadAttach t;
135 clearObject(*t.pEnv);
137 SDBThreadAttach::releaseRef();
139 void java_lang_Object::clearObject(JNIEnv& rEnv)
141 if( object )
143 rEnv.DeleteGlobalRef( object );
144 object = NULL;
148 void java_lang_Object::clearObject()
150 if( object )
152 SDBThreadAttach t;
153 clearObject(*t.pEnv);
156 // the protected-constructor for the derived classes
157 void java_lang_Object::saveRef( JNIEnv * pXEnv, jobject myObj )
159 OSL_ENSURE( myObj, "object in c++ -> Java Wrapper" );
160 if( myObj )
161 object = pXEnv->NewGlobalRef( myObj );
165 ::rtl::OUString java_lang_Object::toString() const
167 static jmethodID mID(NULL);
168 return callStringMethod("toString",mID);
171 // --------------------------------------------------------------------------------
172 namespace
174 bool lcl_translateJNIExceptionToUNOException(
175 JNIEnv* _pEnvironment, const Reference< XInterface >& _rxContext, SQLException& _out_rException )
177 jthrowable jThrow = _pEnvironment ? _pEnvironment->ExceptionOccurred() : NULL;
178 if ( !jThrow )
179 return false;
181 _pEnvironment->ExceptionClear();
182 // we have to clear the exception here because we want to handle it itself
184 if ( _pEnvironment->IsInstanceOf( jThrow, java_sql_SQLException_BASE::st_getMyClass() ) )
186 ::std::auto_ptr< java_sql_SQLException_BASE > pException( new java_sql_SQLException_BASE( _pEnvironment, jThrow ) );
187 _out_rException = SQLException( pException->getMessage(), _rxContext,
188 pException->getSQLState(), pException->getErrorCode(), Any() );
189 return true;
191 else if ( _pEnvironment->IsInstanceOf( jThrow, java_lang_Throwable::st_getMyClass() ) )
193 ::std::auto_ptr< java_lang_Throwable > pThrow( new java_lang_Throwable( _pEnvironment, jThrow ) );
194 ::rtl::OUString sMessage = pThrow->getMessage();
195 if ( sMessage.isEmpty() )
196 sMessage = pThrow->getLocalizedMessage();
197 if( sMessage.isEmpty() )
198 sMessage = pThrow->toString();
199 _out_rException = SQLException( sMessage, _rxContext, ::rtl::OUString(), -1, Any() );
200 return true;
202 else
203 _pEnvironment->DeleteLocalRef( jThrow );
204 return false;
208 // --------------------------------------------------------------------------------
209 void java_lang_Object::ThrowLoggedSQLException( const ::comphelper::ResourceBasedEventLogger& _rLogger, JNIEnv* _pEnvironment,
210 const Reference< XInterface >& _rxContext )
212 SQLException aException;
213 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
215 _rLogger.log( ::com::sun::star::logging::LogLevel::SEVERE, STR_LOG_THROWING_EXCEPTION, aException.Message, aException.SQLState, aException.ErrorCode );
216 throw aException;
220 // --------------------------------------------------------------------------------
221 void java_lang_Object::ThrowSQLException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
223 SQLException aException;
224 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
225 throw aException;
227 // -----------------------------------------------------------------------------
228 void java_lang_Object::obtainMethodId(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
230 if ( !_inout_MethodID )
232 _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
233 OSL_ENSURE( _inout_MethodID, _pSignature );
234 if ( !_inout_MethodID )
235 throw SQLException();
236 } // if ( !_inout_MethodID )
238 // -----------------------------------------------------------------------------
239 sal_Bool java_lang_Object::callBooleanMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
241 jboolean out( sal_False );
243 SDBThreadAttach t;
244 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethod: no Java enviroment anymore!" );
245 obtainMethodId(t.pEnv, _pMethodName,"()Z", _inout_MethodID);
246 // call method
247 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID );
248 ThrowSQLException( t.pEnv, NULL );
250 return out;
252 // -----------------------------------------------------------------------------
253 sal_Bool java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
255 jboolean out( sal_False );
256 SDBThreadAttach t;
257 OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethodWithIntArg: no Java enviroment anymore!" );
258 obtainMethodId(t.pEnv, _pMethodName,"(I)Z", _inout_MethodID);
259 // call method
260 out = t.pEnv->CallBooleanMethod( object, _inout_MethodID, _nArgument );
261 ThrowSQLException( t.pEnv, NULL );
263 return out;
265 // -------------------------------------------------------------------------
266 jobject java_lang_Object::callResultSetMethod( JNIEnv& _rEnv,const char* _pMethodName, jmethodID& _inout_MethodID ) const
268 // call method
269 jobject out = callObjectMethod(&_rEnv,_pMethodName,"()Ljava/sql/ResultSet;", _inout_MethodID);
270 return out;
272 // -------------------------------------------------------------------------
273 sal_Int32 java_lang_Object::callIntMethod( const char* _pMethodName, jmethodID& _inout_MethodID,bool _bIgnoreException ) const
275 SDBThreadAttach t;
276 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
277 obtainMethodId(t.pEnv, _pMethodName,"()I", _inout_MethodID);
279 // call method
280 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
281 if ( _bIgnoreException )
282 isExceptionOccurred(t.pEnv,sal_True);
283 else
284 ThrowSQLException( t.pEnv, NULL );
286 return (sal_Int32)out;
288 // -------------------------------------------------------------------------
289 sal_Int32 java_lang_Object::callIntMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
291 SDBThreadAttach t;
292 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
293 obtainMethodId(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
294 // call method
295 jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
296 ThrowSQLException( t.pEnv, NULL );
298 return (sal_Int32)out;
300 // -------------------------------------------------------------------------
301 void java_lang_Object::callVoidMethod( const char* _pMethodName, jmethodID& _inout_MethodID) const
303 SDBThreadAttach t;
304 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
305 obtainMethodId(t.pEnv, _pMethodName,"()V", _inout_MethodID);
307 // call method
308 t.pEnv->CallVoidMethod( object, _inout_MethodID );
309 ThrowSQLException( t.pEnv, NULL );
311 // -------------------------------------------------------------------------
312 void java_lang_Object::callVoidMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument,bool _bIgnoreException ) const
314 SDBThreadAttach t;
315 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
316 obtainMethodId(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
318 // call method
319 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
320 if ( _bIgnoreException )
321 isExceptionOccurred(t.pEnv,sal_True);
322 else
323 ThrowSQLException( t.pEnv, NULL );
325 // -------------------------------------------------------------------------
326 void java_lang_Object::callVoidMethodWithBoolArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument,bool _bIgnoreException ) const
328 SDBThreadAttach t;
329 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
330 obtainMethodId(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
331 // call method
332 t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
333 if ( _bIgnoreException )
334 isExceptionOccurred(t.pEnv,sal_True);
335 else
336 ThrowSQLException( t.pEnv, NULL );
338 // -----------------------------------------------------------------------------
339 ::rtl::OUString java_lang_Object::callStringMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
341 SDBThreadAttach t;
342 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java enviroment anymore!" );
344 // call method
345 jstring out = (jstring)callObjectMethod(t.pEnv,_pMethodName,"()Ljava/lang/String;", _inout_MethodID);
346 return JavaString2String( t.pEnv, out );
348 // -----------------------------------------------------------------------------
349 jobject java_lang_Object::callObjectMethod( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID ) const
351 // obtain method ID
352 obtainMethodId(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
353 // call method
354 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID);
355 ThrowSQLException( _pEnv, NULL );
356 return out;
359 // -----------------------------------------------------------------------------
360 jobject java_lang_Object::callObjectMethodWithIntArg( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
362 obtainMethodId(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
363 // call method
364 jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID,_nArgument );
365 ThrowSQLException( _pEnv, NULL );
366 return out;
368 // -----------------------------------------------------------------------------
369 ::rtl::OUString java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
371 SDBThreadAttach t;
372 OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java enviroment anymore!" );
373 jstring out = (jstring)callObjectMethodWithIntArg(t.pEnv,_pMethodName,"(I)Ljava/lang/String;",_inout_MethodID,_nArgument);
374 return JavaString2String( t.pEnv, out );
376 // -------------------------------------------------------------------------
377 void java_lang_Object::callVoidMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const ::rtl::OUString& _nArgument ) const
379 SDBThreadAttach t;
380 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
381 obtainMethodId(t.pEnv, _pMethodName,"(Ljava/lang/String;)V", _inout_MethodID);
383 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
384 // call method
385 t.pEnv->CallVoidMethod( object, _inout_MethodID , str.get());
386 ThrowSQLException( t.pEnv, NULL );
388 // -------------------------------------------------------------------------
389 sal_Int32 java_lang_Object::callIntMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const ::rtl::OUString& _nArgument ) const
391 SDBThreadAttach t;
392 OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethodWithStringArg: no Java enviroment anymore!" );
393 obtainMethodId(t.pEnv, _pMethodName,"(Ljava/lang/String;)I", _inout_MethodID);
395 //TODO: Check if the code below is needed
396 //jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
398 // jdbc::ContextClassLoaderScope ccl( t.env(),
399 // m_pConnection ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
400 // m_aLogger,
401 // *this
402 // );
404 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
405 // call method
406 jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str.get());
407 ThrowSQLException( t.pEnv, NULL );
408 return (sal_Int32)out;
410 // -----------------------------------------------------------------------------
411 jclass java_lang_Object::findMyClass(const char* _pClassName)
413 // the class must be fetched only once, therefore static
414 SDBThreadAttach t;
415 jclass tempClass = t.pEnv->FindClass(_pClassName); OSL_ENSURE(tempClass,"Java : FindClass nicht erfolgreich!");
416 if(!tempClass)
418 t.pEnv->ExceptionDescribe();
419 t.pEnv->ExceptionClear();
421 jclass globClass = (jclass)t.pEnv->NewGlobalRef( tempClass );
422 t.pEnv->DeleteLocalRef( tempClass );
423 return globClass;
426 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */