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>
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
)
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
));
72 // -----------------------------------------------------------------------------
73 SDBThreadAttach::SDBThreadAttach()
74 : m_aGuard(java_lang_Object::getVM())
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;
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
111 theClass
= findMyClass("java/lang/Object");
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
)
125 SDBThreadAttach::addRef();
127 object
= pXEnv
->NewGlobalRef( myObj
);
130 java_lang_Object::~java_lang_Object()
135 clearObject(*t
.pEnv
);
137 SDBThreadAttach::releaseRef();
139 void java_lang_Object::clearObject(JNIEnv
& rEnv
)
143 rEnv
.DeleteGlobalRef( object
);
148 void java_lang_Object::clearObject()
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" );
161 object
= pXEnv
->NewGlobalRef( myObj
);
165 ::rtl::OUString
java_lang_Object::toString() const
167 static jmethodID
mID(NULL
);
168 return callStringMethod("toString",mID
);
171 // --------------------------------------------------------------------------------
174 bool lcl_translateJNIExceptionToUNOException(
175 JNIEnv
* _pEnvironment
, const Reference
< XInterface
>& _rxContext
, SQLException
& _out_rException
)
177 jthrowable jThrow
= _pEnvironment
? _pEnvironment
->ExceptionOccurred() : NULL
;
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() );
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() );
203 _pEnvironment
->DeleteLocalRef( jThrow
);
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
);
220 // --------------------------------------------------------------------------------
221 void java_lang_Object::ThrowSQLException( JNIEnv
* _pEnvironment
, const Reference
< XInterface
>& _rxContext
)
223 SQLException aException
;
224 if ( lcl_translateJNIExceptionToUNOException( _pEnvironment
, _rxContext
, 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
);
244 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callBooleanMethod: no Java enviroment anymore!" );
245 obtainMethodId(t
.pEnv
, _pMethodName
,"()Z", _inout_MethodID
);
247 out
= t
.pEnv
->CallBooleanMethod( object
, _inout_MethodID
);
248 ThrowSQLException( t
.pEnv
, NULL
);
252 // -----------------------------------------------------------------------------
253 sal_Bool
java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName
, jmethodID
& _inout_MethodID
, sal_Int32 _nArgument
) const
255 jboolean
out( sal_False
);
257 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callBooleanMethodWithIntArg: no Java enviroment anymore!" );
258 obtainMethodId(t
.pEnv
, _pMethodName
,"(I)Z", _inout_MethodID
);
260 out
= t
.pEnv
->CallBooleanMethod( object
, _inout_MethodID
, _nArgument
);
261 ThrowSQLException( t
.pEnv
, NULL
);
265 // -------------------------------------------------------------------------
266 jobject
java_lang_Object::callResultSetMethod( JNIEnv
& _rEnv
,const char* _pMethodName
, jmethodID
& _inout_MethodID
) const
269 jobject out
= callObjectMethod(&_rEnv
,_pMethodName
,"()Ljava/sql/ResultSet;", _inout_MethodID
);
272 // -------------------------------------------------------------------------
273 sal_Int32
java_lang_Object::callIntMethod( const char* _pMethodName
, jmethodID
& _inout_MethodID
,bool _bIgnoreException
) const
276 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
277 obtainMethodId(t
.pEnv
, _pMethodName
,"()I", _inout_MethodID
);
280 jint
out( t
.pEnv
->CallIntMethod( object
, _inout_MethodID
) );
281 if ( _bIgnoreException
)
282 isExceptionOccurred(t
.pEnv
,sal_True
);
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
292 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
293 obtainMethodId(t
.pEnv
, _pMethodName
,"(I)I", _inout_MethodID
);
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
304 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
305 obtainMethodId(t
.pEnv
, _pMethodName
,"()V", _inout_MethodID
);
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
315 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
316 obtainMethodId(t
.pEnv
, _pMethodName
,"(I)V", _inout_MethodID
);
319 t
.pEnv
->CallVoidMethod( object
, _inout_MethodID
,_nArgument
);
320 if ( _bIgnoreException
)
321 isExceptionOccurred(t
.pEnv
,sal_True
);
323 ThrowSQLException( t
.pEnv
, NULL
);
325 // -------------------------------------------------------------------------
326 void java_lang_Object::callVoidMethodWithBoolArg( const char* _pMethodName
, jmethodID
& _inout_MethodID
, sal_Int32 _nArgument
,bool _bIgnoreException
) const
329 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callIntMethod: no Java enviroment anymore!" );
330 obtainMethodId(t
.pEnv
, _pMethodName
,"(Z)V", _inout_MethodID
);
332 t
.pEnv
->CallVoidMethod( object
, _inout_MethodID
,_nArgument
);
333 if ( _bIgnoreException
)
334 isExceptionOccurred(t
.pEnv
,sal_True
);
336 ThrowSQLException( t
.pEnv
, NULL
);
338 // -----------------------------------------------------------------------------
339 ::rtl::OUString
java_lang_Object::callStringMethod( const char* _pMethodName
, jmethodID
& _inout_MethodID
) const
342 OSL_ENSURE( t
.pEnv
, "java_lang_Object::callStringMethod: no Java enviroment anymore!" );
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
352 obtainMethodId(_pEnv
, _pMethodName
,_pSignature
, _inout_MethodID
);
354 jobject out
= _pEnv
->CallObjectMethod( object
, _inout_MethodID
);
355 ThrowSQLException( _pEnv
, NULL
);
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
);
364 jobject out
= _pEnv
->CallObjectMethod( object
, _inout_MethodID
,_nArgument
);
365 ThrowSQLException( _pEnv
, NULL
);
368 // -----------------------------------------------------------------------------
369 ::rtl::OUString
java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName
, jmethodID
& _inout_MethodID
, sal_Int32 _nArgument
) const
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
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
));
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
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 >(),
404 jdbc::LocalRef
< jstring
> str( t
.env(),convertwchar_tToJavaString(t
.pEnv
,_nArgument
));
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
415 jclass tempClass
= t
.pEnv
->FindClass(_pClassName
); OSL_ENSURE(tempClass
,"Java : FindClass nicht erfolgreich!");
418 t
.pEnv
->ExceptionDescribe();
419 t
.pEnv
->ExceptionClear();
421 jclass globClass
= (jclass
)t
.pEnv
->NewGlobalRef( tempClass
);
422 t
.pEnv
->DeleteLocalRef( tempClass
);
426 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */