1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Object.cxx,v $
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"
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>
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
)
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
));
79 // -----------------------------------------------------------------------------
80 SDBThreadAttach::SDBThreadAttach()
81 : m_aGuard(java_lang_Object::getVM())
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;
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
118 theClass
= findMyClass("java/lang/Object");
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
)
132 SDBThreadAttach::addRef();
134 object
= pXEnv
->NewGlobalRef( myObj
);
137 java_lang_Object::~java_lang_Object()
142 clearObject(*t
.pEnv
);
144 SDBThreadAttach::releaseRef();
146 void java_lang_Object::clearObject(JNIEnv
& rEnv
)
150 rEnv
.DeleteGlobalRef( object
);
155 void java_lang_Object::clearObject()
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" );
168 object
= pXEnv
->NewGlobalRef( myObj
);
172 java_lang_Class
* java_lang_Object::getClass()
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 // --------------------------------------------------------------------------------
189 bool lcl_translateJNIExceptionToUNOException(
190 JNIEnv
* _pEnvironment
, const Reference
< XInterface
>& _rxContext
, SQLException
& _out_rException
)
192 jthrowable jThrow
= _pEnvironment
? _pEnvironment
->ExceptionOccurred() : NULL
;
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() );
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() );
218 _pEnvironment
->DeleteLocalRef( jThrow
);
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
);
235 // --------------------------------------------------------------------------------
236 void java_lang_Object::ThrowSQLException( JNIEnv
* _pEnvironment
, const Reference
< XInterface
>& _rxContext
)
238 SQLException aException
;
239 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment
, _rxContext
, 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
);
259 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callBooleanMethod: no Java enviroment anymore!" );
260 obtainMethodId(t
.pEnv
, _pMethodName
,"()Z", _inout_MethodID
);
262 out
= t
.pEnv
->CallBooleanMethod( object
, _inout_MethodID
);
263 ThrowSQLException( t
.pEnv
, NULL
);
267 // -----------------------------------------------------------------------------
268 sal_Bool
java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName
, jmethodID
& _inout_MethodID
, sal_Int32 _nArgument
) const
270 jboolean
out( sal_False
);
272 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callBooleanMethodWithIntArg: no Java enviroment anymore!" );
273 obtainMethodId(t
.pEnv
, _pMethodName
,"(I)Z", _inout_MethodID
);
275 out
= t
.pEnv
->CallBooleanMethod( object
, _inout_MethodID
, _nArgument
);
276 ThrowSQLException( t
.pEnv
, NULL
);
280 // -------------------------------------------------------------------------
281 jobject
java_lang_Object::callResultSetMethod( JNIEnv
& _rEnv
,const char* _pMethodName
, jmethodID
& _inout_MethodID
) const
284 jobject out
= callObjectMethod(&_rEnv
,_pMethodName
,"()Ljava/sql/ResultSet;", _inout_MethodID
);
287 // -------------------------------------------------------------------------
288 sal_Int32
java_lang_Object::callIntMethod( const char* _pMethodName
, jmethodID
& _inout_MethodID
,bool _bIgnoreException
) const
291 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
292 obtainMethodId(t
.pEnv
, _pMethodName
,"()I", _inout_MethodID
);
295 jint
out( t
.pEnv
->CallIntMethod( object
, _inout_MethodID
) );
296 if ( _bIgnoreException
)
297 isExceptionOccured(t
.pEnv
,sal_True
);
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
307 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
308 obtainMethodId(t
.pEnv
, _pMethodName
,"(I)I", _inout_MethodID
);
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
319 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
320 obtainMethodId(t
.pEnv
, _pMethodName
,"()V", _inout_MethodID
);
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
330 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
331 obtainMethodId(t
.pEnv
, _pMethodName
,"(I)V", _inout_MethodID
);
334 t
.pEnv
->CallVoidMethod( object
, _inout_MethodID
,_nArgument
);
335 if ( _bIgnoreException
)
336 isExceptionOccured(t
.pEnv
,sal_True
);
338 ThrowSQLException( t
.pEnv
, NULL
);
340 // -------------------------------------------------------------------------
341 void java_lang_Object::callVoidMethodWithBoolArg( const char* _pMethodName
, jmethodID
& _inout_MethodID
, sal_Int32 _nArgument
,bool _bIgnoreException
) const
344 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
345 obtainMethodId(t
.pEnv
, _pMethodName
,"(Z)V", _inout_MethodID
);
347 t
.pEnv
->CallVoidMethod( object
, _inout_MethodID
,_nArgument
);
348 if ( _bIgnoreException
)
349 isExceptionOccured(t
.pEnv
,sal_True
);
351 ThrowSQLException( t
.pEnv
, NULL
);
353 // -----------------------------------------------------------------------------
354 ::rtl::OUString
java_lang_Object::callStringMethod( const char* _pMethodName
, jmethodID
& _inout_MethodID
) const
357 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callStringMethod: no Java enviroment anymore!" );
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
367 obtainMethodId(_pEnv
, _pMethodName
,_pSignature
, _inout_MethodID
);
369 jobject out
= _pEnv
->CallObjectMethod( object
, _inout_MethodID
);
370 ThrowSQLException( _pEnv
, NULL
);
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
);
379 jobject out
= _pEnv
->CallObjectMethod( object
, _inout_MethodID
,_nArgument
);
380 ThrowSQLException( _pEnv
, NULL
);
383 // -----------------------------------------------------------------------------
384 ::rtl::OUString
java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName
, jmethodID
& _inout_MethodID
, sal_Int32 _nArgument
) const
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
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
);
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
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 >(),
420 jstring str
= convertwchar_tToJavaString(t
.pEnv
,_nArgument
);
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
432 jclass tempClass
= t
.pEnv
->FindClass(_pClassName
); OSL_ENSURE(tempClass
,"Java : FindClass nicht erfolgreich!");
435 t
.pEnv
->ExceptionDescribe();
436 t
.pEnv
->ExceptionClear();
438 jclass globClass
= (jclass
)t
.pEnv
->NewGlobalRef( tempClass
);
439 t
.pEnv
->DeleteLocalRef( tempClass
);