summaryrefslogtreecommitdiffstats
path: root/connectivity/source/drivers/jdbc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /connectivity/source/drivers/jdbc
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'connectivity/source/drivers/jdbc')
-rw-r--r--connectivity/source/drivers/jdbc/Array.cxx132
-rw-r--r--connectivity/source/drivers/jdbc/Blob.cxx144
-rw-r--r--connectivity/source/drivers/jdbc/Boolean.cxx38
-rw-r--r--connectivity/source/drivers/jdbc/CallableStatement.cxx354
-rw-r--r--connectivity/source/drivers/jdbc/Class.cxx70
-rw-r--r--connectivity/source/drivers/jdbc/Clob.cxx132
-rw-r--r--connectivity/source/drivers/jdbc/ConnectionLog.cxx110
-rw-r--r--connectivity/source/drivers/jdbc/ContextClassLoader.cxx111
-rw-r--r--connectivity/source/drivers/jdbc/DatabaseMetaData.cxx1463
-rw-r--r--connectivity/source/drivers/jdbc/Date.cxx38
-rw-r--r--connectivity/source/drivers/jdbc/DriverPropertyInfo.cxx40
-rw-r--r--connectivity/source/drivers/jdbc/Exception.cxx37
-rw-r--r--connectivity/source/drivers/jdbc/InputStream.cxx113
-rw-r--r--connectivity/source/drivers/jdbc/JBigDecimal.cxx79
-rw-r--r--connectivity/source/drivers/jdbc/JConnection.cxx803
-rw-r--r--connectivity/source/drivers/jdbc/JDriver.cxx231
-rw-r--r--connectivity/source/drivers/jdbc/JStatement.cxx864
-rw-r--r--connectivity/source/drivers/jdbc/Object.cxx481
-rw-r--r--connectivity/source/drivers/jdbc/PreparedStatement.cxx697
-rw-r--r--connectivity/source/drivers/jdbc/Reader.cxx178
-rw-r--r--connectivity/source/drivers/jdbc/Ref.cxx48
-rw-r--r--connectivity/source/drivers/jdbc/ResultSet.cxx1013
-rw-r--r--connectivity/source/drivers/jdbc/ResultSetMetaData.cxx200
-rw-r--r--connectivity/source/drivers/jdbc/SQLException.cxx87
-rw-r--r--connectivity/source/drivers/jdbc/SQLWarning.cxx37
-rw-r--r--connectivity/source/drivers/jdbc/String.cxx47
-rw-r--r--connectivity/source/drivers/jdbc/Throwable.cxx59
-rw-r--r--connectivity/source/drivers/jdbc/Timestamp.cxx189
-rw-r--r--connectivity/source/drivers/jdbc/jdbc.component37
-rw-r--r--connectivity/source/drivers/jdbc/tools.cxx261
30 files changed, 8093 insertions, 0 deletions
diff --git a/connectivity/source/drivers/jdbc/Array.cxx b/connectivity/source/drivers/jdbc/Array.cxx
new file mode 100644
index 000000000..d03b01928
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Array.cxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/Array.hxx>
+#include <java/tools.hxx>
+#include <osl/diagnose.h>
+
+using namespace connectivity;
+
+//************ Class: java.sql.Array
+
+
+jclass java_sql_Array::theClass = nullptr;
+
+java_sql_Array::~java_sql_Array()
+{}
+
+jclass java_sql_Array::getMyClass() const
+{
+ // the class must be fetched once, therefore it's static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Array");
+
+ return theClass;
+}
+
+OUString SAL_CALL java_sql_Array::getBaseTypeName( )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("getBaseTypeName",mID);
+}
+
+sal_Int32 SAL_CALL java_sql_Array::getBaseType( )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowSQL("getBaseType", mID);
+}
+
+css::uno::Sequence< css::uno::Any > SAL_CALL java_sql_Array::getArray( const css::uno::Reference< css::container::XNameAccess >& typeMap )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ jobject obj = convertTypeMapToJavaMap(typeMap);
+ static const char * const cSignature = "(Ljava/util/Map;)[Ljava/lang/Object;";
+ static const char * const cMethodName = "getArray";
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ // submit Java-Call
+ t.pEnv->CallObjectMethod( object, mID, obj);
+ ThrowSQLException(t.pEnv,*this);
+ // and clean up
+ t.pEnv->DeleteLocalRef(obj);
+ } //t.pEnv
+ return css::uno::Sequence< css::uno::Any >();
+}
+
+css::uno::Sequence< css::uno::Any > SAL_CALL java_sql_Array::getArrayAtIndex( sal_Int32 index, sal_Int32 count, const css::uno::Reference< css::container::XNameAccess >& typeMap )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ jobject obj = convertTypeMapToJavaMap(typeMap);
+ static const char * const cSignature = "(IILjava/util/Map;)[Ljava/lang/Object;";
+ static const char * const cMethodName = "getArray";
+ // submit Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ t.pEnv->CallObjectMethod( object, mID, index,count,obj);
+ ThrowSQLException(t.pEnv,*this);
+ // and clean up
+ t.pEnv->DeleteLocalRef(obj);
+ }
+ return css::uno::Sequence< css::uno::Any >();
+}
+
+css::uno::Reference< css::sdbc::XResultSet > SAL_CALL java_sql_Array::getResultSet( const css::uno::Reference< css::container::XNameAccess >& typeMap )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ // convert Parameter
+ jobject obj = convertTypeMapToJavaMap(typeMap);
+ // initialize temporary variable
+ static const char * const cSignature = "(Ljava/util/Map;)Ljava/sql/ResultSet;";
+ static const char * const cMethodName = "getResultSet";
+ // submit Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ t.pEnv->CallObjectMethod( object, mID, obj);
+ ThrowSQLException(t.pEnv,*this);
+ // and cleanup
+ t.pEnv->DeleteLocalRef(obj);
+ }
+ return nullptr;
+}
+
+css::uno::Reference< css::sdbc::XResultSet > SAL_CALL java_sql_Array::getResultSetAtIndex( sal_Int32 index, sal_Int32 count, const css::uno::Reference< css::container::XNameAccess >& typeMap )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ // convert parameter
+ jobject obj = convertTypeMapToJavaMap(typeMap);
+ // initialize temporary variable
+ static const char * const cSignature = "(Ljava/util/Map;)Ljava/sql/ResultSet;";
+ static const char * const cMethodName = "getResultSetAtIndex";
+ // submit Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ t.pEnv->CallObjectMethod( object, mID, index,count,obj);
+ ThrowSQLException(t.pEnv,*this);
+ // and cleanup
+ t.pEnv->DeleteLocalRef(obj);
+ }
+ return nullptr;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Blob.cxx b/connectivity/source/drivers/jdbc/Blob.cxx
new file mode 100644
index 000000000..4531fc9b8
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Blob.cxx
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/Blob.hxx>
+#include <java/io/InputStream.hxx>
+#include <connectivity/dbexception.hxx>
+#include <osl/diagnose.h>
+
+#include <string.h>
+
+using namespace connectivity;
+
+//************ Class: java.sql.Blob
+
+
+jclass java_sql_Blob::theClass = nullptr;
+java_sql_Blob::java_sql_Blob( JNIEnv * pEnv, jobject myObj )
+ : java_lang_Object( pEnv, myObj )
+{
+ SDBThreadAttach::addRef();
+}
+java_sql_Blob::~java_sql_Blob()
+{
+ SDBThreadAttach::releaseRef();
+}
+
+jclass java_sql_Blob::getMyClass() const
+{
+ // the class must be fetched only once, therefore it's static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Blob");
+ return theClass;
+}
+
+sal_Int64 SAL_CALL java_sql_Blob::length( )
+{
+ jlong out(0);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ // initialize temporary variable
+ static const char * const cSignature = "()J";
+ static const char * const cMethodName = "length";
+ // submit Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ out = t.pEnv->CallLongMethod( object, mID );
+ ThrowSQLException(t.pEnv,*this);
+ } //t.pEnv
+ return static_cast<sal_Int64>(out);
+}
+css::uno::Sequence< sal_Int8 > SAL_CALL java_sql_Blob::getBytes( sal_Int64 pos, sal_Int32 count )
+{
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ css::uno::Sequence< sal_Int8 > aSeq;
+ {
+ // initialize temporary variable
+ static const char * const cSignature = "(JI)[B";
+ static const char * const cMethodName = "getBytes";
+ // submit Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jbyteArray out = static_cast<jbyteArray>(t.pEnv->CallObjectMethod( object, mID,pos,count));
+ ThrowSQLException(t.pEnv,*this);
+ if(out)
+ {
+ jboolean p = false;
+ aSeq.realloc(t.pEnv->GetArrayLength(out));
+ memcpy(aSeq.getArray(),t.pEnv->GetByteArrayElements(out,&p),aSeq.getLength());
+ t.pEnv->DeleteLocalRef(out);
+ }
+ } //t.pEnv
+ // WARNING: the caller becomes the owner of the returned pointer
+ return aSeq;
+}
+
+css::uno::Reference< css::io::XInputStream > SAL_CALL java_sql_Blob::getBinaryStream( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getBinaryStream","()Ljava/io/InputStream;", mID);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_io_InputStream( t.pEnv, out );
+}
+
+sal_Int64 SAL_CALL java_sql_Blob::position( const css::uno::Sequence< sal_Int8 >& pattern, sal_Int64 start )
+{
+ jlong out(0);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ // initialize temporary variable
+ static const char * const cSignature = "([BI)J";
+ static const char * const cMethodName = "position";
+ // submit Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ // convert Parameter
+ jbyteArray pByteArray = t.pEnv->NewByteArray(pattern.getLength());
+ jbyte * patternData = reinterpret_cast<jbyte *>(
+ const_cast<sal_Int8 *>(pattern.getConstArray()));
+ // 4th param of Set*ArrayRegion changed from pointer to non-const to
+ // pointer to const between <http://docs.oracle.com/javase/6/docs/
+ // technotes/guides/jni/spec/functions.html#wp22933> and
+ // <http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/
+ // functions.html#wp22933>; work around that difference in a way
+ // that doesn't trigger loplugin:redundantcast
+ t.pEnv->SetByteArrayRegion(pByteArray,0,pattern.getLength(),patternData);
+ out = t.pEnv->CallLongMethod( object, mID, pByteArray,start );
+ t.pEnv->DeleteLocalRef(pByteArray);
+ ThrowSQLException(t.pEnv,*this);
+ } //t.pEnv
+ return static_cast<sal_Int64>(out);
+}
+
+sal_Int64 SAL_CALL java_sql_Blob::positionOfBlob( const css::uno::Reference< css::sdbc::XBlob >& /*pattern*/, sal_Int64 /*start*/ )
+{
+ ::dbtools::throwFeatureNotImplementedSQLException( "XBlob::positionOfBlob", *this );
+ // this was put here in CWS warnings01. The previous implementation was defective, as it did ignore
+ // the pattern parameter. Since the effort for proper implementation is rather high - we would need
+ // to translated pattern into a byte[] -, we defer this functionality for the moment (hey, it was
+ // unusable, anyway)
+ // #i57457#
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Boolean.cxx b/connectivity/source/drivers/jdbc/Boolean.cxx
new file mode 100644
index 000000000..5709674f3
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Boolean.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/lang/Boolean.hxx>
+using namespace connectivity;
+
+//************ Class: java.lang.Boolean
+
+jclass java_lang_Boolean::theClass = nullptr;
+
+java_lang_Boolean::~java_lang_Boolean() {}
+jclass java_lang_Boolean::st_getMyClass()
+{
+ // the class must be fetched only once, therefore static
+ if (!theClass)
+ theClass = findMyClass("java/lang/Boolean");
+ return theClass;
+}
+
+jclass java_lang_Boolean::getMyClass() const { return st_getMyClass(); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/CallableStatement.cxx b/connectivity/source/drivers/jdbc/CallableStatement.cxx
new file mode 100644
index 000000000..884de3d4c
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/CallableStatement.cxx
@@ -0,0 +1,354 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/CallableStatement.hxx>
+#include <java/tools.hxx>
+#include <java/sql/Array.hxx>
+#include <java/sql/Clob.hxx>
+#include <java/sql/Blob.hxx>
+#include <java/sql/Connection.hxx>
+#include <java/sql/Ref.hxx>
+#include <java/sql/Timestamp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <string.h>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+
+IMPLEMENT_SERVICE_INFO(java_sql_CallableStatement,"com.sun.star.sdbcx.ACallableStatement","com.sun.star.sdbc.CallableStatement");
+
+
+//************ Class: java.sql.CallableStatement
+
+java_sql_CallableStatement::java_sql_CallableStatement( JNIEnv * pEnv, java_sql_Connection& _rCon,const OUString& sql )
+ : java_sql_PreparedStatement( pEnv, _rCon, sql )
+{
+}
+
+java_sql_CallableStatement::~java_sql_CallableStatement()
+{
+}
+
+
+Any SAL_CALL java_sql_CallableStatement::queryInterface( const Type & rType )
+{
+ Any aRet = java_sql_PreparedStatement::queryInterface(rType);
+ return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< css::sdbc::XRow*>(this),static_cast< css::sdbc::XOutParameters*>(this));
+}
+
+css::uno::Sequence< css::uno::Type > SAL_CALL java_sql_CallableStatement::getTypes( )
+{
+ ::cppu::OTypeCollection aTypes( cppu::UnoType<css::sdbc::XRow>::get(),
+ cppu::UnoType<css::sdbc::XOutParameters>::get());
+
+ return ::comphelper::concatSequences(aTypes.getTypes(),java_sql_PreparedStatement::getTypes());
+}
+
+sal_Bool SAL_CALL java_sql_CallableStatement::wasNull( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "wasNull", mID );
+}
+
+sal_Bool SAL_CALL java_sql_CallableStatement::getBoolean( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "getBoolean", mID,columnIndex );
+}
+sal_Int8 SAL_CALL java_sql_CallableStatement::getByte( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jbyte (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallByteMethod;
+ return callMethodWithIntArg<jbyte>(pCallMethod,"getByte","(I)B",mID,columnIndex);
+}
+Sequence< sal_Int8 > SAL_CALL java_sql_CallableStatement::getBytes( sal_Int32 columnIndex )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ Sequence< sal_Int8 > aSeq;
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jbyteArray out = static_cast<jbyteArray>(callObjectMethodWithIntArg(t.pEnv,"getBytes","(I)[B", mID, columnIndex));
+ if (out)
+ {
+ jboolean p = false;
+ aSeq.realloc(t.pEnv->GetArrayLength(out));
+ memcpy(aSeq.getArray(),t.pEnv->GetByteArrayElements(out,&p),aSeq.getLength());
+ t.pEnv->DeleteLocalRef(out);
+ }
+ return aSeq;
+}
+css::util::Date SAL_CALL java_sql_CallableStatement::getDate( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getDate","(I)Ljava/sql/Date;", mID, columnIndex);
+ return out ? static_cast <css::util::Date>(java_sql_Date( t.pEnv, out )) : css::util::Date();
+}
+double SAL_CALL java_sql_CallableStatement::getDouble( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ double (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallDoubleMethod;
+ return callMethodWithIntArg<double>(pCallMethod,"getDouble","(I)D",mID,columnIndex);
+}
+
+float SAL_CALL java_sql_CallableStatement::getFloat( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jfloat (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallFloatMethod;
+ return callMethodWithIntArg<jfloat>(pCallMethod,"getFloat","(I)F",mID,columnIndex);
+}
+
+sal_Int32 SAL_CALL java_sql_CallableStatement::getInt( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("getInt",mID,columnIndex);
+}
+
+sal_Int64 SAL_CALL java_sql_CallableStatement::getLong( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jlong (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallLongMethod;
+ return callMethodWithIntArg<jlong>(pCallMethod,"getLong","(I)J",mID,columnIndex);
+}
+
+Any SAL_CALL java_sql_CallableStatement::getObject( sal_Int32 columnIndex, const Reference< css::container::XNameAccess >& /*typeMap*/ )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callObjectMethodWithIntArg(t.pEnv,"getObject","(I)Ljava/lang/Object;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return Any();
+}
+
+sal_Int16 SAL_CALL java_sql_CallableStatement::getShort( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jshort (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallShortMethod;
+ return callMethodWithIntArg<jshort>(pCallMethod,"getShort","(I)S",mID,columnIndex);
+}
+
+OUString SAL_CALL java_sql_CallableStatement::getString( sal_Int32 columnIndex )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getString",mID,columnIndex);
+}
+
+ css::util::Time SAL_CALL java_sql_CallableStatement::getTime( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getTime","(I)Ljava/sql/Time;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out ? static_cast <css::util::Time> (java_sql_Time( t.pEnv, out )) : css::util::Time();
+}
+
+ css::util::DateTime SAL_CALL java_sql_CallableStatement::getTimestamp( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getTimestamp","(I)Ljava/sql/Timestamp;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out ? static_cast <css::util::DateTime> (java_sql_Timestamp( t.pEnv, out )) : css::util::DateTime();
+}
+
+void SAL_CALL java_sql_CallableStatement::registerOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& typeName )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ createStatement(t.pEnv);
+
+ // initialize temporary variable
+ static const char * const cSignature = "(IILjava/lang/String;)V";
+ static const char * const cMethodName = "registerOutParameter";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ // Convert Parameter
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,typeName));
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,sqlType,str.get());
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+}
+void SAL_CALL java_sql_CallableStatement::registerNumericOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, sal_Int32 scale )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ createStatement(t.pEnv);
+ // initialize temporary variable
+ static const char * const cSignature = "(III)V";
+ static const char * const cMethodName = "registerOutParameter";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,sqlType,scale);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+}
+
+jclass java_sql_CallableStatement::theClass = nullptr;
+
+jclass java_sql_CallableStatement::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/CallableStatement");
+ return theClass;
+}
+
+Reference< css::io::XInputStream > SAL_CALL java_sql_CallableStatement::getBinaryStream( sal_Int32 columnIndex )
+{
+ Reference< css::sdbc::XBlob > xBlob = getBlob(columnIndex);
+ return xBlob.is() ? xBlob->getBinaryStream() : Reference< css::io::XInputStream >();
+}
+Reference< css::io::XInputStream > SAL_CALL java_sql_CallableStatement::getCharacterStream( sal_Int32 columnIndex )
+{
+ Reference< css::sdbc::XClob > xClob = getClob(columnIndex);
+ return xClob.is() ? xClob->getCharacterStream() : Reference< css::io::XInputStream >();
+}
+
+Reference< css::sdbc::XArray > SAL_CALL java_sql_CallableStatement::getArray( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getArray","(I)Ljava/sql/Array;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Array( t.pEnv, out );
+}
+
+Reference< css::sdbc::XClob > SAL_CALL java_sql_CallableStatement::getClob( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getClob","(I)Ljava/sql/Clob;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Clob( t.pEnv, out );
+}
+Reference< css::sdbc::XBlob > SAL_CALL java_sql_CallableStatement::getBlob( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getBlob","(I)Ljava/sql/Blob;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Blob( t.pEnv, out );
+}
+
+Reference< css::sdbc::XRef > SAL_CALL java_sql_CallableStatement::getRef( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getRef","(I)Ljava/sql/Ref;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Ref( t.pEnv, out );
+}
+
+void SAL_CALL java_sql_CallableStatement::acquire() noexcept
+{
+ java_sql_PreparedStatement::acquire();
+}
+
+void SAL_CALL java_sql_CallableStatement::release() noexcept
+{
+ java_sql_PreparedStatement::release();
+}
+
+void java_sql_CallableStatement::createStatement(JNIEnv* /*_pEnv*/)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ if( !t.pEnv || object )
+ return;
+
+ // initialize temporary variable
+ static const char * const cMethodName = "prepareCall";
+ // execute Java-Call
+ jobject out = nullptr;
+ // convert Parameter
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,m_sSqlStatement));
+
+ static jmethodID mID = [&]()
+ {
+ static const char * const cSignature = "(Ljava/lang/String;II)Ljava/sql/CallableStatement;";
+ return t.pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature );
+ }();
+ if( mID ){
+ out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID, str.get() ,m_nResultSetType,m_nResultSetConcurrency);
+ } //mID
+ else
+ {
+ static const char * const cSignature2 = "(Ljava/lang/String;)Ljava/sql/CallableStatement;";
+ static jmethodID mID2 = t.pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature2 );OSL_ENSURE(mID2,"Unknown method id!");
+ if( mID2 ){
+ out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID2, str.get() );
+ } //mID
+ }
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+
+ if ( out )
+ object = t.pEnv->NewGlobalRef( out );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Class.cxx b/connectivity/source/drivers/jdbc/Class.cxx
new file mode 100644
index 000000000..862827d12
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Class.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/lang/Class.hxx>
+#include <rtl/ustring.hxx>
+
+using namespace connectivity;
+
+//************ Class: java.lang.Class
+
+jclass java_lang_Class::theClass = nullptr;
+
+java_lang_Class::~java_lang_Class() {}
+
+jclass java_lang_Class::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if (!theClass)
+ theClass = findMyClass("java/lang/Class");
+ return theClass;
+}
+
+java_lang_Class* java_lang_Class::forName(std::u16string_view _par0)
+{
+ jobject out(nullptr);
+ SDBThreadAttach t;
+
+ {
+ OString sClassName = OUStringToOString(_par0, RTL_TEXTENCODING_JAVA_UTF8);
+ sClassName = sClassName.replace('.', '/');
+ out = t.pEnv->FindClass(sClassName.getStr());
+ ThrowSQLException(t.pEnv, nullptr);
+ } //t.pEnv
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out == nullptr ? nullptr : new java_lang_Class(t.pEnv, out);
+}
+
+jobject java_lang_Class::newInstanceObject()
+{
+ SDBThreadAttach t;
+ auto const id = t.pEnv->GetMethodID(static_cast<jclass>(object), "<init>", "()V");
+ if (id == nullptr)
+ {
+ ThrowSQLException(t.pEnv, nullptr);
+ }
+ auto const obj = t.pEnv->NewObject(static_cast<jclass>(object), id);
+ if (obj == nullptr)
+ {
+ ThrowSQLException(t.pEnv, nullptr);
+ }
+ return obj;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Clob.cxx b/connectivity/source/drivers/jdbc/Clob.cxx
new file mode 100644
index 000000000..6108981ac
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Clob.cxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/Clob.hxx>
+#include <java/tools.hxx>
+#include <java/io/Reader.hxx>
+#include <connectivity/dbexception.hxx>
+#include <osl/diagnose.h>
+
+using namespace connectivity;
+
+//************ Class: java.sql.Clob
+
+
+jclass java_sql_Clob::theClass = nullptr;
+
+java_sql_Clob::java_sql_Clob( JNIEnv * pEnv, jobject myObj )
+ : java_lang_Object( pEnv, myObj )
+{
+ SDBThreadAttach::addRef();
+}
+java_sql_Clob::~java_sql_Clob()
+{
+ SDBThreadAttach::releaseRef();
+}
+
+jclass java_sql_Clob::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Clob");
+ return theClass;
+}
+
+sal_Int64 SAL_CALL java_sql_Clob::length( )
+{
+ jlong out(0);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ // initialize temporary variable
+ static const char * const cSignature = "()J";
+ static const char * const cMethodName = "length";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ out = t.pEnv->CallLongMethod( object, mID );
+ ThrowSQLException(t.pEnv,*this);
+ } //t.pEnv
+ return static_cast<sal_Int64>(out);
+}
+
+OUString SAL_CALL java_sql_Clob::getSubString( sal_Int64 pos, sal_Int32 subStringLength )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ OUString aStr;
+ {
+ // initialize temporary variable
+ static const char * const cSignature = "(JI)Ljava/lang/String;";
+ static const char * const cMethodName = "getSubString";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jstring out = static_cast<jstring>(t.pEnv->CallObjectMethod( object, mID,pos,subStringLength));
+ ThrowSQLException(t.pEnv,*this);
+ aStr = JavaString2String(t.pEnv,out);
+ } //t.pEnv
+ // WARNING: the caller becomes the owner of the returned pointer
+ return aStr;
+}
+
+css::uno::Reference< css::io::XInputStream > SAL_CALL java_sql_Clob::getCharacterStream( )
+{
+ SDBThreadAttach t;
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getCharacterStream","()Ljava/io/Reader;", mID);
+
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_io_Reader( t.pEnv, out );
+}
+
+sal_Int64 SAL_CALL java_sql_Clob::position( const OUString& searchstr, sal_Int32 start )
+{
+ jlong out(0);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ jvalue args[1];
+ // convert Parameter
+ args[0].l = convertwchar_tToJavaString(t.pEnv,searchstr);
+ // initialize temporary Variable
+ static const char * const cSignature = "(Ljava/lang/String;I)J";
+ static const char * const cMethodName = "position";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ out = t.pEnv->CallLongMethod( object, mID, args[0].l,start );
+ ThrowSQLException(t.pEnv,*this);
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ } //t.pEnv
+ return static_cast<sal_Int64>(out);
+}
+
+sal_Int64 SAL_CALL java_sql_Clob::positionOfClob( const css::uno::Reference< css::sdbc::XClob >& /*pattern*/, sal_Int64 /*start*/ )
+{
+ ::dbtools::throwFeatureNotImplementedSQLException( "XClob::positionOfClob", *this );
+ // this was put here in CWS warnings01. The previous implementation was defective, as it did ignore
+ // the pattern parameter. Since the effort for proper implementation is rather high - we would need
+ // to translated pattern into a byte[] -, we defer this functionality for the moment (hey, it was
+ // unusable, anyway)
+ // 2005-11-15 / #i57457# / frank.schoenheit@sun.com
+ return 0;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/ConnectionLog.cxx b/connectivity/source/drivers/jdbc/ConnectionLog.cxx
new file mode 100644
index 000000000..96a82fb61
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/ConnectionLog.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <java/sql/ConnectionLog.hxx>
+
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+
+#include <stdio.h>
+
+
+namespace connectivity::java::sql {
+
+
+ namespace
+ {
+ sal_Int32 lcl_getFreeID( ConnectionLog::ObjectType _eType )
+ {
+ static oslInterlockedCount s_nCounts[ ConnectionLog::ObjectTypeCount ] = { 0, 0 };
+ return osl_atomic_increment( s_nCounts + _eType );
+ }
+ }
+
+ ConnectionLog::ConnectionLog( const ::comphelper::EventLogger& _rDriverLog )
+ :ConnectionLog_Base( _rDriverLog )
+ ,m_nObjectID( lcl_getFreeID( CONNECTION ) )
+ {
+ }
+
+
+ ConnectionLog::ConnectionLog( const ConnectionLog& _rSourceLog )
+ :ConnectionLog_Base( _rSourceLog )
+ ,m_nObjectID( _rSourceLog.m_nObjectID )
+ {
+ }
+
+
+ ConnectionLog::ConnectionLog( const ConnectionLog& _rSourceLog, ConnectionLog::ObjectType _eType )
+ :ConnectionLog_Base( _rSourceLog )
+ ,m_nObjectID( lcl_getFreeID( _eType ) )
+ {
+ }
+
+
+} // namespace connectivity::java::sql
+
+
+namespace comphelper::log::convert
+{
+
+
+ using ::com::sun::star::util::Date;
+ using ::com::sun::star::util::Time;
+ using ::com::sun::star::util::DateTime;
+
+
+ OUString convertLogArgToString( const Date& _rDate )
+ {
+ char buffer[ 30 ];
+ const size_t buffer_size = sizeof( buffer );
+ snprintf( buffer, buffer_size, "%04i-%02i-%02i",
+ static_cast<int>(_rDate.Year), static_cast<int>(_rDate.Month), static_cast<int>(_rDate.Day) );
+ return OUString::createFromAscii( buffer );
+ }
+
+
+ OUString convertLogArgToString( const css::util::Time& _rTime )
+ {
+ char buffer[ 30 ];
+ const size_t buffer_size = sizeof( buffer );
+ snprintf( buffer, buffer_size, "%02i:%02i:%02i.%09i",
+ static_cast<int>(_rTime.Hours), static_cast<int>(_rTime.Minutes), static_cast<int>(_rTime.Seconds), static_cast<int>(_rTime.NanoSeconds) );
+ return OUString::createFromAscii( buffer );
+ }
+
+
+ OUString convertLogArgToString( const DateTime& _rDateTime )
+ {
+ char buffer[ sizeof("-32768-65535-65535 65535:65535:65535.4294967295") ];
+ // reserve enough space for hypothetical max length
+ const size_t buffer_size = sizeof( buffer );
+ snprintf( buffer, buffer_size, "%04" SAL_PRIdINT32 "-%02" SAL_PRIuUINT32 "-%02" SAL_PRIuUINT32 " %02" SAL_PRIuUINT32 ":%02" SAL_PRIuUINT32 ":%02" SAL_PRIuUINT32 ".%09" SAL_PRIuUINT32,
+ static_cast<sal_Int32>(_rDateTime.Year), static_cast<sal_uInt32>(_rDateTime.Month), static_cast<sal_uInt32>(_rDateTime.Day),
+ static_cast<sal_uInt32>(_rDateTime.Hours), static_cast<sal_uInt32>(_rDateTime.Minutes), static_cast<sal_uInt32>(_rDateTime.Seconds), _rDateTime.NanoSeconds );
+ return OUString::createFromAscii( buffer );
+ }
+
+
+} // comphelper::log::convert
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/ContextClassLoader.cxx b/connectivity/source/drivers/jdbc/ContextClassLoader.cxx
new file mode 100644
index 000000000..3ab1b88eb
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/ContextClassLoader.cxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/ContextClassLoader.hxx>
+#include <java/lang/Object.hxx>
+
+
+namespace connectivity::jdbc
+{
+
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+
+ using ::connectivity::java_lang_Object;
+
+ ContextClassLoaderScope::ContextClassLoaderScope( JNIEnv& environment, const GlobalRef< jobject >& newClassLoader,
+ const ::comphelper::EventLogger& _rLoggerForErrors, const Reference< XInterface >& _rxErrorContext )
+ :m_environment( environment )
+ ,m_currentThread( environment )
+ ,m_oldContextClassLoader( environment )
+ ,m_setContextClassLoaderMethod( nullptr )
+ {
+ if ( !newClassLoader.is() )
+ return;
+
+ do // artificial loop for easier flow control
+ {
+
+ LocalRef< jclass > threadClass( m_environment );
+ threadClass.set( m_environment.FindClass( "java/lang/Thread" ) );
+ if ( !threadClass.is() )
+ break;
+
+ jmethodID currentThreadMethod( m_environment.GetStaticMethodID(
+ threadClass.get(), "currentThread", "()Ljava/lang/Thread;" ) );
+ if ( currentThreadMethod == nullptr )
+ break;
+
+ m_currentThread.set( m_environment.CallStaticObjectMethod( threadClass.get(), currentThreadMethod ) );
+ if ( !m_currentThread.is() )
+ break;
+
+ jmethodID getContextClassLoaderMethod( m_environment.GetMethodID(
+ threadClass.get(), "getContextClassLoader", "()Ljava/lang/ClassLoader;" ) );
+ if ( getContextClassLoaderMethod == nullptr )
+ break;
+ m_oldContextClassLoader.set( m_environment.CallObjectMethod( m_currentThread.get(), getContextClassLoaderMethod ) );
+ LocalRef< jthrowable > throwable( m_environment, m_environment.ExceptionOccurred() );
+ if ( throwable.is() )
+ break;
+
+ m_setContextClassLoaderMethod = m_environment.GetMethodID(
+ threadClass.get(), "setContextClassLoader", "(Ljava/lang/ClassLoader;)V" );
+ if ( m_setContextClassLoaderMethod == nullptr )
+ break;
+
+ }
+ while ( false );
+
+ if ( !isActive() )
+ {
+ java_lang_Object::ThrowLoggedSQLException( _rLoggerForErrors, &environment, _rxErrorContext );
+ return;
+ }
+
+ // set the new class loader
+ m_environment.CallObjectMethod( m_currentThread.get(), m_setContextClassLoaderMethod, newClassLoader.get() );
+ LocalRef< jthrowable > throwable( m_environment, m_environment.ExceptionOccurred() );
+ if ( throwable.is() )
+ {
+ m_currentThread.reset();
+ m_setContextClassLoaderMethod = nullptr;
+ java_lang_Object::ThrowLoggedSQLException( _rLoggerForErrors, &environment, _rxErrorContext );
+ }
+ }
+
+
+ ContextClassLoaderScope::~ContextClassLoaderScope()
+ {
+ if ( isActive() )
+ {
+ LocalRef< jobject > currentThread( m_currentThread.env(), m_currentThread.release() );
+ jmethodID setContextClassLoaderMethod( m_setContextClassLoaderMethod );
+ m_setContextClassLoaderMethod = nullptr;
+
+ m_environment.CallObjectMethod( currentThread.get(), setContextClassLoaderMethod, m_oldContextClassLoader.get() );
+ m_environment.ExceptionClear();
+ }
+ }
+
+} // namespace connectivity::jdbc
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx b/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx
new file mode 100644
index 000000000..2633fd09b
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/DatabaseMetaData.cxx
@@ -0,0 +1,1463 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <sal/macros.h>
+#include <java/sql/DatabaseMetaData.hxx>
+#include <java/sql/Connection.hxx>
+#include <java/sql/ResultSet.hxx>
+#include <java/sql/SQLException.hxx>
+#include <java/tools.hxx>
+#include <java/lang/String.hxx>
+#include <FDatabaseMetaDataResultSet.hxx>
+#include <comphelper/types.hxx>
+#include <TPrivilegesResultSet.hxx>
+#include <strings.hxx>
+
+using namespace ::comphelper;
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+jclass java_sql_DatabaseMetaData::theClass = nullptr;
+
+java_sql_DatabaseMetaData::~java_sql_DatabaseMetaData()
+{
+ SDBThreadAttach::releaseRef();
+}
+
+jclass java_sql_DatabaseMetaData::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/DatabaseMetaData");
+ return theClass;
+}
+
+java_sql_DatabaseMetaData::java_sql_DatabaseMetaData( JNIEnv * pEnv, jobject myObj, java_sql_Connection& _rConnection )
+ :ODatabaseMetaDataBase( &_rConnection,_rConnection.getConnectionInfo() )
+ ,java_lang_Object( pEnv, myObj )
+ ,m_pConnection( &_rConnection )
+ ,m_aLogger( _rConnection.getLogger() )
+{
+ SDBThreadAttach::addRef();
+}
+
+
+Reference< XResultSet > java_sql_DatabaseMetaData::impl_getTypeInfo_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethod( "getTypeInfo", mID );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getCatalogs( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethod( "getCatalogs", mID );
+}
+
+OUString java_sql_DatabaseMetaData::impl_getCatalogSeparator_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getCatalogSeparator", mID );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getSchemas( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethod( "getSchemas", mID );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getColumnPrivileges(
+ const Any& catalog, const OUString& schema, const OUString& table, const OUString& columnNamePattern )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getColumnPrivileges", mID, catalog, schema, table, &columnNamePattern );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getColumns(
+ const Any& catalog, const OUString& schemaPattern, const OUString& tableNamePattern, const OUString& columnNamePattern )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getColumns", mID, catalog, schemaPattern, tableNamePattern, &columnNamePattern );
+}
+
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getTables(
+ const Any& catalog, const OUString& schemaPattern, const OUString& tableNamePattern, const Sequence< OUString >& _types )
+{
+ static const char * const cMethodName = "getTables";
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, cMethodName );
+
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)Ljava/sql/ResultSet;";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ OSL_VERIFY( !isExceptionOccurred(t.pEnv) );
+ jvalue args[4];
+
+ args[3].l = nullptr;
+ sal_Int32 typeFilterCount = _types.getLength();
+ if ( typeFilterCount )
+ {
+ jobjectArray pObjArray = t.pEnv->NewObjectArray( static_cast<jsize>(typeFilterCount), java_lang_String::st_getMyClass(), nullptr );
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ const OUString* typeFilter = _types.getConstArray();
+ bool bIncludeAllTypes = false;
+ for ( sal_Int32 i=0; i<typeFilterCount; ++i, ++typeFilter )
+ {
+ if ( *typeFilter == "%" )
+ {
+ bIncludeAllTypes = true;
+ break;
+ }
+ jstring aT = convertwchar_tToJavaString( t.pEnv, *typeFilter );
+ t.pEnv->SetObjectArrayElement( pObjArray, static_cast<jsize>(i), aT );
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ }
+
+ if ( bIncludeAllTypes )
+ {
+ // the SDBC API allows to pass "%" as table type filter, but in JDBC, "all table types"
+ // is represented by the table type being <null/>
+ t.pEnv->DeleteLocalRef( pObjArray );
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ }
+ else
+ {
+ args[3].l = pObjArray;
+ }
+ }
+ // if we are to display "all catalogs", then respect m_aCatalogRestriction
+ Any aCatalogFilter( catalog );
+ if ( !aCatalogFilter.hasValue() )
+ aCatalogFilter = m_pConnection->getCatalogRestriction();
+ // similar for schema
+ Any aSchemaFilter;
+ if ( schemaPattern == "%" )
+ aSchemaFilter = m_pConnection->getSchemaRestriction();
+ else
+ aSchemaFilter <<= schemaPattern;
+
+ args[0].l = aCatalogFilter.hasValue() ? convertwchar_tToJavaString( t.pEnv, ::comphelper::getString( aCatalogFilter ) ) : nullptr;
+ args[1].l = aSchemaFilter.hasValue() ? convertwchar_tToJavaString( t.pEnv, ::comphelper::getString( aSchemaFilter ) ) : nullptr;
+ args[2].l = convertwchar_tToJavaString(t.pEnv,tableNamePattern);
+ out = t.pEnv->CallObjectMethod( object, mID, args[0].l, args[1].l,args[2].l,args[3].l);
+ jthrowable jThrow = t.pEnv->ExceptionOccurred();
+ if ( jThrow )
+ t.pEnv->ExceptionClear();// we have to clear the exception here because we want to handle it below
+ if ( aCatalogFilter.hasValue() )
+ {
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ }
+ if(args[1].l)
+ {
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ }
+ if(!tableNamePattern.isEmpty())
+ {
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[2].l));
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ }
+ //for(INT16 i=0;i<len;i++)
+ if ( args[3].l )
+ {
+ t.pEnv->DeleteLocalRef( static_cast<jobjectArray>(args[3].l) );
+ OSL_VERIFY( !isExceptionOccurred( t.pEnv ) );
+ }
+
+ if ( jThrow )
+ {
+ if ( t.pEnv->IsInstanceOf( jThrow,java_sql_SQLException_BASE::st_getMyClass() ) )
+ {
+ java_sql_SQLException_BASE aException( t.pEnv, jThrow );
+ SQLException e( aException.getMessage(),
+ *this,
+ aException.getSQLState(),
+ aException.getErrorCode(),
+ Any()
+ );
+ throw e;
+ }
+ }
+ }
+
+ if ( !out )
+ return nullptr;
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_SUCCESS, cMethodName );
+ return new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection);
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getProcedureColumns(
+ const Any& catalog, const OUString& schemaPattern, const OUString& procedureNamePattern, const OUString& columnNamePattern )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getProcedureColumns", mID, catalog, schemaPattern, procedureNamePattern, &columnNamePattern );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getProcedures( const Any&
+ catalog, const OUString& schemaPattern, const OUString& procedureNamePattern )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getProcedures", mID, catalog, schemaPattern, procedureNamePattern );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getVersionColumns(
+ const Any& catalog, const OUString& schema, const OUString& table )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getVersionColumns", mID, catalog, schema, table );
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxBinaryLiteralLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxBinaryLiteralLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxRowSize( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxRowSize", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxCatalogNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxCatalogNameLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxCharLiteralLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxCharLiteralLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxColumnNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxColumnNameLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxColumnsInIndex( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxColumnsInIndex", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxCursorNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxCursorNameLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxConnections( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxConnections", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxColumnsInTable( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxColumnsInTable", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxStatementLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxStatementLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxTableNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxTableNameLength", mID);
+}
+
+sal_Int32 java_sql_DatabaseMetaData::impl_getMaxTablesInSelect_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxTablesInSelect", mID);
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getExportedKeys(
+ const Any& catalog, const OUString& schema, const OUString& table )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getExportedKeys", mID, catalog, schema, table );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getImportedKeys(
+ const Any& catalog, const OUString& schema, const OUString& table )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getImportedKeys", mID, catalog, schema, table );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getPrimaryKeys(
+ const Any& catalog, const OUString& schema, const OUString& table )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethodWithStrings( "getPrimaryKeys", mID, catalog, schema, table );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getIndexInfo(
+ const Any& catalog, const OUString& schema, const OUString& table,
+ sal_Bool unique, sal_Bool approximate )
+{
+ static const char * const cMethodName = "getIndexInfo";
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, cMethodName );
+
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZ)Ljava/sql/ResultSet;";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jvalue args[5];
+ // convert Parameter
+ args[0].l = catalog.hasValue() ? convertwchar_tToJavaString(t.pEnv,comphelper::getString(catalog)) : nullptr;
+ args[1].l = schema.toChar() == '%' ? nullptr : convertwchar_tToJavaString(t.pEnv,schema);
+ args[2].l = convertwchar_tToJavaString(t.pEnv,table);
+ args[3].z = unique;
+ args[4].z = approximate;
+ out = t.pEnv->CallObjectMethod( object, mID, args[0].l,args[1].l,args[2].l,args[3].z,args[4].z );
+
+ // and clean up
+ if(catalog.hasValue())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ if(args[1].l)
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ if(!table.isEmpty())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[2].l));
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ if ( !out )
+ return nullptr;
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_SUCCESS, cMethodName );
+ return new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection);
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getBestRowIdentifier(
+ const Any& catalog, const OUString& schema, const OUString& table, sal_Int32 scope,
+ sal_Bool nullable )
+{
+ static const char * const cMethodName = "getBestRowIdentifier";
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, cMethodName );
+
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZ)Ljava/sql/ResultSet;";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jvalue args[3];
+ // convert Parameter
+ args[0].l = catalog.hasValue() ? convertwchar_tToJavaString(t.pEnv,comphelper::getString(catalog)) : nullptr;
+ args[1].l = schema.toChar() == '%' ? nullptr : convertwchar_tToJavaString(t.pEnv,schema);
+ args[2].l = convertwchar_tToJavaString(t.pEnv,table);
+ out = t.pEnv->CallObjectMethod( object, mID, args[0].l,args[1].l,args[2].l,scope,nullable);
+
+ // and cleanup
+ if(catalog.hasValue())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ if(args[1].l)
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ if(!table.isEmpty())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[2].l));
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+
+ if ( !out )
+ return nullptr;
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_SUCCESS, cMethodName );
+ return new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection);
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getTablePrivileges(
+ const Any& catalog, const OUString& schemaPattern, const OUString& tableNamePattern )
+{
+ if ( m_pConnection->isIgnoreDriverPrivilegesEnabled() )
+ return new OResultSetPrivileges(this,catalog,schemaPattern,tableNamePattern);
+
+ static jmethodID mID(nullptr);
+ Reference< XResultSet > xReturn( impl_callResultSetMethodWithStrings( "getTablePrivileges", mID, catalog, schemaPattern, tableNamePattern ) );
+
+ if ( xReturn.is() )
+ {
+ // we have to check the result columns for the tables privileges
+ Reference< XResultSetMetaDataSupplier > xMetaSup(xReturn,UNO_QUERY);
+ if ( xMetaSup.is() )
+ {
+ Reference< XResultSetMetaData> xMeta = xMetaSup->getMetaData();
+ if ( xMeta.is() && xMeta->getColumnCount() != 7 )
+ {
+ // here we know that the count of column doesn't match
+ std::map<sal_Int32,sal_Int32> aColumnMatching;
+ static const std::u16string_view sPrivs[] = {
+ u"TABLE_CAT",
+ u"TABLE_SCHEM",
+ u"TABLE_NAME",
+ u"GRANTOR",
+ u"GRANTEE",
+ u"PRIVILEGE",
+ u"IS_GRANTABLE"
+ };
+
+ OUString sColumnName;
+ sal_Int32 nCount = xMeta->getColumnCount();
+ for (sal_Int32 i = 1 ; i <= nCount ; ++i)
+ {
+ sColumnName = xMeta->getColumnName(i);
+ for (size_t j = 0 ; j < std::size(sPrivs); ++j)
+ {
+ if ( sPrivs[j] == sColumnName )
+ {
+ aColumnMatching.emplace(i,j+1);
+ break;
+ }
+ }
+
+ }
+ // fill our own resultset
+ rtl::Reference<ODatabaseMetaDataResultSet> pNewPrivRes = new ODatabaseMetaDataResultSet( ODatabaseMetaDataResultSet::eTablePrivileges );
+ Reference< XResultSet > xTemp = xReturn;
+ xReturn = pNewPrivRes;
+ ODatabaseMetaDataResultSet::ORows aRows;
+ Reference< XRow > xRow(xTemp,UNO_QUERY);
+ OUString sValue;
+
+ ODatabaseMetaDataResultSet::ORow aRow(8);
+ while ( xRow.is() && xTemp->next() )
+ {
+ for (const auto& [nCol, nPriv] : aColumnMatching)
+ {
+ sValue = xRow->getString(nCol);
+ if ( xRow->wasNull() )
+ aRow[nPriv] = ODatabaseMetaDataResultSet::getEmptyValue();
+ else
+ aRow[nPriv] = new ORowSetValueDecorator(sValue);
+ }
+
+ aRows.push_back(aRow);
+ }
+ pNewPrivRes->setRows(std::move(aRows));
+ }
+ }
+ }
+ return xReturn;
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getCrossReference(
+ const Any& primaryCatalog, const OUString& primarySchema,
+ const OUString& primaryTable, const Any& foreignCatalog,
+ const OUString& foreignSchema, const OUString& foreignTable )
+{
+ static const char * const cMethodName = "getCrossReference";
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, cMethodName );
+
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/sql/ResultSet;";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jvalue args[6];
+ // convert Parameter
+ args[0].l = primaryCatalog.hasValue() ? convertwchar_tToJavaString(t.pEnv,comphelper::getString(primaryCatalog)) : nullptr;
+ args[1].l = primarySchema.toChar() == '%' ? nullptr : convertwchar_tToJavaString(t.pEnv,primarySchema);
+ args[2].l = convertwchar_tToJavaString(t.pEnv,primaryTable);
+ args[3].l = foreignCatalog.hasValue() ? convertwchar_tToJavaString(t.pEnv,comphelper::getString(foreignCatalog)) : nullptr;
+ args[4].l = foreignSchema.toChar() == '%' ? nullptr : convertwchar_tToJavaString(t.pEnv,foreignSchema);
+ args[5].l = convertwchar_tToJavaString(t.pEnv,foreignTable);
+ out = t.pEnv->CallObjectMethod( object, mID, args[0].l,args[2].l,args[2].l,args[3].l,args[4].l,args[5].l );
+
+ // and clean up
+ if(primaryCatalog.hasValue())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ if(args[1].l)
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ if(!primaryTable.isEmpty())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[2].l));
+ if(foreignCatalog.hasValue())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[3].l));
+ if(args[4].l)
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[4].l));
+ if(!foreignTable.isEmpty())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[5].l));
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+
+ if ( !out )
+ return nullptr;
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_SUCCESS, cMethodName );
+ return new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection);
+}
+
+
+bool java_sql_DatabaseMetaData::impl_callBooleanMethod( const char* _pMethodName, jmethodID& _inout_MethodID )
+{
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, _pMethodName );
+ bool out( java_lang_Object::callBooleanMethod(_pMethodName,_inout_MethodID) );
+ m_aLogger.log< const char*, bool>( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, _pMethodName, out );
+ return out;
+}
+
+
+OUString java_sql_DatabaseMetaData::impl_callStringMethod( const char* _pMethodName, jmethodID& _inout_MethodID )
+{
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, _pMethodName );
+
+ const OUString sReturn( callStringMethod(_pMethodName,_inout_MethodID) );
+ if ( m_aLogger.isLoggable( LogLevel::FINEST ) )
+ {
+ OUString sLoggedResult( sReturn );
+ if ( sLoggedResult.isEmpty() )
+ sLoggedResult = "<empty string>";
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, _pMethodName, sLoggedResult );
+ }
+
+ return sReturn;
+}
+
+sal_Int32 java_sql_DatabaseMetaData::impl_callIntMethod_ThrowSQL(const char* _pMethodName, jmethodID& _inout_MethodID)
+{
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, _pMethodName );
+ sal_Int32 out( callIntMethod_ThrowSQL(_pMethodName,_inout_MethodID) );
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, _pMethodName, out );
+ return out;
+}
+
+sal_Int32 java_sql_DatabaseMetaData::impl_callIntMethod_ThrowRuntime(const char* _pMethodName, jmethodID& _inout_MethodID)
+{
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, _pMethodName );
+ sal_Int32 out( callIntMethod_ThrowRuntime(_pMethodName,_inout_MethodID) );
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, _pMethodName, out );
+ return out;
+}
+
+bool java_sql_DatabaseMetaData::impl_callBooleanMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument )
+{
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD_ARG1, _pMethodName, _nArgument );
+
+ bool out( callBooleanMethodWithIntArg(_pMethodName,_inout_MethodID,_nArgument) );
+
+ m_aLogger.log< const char*, bool >( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, _pMethodName, out );
+ return out;
+}
+
+
+Reference< XResultSet > java_sql_DatabaseMetaData::impl_callResultSetMethod( const char* _pMethodName, jmethodID& _inout_MethodID )
+{
+ SDBThreadAttach t;
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD, _pMethodName );
+ jobject out(callResultSetMethod(t.env(),_pMethodName,_inout_MethodID));
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_SUCCESS, _pMethodName );
+ return new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection);
+}
+
+
+Reference< XResultSet > java_sql_DatabaseMetaData::impl_callResultSetMethodWithStrings( const char* _pMethodName, jmethodID& _inout_MethodID,
+ const Any& _rCatalog, const OUString& _rSchemaPattern, const OUString& _rLeastPattern,
+ const OUString* _pOptionalAdditionalString )
+{
+ bool bCatalog = _rCatalog.hasValue();
+ OUString sCatalog;
+ _rCatalog >>= sCatalog;
+
+ bool bSchema = _rSchemaPattern.toChar() != '%';
+
+ // log the call
+ if ( m_aLogger.isLoggable( LogLevel::FINEST ) )
+ {
+ OUString sCatalogLog = bCatalog ? sCatalog : OUString( "null" );
+ OUString sSchemaLog = bSchema ? _rSchemaPattern : OUString( "null" );
+ if ( _pOptionalAdditionalString )
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD_ARG4, _pMethodName, sCatalogLog, sSchemaLog, _rLeastPattern, *_pOptionalAdditionalString );
+ else
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD_ARG3, _pMethodName, sCatalogLog, sSchemaLog, _rLeastPattern );
+ }
+
+ jobject out(nullptr);
+
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_sql_DatabaseMetaData::impl_callResultSetMethodWithStrings: no Java environment anymore!" );
+
+ {
+ const char* pSignature = _pOptionalAdditionalString
+ ? "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/sql/ResultSet;"
+ : "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/sql/ResultSet;";
+ // obtain method ID
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,pSignature, _inout_MethodID);
+
+ // call method
+
+ {
+ jvalue args[4];
+ // convert parameters
+ args[0].l = bCatalog ? convertwchar_tToJavaString( t.pEnv, sCatalog ) : nullptr;
+ args[1].l = bSchema ? convertwchar_tToJavaString( t.pEnv, _rSchemaPattern ) : nullptr;
+ args[2].l = convertwchar_tToJavaString( t.pEnv, _rLeastPattern );
+ args[3].l = _pOptionalAdditionalString ? convertwchar_tToJavaString( t.pEnv, *_pOptionalAdditionalString ) : nullptr;
+
+ // actually do the call
+ if ( _pOptionalAdditionalString )
+ out = t.pEnv->CallObjectMethod( object, _inout_MethodID, args[0].l, args[1].l, args[2].l, args[3].l );
+ else
+ out = t.pEnv->CallObjectMethod( object, _inout_MethodID, args[0].l, args[1].l, args[2].l );
+
+ // clean up
+ if ( args[0].l )
+ t.pEnv->DeleteLocalRef( static_cast<jstring>(args[0].l) );
+ if ( args[1].l )
+ t.pEnv->DeleteLocalRef( static_cast<jstring>(args[1].l) );
+ if ( args[2].l )
+ t.pEnv->DeleteLocalRef( static_cast<jstring>(args[2].l) );
+ if ( args[3].l )
+ t.pEnv->DeleteLocalRef( static_cast<jstring>(args[3].l) );
+
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+
+ if ( !out )
+ return nullptr;
+
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_SUCCESS, _pMethodName );
+ return new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection);
+}
+
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::doesMaxRowSizeIncludeBlobs( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "doesMaxRowSizeIncludeBlobs", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::storesLowerCaseQuotedIdentifiers( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "storesLowerCaseQuotedIdentifiers", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::storesLowerCaseIdentifiers( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "storesLowerCaseIdentifiers", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_storesMixedCaseQuotedIdentifiers_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "storesMixedCaseQuotedIdentifiers", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::storesMixedCaseIdentifiers( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "storesMixedCaseIdentifiers", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::storesUpperCaseQuotedIdentifiers( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "storesUpperCaseQuotedIdentifiers", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::storesUpperCaseIdentifiers( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "storesUpperCaseIdentifiers", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsAlterTableWithAddColumn_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsAlterTableWithAddColumn", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsAlterTableWithDropColumn_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsAlterTableWithDropColumn", mID );
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxIndexLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxIndexLength", mID);
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsNonNullableColumns( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsNonNullableColumns", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getCatalogTerm( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getCatalogTerm", mID );
+}
+
+OUString java_sql_DatabaseMetaData::impl_getIdentifierQuoteString_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getIdentifierQuoteString", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getExtraNameCharacters( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getExtraNameCharacters", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsDifferentTableCorrelationNames( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsDifferentTableCorrelationNames", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_isCatalogAtStart_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "isCatalogAtStart", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::dataDefinitionIgnoredInTransactions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "dataDefinitionIgnoredInTransactions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::dataDefinitionCausesTransactionCommit( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "dataDefinitionCausesTransactionCommit", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsDataManipulationTransactionsOnly( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsDataManipulationTransactionsOnly", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsDataDefinitionAndDataManipulationTransactions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsPositionedDelete( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsPositionedDelete", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsPositionedUpdate( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsPositionedUpdate", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsOpenStatementsAcrossRollback( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsOpenStatementsAcrossRollback", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsOpenStatementsAcrossCommit( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsOpenStatementsAcrossCommit", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsOpenCursorsAcrossCommit( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsOpenCursorsAcrossCommit", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsOpenCursorsAcrossRollback( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsOpenCursorsAcrossRollback", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "supportsTransactionIsolationLevel", mID, level );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsSchemasInDataManipulation_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSchemasInDataManipulation", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsANSI92FullSQL( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsANSI92FullSQL", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsANSI92EntryLevelSQL( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsANSI92EntryLevelSQL", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsIntegrityEnhancementFacility( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsIntegrityEnhancementFacility", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSchemasInIndexDefinitions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSchemasInIndexDefinitions", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsSchemasInTableDefinitions_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSchemasInTableDefinitions", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsCatalogsInTableDefinitions_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCatalogsInTableDefinitions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsCatalogsInIndexDefinitions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCatalogsInIndexDefinitions", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsCatalogsInDataManipulation_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCatalogsInDataManipulation", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsOuterJoins( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsOuterJoins", mID );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getTableTypes( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callResultSetMethod( "getTableTypes", mID );
+}
+
+sal_Int32 java_sql_DatabaseMetaData::impl_getMaxStatements_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxStatements", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxProcedureNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxProcedureNameLength", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxSchemaNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxSchemaNameLength", mID);
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsTransactions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsTransactions", mID );
+}
+
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::allProceduresAreCallable( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "allProceduresAreCallable", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsStoredProcedures( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsStoredProcedures", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSelectForUpdate( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSelectForUpdate", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::allTablesAreSelectable( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "allTablesAreSelectable", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::isReadOnly( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "isReadOnly", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::usesLocalFiles( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "usesLocalFiles", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::usesLocalFilePerTable( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "usesLocalFilePerTable", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsTypeConversion( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsTypeConversion", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::nullPlusNonNullIsNull( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "nullPlusNonNullIsNull", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsColumnAliasing( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsColumnAliasing", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsTableCorrelationNames( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsTableCorrelationNames", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_Int32 toType )
+{
+ static const char* const pMethodName = "supportsConvert";
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD_ARG2, pMethodName, fromType, toType );
+
+ bool out( false );
+ SDBThreadAttach t;
+
+ {
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, pMethodName,"(II)Z", mID);
+ out = t.pEnv->CallBooleanMethod( object, mID, fromType, toType );
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+
+ m_aLogger.log< const char*, bool >( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, pMethodName, out );
+ return out;
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsExpressionsInOrderBy( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsExpressionsInOrderBy", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsGroupBy( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsGroupBy", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsGroupByBeyondSelect( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsGroupByBeyondSelect", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsGroupByUnrelated( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsGroupByUnrelated", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsMultipleTransactions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsMultipleTransactions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsMultipleResultSets( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsMultipleResultSets", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsLikeEscapeClause( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsLikeEscapeClause", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsOrderByUnrelated( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsOrderByUnrelated", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsUnion( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsUnion", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsUnionAll( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsUnionAll", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsMixedCaseIdentifiers( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsMixedCaseIdentifiers", mID );
+}
+
+bool java_sql_DatabaseMetaData::impl_supportsMixedCaseQuotedIdentifiers_throw( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsMixedCaseQuotedIdentifiers", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::nullsAreSortedAtEnd( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "nullsAreSortedAtEnd", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::nullsAreSortedAtStart( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "nullsAreSortedAtStart", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::nullsAreSortedHigh( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "nullsAreSortedHigh", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::nullsAreSortedLow( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "nullsAreSortedLow", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSchemasInProcedureCalls( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSchemasInProcedureCalls", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSchemasInPrivilegeDefinitions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSchemasInPrivilegeDefinitions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsCatalogsInProcedureCalls( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCatalogsInProcedureCalls", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCatalogsInPrivilegeDefinitions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsCorrelatedSubqueries( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCorrelatedSubqueries", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSubqueriesInComparisons( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSubqueriesInComparisons", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSubqueriesInExists( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSubqueriesInExists", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSubqueriesInIns( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSubqueriesInIns", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsSubqueriesInQuantifieds( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsSubqueriesInQuantifieds", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsANSI92IntermediateSQL( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsANSI92IntermediateSQL", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getURL( )
+{
+ OUString sURL = m_pConnection->getURL();
+ if ( sURL.isEmpty() )
+ {
+ static jmethodID mID(nullptr);
+ sURL = impl_callStringMethod( "getURL", mID );
+ }
+ return sURL;
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getUserName( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getUserName", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getDriverName( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getDriverName", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getDriverVersion( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getDriverVersion", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getDatabaseProductVersion( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getDatabaseProductVersion", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getDatabaseProductName( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getDatabaseProductName", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getProcedureTerm( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getProcedureTerm", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getSchemaTerm( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getSchemaTerm", mID );
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getDriverMajorVersion( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowRuntime("getDriverMajorVersion", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getDefaultTransactionIsolation( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getDefaultTransactionIsolation", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getDriverMinorVersion( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowRuntime("getDriverMinorVersion", mID);
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getSQLKeywords( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getSQLKeywords", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getSearchStringEscape( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getSearchStringEscape", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getStringFunctions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getStringFunctions", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getTimeDateFunctions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getTimeDateFunctions", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getSystemFunctions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getSystemFunctions", mID );
+}
+
+OUString SAL_CALL java_sql_DatabaseMetaData::getNumericFunctions( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callStringMethod( "getNumericFunctions", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsExtendedSQLGrammar( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsExtendedSQLGrammar", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsCoreSQLGrammar( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsCoreSQLGrammar", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsMinimumSQLGrammar( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsMinimumSQLGrammar", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsFullOuterJoins( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsFullOuterJoins", mID );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsLimitedOuterJoins( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsLimitedOuterJoins", mID );
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxColumnsInGroupBy( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxColumnsInGroupBy", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxColumnsInOrderBy( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxColumnsInOrderBy", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxColumnsInSelect( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxColumnsInSelect", mID);
+}
+
+sal_Int32 SAL_CALL java_sql_DatabaseMetaData::getMaxUserNameLength( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callIntMethod_ThrowSQL("getMaxUserNameLength", mID);
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsResultSetType( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "supportsResultSetType", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsResultSetConcurrency( sal_Int32 setType, sal_Int32 concurrency )
+{
+ static const char* const pMethodName = "supportsResultSetConcurrency";
+ m_aLogger.log( LogLevel::FINEST, STR_LOG_META_DATA_METHOD_ARG2, pMethodName, setType, concurrency );
+
+ bool out( false );
+ SDBThreadAttach t;
+
+ {
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, pMethodName,"(II)Z", mID);
+ out = t.pEnv->CallBooleanMethod( object, mID, setType, concurrency);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+
+ m_aLogger.log< const char*, bool >( LogLevel::FINEST, STR_LOG_META_DATA_RESULT, pMethodName, out );
+ return out;
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "ownUpdatesAreVisible", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "ownDeletesAreVisible", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "ownInsertsAreVisible", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "othersUpdatesAreVisible", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "othersDeletesAreVisible", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "othersInsertsAreVisible", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::updatesAreDetected( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "updatesAreDetected", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::deletesAreDetected( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "deletesAreDetected", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::insertsAreDetected( sal_Int32 setType )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethodWithIntArg( "insertsAreDetected", mID, setType );
+}
+
+sal_Bool SAL_CALL java_sql_DatabaseMetaData::supportsBatchUpdates( )
+{
+ static jmethodID mID(nullptr);
+ return impl_callBooleanMethod( "supportsBatchUpdates", mID );
+}
+
+Reference< XResultSet > SAL_CALL java_sql_DatabaseMetaData::getUDTs(
+ const Any& catalog, const OUString& schemaPattern, const OUString& typeNamePattern,
+ const Sequence< sal_Int32 >& types )
+{
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+
+
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I)Ljava/sql/ResultSet;";
+ static const char * const cMethodName = "getUDTs";
+ // dismiss Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ {
+ jvalue args[4];
+ // initialize temporary Variable
+ args[0].l = catalog.hasValue() ? convertwchar_tToJavaString(t.pEnv,comphelper::getString(catalog)) : nullptr;
+ args[1].l = schemaPattern.toChar() == '%' ? nullptr : convertwchar_tToJavaString(t.pEnv,schemaPattern);
+ args[2].l = convertwchar_tToJavaString(t.pEnv,typeNamePattern);
+ jintArray pArray = t.pEnv->NewIntArray(types.getLength());
+ jint * typesData = reinterpret_cast<jint *>(
+ const_cast<sal_Int32 *>(types.getConstArray()));
+ // 4th param of Set*ArrayRegion changed from pointer to non-const to
+ // pointer to const between <http://docs.oracle.com/javase/6/docs/
+ // technotes/guides/jni/spec/functions.html#wp22933> and
+ // <http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/
+ // functions.html#wp22933>; work around that difference in a way
+ // that doesn't trigger loplugin:redundantcast
+ t.pEnv->SetIntArrayRegion(pArray,0,types.getLength(),typesData);
+ args[3].l = pArray;
+
+ out = t.pEnv->CallObjectMethod( object, mID, args[0].l, args[1].l,args[2].l,args[3].l);
+
+ if(catalog.hasValue())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ if(!schemaPattern.isEmpty())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ if(!typeNamePattern.isEmpty())
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[2].l));
+ if(args[3].l)
+ t.pEnv->DeleteLocalRef(static_cast<jintArray>(args[3].l));
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+
+ return out ? new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection ) : nullptr;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Date.cxx b/connectivity/source/drivers/jdbc/Date.cxx
new file mode 100644
index 000000000..6086e8190
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Date.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/util/Date.hxx>
+
+using namespace connectivity;
+
+//************ Class: java.util.Date
+
+jclass java_util_Date::theClass = nullptr;
+
+java_util_Date::~java_util_Date() {}
+
+jclass java_util_Date::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if (!theClass)
+ theClass = findMyClass("java/util/Date");
+ return theClass;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/DriverPropertyInfo.cxx b/connectivity/source/drivers/jdbc/DriverPropertyInfo.cxx
new file mode 100644
index 000000000..3fb157fb2
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/DriverPropertyInfo.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/DriverPropertyInfo.hxx>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+//************ Class: java.sql.Driver
+
+jclass java_sql_DriverPropertyInfo::theClass = nullptr;
+
+java_sql_DriverPropertyInfo::~java_sql_DriverPropertyInfo() {}
+
+jclass java_sql_DriverPropertyInfo::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if (!theClass)
+ theClass = findMyClass("java/sql/DriverPropertyInfo");
+ return theClass;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Exception.cxx b/connectivity/source/drivers/jdbc/Exception.cxx
new file mode 100644
index 000000000..9fa2d5c18
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Exception.cxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/lang/Exception.hxx>
+using namespace connectivity;
+
+//************ Class: java.lang.Exception
+
+jclass java_lang_Exception::theClass = nullptr;
+
+java_lang_Exception::~java_lang_Exception() {}
+
+jclass java_lang_Exception::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if (!theClass)
+ theClass = findMyClass("java/lang/Exception");
+ return theClass;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/InputStream.cxx b/connectivity/source/drivers/jdbc/InputStream.cxx
new file mode 100644
index 000000000..c384760b3
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/InputStream.cxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <com/sun/star/io/BufferSizeExceededException.hpp>
+#include <java/io/InputStream.hxx>
+#include <osl/diagnose.h>
+
+#include <string.h>
+
+using namespace connectivity;
+
+#if OSL_DEBUG_LEVEL > 0
+#define THROW_WHERE SAL_WHERE
+#else
+#define THROW_WHERE ""
+#endif
+
+
+//************ Class: java.io.InputStream
+
+
+jclass java_io_InputStream::theClass = nullptr;
+java_io_InputStream::java_io_InputStream( JNIEnv * pEnv, jobject myObj )
+ : java_lang_Object( pEnv, myObj )
+{
+ SDBThreadAttach::addRef();
+}
+java_io_InputStream::~java_io_InputStream()
+{
+ SDBThreadAttach::releaseRef();
+}
+
+jclass java_io_InputStream::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/io/InputStream");
+ return theClass;
+}
+
+
+sal_Int32 SAL_CALL java_io_InputStream::readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+{
+ return readBytes(aData,nMaxBytesToRead);
+}
+
+void SAL_CALL java_io_InputStream::skipBytes( sal_Int32 nBytesToSkip )
+{
+ static jmethodID mID(nullptr);
+ callIntMethodWithIntArg_ThrowRuntime("skip",mID,nBytesToSkip);
+}
+
+sal_Int32 SAL_CALL java_io_InputStream::available( )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowRuntime("available", mID);
+}
+
+void SAL_CALL java_io_InputStream::closeInput( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowRuntime("close",mID);
+}
+
+sal_Int32 SAL_CALL java_io_InputStream::readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+{
+ if (nBytesToRead < 0)
+ throw css::io::BufferSizeExceededException( THROW_WHERE, *this );
+
+ jint out(0);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ jbyteArray pByteArray = t.pEnv->NewByteArray(nBytesToRead);
+ static const char * const cSignature = "([BII)I";
+ static const char * const cMethodName = "read";
+ // execute Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwRuntime(t.pEnv, cMethodName,cSignature, mID);
+ out = t.pEnv->CallIntMethod( object, mID, pByteArray, 0, nBytesToRead );
+ if ( !out )
+ ThrowRuntimeException(t.pEnv,*this);
+ if(out > 0)
+ {
+ jboolean p = false;
+ aData.realloc ( out );
+ memcpy(aData.getArray(),t.pEnv->GetByteArrayElements(pByteArray,&p),out);
+ }
+ t.pEnv->DeleteLocalRef(pByteArray);
+ } //t.pEnv
+ return out;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/JBigDecimal.cxx b/connectivity/source/drivers/jdbc/JBigDecimal.cxx
new file mode 100644
index 000000000..7cbcd6486
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/JBigDecimal.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/math/BigDecimal.hxx>
+#include <java/tools.hxx>
+using namespace connectivity;
+
+//************ Class: java.lang.Boolean
+
+
+jclass java_math_BigDecimal::theClass = nullptr;
+
+java_math_BigDecimal::~java_math_BigDecimal()
+{}
+
+jclass java_math_BigDecimal::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/math/BigDecimal");
+ return theClass;
+}
+
+java_math_BigDecimal::java_math_BigDecimal( const OUString& _par0 ): java_lang_Object( nullptr, nullptr )
+{
+ SDBThreadAttach t;
+ if( !t.pEnv )
+ return;
+ // Java-Call for the Constructor
+ // initialize temporary Variable
+ static const char * const cSignature = "(Ljava/lang/String;)V";
+ jobject tempObj;
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, "<init>",cSignature, mID);
+
+ jstring str = convertwchar_tToJavaString(t.pEnv,_par0.replace(',','.'));
+ tempObj = t.pEnv->NewObject( getMyClass(), mID, str );
+ t.pEnv->DeleteLocalRef(str);
+ saveRef( t.pEnv, tempObj );
+ t.pEnv->DeleteLocalRef( tempObj );
+ ThrowSQLException( t.pEnv, nullptr );
+ // and cleanup
+}
+
+java_math_BigDecimal::java_math_BigDecimal( const double& _par0 ): java_lang_Object( nullptr, nullptr )
+{
+ SDBThreadAttach t;
+ if( !t.pEnv )
+ return;
+ // Java-Call for the Constructor
+ // initialize temporary Variable
+ static const char * const cSignature = "(D)V";
+ jobject tempObj;
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, "<init>",cSignature, mID);
+ tempObj = t.pEnv->NewObject( getMyClass(), mID, _par0 );
+ saveRef( t.pEnv, tempObj );
+ t.pEnv->DeleteLocalRef( tempObj );
+ ThrowSQLException( t.pEnv, nullptr );
+ // and cleanup
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/JConnection.cxx b/connectivity/source/drivers/jdbc/JConnection.cxx
new file mode 100644
index 000000000..19391e60e
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/JConnection.cxx
@@ -0,0 +1,803 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <java/sql/Connection.hxx>
+#include <java/lang/Class.hxx>
+#include <java/tools.hxx>
+#include <java/ContextClassLoader.hxx>
+#include <java/sql/DatabaseMetaData.hxx>
+#include <java/sql/JStatement.hxx>
+#include <java/sql/Driver.hxx>
+#include <java/sql/PreparedStatement.hxx>
+#include <java/sql/CallableStatement.hxx>
+#include <java/sql/SQLWarning.hxx>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <connectivity/dbexception.hxx>
+#include <java/util/Property.hxx>
+#include <java/LocalRef.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <jvmaccess/classpath.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <jni.h>
+#include <strings.hrc>
+#include <unotools/confignode.hxx>
+#include <strings.hxx>
+
+#include <vector>
+#include <memory>
+
+using namespace connectivity;
+using namespace connectivity::jdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+namespace {
+
+struct ClassMapEntry {
+ ClassMapEntry(
+ OUString const & theClassPath, OUString const & theClassName):
+ classPath(theClassPath), className(theClassName), classLoader(nullptr),
+ classObject(nullptr) {}
+
+ OUString classPath;
+ OUString className;
+ jweak classLoader;
+ jweak classObject;
+};
+
+typedef std::vector< ClassMapEntry > ClassMap;
+
+struct ClassMapData {
+ osl::Mutex mutex;
+
+ ClassMap map;
+};
+
+template < typename T >
+bool getLocalFromWeakRef( jweak& _weak, LocalRef< T >& _inout_local )
+{
+ _inout_local.set( static_cast< T >( _inout_local.env().NewLocalRef( _weak ) ) );
+
+ if ( !_inout_local.is() )
+ {
+ if ( _inout_local.env().ExceptionCheck())
+ {
+ return false;
+ }
+ else if ( _weak != nullptr )
+ {
+ _inout_local.env().DeleteWeakGlobalRef( _weak );
+ _weak = nullptr;
+ }
+ }
+ return true;
+}
+
+// Load a class. A map from pairs of (classPath, name) to pairs of weak Java
+// references to (ClassLoader, Class) is maintained, so that a class is only
+// loaded once.
+//
+// It may happen that the weak reference to the ClassLoader becomes null while
+// the reference to the Class remains non-null (in case the Class was actually
+// loaded by some parent of the ClassLoader), in which case the ClassLoader is
+// resurrected (which cannot cause any classes to be loaded multiple times, as
+// the ClassLoader is no longer reachable, so no classes it has ever loaded are
+// still reachable).
+//
+// Similarly, it may happen that the weak reference to the Class becomes null
+// while the reference to the ClassLoader remains non-null, in which case the
+// Class is simply re-loaded.
+//
+// This code is close to the implementation of jvmaccess::ClassPath::loadClass
+// in jvmaccess/classpath.hxx, but not close enough to avoid the duplication.
+//
+// If false is returned, a (still pending) JNI exception occurred.
+bool loadClass(
+ Reference< XComponentContext > const & context, JNIEnv& environment,
+ OUString const & classPath, OUString const & name,
+ LocalRef< jobject > * classLoaderPtr, LocalRef< jclass > * classPtr)
+{
+ OSL_ASSERT(classLoaderPtr != nullptr);
+ // For any jweak entries still present in the map upon destruction,
+ // DeleteWeakGlobalRef is not called (which is a leak):
+ static ClassMapData classMapData;
+ osl::MutexGuard g(classMapData.mutex);
+ ClassMap::iterator i(classMapData.map.begin());
+ LocalRef< jobject > cloader(environment);
+ LocalRef< jclass > cl(environment);
+ // Prune dangling weak references from the list while searching for a match,
+ // so that the list cannot grow unbounded:
+ for (; i != classMapData.map.end();)
+ {
+ LocalRef< jobject > classLoader( environment );
+ if ( !getLocalFromWeakRef( i->classLoader, classLoader ) )
+ return false;
+
+ LocalRef< jclass > classObject( environment );
+ if ( !getLocalFromWeakRef( i->classObject, classObject ) )
+ return false;
+
+ if ( !classLoader.is() && !classObject.is() )
+ {
+ i = classMapData.map.erase(i);
+ }
+ else if ( i->classPath == classPath && i->className == name )
+ {
+ cloader.set( classLoader.release() );
+ cl.set( classObject.release() );
+ break;
+ }
+ else
+ {
+ ++i;
+ }
+ }
+ if ( !cloader.is() || !cl.is() )
+ {
+ if ( i == classMapData.map.end() )
+ {
+ // Push a new ClassMapEntry (which can potentially fail) before
+ // loading the class, so that it never happens that a class is
+ // loaded but not added to the map (which could have effects on the
+ // JVM that are not easily undone). If the pushed ClassMapEntry is
+ // not used after all (return false, etc.) it will be pruned on next
+ // call because its classLoader/classObject are null:
+ classMapData.map.push_back( ClassMapEntry( classPath, name ) );
+ i = std::prev(classMapData.map.end());
+ }
+
+ LocalRef< jclass > clClass( environment );
+ clClass.set( environment.FindClass( "java/net/URLClassLoader" ) );
+ if ( !clClass.is() )
+ return false;
+
+ jweak wcloader = nullptr;
+ if (!cloader.is())
+ {
+ jmethodID ctorLoader( environment.GetMethodID( clClass.get(), "<init>", "([Ljava/net/URL;)V" ) );
+ if (ctorLoader == nullptr)
+ return false;
+
+ LocalRef< jobjectArray > arr( environment );
+ arr.set( jvmaccess::ClassPath::translateToUrls( context, &environment, classPath ) );
+ if ( !arr.is() )
+ return false;
+
+ jvalue arg;
+ arg.l = arr.get();
+ cloader.set( environment.NewObjectA( clClass.get(), ctorLoader, &arg ) );
+ if ( !cloader.is() )
+ return false;
+
+ wcloader = environment.NewWeakGlobalRef( cloader.get() );
+ if ( wcloader == nullptr )
+ return false;
+ }
+
+ jweak wcl = nullptr;
+ if ( !cl.is() )
+ {
+ jmethodID methLoadClass( environment.GetMethodID( clClass.get(), "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;" ) );
+ if ( methLoadClass == nullptr )
+ return false;
+
+ LocalRef< jstring > str( environment );
+ str.set( convertwchar_tToJavaString( &environment, name ) );
+ if ( !str.is() )
+ return false;
+
+ jvalue arg;
+ arg.l = str.get();
+ cl.set( static_cast< jclass >( environment.CallObjectMethodA( cloader.get(), methLoadClass, &arg ) ) );
+ if ( !cl.is() )
+ return false;
+
+ wcl = environment.NewWeakGlobalRef( cl.get() );
+ if ( wcl == nullptr )
+ return false;
+ }
+
+ if ( wcloader != nullptr)
+ {
+ i->classLoader = wcloader;
+ }
+ if ( wcl != nullptr )
+ {
+ i->classObject = wcl;
+ }
+ }
+
+ classLoaderPtr->set( cloader.release() );
+ classPtr->set( cl.release() );
+ return true;
+}
+
+}
+
+
+IMPLEMENT_SERVICE_INFO(java_sql_Connection,"com.sun.star.sdbcx.JConnection","com.sun.star.sdbc.Connection");
+
+
+//************ Class: java.sql.Connection
+
+jclass java_sql_Connection::theClass = nullptr;
+
+java_sql_Connection::java_sql_Connection( const java_sql_Driver& _rDriver )
+ :m_xContext( _rDriver.getContext() )
+ ,m_pDriver( &_rDriver )
+ ,m_pDriverobject(nullptr)
+ ,m_Driver_theClass(nullptr)
+ ,m_aLogger( _rDriver.getLogger() )
+ ,m_bIgnoreDriverPrivileges(true)
+ ,m_bIgnoreCurrency(false)
+{
+}
+
+java_sql_Connection::~java_sql_Connection()
+{
+ ::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM();
+ if ( !xTest.is() )
+ return;
+
+ SDBThreadAttach t;
+ clearObject(*t.pEnv);
+
+ {
+ if ( m_pDriverobject )
+ t.pEnv->DeleteGlobalRef( m_pDriverobject );
+ m_pDriverobject = nullptr;
+ if ( m_Driver_theClass )
+ t.pEnv->DeleteGlobalRef( m_Driver_theClass );
+ m_Driver_theClass = nullptr;
+ }
+ SDBThreadAttach::releaseRef();
+}
+
+void java_sql_Connection::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ m_aLogger.log( LogLevel::INFO, STR_LOG_SHUTDOWN_CONNECTION );
+
+ java_sql_Connection_BASE::disposing();
+
+ if ( object )
+ {
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("close", mID);
+ }
+}
+
+jclass java_sql_Connection::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Connection");
+ return theClass;
+}
+
+
+OUString SAL_CALL java_sql_Connection::getCatalog( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ static jmethodID mID(nullptr);
+ return callStringMethod("getCatalog",mID);
+}
+
+Reference< XDatabaseMetaData > SAL_CALL java_sql_Connection::getMetaData( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+
+ Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
+ if(!xMetaData.is())
+ {
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getMetaData","()Ljava/sql/DatabaseMetaData;", mID);
+ if(out)
+ {
+ xMetaData = new java_sql_DatabaseMetaData( t.pEnv, out, *this );
+ m_xMetaData = xMetaData;
+ }
+ }
+
+ return xMetaData;
+}
+
+void SAL_CALL java_sql_Connection::close( )
+{
+ dispose();
+}
+
+void SAL_CALL java_sql_Connection::commit( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("commit", mID);
+}
+
+sal_Bool SAL_CALL java_sql_Connection::isClosed( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "isClosed", mID ) && java_sql_Connection_BASE::rBHelper.bDisposed;
+}
+
+sal_Bool SAL_CALL java_sql_Connection::isReadOnly( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "isReadOnly", mID );
+}
+
+void SAL_CALL java_sql_Connection::setCatalog( const OUString& catalog )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethodWithStringArg("setCatalog",mID,catalog);
+}
+
+void SAL_CALL java_sql_Connection::rollback( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("rollback", mID);
+}
+
+sal_Bool SAL_CALL java_sql_Connection::getAutoCommit( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "getAutoCommit", mID );
+}
+
+void SAL_CALL java_sql_Connection::setReadOnly( sal_Bool readOnly )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethodWithBoolArg_ThrowSQL("setReadOnly", mID, readOnly);
+}
+
+void SAL_CALL java_sql_Connection::setAutoCommit( sal_Bool autoCommit )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethodWithBoolArg_ThrowSQL("setAutoCommit", mID, autoCommit);
+}
+
+Reference< css::container::XNameAccess > SAL_CALL java_sql_Connection::getTypeMap( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ callObjectMethod(t.pEnv,"getTypeMap","()Ljava/util/Map;", mID);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return nullptr;
+}
+
+void SAL_CALL java_sql_Connection::setTypeMap( const Reference< css::container::XNameAccess >& /*typeMap*/ )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ ::dbtools::throwFeatureNotImplementedSQLException( "XConnection::setTypeMap", *this );
+}
+
+
+sal_Int32 SAL_CALL java_sql_Connection::getTransactionIsolation( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowSQL("getTransactionIsolation", mID);
+}
+
+void SAL_CALL java_sql_Connection::setTransactionIsolation( sal_Int32 level )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowSQL("setTransactionIsolation", mID, level);
+}
+
+Reference< XStatement > SAL_CALL java_sql_Connection::createStatement( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_CREATE_STATEMENT );
+
+ SDBThreadAttach t;
+ rtl::Reference<java_sql_Statement> pStatement = new java_sql_Statement( t.pEnv, *this );
+ Reference< XStatement > xStmt = pStatement;
+ m_aStatements.push_back( WeakReferenceHelper( xStmt ) );
+
+ m_aLogger.log( LogLevel::FINE, STR_LOG_CREATED_STATEMENT_ID, pStatement->getStatementObjectID() );
+ return xStmt;
+}
+
+Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareStatement( const OUString& sql )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_STATEMENT, sql );
+
+ SDBThreadAttach t;
+
+ rtl::Reference<java_sql_PreparedStatement> pStatement = new java_sql_PreparedStatement( t.pEnv, *this, sql );
+ Reference< XPreparedStatement > xReturn( pStatement );
+ m_aStatements.push_back(WeakReferenceHelper(xReturn));
+
+ m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_STATEMENT_ID, pStatement->getStatementObjectID() );
+ return xReturn;
+}
+
+Reference< XPreparedStatement > SAL_CALL java_sql_Connection::prepareCall( const OUString& sql )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARE_CALL, sql );
+
+ SDBThreadAttach t;
+
+ rtl::Reference<java_sql_CallableStatement> pStatement = new java_sql_CallableStatement( t.pEnv, *this, sql );
+ Reference< XPreparedStatement > xStmt( pStatement );
+ m_aStatements.push_back(WeakReferenceHelper(xStmt));
+
+ m_aLogger.log( LogLevel::FINE, STR_LOG_PREPARED_CALL_ID, pStatement->getStatementObjectID() );
+ return xStmt;
+}
+
+OUString SAL_CALL java_sql_Connection::nativeSQL( const OUString& sql )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ OUString aStr;
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+
+ // initialize temporary Variable
+ static const char * const cSignature = "(Ljava/lang/String;)Ljava/lang/String;";
+ static const char * const cMethodName = "nativeSQL";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ // Convert Parameter
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,sql));
+
+ jobject out = t.pEnv->CallObjectMethod( object, mID, str.get() );
+ aStr = JavaString2String(t.pEnv, static_cast<jstring>(out) );
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ } //t.pEnv
+
+ m_aLogger.log( LogLevel::FINER, STR_LOG_NATIVE_SQL, sql, aStr );
+
+ return aStr;
+}
+
+void SAL_CALL java_sql_Connection::clearWarnings( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("clearWarnings", mID);
+}
+
+Any SAL_CALL java_sql_Connection::getWarnings( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Connection_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t;
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID);
+ // WARNING: the caller becomes the owner of the returned pointer
+ if( out )
+ {
+ java_sql_SQLWarning_BASE warn_base(t.pEnv, out);
+ SQLException aAsException( java_sql_SQLWarning( warn_base, *this ) );
+
+ // translate to warning
+ SQLWarning aWarning;
+ aWarning.Context = aAsException.Context;
+ aWarning.Message = aAsException.Message;
+ aWarning.SQLState = aAsException.SQLState;
+ aWarning.ErrorCode = aAsException.ErrorCode;
+ aWarning.NextException = aAsException.NextException;
+
+ return Any( aWarning );
+ }
+
+ return Any();
+}
+
+
+namespace
+{
+ OUString lcl_getDriverLoadErrorMessage( const ::connectivity::SharedResources& _aResource,const OUString& _rDriverClass, const OUString& _rDriverClassPath )
+ {
+ OUString sError1( _aResource.getResourceStringWithSubstitution(
+ STR_NO_CLASSNAME,
+ "$classname$", _rDriverClass
+ ) );
+ if ( !_rDriverClassPath.isEmpty() )
+ {
+ const OUString sError2( _aResource.getResourceStringWithSubstitution(
+ STR_NO_CLASSNAME_PATH,
+ "$classpath$", _rDriverClassPath
+ ) );
+ sError1 += sError2;
+ } // if ( _rDriverClassPath.getLength() )
+ return sError1;
+ }
+}
+
+
+namespace
+{
+ bool lcl_setSystemProperties_nothrow( const java::sql::ConnectionLog& _rLogger,
+ JNIEnv& _rEnv, const Sequence< NamedValue >& _rSystemProperties )
+ {
+ if ( !_rSystemProperties.hasElements() )
+ // nothing to do
+ return true;
+
+ LocalRef< jclass > systemClass( _rEnv );
+ jmethodID nSetPropertyMethodID = nullptr;
+ // retrieve the java.lang.System class
+ systemClass.set( _rEnv.FindClass( "java/lang/System" ) );
+ if ( systemClass.is() )
+ {
+ nSetPropertyMethodID = _rEnv.GetStaticMethodID(
+ systemClass.get(), "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" );
+ }
+
+ if ( nSetPropertyMethodID == nullptr )
+ return false;
+
+ for ( auto const & systemProp : _rSystemProperties )
+ {
+ OUString sValue;
+ OSL_VERIFY( systemProp.Value >>= sValue );
+
+ _rLogger.log( LogLevel::FINER, STR_LOG_SETTING_SYSTEM_PROPERTY, systemProp.Name, sValue );
+
+ LocalRef< jstring > jName( _rEnv, convertwchar_tToJavaString( &_rEnv, systemProp.Name ) );
+ LocalRef< jstring > jValue( _rEnv, convertwchar_tToJavaString( &_rEnv, sValue ) );
+
+ _rEnv.CallStaticObjectMethod( systemClass.get(), nSetPropertyMethodID, jName.get(), jValue.get() );
+ LocalRef< jthrowable > throwable( _rEnv, _rEnv.ExceptionOccurred() );
+ if ( throwable.is() )
+ return false;
+ }
+
+ return true;
+ }
+}
+
+
+void java_sql_Connection::loadDriverFromProperties( const OUString& _sDriverClass, const OUString& _sDriverClassPath,
+ const Sequence< NamedValue >& _rSystemProperties )
+{
+ // first try if the jdbc driver is already registered at the driver manager
+ SDBThreadAttach t;
+ try
+ {
+ if ( !object )
+ {
+ if ( !lcl_setSystemProperties_nothrow( getLogger(), *t.pEnv, _rSystemProperties ) )
+ ThrowLoggedSQLException( getLogger(), t.pEnv, *this );
+
+ m_pDriverClassLoader.reset();
+
+ // here I try to find the class for jdbc driver
+ java_sql_SQLException_BASE::st_getMyClass();
+ java_lang_Throwable::st_getMyClass();
+
+ if ( _sDriverClass.isEmpty() )
+ {
+ m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_DRIVER_CLASS );
+ ::dbtools::throwGenericSQLException(
+ lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
+ *this
+ );
+ }
+ else
+ {
+ m_aLogger.log( LogLevel::INFO, STR_LOG_LOADING_DRIVER, _sDriverClass );
+ // the driver manager holds the class of the driver for later use
+ std::unique_ptr< java_lang_Class > pDrvClass;
+ if ( _sDriverClassPath.isEmpty() )
+ {
+ // if forName didn't find the class it will throw an exception
+ pDrvClass.reset(java_lang_Class::forName(_sDriverClass));
+ }
+ else
+ {
+ LocalRef< jclass > driverClass(t.env());
+ LocalRef< jobject > driverClassLoader(t.env());
+
+ loadClass(
+ m_pDriver->getContext(),
+ t.env(), _sDriverClassPath, _sDriverClass, &driverClassLoader, &driverClass );
+
+ m_pDriverClassLoader.set( driverClassLoader );
+ pDrvClass.reset( new java_lang_Class( t.pEnv, driverClass.release() ) );
+
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ if (pDrvClass)
+ {
+ LocalRef< jobject > driverObject( t.env() );
+ driverObject.set( pDrvClass->newInstanceObject() );
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ m_pDriverobject = driverObject.release();
+
+ if( m_pDriverobject )
+ m_pDriverobject = t.pEnv->NewGlobalRef( m_pDriverobject );
+
+ {
+ jclass tempClass = t.pEnv->GetObjectClass(m_pDriverobject);
+ if ( m_pDriverobject )
+ {
+ m_Driver_theClass = static_cast<jclass>(t.pEnv->NewGlobalRef( tempClass ));
+ t.pEnv->DeleteLocalRef( tempClass );
+ }
+ }
+ }
+ m_aLogger.log( LogLevel::INFO, STR_LOG_CONN_SUCCESS );
+ }
+ }
+ }
+ catch( const SQLException& )
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw SQLException(
+ lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
+ *this,
+ OUString(),
+ 1000,
+ anyEx);
+ }
+ catch( Exception& )
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ ::dbtools::throwGenericSQLException(
+ lcl_getDriverLoadErrorMessage( getResources(),_sDriverClass, _sDriverClassPath ),
+ *this,
+ anyEx
+ );
+ }
+}
+
+OUString java_sql_Connection::impl_getJavaDriverClassPath_nothrow(const OUString& _sDriverClass)
+{
+ static constexpr OUStringLiteral s_sNodeName
+ = u"org.openoffice.Office.DataAccess/JDBC/DriverClassPaths";
+ ::utl::OConfigurationTreeRoot aNamesRoot = ::utl::OConfigurationTreeRoot::createWithComponentContext(
+ m_pDriver->getContext(), s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY);
+ OUString sURL;
+ if ( aNamesRoot.isValid() && aNamesRoot.hasByName( _sDriverClass ) )
+ {
+ ::utl::OConfigurationNode aRegisterObj = aNamesRoot.openNode( _sDriverClass );
+ OSL_VERIFY( aRegisterObj.getNodeValue( "Path" ) >>= sURL );
+ }
+ return sURL;
+}
+
+bool java_sql_Connection::construct(const OUString& url,
+ const Sequence< PropertyValue >& info)
+{
+ { // initialize the java vm
+ ::rtl::Reference< jvmaccess::VirtualMachine > xTest = java_lang_Object::getVM(m_xContext);
+ if ( !xTest.is() )
+ throwGenericSQLException(STR_NO_JAVA,*this);
+ }
+ SDBThreadAttach t;
+ SDBThreadAttach::addRef(); // will be released in dtor
+ if ( !t.pEnv )
+ throwGenericSQLException(STR_NO_JAVA,*this);
+
+ OUString sGeneratedValueStatement; // contains the statement which should be used when query for automatically generated values
+ bool bAutoRetrievingEnabled = false; // set to <TRUE/> when we should allow to query for generated values
+ OUString sDriverClassPath,sDriverClass;
+ Sequence< NamedValue > aSystemProperties;
+
+ ::comphelper::NamedValueCollection aSettings( info );
+ sDriverClass = aSettings.getOrDefault( "JavaDriverClass", sDriverClass );
+ sDriverClassPath = aSettings.getOrDefault( "JavaDriverClassPath", sDriverClassPath);
+ if ( sDriverClassPath.isEmpty() )
+ sDriverClassPath = impl_getJavaDriverClassPath_nothrow(sDriverClass);
+ bAutoRetrievingEnabled = aSettings.getOrDefault( "IsAutoRetrievingEnabled", bAutoRetrievingEnabled );
+ sGeneratedValueStatement = aSettings.getOrDefault( "AutoRetrievingStatement", sGeneratedValueStatement );
+ m_bIgnoreDriverPrivileges = aSettings.getOrDefault( "IgnoreDriverPrivileges", m_bIgnoreDriverPrivileges );
+ m_bIgnoreCurrency = aSettings.getOrDefault( "IgnoreCurrency", m_bIgnoreCurrency );
+ aSystemProperties = aSettings.getOrDefault( "SystemProperties", aSystemProperties );
+ m_aCatalogRestriction = aSettings.getOrDefault( "ImplicitCatalogRestriction", Any() );
+ m_aSchemaRestriction = aSettings.getOrDefault( "ImplicitSchemaRestriction", Any() );
+
+ loadDriverFromProperties( sDriverClass, sDriverClassPath, aSystemProperties );
+
+ enableAutoRetrievingEnabled(bAutoRetrievingEnabled);
+ setAutoRetrievingStatement(sGeneratedValueStatement);
+
+ if ( t.pEnv && m_Driver_theClass && m_pDriverobject )
+ {
+ // Java-Call
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
+ static const char * const cMethodName = "connect";
+ jmethodID mID = t.pEnv->GetMethodID( m_Driver_theClass, cMethodName, cSignature );
+
+ if ( mID )
+ {
+ jvalue args[2];
+ // convert Parameter
+ args[0].l = convertwchar_tToJavaString(t.pEnv,url);
+ std::unique_ptr<java_util_Properties> pProps = createStringPropertyArray(info);
+ args[1].l = pProps->getJavaObject();
+
+ LocalRef< jobject > ensureDelete( t.env(), args[0].l );
+
+ jobject out = nullptr;
+ // In some cases (e.g.,
+ // connectivity/source/drivers/hsqldb/HDriver.cxx:1.24
+ // l. 249) the JavaDriverClassPath contains multiple jars,
+ // as creating the JavaDriverClass instance requires
+ // (reflective) access to those other jars. Now, if the
+ // JavaDriverClass is actually loaded by some parent class
+ // loader (e.g., because its jar is also on the global
+ // class path), it would still not have access to the
+ // additional jars on the JavaDriverClassPath. Hence, the
+ // JavaDriverClassPath class loader is pushed as context
+ // class loader around the JavaDriverClass instance
+ // creation:
+ // #i82222# / 2007-10-15
+ {
+ ContextClassLoaderScope ccl( t.env(), getDriverClassLoader(), getLogger(), *this );
+ out = t.pEnv->CallObjectMethod( m_pDriverobject, mID, args[0].l,args[1].l );
+ pProps.reset();
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+
+ if ( !out )
+ m_aLogger.log( LogLevel::SEVERE, STR_LOG_NO_SYSTEM_CONNECTION );
+
+ if ( out )
+ object = t.pEnv->NewGlobalRef( out );
+
+ if ( object )
+ m_aLogger.log( LogLevel::INFO, STR_LOG_GOT_JDBC_CONNECTION, url );
+
+ m_aConnectionInfo = info;
+ } //mID
+ } //t.pEnv
+ return object != nullptr;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/JDriver.cxx b/connectivity/source/drivers/jdbc/JDriver.cxx
new file mode 100644
index 000000000..f294d30b4
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/JDriver.cxx
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/Driver.hxx>
+#include <java/sql/Connection.hxx>
+#include <sal/log.hxx>
+#include <connectivity/dbexception.hxx>
+#include <jvmfwk/framework.hxx>
+#include <strings.hrc>
+#include <resource/sharedresources.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <strings.hxx>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+
+java_sql_Driver::java_sql_Driver(const Reference< css::uno::XComponentContext >& _rxContext)
+ :m_aContext( _rxContext )
+ ,m_aLogger( _rxContext, "org.openoffice.sdbc.jdbcBridge" )
+{
+}
+
+java_sql_Driver::~java_sql_Driver()
+{
+}
+
+OUString SAL_CALL java_sql_Driver::getImplementationName( )
+{
+ return "com.sun.star.comp.sdbc.JDBCDriver";
+ // this name is referenced in the configuration and in the jdbc.xml
+ // Please take care when changing it.
+}
+
+sal_Bool SAL_CALL java_sql_Driver::supportsService( const OUString& _rServiceName )
+{
+ return cppu::supportsService(this, _rServiceName);
+}
+
+
+Sequence< OUString > SAL_CALL java_sql_Driver::getSupportedServiceNames( )
+{
+ return { "com.sun.star.sdbc.Driver" };
+}
+
+Reference< XConnection > SAL_CALL java_sql_Driver::connect( const OUString& url, const
+ Sequence< PropertyValue >& info )
+{
+ m_aLogger.log( LogLevel::INFO, STR_LOG_DRIVER_CONNECTING_URL, url );
+
+ Reference< XConnection > xOut;
+ if ( acceptsURL(url ) )
+ {
+ rtl::Reference<java_sql_Connection> pConnection = new java_sql_Connection( *this );
+ xOut = pConnection;
+ if ( !pConnection->construct(url,info) )
+ xOut.clear(); // an error occurred and the java driver didn't throw an exception
+ else
+ m_aLogger.log( LogLevel::INFO, STR_LOG_DRIVER_SUCCESS );
+ }
+ return xOut;
+}
+
+sal_Bool SAL_CALL java_sql_Driver::acceptsURL( const OUString& url )
+{
+ // don't ask the real driver for the url
+ // I feel responsible for all jdbc url's
+ bool bEnabled = false;
+ javaFrameworkError e = jfw_getEnabled(&bEnabled);
+ switch (e) {
+ case JFW_E_NONE:
+ break;
+ case JFW_E_DIRECT_MODE:
+ SAL_INFO(
+ "connectivity.jdbc",
+ "jfw_getEnabled: JFW_E_DIRECT_MODE, assuming true");
+ bEnabled = true;
+ break;
+ default:
+ SAL_WARN("connectivity.jdbc", "jfw_getEnabled: error code " << +e);
+ break;
+ }
+ return bEnabled && url.startsWith("jdbc:");
+}
+
+Sequence< DriverPropertyInfo > SAL_CALL java_sql_Driver::getPropertyInfo( const OUString& url,
+ const Sequence< PropertyValue >& /*info*/ )
+{
+ if ( acceptsURL(url) )
+ {
+ Sequence< OUString > aBooleanValues{ "false", "true" };
+
+ return
+ {
+ {
+ "JavaDriverClass"
+ ,"The JDBC driver class name."
+ ,true
+ ,OUString()
+ ,Sequence< OUString >()
+ },
+ {
+ "JavaDriverClassPath"
+ ,"The class path where to look for the JDBC driver."
+ ,true
+ , ""
+ ,Sequence< OUString >()
+ },
+ {
+ "SystemProperties"
+ ,"Additional properties to set at java.lang.System before loading the driver."
+ ,true
+ , ""
+ ,Sequence< OUString >()
+ },
+ {
+ "ParameterNameSubstitution"
+ ,"Change named parameters with '?'."
+ ,false
+ ,"false"
+ ,aBooleanValues
+ },
+ {
+ "IgnoreDriverPrivileges"
+ ,"Ignore the privileges from the database driver."
+ ,false
+ , "false"
+ ,aBooleanValues
+ },
+ {
+ "IsAutoRetrievingEnabled"
+ ,"Retrieve generated values."
+ ,false
+ ,"false"
+ ,aBooleanValues
+ },
+ {
+ "AutoRetrievingStatement"
+ ,"Auto-increment statement."
+ ,false
+ ,OUString()
+ ,Sequence< OUString >()
+ },
+ {
+ "GenerateASBeforeCorrelationName"
+ ,"Generate AS before table correlation names."
+ ,false
+ ,"false"
+ ,aBooleanValues
+ },
+ {
+ "IgnoreCurrency"
+ ,"Ignore the currency field from the ResultsetMetaData."
+ ,false
+ ,"false"
+ ,aBooleanValues
+ },
+ {
+ "EscapeDateTime"
+ ,"Escape date time format."
+ ,false
+ ,"true"
+ ,aBooleanValues
+ },
+ {
+ "TypeInfoSettings"
+ ,"Defines how the type info of the database metadata should be manipulated."
+ ,false
+ ,OUString()
+ ,Sequence< OUString > ()
+ },
+ {
+ "ImplicitCatalogRestriction"
+ ,"The catalog which should be used in getTables calls, when the caller passed NULL."
+ ,false
+ ,OUString( )
+ ,Sequence< OUString > ()
+ },
+ {
+ "ImplicitSchemaRestriction"
+ ,"The schema which should be used in getTables calls, when the caller passed NULL."
+ ,false
+ ,OUString( )
+ ,Sequence< OUString > ()
+ }
+ };
+ }
+ ::connectivity::SharedResources aResources;
+ const OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
+ ::dbtools::throwGenericSQLException(sMessage ,*this);
+ return Sequence< DriverPropertyInfo >();
+}
+
+sal_Int32 SAL_CALL java_sql_Driver::getMajorVersion( )
+{
+ return 1;
+}
+
+sal_Int32 SAL_CALL java_sql_Driver::getMinorVersion( )
+{
+ return 0;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+connectivity_java_sql_Driver_get_implementation(
+ css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new java_sql_Driver(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/JStatement.cxx b/connectivity/source/drivers/jdbc/JStatement.cxx
new file mode 100644
index 000000000..c94f0fd68
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/JStatement.cxx
@@ -0,0 +1,864 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <java/sql/JStatement.hxx>
+#include <java/sql/ResultSet.hxx>
+#include <java/sql/Connection.hxx>
+#include <java/sql/SQLWarning.hxx>
+#include <java/tools.hxx>
+#include <java/ContextClassLoader.hxx>
+#include <comphelper/property.hxx>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <comphelper/sequence.hxx>
+#include <TConnection.hxx>
+#include <comphelper/types.hxx>
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
+#include <com/sun/star/sdbc/ResultSetType.hpp>
+
+#include <strings.hxx>
+
+#include <algorithm>
+#include <string.h>
+
+using namespace ::comphelper;
+using namespace connectivity;
+using namespace ::cppu;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+
+//************ Class: java.sql.Statement
+
+
+jclass java_sql_Statement_Base::theClass = nullptr;
+
+
+java_sql_Statement_Base::java_sql_Statement_Base( JNIEnv * pEnv, java_sql_Connection& _rCon )
+ :java_sql_Statement_BASE(m_aMutex)
+ ,java_lang_Object( pEnv, nullptr )
+ ,OPropertySetHelper(java_sql_Statement_BASE::rBHelper)
+ ,m_pConnection( &_rCon )
+ ,m_aLogger( _rCon.getLogger(), java::sql::ConnectionLog::STATEMENT )
+ ,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY)
+ ,m_nResultSetType(ResultSetType::FORWARD_ONLY)
+ ,m_bEscapeProcessing(true)
+{
+}
+
+
+java_sql_Statement_Base::~java_sql_Statement_Base()
+{
+}
+
+
+void SAL_CALL OStatement_BASE2::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if ( object )
+ {
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("close", mID);
+ }
+
+ ::comphelper::disposeComponent(m_xGeneratedStatement);
+ m_pConnection.clear();
+
+ java_sql_Statement_Base::disposing();
+}
+
+jclass java_sql_Statement_Base::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Statement");
+ return theClass;
+}
+
+void SAL_CALL java_sql_Statement_Base::disposing()
+{
+ m_aLogger.log( LogLevel::FINE, STR_LOG_CLOSING_STATEMENT );
+ java_sql_Statement_BASE::disposing();
+ clearObject();
+}
+
+
+Any SAL_CALL java_sql_Statement_Base::queryInterface( const Type & rType )
+{
+ if ( m_pConnection.is() && !m_pConnection->isAutoRetrievingEnabled() && rType == cppu::UnoType<XGeneratedResultSet>::get())
+ return Any();
+ Any aRet( java_sql_Statement_BASE::queryInterface(rType) );
+ return aRet.hasValue() ? aRet : OPropertySetHelper::queryInterface(rType);
+}
+
+Sequence< Type > SAL_CALL java_sql_Statement_Base::getTypes( )
+{
+ ::cppu::OTypeCollection aTypes( cppu::UnoType<css::beans::XMultiPropertySet>::get(),
+ cppu::UnoType<css::beans::XFastPropertySet>::get(),
+ cppu::UnoType<css::beans::XPropertySet>::get());
+
+ Sequence< Type > aOldTypes = java_sql_Statement_BASE::getTypes();
+ if ( m_pConnection.is() && !m_pConnection->isAutoRetrievingEnabled() )
+ {
+ auto [begin, end] = asNonConstRange(aOldTypes);
+ auto newEnd = std::remove(begin, end,
+ cppu::UnoType<XGeneratedResultSet>::get());
+ aOldTypes.realloc(std::distance(begin, newEnd));
+ }
+
+ return ::comphelper::concatSequences(aTypes.getTypes(),aOldTypes);
+}
+
+Reference< XResultSet > SAL_CALL java_sql_Statement_Base::getGeneratedValues( )
+{
+ m_aLogger.log( LogLevel::FINE, STR_LOG_GENERATED_VALUES );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ // initialize temporary Variable
+ try
+ {
+ static jmethodID mID(nullptr);
+ out = callResultSetMethod(t.env(),"getGeneratedKeys",mID);
+ }
+ catch(const SQLException&)
+ {
+ // ignore
+ }
+
+ Reference< XResultSet > xRes;
+ if ( !out )
+ {
+ OSL_ENSURE( m_pConnection.is() && m_pConnection->isAutoRetrievingEnabled(),"Illegal call here. isAutoRetrievingEnabled is false!");
+ if ( m_pConnection.is() )
+ {
+ OUString sStmt = m_pConnection->getTransformedGeneratedStatement(m_sSqlStatement);
+ if ( !sStmt.isEmpty() )
+ {
+ m_aLogger.log( LogLevel::FINER, STR_LOG_GENERATED_VALUES_FALLBACK, sStmt );
+ ::comphelper::disposeComponent(m_xGeneratedStatement);
+ m_xGeneratedStatement = m_pConnection->createStatement();
+ xRes = m_xGeneratedStatement->executeQuery(sStmt);
+ }
+ }
+ }
+ else
+ xRes = new java_sql_ResultSet( t.pEnv, out, m_aLogger,*m_pConnection, this );
+ return xRes;
+}
+
+
+void SAL_CALL java_sql_Statement_Base::cancel( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowRuntime("cancel",mID);
+}
+
+
+void SAL_CALL java_sql_Statement_Base::close( )
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (java_sql_Statement_BASE::rBHelper.bDisposed)
+ throw DisposedException();
+ }
+ dispose();
+}
+
+
+void SAL_CALL java_sql_Statement::clearBatch( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("clearBatch", mID);
+ } //t.pEnv
+}
+
+
+sal_Bool SAL_CALL java_sql_Statement_Base::execute( const OUString& sql )
+{
+ m_aLogger.log( LogLevel::FINE, STR_LOG_EXECUTE_STATEMENT, sql );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ bool out(false);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+ m_sSqlStatement = sql;
+ // initialize temporary Variable
+ static const char * const cSignature = "(Ljava/lang/String;)Z";
+ static const char * const cMethodName = "execute";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ // convert Parameter
+ jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
+ {
+ jdbc::ContextClassLoaderScope ccl( t.env(),
+ m_pConnection.is() ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
+ m_aLogger,
+ *this
+ );
+
+ out = t.pEnv->CallBooleanMethod( object, mID, str.get() );
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ } //t.pEnv
+ return out;
+}
+
+
+Reference< XResultSet > SAL_CALL java_sql_Statement_Base::executeQuery( const OUString& sql )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_EXECUTE_QUERY, sql );
+
+ jobject out(nullptr);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ createStatement(t.pEnv);
+ m_sSqlStatement = sql;
+ // initialize temporary variable
+ static const char * const cSignature = "(Ljava/lang/String;)Ljava/sql/ResultSet;";
+ static const char * const cMethodName = "executeQuery";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ // convert Parameter
+ jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
+ {
+ jdbc::ContextClassLoaderScope ccl( t.env(),
+ m_pConnection.is() ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
+ m_aLogger,
+ *this
+ );
+
+ out = t.pEnv->CallObjectMethod( object, mID, str.get() );
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ } //t.pEnv
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_ResultSet( t.pEnv, out, m_aLogger, *m_pConnection,this );
+}
+
+Reference< XConnection > SAL_CALL java_sql_Statement_Base::getConnection( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ return m_pConnection;
+}
+
+
+Any SAL_CALL java_sql_Statement::queryInterface( const Type & rType )
+{
+ Any aRet = ::cppu::queryInterface(rType,static_cast< XBatchExecution*> (this));
+ return aRet.hasValue() ? aRet : java_sql_Statement_Base::queryInterface(rType);
+}
+
+
+void SAL_CALL java_sql_Statement::addBatch( const OUString& sql )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithStringArg("addBatch",mID,sql);
+ } //t.pEnv
+}
+
+
+Sequence< sal_Int32 > SAL_CALL java_sql_Statement::executeBatch( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ Sequence< sal_Int32 > aSeq;
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jintArray out = static_cast<jintArray>(callObjectMethod(t.pEnv,"executeBatch","()[I", mID));
+ if (out)
+ {
+ jboolean p = false;
+ aSeq.realloc(t.pEnv->GetArrayLength(out));
+ memcpy(aSeq.getArray(),t.pEnv->GetIntArrayElements(out,&p),aSeq.getLength());
+ t.pEnv->DeleteLocalRef(out);
+ }
+ return aSeq;
+}
+
+
+sal_Int32 SAL_CALL java_sql_Statement_Base::executeUpdate( const OUString& sql )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_EXECUTE_UPDATE, sql );
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ m_sSqlStatement = sql;
+ static jmethodID mID(nullptr);
+ return callIntMethodWithStringArg("executeUpdate",mID,sql);
+}
+
+
+Reference< css::sdbc::XResultSet > SAL_CALL java_sql_Statement_Base::getResultSet( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callResultSetMethod(t.env(),"getResultSet",mID);
+
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_ResultSet( t.pEnv, out, m_aLogger, *m_pConnection,this );
+}
+
+
+sal_Int32 SAL_CALL java_sql_Statement_Base::getUpdateCount( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ sal_Int32 out = callIntMethod_ThrowSQL("getUpdateCount", mID);
+ m_aLogger.log( LogLevel::FINER, STR_LOG_UPDATE_COUNT, out );
+ return out;
+}
+
+
+sal_Bool SAL_CALL java_sql_Statement_Base::getMoreResults( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "getMoreResults", mID );
+}
+
+
+Any SAL_CALL java_sql_Statement_Base::getWarnings( )
+{
+ SDBThreadAttach t;
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID);
+ // WARNING: the caller becomes the owner of the returned pointer
+ if( out )
+ {
+ java_sql_SQLWarning_BASE warn_base( t.pEnv, out );
+ return Any(
+ static_cast< css::sdbc::SQLException >(
+ java_sql_SQLWarning(warn_base,*static_cast<cppu::OWeakObject*>(this))));
+ }
+
+ return Any();
+}
+
+void SAL_CALL java_sql_Statement_Base::clearWarnings( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t;
+
+ {
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("clearWarnings", mID);
+ }
+}
+
+sal_Int32 java_sql_Statement_Base::getQueryTimeOut()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getQueryTimeOut",mID);
+}
+
+sal_Int32 java_sql_Statement_Base::getMaxRows()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getMaxRows",mID);
+}
+
+sal_Int32 java_sql_Statement_Base::getResultSetConcurrency()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getResultSetConcurrency",mID,m_nResultSetConcurrency);
+}
+
+
+sal_Int32 java_sql_Statement_Base::getResultSetType()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getResultSetType",mID,m_nResultSetType);
+}
+
+sal_Int32 java_sql_Statement_Base::impl_getProperty(const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nDefault)
+{
+ sal_Int32 out = _nDefault;
+ if ( object )
+ out = callIntMethod_ThrowRuntime(_pMethodName, _inout_MethodID);
+ return out;
+}
+
+sal_Int32 java_sql_Statement_Base::impl_getProperty(const char* _pMethodName, jmethodID& _inout_MethodID)
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ return callIntMethod_ThrowRuntime(_pMethodName, _inout_MethodID);
+}
+
+sal_Int32 java_sql_Statement_Base::getFetchDirection()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getFetchDirection",mID);
+}
+
+sal_Int32 java_sql_Statement_Base::getFetchSize()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getFetchSize",mID);
+}
+
+sal_Int32 java_sql_Statement_Base::getMaxFieldSize()
+{
+ static jmethodID mID(nullptr);
+ return impl_getProperty("getMaxFieldSize",mID);
+}
+
+OUString java_sql_Statement_Base::getCursorName()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ try
+ {
+ return callStringMethod("getCursorName",mID);
+ }
+ catch(const SQLException&)
+ {
+ }
+ return OUString();
+}
+
+void java_sql_Statement_Base::setQueryTimeOut(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setQueryTimeOut", mID, _par0);
+}
+
+
+void java_sql_Statement_Base::setEscapeProcessing(bool _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_SET_ESCAPE_PROCESSING, _par0 );
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ m_bEscapeProcessing = _par0;
+ createStatement( t.pEnv );
+ static jmethodID mID(nullptr);
+ callVoidMethodWithBoolArg_ThrowRuntime("setEscapeProcessing", mID, _par0);
+}
+
+void java_sql_Statement_Base::setMaxRows(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setMaxRows", mID, _par0);
+}
+
+void java_sql_Statement_Base::setResultSetConcurrency(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_RESULT_SET_CONCURRENCY, _par0 );
+ m_nResultSetConcurrency = _par0;
+
+ clearObject();
+}
+
+void java_sql_Statement_Base::setResultSetType(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_RESULT_SET_TYPE, _par0 );
+ m_nResultSetType = _par0;
+
+ clearObject();
+}
+
+void java_sql_Statement_Base::setFetchDirection(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINER, STR_LOG_FETCH_DIRECTION, _par0 );
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setFetchDirection", mID, _par0);
+}
+
+void java_sql_Statement_Base::setFetchSize(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINER, STR_LOG_FETCH_SIZE, _par0 );
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setFetchSize", mID, _par0);
+}
+
+void java_sql_Statement_Base::setMaxFieldSize(sal_Int32 _par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setMaxFieldSize", mID, _par0);
+}
+
+void java_sql_Statement_Base::setCursorName(const OUString &_par0)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethodWithStringArg("setCursorName",mID,_par0);
+ } //t.pEnv
+}
+
+
+::cppu::IPropertyArrayHelper* java_sql_Statement_Base::createArrayHelper( ) const
+{
+ return new ::cppu::OPropertyArrayHelper
+ {
+ {
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),
+ PROPERTY_ID_CURSORNAME,
+ cppu::UnoType<OUString>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING),
+ PROPERTY_ID_ESCAPEPROCESSING,
+ cppu::UnoType<bool>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
+ PROPERTY_ID_FETCHDIRECTION,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
+ PROPERTY_ID_FETCHSIZE,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE),
+ PROPERTY_ID_MAXFIELDSIZE,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS),
+ PROPERTY_ID_MAXROWS,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT),
+ PROPERTY_ID_QUERYTIMEOUT,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
+ PROPERTY_ID_RESULTSETCONCURRENCY,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
+ PROPERTY_ID_RESULTSETTYPE,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_USEBOOKMARKS),
+ PROPERTY_ID_USEBOOKMARKS,
+ cppu::UnoType<bool>::get(),
+ 0
+ }
+ }
+ };
+}
+
+
+::cppu::IPropertyArrayHelper & java_sql_Statement_Base::getInfoHelper()
+
+{
+ return *getArrayHelper();
+}
+
+sal_Bool java_sql_Statement_Base::convertFastPropertyValue(
+ Any & rConvertedValue,
+ Any & rOldValue,
+ sal_Int32 nHandle,
+ const Any& rValue )
+{
+ try
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_QUERYTIMEOUT:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getQueryTimeOut());
+ case PROPERTY_ID_MAXFIELDSIZE:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxFieldSize());
+ case PROPERTY_ID_MAXROWS:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getMaxRows());
+ case PROPERTY_ID_CURSORNAME:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getCursorName());
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetConcurrency());
+ case PROPERTY_ID_RESULTSETTYPE:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getResultSetType());
+ case PROPERTY_ID_FETCHDIRECTION:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
+ case PROPERTY_ID_FETCHSIZE:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
+ case PROPERTY_ID_ESCAPEPROCESSING:
+ return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEscapeProcessing );
+ case PROPERTY_ID_USEBOOKMARKS:
+ // return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAsLink);
+ default:
+ ;
+ }
+ }
+ catch(const css::lang::IllegalArgumentException&)
+ {
+ throw;
+ }
+ catch(const css::uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("connectivity.jdbc");
+ }
+ return false;
+}
+
+void java_sql_Statement_Base::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const Any& rValue
+ )
+{
+ switch(nHandle)
+ {
+ case PROPERTY_ID_QUERYTIMEOUT:
+ setQueryTimeOut(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_MAXFIELDSIZE:
+ setMaxFieldSize(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_MAXROWS:
+ setMaxRows(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_CURSORNAME:
+ setCursorName(comphelper::getString(rValue));
+ break;
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ setResultSetConcurrency(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_RESULTSETTYPE:
+ setResultSetType(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_FETCHDIRECTION:
+ setFetchDirection(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ setFetchSize(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_ESCAPEPROCESSING:
+ setEscapeProcessing( ::comphelper::getBOOL( rValue ) );
+ break;
+ case PROPERTY_ID_USEBOOKMARKS:
+ // return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAsLink);
+ default:
+ ;
+ }
+}
+
+void java_sql_Statement_Base::getFastPropertyValue(
+ Any& rValue,
+ sal_Int32 nHandle
+ ) const
+{
+ java_sql_Statement_Base* THIS = const_cast<java_sql_Statement_Base*>(this);
+ try
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_QUERYTIMEOUT:
+ rValue <<= THIS->getQueryTimeOut();
+ break;
+ case PROPERTY_ID_MAXFIELDSIZE:
+ rValue <<= THIS->getMaxFieldSize();
+ break;
+ case PROPERTY_ID_MAXROWS:
+ rValue <<= THIS->getMaxRows();
+ break;
+ case PROPERTY_ID_CURSORNAME:
+ rValue <<= THIS->getCursorName();
+ break;
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ rValue <<= THIS->getResultSetConcurrency();
+ break;
+ case PROPERTY_ID_RESULTSETTYPE:
+ rValue <<= THIS->getResultSetType();
+ break;
+ case PROPERTY_ID_FETCHDIRECTION:
+ rValue <<= THIS->getFetchDirection();
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ rValue <<= THIS->getFetchSize();
+ break;
+ case PROPERTY_ID_ESCAPEPROCESSING:
+ rValue <<= m_bEscapeProcessing;
+ break;
+ case PROPERTY_ID_USEBOOKMARKS:
+ default:
+ ;
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+}
+
+jclass java_sql_Statement::theClass = nullptr;
+
+java_sql_Statement::~java_sql_Statement()
+{}
+
+jclass java_sql_Statement::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Statement");
+ return theClass;
+}
+
+
+void java_sql_Statement::createStatement(JNIEnv* _pEnv)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ if( !_pEnv || object )
+ return;
+
+ // initialize temporary variable
+ static const char * const cMethodName = "createStatement";
+ // Java-Call
+ jobject out = nullptr;
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(II)Ljava/sql/Statement;";
+ mID = _pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature );
+ }
+ if( mID ){
+ out = _pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID,m_nResultSetType,m_nResultSetConcurrency );
+ } //mID
+ else
+ {
+ static const char * const cSignature2 = "()Ljava/sql/Statement;";
+ static jmethodID mID2 = _pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature2 );OSL_ENSURE(mID2,"Unknown method id!");
+ if( mID2 ){
+ out = _pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID2);
+ } //mID
+ }
+ ThrowLoggedSQLException( m_aLogger, _pEnv, *this );
+
+ if ( out )
+ object = _pEnv->NewGlobalRef( out );
+}
+
+
+IMPLEMENT_SERVICE_INFO(java_sql_Statement,"com.sun.star.sdbcx.JStatement","com.sun.star.sdbc.Statement");
+
+void SAL_CALL java_sql_Statement_Base::acquire() noexcept
+{
+ java_sql_Statement_BASE::acquire();
+}
+
+void SAL_CALL java_sql_Statement_Base::release() noexcept
+{
+ java_sql_Statement_BASE::release();
+}
+
+void SAL_CALL java_sql_Statement::acquire() noexcept
+{
+ OStatement_BASE2::acquire();
+}
+
+void SAL_CALL java_sql_Statement::release() noexcept
+{
+ OStatement_BASE2::release();
+}
+
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL java_sql_Statement_Base::getPropertySetInfo( )
+{
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Object.cxx b/connectivity/source/drivers/jdbc/Object.cxx
new file mode 100644
index 000000000..f05eced9d
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Object.cxx
@@ -0,0 +1,481 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <connectivity/CommonTools.hxx>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/logging/LogLevel.hpp>
+#include <java/tools.hxx>
+#include <java/sql/SQLException.hxx>
+#include <osl/diagnose.h>
+#include <java/LocalRef.hxx>
+#include <strings.hxx>
+
+#include <comphelper/logging.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+
+static ::rtl::Reference< jvmaccess::VirtualMachine > const & getJavaVM2(const ::rtl::Reference< jvmaccess::VirtualMachine >& _rVM = ::rtl::Reference< jvmaccess::VirtualMachine >(),
+ bool _bSet = false)
+{
+ static ::rtl::Reference< jvmaccess::VirtualMachine > s_VM;
+ if ( _rVM.is() || _bSet )
+ s_VM = _rVM;
+ return s_VM;
+}
+
+::rtl::Reference< jvmaccess::VirtualMachine > java_lang_Object::getVM(const Reference<XComponentContext >& _rxContext)
+{
+ ::rtl::Reference< jvmaccess::VirtualMachine > xVM = getJavaVM2();
+ if ( !xVM.is() && _rxContext.is() )
+ xVM = getJavaVM2(::connectivity::getJavaVM(_rxContext));
+
+ return xVM;
+}
+
+SDBThreadAttach::SDBThreadAttach()
+ : m_aGuard(java_lang_Object::getVM())
+ , pEnv(nullptr)
+{
+ pEnv = m_aGuard.getEnvironment();
+ OSL_ENSURE(pEnv,"Environment is nULL!");
+}
+
+SDBThreadAttach::~SDBThreadAttach()
+{
+}
+
+static oslInterlockedCount& getJavaVMRefCount()
+{
+ static oslInterlockedCount s_nRefCount = 0;
+ return s_nRefCount;
+}
+
+void SDBThreadAttach::addRef()
+{
+ osl_atomic_increment(&getJavaVMRefCount());
+}
+
+void SDBThreadAttach::releaseRef()
+{
+ osl_atomic_decrement(&getJavaVMRefCount());
+ if ( getJavaVMRefCount() == 0 )
+ {
+ getJavaVM2(::rtl::Reference< jvmaccess::VirtualMachine >(),true);
+ }
+}
+
+// static variables of the class
+jclass java_lang_Object::theClass = nullptr;
+
+jclass java_lang_Object::getMyClass() const
+{
+ if( !theClass )
+ theClass = findMyClass("java/lang/Object");
+ return theClass;
+}
+// the actual constructor
+java_lang_Object::java_lang_Object()
+ : object( nullptr )
+{
+ SDBThreadAttach::addRef();
+}
+
+// the protected-constructor for the derived classes
+java_lang_Object::java_lang_Object( JNIEnv * pXEnv, jobject myObj )
+ : object( nullptr )
+{
+ SDBThreadAttach::addRef();
+ if( pXEnv && myObj )
+ object = pXEnv->NewGlobalRef( myObj );
+}
+
+java_lang_Object::~java_lang_Object() COVERITY_NOEXCEPT_FALSE
+{
+ if( object )
+ {
+ SDBThreadAttach t;
+ clearObject(*t.pEnv);
+ }
+ SDBThreadAttach::releaseRef();
+}
+void java_lang_Object::clearObject(JNIEnv& rEnv)
+{
+ if( object )
+ {
+ rEnv.DeleteGlobalRef( object );
+ object = nullptr;
+ }
+}
+
+void java_lang_Object::clearObject()
+{
+ if( object )
+ {
+ SDBThreadAttach t;
+ clearObject(*t.pEnv);
+ }
+}
+// the protected-constructor for the derived classes
+void java_lang_Object::saveRef( JNIEnv * pXEnv, jobject myObj )
+{
+ OSL_ENSURE( myObj, "object in c++ -> Java Wrapper" );
+ if( myObj )
+ object = pXEnv->NewGlobalRef( myObj );
+}
+
+
+OUString java_lang_Object::toString() const
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("toString",mID);
+}
+
+
+namespace
+{
+ bool lcl_translateJNIExceptionToUNOException(
+ JNIEnv* _pEnvironment, const Reference< XInterface >& _rxContext, SQLException& _out_rException )
+ {
+ jthrowable jThrow = _pEnvironment ? _pEnvironment->ExceptionOccurred() : nullptr;
+ if ( !jThrow )
+ return false;
+
+ _pEnvironment->ExceptionClear();
+ // we have to clear the exception here because we want to handle it itself
+
+ if ( _pEnvironment->IsInstanceOf( jThrow, java_sql_SQLException_BASE::st_getMyClass() ) )
+ {
+ java_sql_SQLException_BASE aException( _pEnvironment, jThrow );
+ _out_rException = SQLException( aException.getMessage(), _rxContext,
+ aException.getSQLState(), aException.getErrorCode(), Any() );
+ return true;
+ }
+ else if ( _pEnvironment->IsInstanceOf( jThrow, java_lang_Throwable::st_getMyClass() ) )
+ {
+ java_lang_Throwable aThrow( _pEnvironment, jThrow );
+#if OSL_DEBUG_LEVEL > 0
+ aThrow.printStackTrace();
+#endif
+ OUString sMessage = aThrow.getMessage();
+ if ( sMessage.isEmpty() )
+ sMessage = aThrow.getLocalizedMessage();
+ if( sMessage.isEmpty() )
+ sMessage = aThrow.toString();
+ _out_rException = SQLException( sMessage, _rxContext, OUString(), -1, Any() );
+ return true;
+ }
+ else
+ _pEnvironment->DeleteLocalRef( jThrow );
+ return false;
+ }
+}
+
+
+void java_lang_Object::ThrowLoggedSQLException( const ::comphelper::EventLogger& _rLogger, JNIEnv* _pEnvironment,
+ const Reference< XInterface >& _rxContext )
+{
+ SQLException aException;
+ if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
+ {
+ _rLogger.log( css::logging::LogLevel::SEVERE, STR_LOG_THROWING_EXCEPTION, aException.Message, aException.SQLState, aException.ErrorCode );
+ throw aException;
+ }
+}
+
+void java_lang_Object::ThrowSQLException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
+{
+ SQLException aException;
+ if ( lcl_translateJNIExceptionToUNOException( _pEnvironment, _rxContext, aException ) )
+ throw aException;
+}
+
+void java_lang_Object::ThrowRuntimeException( JNIEnv* _pEnvironment, const Reference< XInterface>& _rxContext )
+{
+ try
+ {
+ ThrowSQLException(_pEnvironment, _rxContext);
+ }
+ catch (const SQLException& e)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException( e.Message,
+ e.Context, anyEx );
+ }
+}
+
+void java_lang_Object::obtainMethodId_throwSQL(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
+{
+ if ( !_inout_MethodID )
+ {
+ _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
+ OSL_ENSURE( _inout_MethodID, _pSignature );
+ if ( !_inout_MethodID )
+ throw SQLException();
+ } // if ( !_inout_MethodID )
+}
+
+void java_lang_Object::obtainMethodId_throwRuntime(JNIEnv* _pEnv,const char* _pMethodName, const char* _pSignature,jmethodID& _inout_MethodID) const
+{
+ if ( !_inout_MethodID )
+ {
+ _inout_MethodID = _pEnv->GetMethodID( getMyClass(), _pMethodName, _pSignature );
+ OSL_ENSURE( _inout_MethodID, _pSignature );
+ if ( !_inout_MethodID )
+ throw RuntimeException();
+ } // if ( !_inout_MethodID )
+}
+
+
+bool java_lang_Object::callBooleanMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
+{
+ bool out( false );
+
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()Z", _inout_MethodID);
+ // call method
+ out = t.pEnv->CallBooleanMethod( object, _inout_MethodID );
+ ThrowSQLException( t.pEnv, nullptr );
+
+ return out;
+}
+
+bool java_lang_Object::callBooleanMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
+{
+ bool out( false );
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callBooleanMethodWithIntArg: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)Z", _inout_MethodID);
+ // call method
+ out = t.pEnv->CallBooleanMethod( object, _inout_MethodID, _nArgument );
+ ThrowSQLException( t.pEnv, nullptr );
+
+ return out;
+}
+
+jobject java_lang_Object::callResultSetMethod( JNIEnv& _rEnv,const char* _pMethodName, jmethodID& _inout_MethodID ) const
+{
+ // call method
+ jobject out = callObjectMethod(&_rEnv,_pMethodName,"()Ljava/sql/ResultSet;", _inout_MethodID);
+ return out;
+}
+
+sal_Int32 java_lang_Object::callIntMethod_ThrowSQL(const char* _pMethodName, jmethodID& _inout_MethodID) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()I", _inout_MethodID);
+ // call method
+ jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
+ ThrowSQLException( t.pEnv, nullptr );
+ return static_cast<sal_Int32>(out);
+}
+
+sal_Int32 java_lang_Object::callIntMethod_ThrowRuntime(const char* _pMethodName, jmethodID& _inout_MethodID) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"()I", _inout_MethodID);
+ // call method
+ jint out( t.pEnv->CallIntMethod( object, _inout_MethodID ) );
+ ThrowRuntimeException(t.pEnv, nullptr);
+ return static_cast<sal_Int32>(out);
+}
+
+sal_Int32 java_lang_Object::callIntMethodWithIntArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
+ // call method
+ jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
+ ThrowSQLException( t.pEnv, nullptr );
+ return static_cast<sal_Int32>(out);
+}
+
+sal_Int32 java_lang_Object::callIntMethodWithIntArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID,sal_Int32 _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(I)I", _inout_MethodID);
+ // call method
+ jint out( t.pEnv->CallIntMethod( object, _inout_MethodID , _nArgument) );
+ ThrowRuntimeException(t.pEnv, nullptr);
+ return static_cast<sal_Int32>(out);
+}
+
+void java_lang_Object::callVoidMethod_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"()V", _inout_MethodID);
+
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID );
+ ThrowSQLException( t.pEnv, nullptr );
+}
+
+void java_lang_Object::callVoidMethod_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"()V", _inout_MethodID);
+
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID );
+ ThrowRuntimeException(t.pEnv, nullptr);
+}
+
+void java_lang_Object::callVoidMethodWithIntArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
+
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
+ ThrowSQLException( t.pEnv, nullptr );
+}
+
+void java_lang_Object::callVoidMethodWithIntArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID, sal_Int32 _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(I)V", _inout_MethodID);
+
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID,_nArgument );
+ ThrowRuntimeException(t.pEnv, nullptr);
+}
+
+void java_lang_Object::callVoidMethodWithBoolArg_ThrowSQL( const char* _pMethodName, jmethodID& _inout_MethodID, bool _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID,int(_nArgument) );
+ ThrowSQLException( t.pEnv, nullptr );
+}
+
+void java_lang_Object::callVoidMethodWithBoolArg_ThrowRuntime( const char* _pMethodName, jmethodID& _inout_MethodID, bool _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwRuntime(t.pEnv, _pMethodName,"(Z)V", _inout_MethodID);
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID,int(_nArgument) );
+ ThrowRuntimeException(t.pEnv, nullptr);
+}
+
+OUString java_lang_Object::callStringMethod( const char* _pMethodName, jmethodID& _inout_MethodID ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java environment anymore!" );
+
+ // call method
+ jstring out = static_cast<jstring>(callObjectMethod(t.pEnv,_pMethodName,"()Ljava/lang/String;", _inout_MethodID));
+ return JavaString2String( t.pEnv, out );
+}
+
+jobject java_lang_Object::callObjectMethod( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID ) const
+{
+ // obtain method ID
+ obtainMethodId_throwSQL(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
+ // call method
+ jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID);
+ ThrowSQLException( _pEnv, nullptr );
+ return out;
+}
+
+
+jobject java_lang_Object::callObjectMethodWithIntArg( JNIEnv * _pEnv,const char* _pMethodName,const char* _pSignature, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
+{
+ obtainMethodId_throwSQL(_pEnv, _pMethodName,_pSignature, _inout_MethodID);
+ // call method
+ jobject out = _pEnv->CallObjectMethod( object, _inout_MethodID,_nArgument );
+ ThrowSQLException( _pEnv, nullptr );
+ return out;
+}
+
+OUString java_lang_Object::callStringMethodWithIntArg( const char* _pMethodName, jmethodID& _inout_MethodID , sal_Int32 _nArgument) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callStringMethod: no Java environment anymore!" );
+ jstring out = static_cast<jstring>(callObjectMethodWithIntArg(t.pEnv,_pMethodName,"(I)Ljava/lang/String;",_inout_MethodID,_nArgument));
+ return JavaString2String( t.pEnv, out );
+}
+
+void java_lang_Object::callVoidMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const OUString& _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethod: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Ljava/lang/String;)V", _inout_MethodID);
+
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
+ // call method
+ t.pEnv->CallVoidMethod( object, _inout_MethodID , str.get());
+ ThrowSQLException( t.pEnv, nullptr );
+}
+
+sal_Int32 java_lang_Object::callIntMethodWithStringArg( const char* _pMethodName, jmethodID& _inout_MethodID,const OUString& _nArgument ) const
+{
+ SDBThreadAttach t;
+ OSL_ENSURE( t.pEnv, "java_lang_Object::callIntMethodWithStringArg: no Java environment anymore!" );
+ obtainMethodId_throwSQL(t.pEnv, _pMethodName,"(Ljava/lang/String;)I", _inout_MethodID);
+
+ //TODO: Check if the code below is needed
+ //jdbc::LocalRef< jstring > str( t.env(), convertwchar_tToJavaString( t.pEnv, sql ) );
+ //{
+ // jdbc::ContextClassLoaderScope ccl( t.env(),
+ // m_pConnection ? m_pConnection->getDriverClassLoader() : jdbc::GlobalRef< jobject >(),
+ // m_aLogger,
+ // *this
+ // );
+
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,_nArgument));
+ // call method
+ jint out = t.pEnv->CallIntMethod( object, _inout_MethodID , str.get());
+ ThrowSQLException( t.pEnv, nullptr );
+ return static_cast<sal_Int32>(out);
+}
+
+jclass java_lang_Object::findMyClass(const char* _pClassName)
+{
+ // the class must be fetched only once, therefore static
+ SDBThreadAttach t;
+ jclass tempClass = t.pEnv->FindClass(_pClassName); OSL_ENSURE(tempClass,"Java : FindClass not successful!");
+ if(!tempClass)
+ {
+ t.pEnv->ExceptionDescribe();
+ t.pEnv->ExceptionClear();
+ }
+ jclass globClass = static_cast<jclass>(t.pEnv->NewGlobalRef( tempClass ));
+ t.pEnv->DeleteLocalRef( tempClass );
+ return globClass;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/PreparedStatement.cxx b/connectivity/source/drivers/jdbc/PreparedStatement.cxx
new file mode 100644
index 000000000..33aadcbca
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/PreparedStatement.cxx
@@ -0,0 +1,697 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/PreparedStatement.hxx>
+#include <java/sql/ResultSet.hxx>
+#include <java/sql/ResultSetMetaData.hxx>
+#include <java/sql/Connection.hxx>
+#include <java/sql/Timestamp.hxx>
+#include <java/math/BigDecimal.hxx>
+#include <java/tools.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/FValue.hxx>
+#include <connectivity/dbexception.hxx>
+#include <strings.hrc>
+#include <resource/sharedresources.hxx>
+#include <java/LocalRef.hxx>
+#include <strings.hxx>
+#include <string.h>
+#include <memory>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+
+//************ Class: java.sql.PreparedStatement
+
+IMPLEMENT_SERVICE_INFO(java_sql_PreparedStatement,"com.sun.star.sdbcx.JPreparedStatement","com.sun.star.sdbc.PreparedStatement");
+
+java_sql_PreparedStatement::java_sql_PreparedStatement( JNIEnv * pEnv, java_sql_Connection& _rCon, const OUString& sql )
+ : OStatement_BASE2( pEnv, _rCon )
+{
+ m_sSqlStatement = sql;
+}
+
+jclass java_sql_PreparedStatement::theClass = nullptr;
+
+java_sql_PreparedStatement::~java_sql_PreparedStatement()
+{
+}
+
+
+jclass java_sql_PreparedStatement::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/PreparedStatement");
+ return theClass;
+}
+
+
+css::uno::Any SAL_CALL java_sql_PreparedStatement::queryInterface( const css::uno::Type & rType )
+{
+ css::uno::Any aRet = OStatement_BASE2::queryInterface(rType);
+ return aRet.hasValue() ? aRet : ::cppu::queryInterface( rType,
+ static_cast< XPreparedStatement*>(this),
+ static_cast< XParameters*>(this),
+ static_cast< XResultSetMetaDataSupplier*>(this),
+ static_cast< XPreparedBatchExecution*>(this));
+}
+
+css::uno::Sequence< css::uno::Type > SAL_CALL java_sql_PreparedStatement::getTypes( )
+{
+ ::cppu::OTypeCollection aTypes( cppu::UnoType<XPreparedStatement>::get(),
+ cppu::UnoType<XParameters>::get(),
+ cppu::UnoType<XResultSetMetaDataSupplier>::get(),
+ cppu::UnoType<XPreparedBatchExecution>::get());
+
+ return ::comphelper::concatSequences(aTypes.getTypes(),OStatement_BASE2::getTypes());
+}
+
+
+sal_Bool SAL_CALL java_sql_PreparedStatement::execute( )
+{
+ m_aLogger.log( LogLevel::FINE, STR_LOG_EXECUTING_PREPARED );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "execute", mID );
+}
+
+
+sal_Int32 SAL_CALL java_sql_PreparedStatement::executeUpdate( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINE, STR_LOG_EXECUTING_PREPARED_UPDATE );
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowSQL("executeUpdate", mID);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setString( sal_Int32 parameterIndex, const OUString& x )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ m_aLogger.log( LogLevel::FINER, STR_LOG_STRING_PARAMETER, parameterIndex, x );
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ { // initialize temporary Variable
+ createStatement(t.pEnv);
+ static const char * const cSignature = "(ILjava/lang/String;)V";
+ static const char * const cMethodName = "setString";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,x));
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,str.get());
+ // and clean up
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ } //t.pEnv
+}
+
+
+css::uno::Reference< css::sdbc::XConnection > SAL_CALL java_sql_PreparedStatement::getConnection( )
+{
+ return m_pConnection;
+}
+
+
+css::uno::Reference< css::sdbc::XResultSet > SAL_CALL java_sql_PreparedStatement::executeQuery( )
+{
+ m_aLogger.log( LogLevel::FINE, STR_LOG_EXECUTING_PREPARED_QUERY );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callResultSetMethod(t.env(),"executeQuery",mID);
+
+ return out==nullptr ? nullptr : new java_sql_ResultSet( t.pEnv, out, m_aLogger, *m_pConnection,this);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_BOOLEAN_PARAMETER, parameterIndex, bool(x) );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setBoolean", "(IZ)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_BYTE_PARAMETER, parameterIndex, static_cast<sal_Int32>(x) );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setByte", "(IB)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setDate( sal_Int32 parameterIndex, const css::util::Date& x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_DATE_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ java_sql_Date aT(x);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setDate", "(ILjava/sql/Date;)V", mID, parameterIndex, aT.getJavaObject());
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setTime( sal_Int32 parameterIndex, const css::util::Time& x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_TIME_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ java_sql_Time aT(x);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setTime", "(ILjava/sql/Time;)V", mID, parameterIndex, aT.getJavaObject());
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setTimestamp( sal_Int32 parameterIndex, const css::util::DateTime& x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_TIMESTAMP_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ java_sql_Timestamp aD(x);
+ callVoidMethod_ThrowSQL("setTimestamp", "(ILjava/sql/Timestamp;)V", mID, parameterIndex, aD.getJavaObject());
+}
+
+void SAL_CALL java_sql_PreparedStatement::setDouble( sal_Int32 parameterIndex, double x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_DOUBLE_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setDouble", "(ID)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setFloat( sal_Int32 parameterIndex, float x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_FLOAT_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setFloat", "(IF)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_INT_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setInt", "(II)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_LONG_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setLong", "(IJ)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_NULL_PARAMETER, parameterIndex, sqlType );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setNull", "(II)V", mID, parameterIndex, sqlType);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setClob( sal_Int32 /*parameterIndex*/, const css::uno::Reference< css::sdbc::XClob >& /*x*/ )
+{
+ ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setClob", *this );
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setBlob( sal_Int32 /*parameterIndex*/, const css::uno::Reference< css::sdbc::XBlob >& /*x*/ )
+{
+ ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setBlob", *this );
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setArray( sal_Int32 /*parameterIndex*/, const css::uno::Reference< css::sdbc::XArray >& /*x*/ )
+{
+ ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setArray", *this );
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const css::uno::Reference< css::sdbc::XRef >& /*x*/ )
+{
+ ::dbtools::throwFeatureNotImplementedSQLException( "XParameters::setRef", *this );
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const css::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_OBJECT_NULL_PARAMETER, parameterIndex );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+
+ // initialize temporary Variable
+ static const char * const cSignature = "(ILjava/lang/Object;II)V";
+ static const char * const cMethodName = "setObject";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ {
+ jobject obj = nullptr;
+ switch(targetSqlType)
+ {
+ case DataType::DECIMAL:
+ case DataType::NUMERIC:
+ {
+ double nTemp = 0.0;
+
+ std::unique_ptr<java_math_BigDecimal> pBigDecimal;
+ if ( x >>= nTemp)
+ {
+ pBigDecimal.reset(new java_math_BigDecimal(nTemp));
+ //setDouble(parameterIndex,nTemp);
+ //return;
+ }
+ else
+ {
+ ORowSetValue aValue;
+ aValue.fill(x);
+ const OUString sValue = aValue.getString();
+ if ( !sValue.isEmpty() )
+ pBigDecimal.reset(new java_math_BigDecimal(sValue));
+ else
+ pBigDecimal.reset(new java_math_BigDecimal(0.0));
+ }
+ //obj = convertwchar_tToJavaString(t.pEnv,::comphelper::getString(x));
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,pBigDecimal->getJavaObject(),targetSqlType,scale);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ return;
+ }
+ default:
+ obj = convertwchar_tToJavaString(t.pEnv,::comphelper::getString(x));
+ break;
+ }
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,obj,targetSqlType,scale);
+ t.pEnv->DeleteLocalRef(obj);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ // and clean up
+ } //mID
+ } //t.pEnv
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 /*sqlType*/, const OUString& /*typeName*/ )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_OBJECT_NULL_PARAMETER, parameterIndex );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL<jobject>("setObject", "(ILjava/lang/Object;)V", mID, parameterIndex, nullptr);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setObject( sal_Int32 parameterIndex, const css::uno::Any& x )
+{
+ if(!::dbtools::implSetObject(this,parameterIndex,x))
+ {
+ const OUString sError( m_pConnection->getResources().getResourceStringWithSubstitution(
+ STR_UNKNOWN_PARA_TYPE,
+ "$position$", OUString::number(parameterIndex)
+ ) );
+ ::dbtools::throwGenericSQLException(sError,*this);
+ }
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_SHORT_PARAMETER, parameterIndex, x );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("setShort", "(IS)V", mID, parameterIndex, x);
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setBytes( sal_Int32 parameterIndex, const css::uno::Sequence< sal_Int8 >& x )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_BYTES_PARAMETER, parameterIndex );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+
+ // initialize temporary Variable
+ static const char * const cSignature = "(I[B)V";
+ static const char * const cMethodName = "setBytes";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jbyteArray pByteArray = t.pEnv->NewByteArray(x.getLength());
+ jbyte * pData = reinterpret_cast<jbyte *>(
+ const_cast<sal_Int8 *>(x.getConstArray()));
+ // 4th param of Set*ArrayRegion changed from pointer to non-const to
+ // pointer to const between <http://docs.oracle.com/javase/6/docs/
+ // technotes/guides/jni/spec/functions.html#wp22933> and
+ // <http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/
+ // functions.html#wp22933>; work around that difference in a way
+ // that doesn't trigger loplugin:redundantcast
+ t.pEnv->SetByteArrayRegion(pByteArray,0,x.getLength(),pData);
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,pByteArray);
+ t.pEnv->DeleteLocalRef(pByteArray);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ } //t.pEnv
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const css::uno::Reference< css::io::XInputStream >& x, sal_Int32 length )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_CHARSTREAM_PARAMETER, parameterIndex );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t;
+ assert(t.pEnv && "Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+
+ // initialize temporary variable
+ static const char * const cSignature = "(ILjava/io/InputStream;I)V";
+ static const char * const cMethodName = "setCharacterStream";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ Sequence< sal_Int8 > aSeq;
+ if ( x.is() )
+ x->readBytes( aSeq, length );
+ sal_Int32 actualLength = aSeq.getLength();
+
+ jvalue args2[3];
+ jbyteArray pByteArray = t.pEnv->NewByteArray( actualLength );
+ jbyte * aSeqData = reinterpret_cast<jbyte *>(
+ const_cast<sal_Int8 *>(aSeq.getConstArray()));
+ // 4th param of Set*ArrayRegion changed from pointer to non-const to
+ // pointer to const between <http://docs.oracle.com/javase/6/docs/
+ // technotes/guides/jni/spec/functions.html#wp22933> and
+ // <http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/
+ // functions.html#wp22933>; work around that difference in a way
+ // that doesn't trigger loplugin:redundantcast
+ t.pEnv->SetByteArrayRegion(pByteArray,0,actualLength,aSeqData);
+ args2[0].l = pByteArray;
+ args2[1].i = 0;
+ args2[2].i = actualLength;
+ // Java-Call
+ jclass aClass = t.pEnv->FindClass("java/io/CharArrayInputStream");
+ static jmethodID mID2 = nullptr;
+ if ( !mID2 )
+ {
+ // initialize temporary variable
+ const char * const cSignatureStream = "([BII)V";
+ mID2 = t.pEnv->GetMethodID( aClass, "<init>", cSignatureStream );
+ }
+ jobject tempObj = nullptr;
+ if(mID2)
+ tempObj = t.pEnv->NewObjectA( aClass, mID2, args2 );
+
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,tempObj,actualLength);
+ // and clean up
+ t.pEnv->DeleteLocalRef(pByteArray);
+ t.pEnv->DeleteLocalRef(tempObj);
+ t.pEnv->DeleteLocalRef(aClass);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ } //t.pEnv
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const css::uno::Reference< css::io::XInputStream >& x, sal_Int32 length )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_BINARYSTREAM_PARAMETER, parameterIndex );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+ // initialize temporary variable
+ static const char * const cSignature = "(ILjava/io/InputStream;I)V";
+ static const char * const cMethodName = "setBinaryStream";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ {
+ Sequence< sal_Int8 > aSeq;
+ if ( x.is() )
+ x->readBytes( aSeq, length );
+ sal_Int32 actualLength = aSeq.getLength();
+
+ jvalue args2[3];
+ jbyteArray pByteArray = t.pEnv->NewByteArray(actualLength);
+ jbyte * aSeqData = reinterpret_cast<jbyte *>(
+ const_cast<sal_Int8 *>(aSeq.getConstArray()));
+ // 4th param of Set*ArrayRegion changed from pointer to non-const to
+ // pointer to const between <http://docs.oracle.com/javase/6/docs/
+ // technotes/guides/jni/spec/functions.html#wp22933> and
+ // <http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/
+ // functions.html#wp22933>; work around that difference in a way
+ // that doesn't trigger loplugin:redundantcast
+ t.pEnv->SetByteArrayRegion(pByteArray,0,actualLength,aSeqData);
+ args2[0].l = pByteArray;
+ args2[1].i = 0;
+ args2[2].i = actualLength;
+
+ // Java-Call
+ jclass aClass = t.pEnv->FindClass("java/io/ByteArrayInputStream");
+ static jmethodID mID2 = nullptr;
+ if ( !mID2 )
+ {
+ // initialize temporary variable
+ const char * const cSignatureStream = "([BII)V";
+ mID2 = t.pEnv->GetMethodID( aClass, "<init>", cSignatureStream );
+ }
+ jobject tempObj = nullptr;
+ if(mID2)
+ tempObj = t.pEnv->NewObjectA( aClass, mID2, args2 );
+ t.pEnv->CallVoidMethod( object, mID, parameterIndex,tempObj,actualLength);
+ // and clean up
+ t.pEnv->DeleteLocalRef(pByteArray);
+ t.pEnv->DeleteLocalRef(tempObj);
+ t.pEnv->DeleteLocalRef(aClass);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ } //t.pEnv
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::clearParameters( )
+{
+ m_aLogger.log( LogLevel::FINER, STR_LOG_CLEAR_PARAMETERS );
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ SDBThreadAttach t;
+ {
+ createStatement(t.pEnv);
+
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("clearParameters",mID);
+ } //t.pEnv
+}
+
+void SAL_CALL java_sql_PreparedStatement::clearBatch( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("clearBatch",mID);
+ } //t.pEnv
+}
+
+
+void SAL_CALL java_sql_PreparedStatement::addBatch( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("addBatch", mID);
+ } //t.pEnv
+}
+
+
+css::uno::Sequence< sal_Int32 > SAL_CALL java_sql_PreparedStatement::executeBatch( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ css::uno::Sequence< sal_Int32 > aSeq;
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jintArray out = static_cast<jintArray>(callObjectMethod(t.pEnv,"executeBatch","()[I", mID));
+ if(out)
+ {
+ jboolean p = false;
+ aSeq.realloc(t.pEnv->GetArrayLength(out));
+ memcpy(aSeq.getArray(),t.pEnv->GetIntArrayElements(out,&p),aSeq.getLength());
+ t.pEnv->DeleteLocalRef(out);
+ }
+ return aSeq;
+}
+
+css::uno::Reference< css::sdbc::XResultSetMetaData > SAL_CALL java_sql_PreparedStatement::getMetaData( )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ createStatement(t.pEnv);
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getMetaData","()Ljava/sql/ResultSetMetaData;", mID);
+
+ return out==nullptr ? nullptr : new java_sql_ResultSetMetaData( t.pEnv, out, *m_pConnection );
+}
+
+void SAL_CALL java_sql_PreparedStatement::acquire() noexcept
+{
+ OStatement_BASE2::acquire();
+}
+
+void SAL_CALL java_sql_PreparedStatement::release() noexcept
+{
+ OStatement_BASE2::release();
+}
+
+void java_sql_PreparedStatement::createStatement(JNIEnv* _pEnv)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed);
+
+ if( object || !_pEnv )
+ return;
+
+ // initialize temporary variable
+ static const char * const cMethodName = "prepareStatement";
+
+ jvalue args[1];
+ // convert Parameter
+ args[0].l = convertwchar_tToJavaString(_pEnv,m_sSqlStatement);
+ // Java-Call
+ jobject out = nullptr;
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(Ljava/lang/String;II)Ljava/sql/PreparedStatement;";
+ mID = _pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature );
+ }
+ if( mID )
+ {
+ out = _pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID, args[0].l ,m_nResultSetType,m_nResultSetConcurrency);
+ }
+ else
+ {
+ static jmethodID mID2 = nullptr;
+ if ( !mID2 )
+ {
+ static const char * const cSignature2 = "(Ljava/lang/String;)Ljava/sql/PreparedStatement;";
+ mID2 = _pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature2 );
+ }
+ if ( mID2 )
+ out = _pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID2, args[0].l );
+ }
+ _pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ ThrowLoggedSQLException( m_aLogger, _pEnv, *this );
+ if ( out )
+ object = _pEnv->NewGlobalRef( out );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Reader.cxx b/connectivity/source/drivers/jdbc/Reader.cxx
new file mode 100644
index 000000000..85d02e87a
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Reader.cxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/io/Reader.hxx>
+#include <string.h>
+#include <osl/diagnose.h>
+using namespace connectivity;
+using ::com::sun::star::uno::Sequence;
+
+
+//************ Class: java.io.Reader
+
+
+jclass java_io_Reader::theClass = nullptr;
+java_io_Reader::java_io_Reader( JNIEnv * pEnv, jobject myObj )
+ : java_lang_Object( pEnv, myObj )
+{
+ SDBThreadAttach::addRef();
+}
+java_io_Reader::~java_io_Reader()
+{
+ SDBThreadAttach::releaseRef();
+}
+
+jclass java_io_Reader::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/io/Reader");
+ return theClass;
+}
+
+sal_Int32 SAL_CALL java_io_Reader::readSomeBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
+{
+ return readBytes(aData,nMaxBytesToRead);
+}
+
+void SAL_CALL java_io_Reader::skipBytes( sal_Int32 nBytesToSkip )
+{
+ static jmethodID mID(nullptr);
+ if(nBytesToSkip <= 0)
+ return;
+
+ if(m_buf)
+ {
+ m_buf.reset();
+ --nBytesToSkip;
+ }
+
+ static_assert(sizeof(jchar) == 2, "I thought Java characters were UTF16 code units?");
+ sal_Int32 nCharsToSkip = nBytesToSkip / sizeof(jchar);
+ callIntMethodWithIntArg_ThrowRuntime("skip",mID,nCharsToSkip);
+ if(nBytesToSkip % sizeof(jchar) != 0)
+ {
+ assert(nBytesToSkip % sizeof(jchar) == 1);
+ Sequence< sal_Int8 > aData(1);
+ assert(m_buf);
+ readBytes(aData, 1);
+ }
+}
+
+sal_Int32 SAL_CALL java_io_Reader::available( )
+{
+ if(m_buf)
+ return 1;
+ bool out;
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ static const char * const cSignature = "()Z";
+ static const char * const cMethodName = "ready";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwRuntime(t.pEnv, cMethodName,cSignature, mID);
+ out = t.pEnv->CallBooleanMethod( object, mID);
+ ThrowRuntimeException(t.pEnv,*this);
+ } //t.pEnv
+ return (m_buf ? 1 : 0) + (out ? 1 : 0); // no way to tell *how much* is ready
+}
+
+void SAL_CALL java_io_Reader::closeInput( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowRuntime("close", mID);
+}
+
+sal_Int32 SAL_CALL java_io_Reader::readBytes( css::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
+{
+ OSL_ENSURE(aData.getLength() >= nBytesToRead," Sequence is smaller than BytesToRead");
+
+ if(nBytesToRead == 0)
+ return 0;
+
+ sal_Int8 *dst(aData.getArray());
+ sal_Int32 nBytesWritten(0);
+
+ if (m_buf)
+ {
+ if(!aData.hasElements())
+ {
+ aData.realloc(1);
+ dst = aData.getArray();
+ }
+ *dst = *m_buf;
+ m_buf.reset();
+ ++nBytesWritten;
+ ++dst;
+ --nBytesToRead;
+ }
+
+ if(nBytesToRead == 0)
+ return nBytesWritten;
+
+ sal_Int32 nCharsToRead = (nBytesToRead + 1)/2;
+
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ jcharArray pCharArray = t.pEnv->NewCharArray(nCharsToRead);
+ static const char * const cSignature = "([CII)I";
+ static const char * const cMethodName = "read";
+ // Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwRuntime(t.pEnv, cMethodName,cSignature, mID);
+ jint outChars = t.pEnv->CallIntMethod( object, mID, pCharArray, 0, nCharsToRead );
+ if ( !outChars )
+ {
+ if(nBytesWritten==0)
+ ThrowRuntimeException(t.pEnv,*this);
+ else
+ return 1;
+ }
+ if(outChars > 0)
+ {
+ static_assert(sizeof(jchar) == 2, "I thought Java characters were UTF16 code units?");
+ const sal_Int32 jcs = sizeof(jchar);
+ const sal_Int32 outBytes = std::min(nBytesToRead, outChars*jcs);
+ assert(outBytes == outChars*jcs || outBytes == outChars*jcs - 1);
+
+ jboolean p = JNI_FALSE;
+ if(aData.getLength() < nBytesWritten + outBytes)
+ {
+ aData.realloc(nBytesWritten + outBytes);
+ dst = aData.getArray() + nBytesWritten;
+ }
+ jchar *outBuf(t.pEnv->GetCharArrayElements(pCharArray,&p));
+
+ memcpy(dst, outBuf, outBytes);
+ nBytesWritten += outBytes;
+ if(outBytes < outChars*jcs)
+ {
+ assert(outChars*jcs - outBytes == 1);
+ assert(!m_buf);
+ m_buf = reinterpret_cast<char*>(outBuf)[outBytes];
+ }
+ }
+ t.pEnv->DeleteLocalRef(pCharArray);
+ } //t.pEnv
+ return nBytesWritten;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Ref.cxx b/connectivity/source/drivers/jdbc/Ref.cxx
new file mode 100644
index 000000000..12ce9fda8
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Ref.cxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/Ref.hxx>
+
+using namespace connectivity;
+
+//************ Class: java.sql.Ref
+
+jclass java_sql_Ref::theClass = nullptr;
+java_sql_Ref::java_sql_Ref(JNIEnv* pEnv, jobject myObj)
+ : java_lang_Object(pEnv, myObj)
+{
+ SDBThreadAttach::addRef();
+}
+java_sql_Ref::~java_sql_Ref() { SDBThreadAttach::releaseRef(); }
+
+jclass java_sql_Ref::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if (!theClass)
+ theClass = findMyClass("java/sql/Ref");
+ return theClass;
+}
+
+OUString SAL_CALL java_sql_Ref::getBaseTypeName()
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("getBaseTypeName", mID);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/ResultSet.cxx b/connectivity/source/drivers/jdbc/ResultSet.cxx
new file mode 100644
index 000000000..c274c521c
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/ResultSet.cxx
@@ -0,0 +1,1013 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/lang/String.hxx>
+#include <java/lang/Boolean.hxx>
+#include <java/sql/ResultSet.hxx>
+#include <java/math/BigDecimal.hxx>
+#include <java/sql/JStatement.hxx>
+#include <java/sql/SQLWarning.hxx>
+#include <java/sql/Timestamp.hxx>
+#include <java/sql/Array.hxx>
+#include <java/sql/Ref.hxx>
+#include <java/sql/Clob.hxx>
+#include <java/sql/Blob.hxx>
+#include <java/sql/ResultSetMetaData.hxx>
+#include <java/io/InputStream.hxx>
+#include <java/io/Reader.hxx>
+#include <java/tools.hxx>
+#include <comphelper/property.hxx>
+#include <connectivity/CommonTools.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <TConnection.hxx>
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <connectivity/dbexception.hxx>
+#include <strings.hrc>
+#include <resource/sharedresources.hxx>
+#include <java/LocalRef.hxx>
+
+#include <string.h>
+#include <memory>
+
+using namespace ::comphelper;
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+IMPLEMENT_SERVICE_INFO(java_sql_ResultSet,"com.sun.star.sdbcx.JResultSet","com.sun.star.sdbc.ResultSet");
+
+//************ Class: java.sql.ResultSet
+
+
+jclass java_sql_ResultSet::theClass = nullptr;
+java_sql_ResultSet::java_sql_ResultSet( JNIEnv * pEnv, jobject myObj, const java::sql::ConnectionLog& _rParentLogger,java_sql_Connection& _rConnection, java_sql_Statement_Base* pStmt)
+ :java_sql_ResultSet_BASE(m_aMutex)
+ ,java_lang_Object( pEnv, myObj )
+ ,OPropertySetHelper(java_sql_ResultSet_BASE::rBHelper)
+ ,m_aLogger( _rParentLogger, java::sql::ConnectionLog::RESULTSET )
+ ,m_pConnection(&_rConnection)
+{
+ SDBThreadAttach::addRef();
+ osl_atomic_increment(&m_refCount);
+ if ( pStmt )
+ m_xStatement = *pStmt;
+
+ osl_atomic_decrement(&m_refCount);
+}
+
+java_sql_ResultSet::~java_sql_ResultSet()
+{
+ if ( !java_sql_ResultSet_BASE::rBHelper.bDisposed && !java_sql_ResultSet_BASE::rBHelper.bInDispose )
+ {
+ // increment ref count to prevent double call of Dtor
+ osl_atomic_increment( &m_refCount );
+ dispose();
+ }
+}
+
+jclass java_sql_ResultSet::getMyClass() const
+{
+ // the class must be fetched only once, therefore static
+ if( !theClass )
+ theClass = findMyClass("java/sql/ResultSet");
+ return theClass;
+}
+
+void java_sql_ResultSet::disposing()
+{
+ OPropertySetHelper::disposing();
+
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if( object )
+ {
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("close", mID);
+ clearObject(*t.pEnv);
+ }
+
+ SDBThreadAttach::releaseRef();
+}
+
+css::uno::Any SAL_CALL java_sql_ResultSet::queryInterface( const css::uno::Type & rType )
+{
+ css::uno::Any aRet = OPropertySetHelper::queryInterface(rType);
+ return aRet.hasValue() ? aRet : java_sql_ResultSet_BASE::queryInterface(rType);
+}
+
+css::uno::Sequence< css::uno::Type > SAL_CALL java_sql_ResultSet::getTypes( )
+{
+ ::cppu::OTypeCollection aTypes( cppu::UnoType<css::beans::XMultiPropertySet>::get(),
+ cppu::UnoType<css::beans::XFastPropertySet>::get(),
+ cppu::UnoType<css::beans::XPropertySet>::get());
+
+ return ::comphelper::concatSequences(aTypes.getTypes(),java_sql_ResultSet_BASE::getTypes());
+}
+
+
+sal_Int32 SAL_CALL java_sql_ResultSet::findColumn( const OUString& columnName )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithStringArg("findColumn",mID,columnName);
+}
+
+Reference< css::io::XInputStream > SAL_CALL java_sql_ResultSet::getBinaryStream( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getBinaryStream","(I)Ljava/io/InputStream;", mID, columnIndex);
+
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_io_InputStream( t.pEnv, out );
+}
+
+Reference< css::io::XInputStream > SAL_CALL java_sql_ResultSet::getCharacterStream( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getCharacterStream","(I)Ljava/io/Reader;", mID, columnIndex);
+
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_io_Reader( t.pEnv, out );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::getBoolean( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "getBoolean", mID,columnIndex );
+}
+
+
+sal_Int8 SAL_CALL java_sql_ResultSet::getByte( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ jbyte (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallByteMethod;
+ return callMethodWithIntArg<jbyte>(pCallMethod,"getByte","(I)B",mID,columnIndex);
+}
+
+
+Sequence< sal_Int8 > SAL_CALL java_sql_ResultSet::getBytes( sal_Int32 columnIndex )
+{
+ Sequence< sal_Int8 > aSeq;
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jbyteArray out = static_cast<jbyteArray>(callObjectMethodWithIntArg(t.pEnv,"getBytes","(I)[B", mID, columnIndex));
+ if (out)
+ {
+ jboolean p = false;
+ aSeq.realloc(t.pEnv->GetArrayLength(out));
+ memcpy(aSeq.getArray(),t.pEnv->GetByteArrayElements(out,&p),aSeq.getLength());
+ t.pEnv->DeleteLocalRef(out);
+ }
+ return aSeq;
+}
+
+
+css::util::Date SAL_CALL java_sql_ResultSet::getDate( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getDate","(I)Ljava/sql/Date;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out ? static_cast <css::util::Date> (java_sql_Date( t.pEnv, out )) : css::util::Date();
+}
+
+
+double SAL_CALL java_sql_ResultSet::getDouble( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ jdouble (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallDoubleMethod;
+ return callMethodWithIntArg<double>(pCallMethod,"getDouble","(I)D",mID,columnIndex);
+}
+
+
+float SAL_CALL java_sql_ResultSet::getFloat( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ jfloat (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallFloatMethod;
+ return callMethodWithIntArg<jfloat>(pCallMethod,"getFloat","(I)F",mID,columnIndex);
+}
+
+
+sal_Int32 SAL_CALL java_sql_ResultSet::getInt( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("getInt",mID,columnIndex);
+}
+
+
+sal_Int32 SAL_CALL java_sql_ResultSet::getRow( )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowSQL("getRow", mID);
+}
+
+
+sal_Int64 SAL_CALL java_sql_ResultSet::getLong( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ jlong (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallLongMethod;
+ return callMethodWithIntArg<jlong>(pCallMethod,"getLong","(I)J",mID,columnIndex);
+}
+
+
+css::uno::Reference< css::sdbc::XResultSetMetaData > SAL_CALL java_sql_ResultSet::getMetaData( )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getMetaData","()Ljava/sql/ResultSetMetaData;", mID);
+
+ return out==nullptr ? nullptr : new java_sql_ResultSetMetaData( t.pEnv, out, *m_pConnection );
+}
+
+Reference< XArray > SAL_CALL java_sql_ResultSet::getArray( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getArray","(I)Ljava/sql/Array;", mID, columnIndex);
+
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Array( t.pEnv, out );
+}
+
+
+Reference< XClob > SAL_CALL java_sql_ResultSet::getClob( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getClob","(I)Ljava/sql/Clob;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Clob( t.pEnv, out );
+}
+
+Reference< XBlob > SAL_CALL java_sql_ResultSet::getBlob( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getBlob","(I)Ljava/sql/Blob;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Blob( t.pEnv, out );
+}
+
+
+Reference< XRef > SAL_CALL java_sql_ResultSet::getRef( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getRef","(I)Ljava/sql/Ref;", mID, columnIndex);
+
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out==nullptr ? nullptr : new java_sql_Ref( t.pEnv, out );
+}
+
+
+Any SAL_CALL java_sql_ResultSet::getObject( sal_Int32 columnIndex, const Reference< css::container::XNameAccess >& typeMap )
+{
+ Any aRet;
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ {
+ jvalue args[2];
+ // convert parameter
+ args[0].i = columnIndex;
+ args[1].l = convertTypeMapToJavaMap(typeMap);
+ // initialize temporary Variable
+ // Java-Call
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(I)Ljava/lang/Object;";
+ static const char * const cMethodName = "getObject";
+
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ }
+
+ jobject out = t.pEnv->CallObjectMethodA( object, mID, args);
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ // and clean up
+ if ( out )
+ {
+ if ( t.pEnv->IsInstanceOf(out,java_lang_String::st_getMyClass()) )
+ {
+ java_lang_String aVal(t.pEnv,out);
+ aRet <<= OUString(aVal);
+ }
+ else if ( t.pEnv->IsInstanceOf(out,java_lang_Boolean::st_getMyClass()) )
+ {
+ java_lang_Boolean aVal(t.pEnv,out);
+ static jmethodID methodID = nullptr;
+ aRet <<= aVal.callBooleanMethod("booleanValue",methodID);
+ }
+ else if ( t.pEnv->IsInstanceOf(out,java_sql_Date::st_getMyClass()) )
+ {
+ java_sql_Date aVal(t.pEnv,out);
+ aRet <<= css::util::Date(aVal);
+ }
+ else if ( t.pEnv->IsInstanceOf(out,java_sql_Time::st_getMyClass()) )
+ {
+ java_sql_Time aVal(t.pEnv,out);
+ aRet <<= css::util::Time(aVal);
+ }
+ else if ( t.pEnv->IsInstanceOf(out,java_sql_Timestamp::st_getMyClass()) )
+ {
+ java_sql_Timestamp aVal(t.pEnv,out);
+ aRet <<= css::util::DateTime(aVal);
+ }
+ else
+ t.pEnv->DeleteLocalRef(out);
+ }
+ } //t.pEnv
+ return aRet;
+}
+
+
+sal_Int16 SAL_CALL java_sql_ResultSet::getShort( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ jshort (JNIEnv::* const pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallShortMethod;
+ return callMethodWithIntArg<jshort>(pCallMethod,"getShort","(I)S",mID,columnIndex);
+}
+
+
+OUString SAL_CALL java_sql_ResultSet::getString( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getString",mID,columnIndex);
+}
+
+
+css::util::Time SAL_CALL java_sql_ResultSet::getTime( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getTime","(I)Ljava/sql/Time;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out ? static_cast <css::util::Time> (java_sql_Time( t.pEnv, out )) : css::util::Time();
+}
+
+
+css::util::DateTime SAL_CALL java_sql_ResultSet::getTimestamp( sal_Int32 columnIndex )
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethodWithIntArg(t.pEnv,"getTimestamp","(I)Ljava/sql/Timestamp;", mID, columnIndex);
+ // WARNING: the caller becomes the owner of the returned pointer
+ return out ? static_cast <css::util::DateTime> (java_sql_Timestamp( t.pEnv, out )) : css::util::DateTime();
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::isAfterLast( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "isAfterLast", mID );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::isFirst( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "isFirst", mID );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::isLast( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "isLast", mID );
+}
+
+void SAL_CALL java_sql_ResultSet::beforeFirst( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("beforeFirst", mID);
+}
+
+void SAL_CALL java_sql_ResultSet::afterLast( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("afterLast", mID);
+}
+
+
+void SAL_CALL java_sql_ResultSet::close( )
+{
+ dispose();
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::first( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "first", mID );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::last( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "last", mID );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::absolute( sal_Int32 row )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "absolute", mID,row );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::relative( sal_Int32 row )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "relative", mID,row );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::previous( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "previous", mID );
+}
+
+Reference< XInterface > SAL_CALL java_sql_ResultSet::getStatement( )
+{
+ return m_xStatement;
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::rowDeleted( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "rowDeleted", mID );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::rowInserted( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "rowInserted", mID );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::rowUpdated( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "rowUpdated", mID );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::isBeforeFirst( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "isBeforeFirst", mID );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSet::next( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "next", mID );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSet::wasNull( )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethod( "wasNull", mID );
+}
+
+void SAL_CALL java_sql_ResultSet::cancel( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowRuntime("cancel", mID);
+}
+
+void SAL_CALL java_sql_ResultSet::clearWarnings( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("clearWarnings", mID);
+}
+
+css::uno::Any SAL_CALL java_sql_ResultSet::getWarnings( )
+{
+ SDBThreadAttach t;
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getWarnings","()Ljava/sql/SQLWarning;", mID);
+ // WARNING: the caller becomes the owner of the returned pointer
+ if( out )
+ {
+ java_sql_SQLWarning_BASE warn_base( t.pEnv, out );
+ return Any(
+ static_cast< css::sdbc::SQLException >(
+ java_sql_SQLWarning(warn_base,*this)));
+ }
+
+ return css::uno::Any();
+}
+
+
+void SAL_CALL java_sql_ResultSet::insertRow( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("insertRow", mID);
+}
+
+void SAL_CALL java_sql_ResultSet::updateRow( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateRow", mID);
+}
+
+void SAL_CALL java_sql_ResultSet::deleteRow( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("deleteRow", mID);
+}
+
+
+void SAL_CALL java_sql_ResultSet::cancelRowUpdates( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("cancelRowUpdates", mID);
+}
+
+
+void SAL_CALL java_sql_ResultSet::moveToInsertRow( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("moveToInsertRow", mID);
+}
+
+
+void SAL_CALL java_sql_ResultSet::moveToCurrentRow( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("moveToCurrentRow", mID);
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateNull( sal_Int32 columnIndex )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowSQL("updateNull", mID, columnIndex);
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateBoolean", "(IZ)V", mID, columnIndex, x);
+}
+
+void SAL_CALL java_sql_ResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateByte", "(IB)V", mID, columnIndex, x);
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateShort", "(IS)V", mID, columnIndex, x);
+}
+
+void SAL_CALL java_sql_ResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateInt", "(II)V", mID, columnIndex, x);
+}
+
+void SAL_CALL java_sql_ResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateLong", "(IJ)V", mID, columnIndex, x);
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateFloat( sal_Int32 columnIndex, float x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateFloat", "(IF)V", mID, columnIndex, x);
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateDouble( sal_Int32 columnIndex, double x )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateDouble", "(ID)V", mID, columnIndex, x);
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateString( sal_Int32 columnIndex, const OUString& x )
+{
+ SDBThreadAttach t;
+
+ {
+ // initialize temporary variable
+ // Java-Call
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(ILjava/lang/String;)V";
+ static const char * const cMethodName = "updateString";
+
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ }
+
+ {
+ // convert parameter
+ jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,x));
+ t.pEnv->CallVoidMethod( object, mID,columnIndex,str.get());
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateBytes( sal_Int32 columnIndex, const css::uno::Sequence< sal_Int8 >& x )
+{
+ SDBThreadAttach t;
+
+ {
+ // initialize temporary variable
+ // Java-Call
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(I[B)V";
+ static const char * const cMethodName = "updateBytes";
+
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ }
+
+ {
+ jbyteArray aArray = t.pEnv->NewByteArray(x.getLength());
+ jbyte * pData = reinterpret_cast<jbyte *>(
+ const_cast<sal_Int8 *>(x.getConstArray()));
+ // 4th param of Set*ArrayRegion changed from pointer to non-const to
+ // pointer to const between <http://docs.oracle.com/javase/6/docs/
+ // technotes/guides/jni/spec/functions.html#wp22933> and
+ // <http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/
+ // functions.html#wp22933>; work around that difference in a way
+ // that doesn't trigger loplugin:redundantcast
+ t.pEnv->SetByteArrayRegion(aArray,0,x.getLength(),pData);
+ // convert parameter
+ t.pEnv->CallVoidMethod( object, mID,columnIndex,aArray);
+ t.pEnv->DeleteLocalRef(aArray);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateDate( sal_Int32 columnIndex, const css::util::Date& x )
+{
+ java_sql_Date aD(x);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateDate", "(ILjava/sql/Date;)V", mID, columnIndex, aD.getJavaObject());
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateTime( sal_Int32 columnIndex, const css::util::Time& x )
+{
+ java_sql_Time aD(x);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateTime", "(ILjava/sql/Time;)V", mID, columnIndex, aD.getJavaObject());
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateTimestamp( sal_Int32 columnIndex, const css::util::DateTime& x )
+{
+ java_sql_Timestamp aD(x);
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("updateTimestamp", "(ILjava/sql/Timestamp;)V", mID, columnIndex, aD.getJavaObject());
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateBinaryStream( sal_Int32 columnIndex, const css::uno::Reference< css::io::XInputStream >& x, sal_Int32 length )
+{
+ try
+ {
+ SDBThreadAttach t;
+ {
+
+ // initialize temporary variable
+ // Java-Call
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(ILjava/io/InputStream;I)V";
+ static const char * const cMethodName = "updateBinaryStream";
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ }
+
+ {
+ // convert Parameter
+ jobject obj = createByteInputStream(x,length);
+ t.pEnv->CallVoidMethod( object, mID, columnIndex,obj,length);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ Any anyEx = ::cppu::getCaughtException();
+ ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::updateBinaryStream", *this, anyEx );
+ }
+}
+
+void SAL_CALL java_sql_ResultSet::updateCharacterStream( sal_Int32 columnIndex, const css::uno::Reference< css::io::XInputStream >& x, sal_Int32 length )
+{
+ try
+ {
+ SDBThreadAttach t;
+ {
+
+ // initialize temporary variable
+ // Java-Call
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(ILjava/io/Reader;I)V";
+ static const char * const cMethodName = "updateCharacterStream";
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ }
+
+ {
+ // convert Parameter
+ jobject obj = createCharArrayReader(x,length);
+ t.pEnv->CallVoidMethod( object, mID, columnIndex,obj,length);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ Any anyEx = ::cppu::getCaughtException();
+ ::dbtools::throwFeatureNotImplementedSQLException( "XRowUpdate::updateCharacterStream", *this, anyEx );
+ }
+}
+
+void SAL_CALL java_sql_ResultSet::updateObject( sal_Int32 columnIndex, const css::uno::Any& x )
+{
+ if(!::dbtools::implUpdateObject(this,columnIndex,x))
+ {
+ ::connectivity::SharedResources aResources;
+ const OUString sError( aResources.getResourceStringWithSubstitution(
+ STR_UNKNOWN_COLUMN_TYPE,
+ "$position$", OUString::number(columnIndex)
+ ) );
+ ::dbtools::throwGenericSQLException(sError,*this);
+ }
+}
+
+
+void SAL_CALL java_sql_ResultSet::updateNumericObject( sal_Int32 columnIndex, const css::uno::Any& x, sal_Int32 scale )
+{
+ // OSL_FAIL("java_sql_ResultSet::updateNumericObject: NYI");
+ try
+ {
+ SDBThreadAttach t;
+
+ {
+
+ // initialize temporary variable
+ // Java-Call
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(ILjava/lang/Object;I)V";
+ static const char * const cMethodName = "updateObject";
+
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ }
+
+ {
+ // convert parameter
+ double nTemp = 0.0;
+ std::unique_ptr<java_math_BigDecimal> pBigDecimal;
+ if ( x >>= nTemp)
+ {
+ pBigDecimal.reset(new java_math_BigDecimal(nTemp));
+ }
+ else
+ pBigDecimal.reset(new java_math_BigDecimal(::comphelper::getString(x)));
+
+ t.pEnv->CallVoidMethod( object, mID, columnIndex,pBigDecimal->getJavaObject(),scale);
+ ThrowLoggedSQLException( m_aLogger, t.pEnv, *this );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ updateObject( columnIndex,x);
+ }
+}
+
+sal_Int32 java_sql_ResultSet::getResultSetConcurrency() const
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowRuntime("getConcurrency", mID);
+}
+
+sal_Int32 java_sql_ResultSet::getResultSetType() const
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowRuntime("getType",mID);
+}
+
+sal_Int32 java_sql_ResultSet::getFetchDirection() const
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowRuntime("getFetchDirection", mID);
+}
+
+sal_Int32 java_sql_ResultSet::getFetchSize() const
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowRuntime("getFetchSize", mID);
+}
+
+OUString java_sql_ResultSet::getCursorName() const
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("getCursorName",mID);
+}
+
+
+void java_sql_ResultSet::setFetchDirection(sal_Int32 _par0)
+{
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setFetchDirection", mID, _par0);
+}
+
+void SAL_CALL java_sql_ResultSet::refreshRow( )
+{
+ static jmethodID mID(nullptr);
+ callVoidMethod_ThrowSQL("refreshRow",mID);
+}
+
+void java_sql_ResultSet::setFetchSize(sal_Int32 _par0)
+{
+ static jmethodID mID(nullptr);
+ callVoidMethodWithIntArg_ThrowRuntime("setFetchSize", mID, _par0);
+}
+
+::cppu::IPropertyArrayHelper* java_sql_ResultSet::createArrayHelper( ) const
+{
+ return new ::cppu::OPropertyArrayHelper
+ {
+ {
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),
+ PROPERTY_ID_CURSORNAME,
+ cppu::UnoType<OUString>::get(),
+ PropertyAttribute::READONLY
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
+ PROPERTY_ID_FETCHDIRECTION,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
+ PROPERTY_ID_FETCHSIZE,
+ cppu::UnoType<sal_Int32>::get(),
+ 0
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
+ PROPERTY_ID_RESULTSETCONCURRENCY,
+ cppu::UnoType<sal_Int32>::get(),
+ PropertyAttribute::READONLY
+ },
+ {
+ ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
+ PROPERTY_ID_RESULTSETTYPE,
+ cppu::UnoType<sal_Int32>::get(),
+ PropertyAttribute::READONLY
+ }
+ }
+ };
+}
+
+::cppu::IPropertyArrayHelper & java_sql_ResultSet::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+sal_Bool java_sql_ResultSet::convertFastPropertyValue(
+ css::uno::Any & rConvertedValue,
+ css::uno::Any & rOldValue,
+ sal_Int32 nHandle,
+ const css::uno::Any& rValue )
+{
+ bool bRet = false;
+ switch(nHandle)
+ {
+ case PROPERTY_ID_CURSORNAME:
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ case PROPERTY_ID_RESULTSETTYPE:
+ throw css::lang::IllegalArgumentException();
+ case PROPERTY_ID_FETCHDIRECTION:
+ bRet = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ bRet = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
+ break;
+ default:
+ break;
+ }
+ return bRet;
+}
+
+
+void java_sql_ResultSet::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle,
+ const css::uno::Any& rValue
+ )
+{
+ switch(nHandle)
+ {
+ case PROPERTY_ID_CURSORNAME:
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ case PROPERTY_ID_RESULTSETTYPE:
+ throw css::uno::Exception("cannot set prop " + OUString::number(nHandle), nullptr);
+ case PROPERTY_ID_FETCHDIRECTION:
+ setFetchDirection(comphelper::getINT32(rValue));
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ setFetchSize(comphelper::getINT32(rValue));
+ break;
+ default:
+ ;
+ }
+}
+
+void java_sql_ResultSet::getFastPropertyValue(
+ css::uno::Any& rValue,
+ sal_Int32 nHandle
+ ) const
+{
+ try
+ {
+ switch(nHandle)
+ {
+ case PROPERTY_ID_CURSORNAME:
+ rValue <<= getCursorName();
+ break;
+ case PROPERTY_ID_RESULTSETCONCURRENCY:
+ rValue <<= getResultSetConcurrency();
+ break;
+ case PROPERTY_ID_RESULTSETTYPE:
+ rValue <<= getResultSetType();
+ break;
+ case PROPERTY_ID_FETCHDIRECTION:
+ rValue <<= getFetchDirection();
+ break;
+ case PROPERTY_ID_FETCHSIZE:
+ rValue <<= getFetchSize();
+ break;
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+}
+
+void SAL_CALL java_sql_ResultSet::acquire() noexcept
+{
+ java_sql_ResultSet_BASE::acquire();
+}
+
+void SAL_CALL java_sql_ResultSet::release() noexcept
+{
+ java_sql_ResultSet_BASE::release();
+}
+
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL java_sql_ResultSet::getPropertySetInfo( )
+{
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/ResultSetMetaData.cxx b/connectivity/source/drivers/jdbc/ResultSetMetaData.cxx
new file mode 100644
index 000000000..fdf5bfe69
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/ResultSetMetaData.cxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/ResultSetMetaData.hxx>
+#include <java/sql/Connection.hxx>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+
+//************ Class: java.sql.ResultSetMetaData
+
+
+jclass java_sql_ResultSetMetaData::theClass = nullptr;
+java_sql_ResultSetMetaData::java_sql_ResultSetMetaData( JNIEnv * pEnv, jobject myObj, java_sql_Connection& _rCon )
+ :java_lang_Object( pEnv, myObj )
+ ,m_pConnection( &_rCon )
+ ,m_nColumnCount(-1)
+{
+ SDBThreadAttach::addRef();
+}
+java_sql_ResultSetMetaData::~java_sql_ResultSetMetaData()
+{
+ SDBThreadAttach::releaseRef();
+}
+
+jclass java_sql_ResultSetMetaData::getMyClass() const
+{
+ // The class needs to be fetched just once, that is why it is static
+ if( !theClass )
+ theClass = findMyClass("java/sql/ResultSetMetaData");
+ return theClass;
+}
+
+
+sal_Int32 SAL_CALL java_sql_ResultSetMetaData::getColumnDisplaySize( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("getColumnDisplaySize",mID,column);
+}
+
+
+sal_Int32 SAL_CALL java_sql_ResultSetMetaData::getColumnType( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("getColumnType",mID,column);
+}
+
+
+sal_Int32 SAL_CALL java_sql_ResultSetMetaData::getColumnCount( )
+{
+ if ( m_nColumnCount == -1 )
+ {
+ static jmethodID mID(nullptr);
+ m_nColumnCount = callIntMethod_ThrowSQL("getColumnCount", mID);
+ } // if ( m_nColumnCount == -1 )
+ return m_nColumnCount;
+
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isCaseSensitive( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isCaseSensitive", mID,column );
+}
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getSchemaName( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getSchemaName",mID,column);
+}
+
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getColumnName( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getColumnName",mID,column);
+}
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getTableName( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getTableName",mID,column);
+}
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getCatalogName( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getCatalogName",mID,column);
+}
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getColumnTypeName( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getColumnTypeName",mID,column);
+}
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getColumnLabel( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getColumnLabel",mID,column);
+}
+
+OUString SAL_CALL java_sql_ResultSetMetaData::getColumnServiceName( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callStringMethodWithIntArg("getColumnClassName",mID,column);
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isCurrency( sal_Int32 column )
+{
+ if ( m_pConnection->isIgnoreCurrencyEnabled() )
+ return false;
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isCurrency", mID,column );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isAutoIncrement( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isAutoIncrement", mID,column );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isSigned( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isSigned", mID,column );
+}
+
+sal_Int32 SAL_CALL java_sql_ResultSetMetaData::getPrecision( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("getPrecision",mID,column);
+}
+
+sal_Int32 SAL_CALL java_sql_ResultSetMetaData::getScale( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("getScale",mID,column);
+}
+
+sal_Int32 SAL_CALL java_sql_ResultSetMetaData::isNullable( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callIntMethodWithIntArg_ThrowSQL("isNullable",mID,column);
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isSearchable( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isSearchable", mID,column );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isReadOnly( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isReadOnly", mID,column );
+}
+
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isDefinitelyWritable( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isDefinitelyWritable", mID,column );
+}
+
+sal_Bool SAL_CALL java_sql_ResultSetMetaData::isWritable( sal_Int32 column )
+{
+ static jmethodID mID(nullptr);
+ return callBooleanMethodWithIntArg( "isWritable", mID,column );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/SQLException.cxx b/connectivity/source/drivers/jdbc/SQLException.cxx
new file mode 100644
index 000000000..9374407d1
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/SQLException.cxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/SQLException.hxx>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::lang;
+
+//************ Class: java.sql.SQLException
+
+java_sql_SQLException::java_sql_SQLException( const java_sql_SQLException_BASE& _rException,const Reference< XInterface> & _rContext)
+ : css::sdbc::SQLException( _rException.getMessage(),
+ _rContext,
+ _rException.getSQLState(),
+ _rException.getErrorCode(),
+ Any(_rException.getNextException())
+ )
+{
+}
+
+java_sql_SQLException_BASE::java_sql_SQLException_BASE( JNIEnv * pEnv, jobject myObj ) : java_lang_Exception( pEnv, myObj )
+{
+}
+
+jclass java_sql_SQLException_BASE::theClass = nullptr;
+
+java_sql_SQLException_BASE::~java_sql_SQLException_BASE()
+{}
+
+
+jclass java_sql_SQLException_BASE::getMyClass() const
+{
+ return st_getMyClass();
+}
+jclass java_sql_SQLException_BASE::st_getMyClass()
+{
+ // The class needs to be fetched just once, that is why it is static
+ if( !theClass )
+ theClass = findMyClass("java/sql/SQLException");
+ return theClass;
+}
+
+css::sdbc::SQLException java_sql_SQLException_BASE::getNextException() const
+{
+ SDBThreadAttach t;
+ static jmethodID mID(nullptr);
+ jobject out = callObjectMethod(t.pEnv,"getNextException","()Ljava/sql/SQLException;", mID);
+ // WARNING: the caller will become the owner of the returned pointers !!!
+ if( out )
+ {
+ java_sql_SQLException_BASE warn_base(t.pEnv,out);
+ return css::sdbc::SQLException(java_sql_SQLException(warn_base,nullptr));
+ }
+
+ return css::sdbc::SQLException();
+}
+
+OUString java_sql_SQLException_BASE::getSQLState() const
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("getSQLState",mID);
+}
+sal_Int32 java_sql_SQLException_BASE::getErrorCode() const
+{
+ static jmethodID mID(nullptr);
+ return callIntMethod_ThrowSQL("getErrorCode", mID);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/SQLWarning.cxx b/connectivity/source/drivers/jdbc/SQLWarning.cxx
new file mode 100644
index 000000000..487665d7d
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/SQLWarning.cxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/SQLWarning.hxx>
+using namespace connectivity;
+
+//************ Class: java.sql.SQLWarning
+
+jclass java_sql_SQLWarning_BASE::theClass = nullptr;
+
+java_sql_SQLWarning_BASE::~java_sql_SQLWarning_BASE() {}
+
+jclass java_sql_SQLWarning_BASE::getMyClass() const
+{
+ // the class needs to be fetched only once, that is why it is static
+ if (!theClass)
+ theClass = findMyClass("java/sql/SQLWarning");
+ return theClass;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/String.cxx b/connectivity/source/drivers/jdbc/String.cxx
new file mode 100644
index 000000000..e229ef54a
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/String.cxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/lang/String.hxx>
+#include <java/tools.hxx>
+using namespace connectivity;
+
+//************ Class: java.lang.String
+
+jclass java_lang_String::theClass = nullptr;
+
+java_lang_String::~java_lang_String() {}
+
+jclass java_lang_String::getMyClass() const { return st_getMyClass(); }
+jclass java_lang_String::st_getMyClass()
+{
+ // the class needs to be fetched only once, that is why it is static
+ if (!theClass)
+ theClass = findMyClass("java/lang/String");
+ return theClass;
+}
+
+java_lang_String::operator OUString()
+{
+ SDBThreadAttach t;
+ if (!t.pEnv)
+ return OUString();
+ return JavaString2String(t.pEnv, static_cast<jstring>(object));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Throwable.cxx b/connectivity/source/drivers/jdbc/Throwable.cxx
new file mode 100644
index 000000000..db4bb8920
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Throwable.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/lang/Throwable.hxx>
+
+using namespace connectivity;
+
+//************ Class: java.lang.Throwable
+
+jclass java_lang_Throwable::theClass = nullptr;
+
+java_lang_Throwable::~java_lang_Throwable() {}
+
+jclass java_lang_Throwable::getMyClass() const { return st_getMyClass(); }
+jclass java_lang_Throwable::st_getMyClass()
+{
+ // the class needs to be fetched only once, that is why it is static
+ if (!theClass)
+ theClass = findMyClass("java/lang/Throwable");
+ return theClass;
+}
+
+OUString java_lang_Throwable::getMessage() const
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("getMessage", mID);
+}
+
+OUString java_lang_Throwable::getLocalizedMessage() const
+{
+ static jmethodID mID(nullptr);
+ return callStringMethod("getLocalizedMessage", mID);
+}
+
+#if OSL_DEBUG_LEVEL > 0
+void java_lang_Throwable::printStackTrace() const
+{
+ static jmethodID mID(nullptr);
+ return callVoidMethod_ThrowSQL("printStackTrace", mID);
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/Timestamp.cxx b/connectivity/source/drivers/jdbc/Timestamp.cxx
new file mode 100644
index 000000000..eb7624719
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/Timestamp.cxx
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <java/sql/Timestamp.hxx>
+#include <java/tools.hxx>
+#include <connectivity/dbconversion.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::comphelper;
+using namespace connectivity;
+
+//************ Class: java.sql.Date
+
+
+jclass java_sql_Date::theClass = nullptr;
+java_sql_Date::java_sql_Date( const css::util::Date& _rOut ) : java_util_Date( nullptr, nullptr )
+{
+ SDBThreadAttach t;
+ if( !t.pEnv )
+ return;
+ jvalue args[1];
+ // Convert parameters
+ OUString sDateStr = ::dbtools::DBTypeConversion::toDateString(_rOut);
+ args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);
+
+ // Turn of Java-Call for the constructor
+ // initialise temporary variables
+ jobject tempObj;
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(Ljava/lang/String;)Ljava/sql/Date;";
+ mID = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
+ }
+ OSL_ENSURE(mID,"Unknown method id!");
+ tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
+ saveRef( t.pEnv, tempObj );
+ t.pEnv->DeleteLocalRef( tempObj );
+ // and clean
+}
+
+java_sql_Date::~java_sql_Date()
+{}
+
+jclass java_sql_Date::getMyClass() const
+{
+ return st_getMyClass();
+}
+jclass java_sql_Date::st_getMyClass()
+{
+ // the class needs only be fetched once, that is why it is static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Date");
+ return theClass;
+}
+
+
+java_sql_Date::operator css::util::Date()
+{
+ return ::dbtools::DBTypeConversion::toDate(toString());
+}
+
+
+//************ Class: java.sql.Time
+
+
+jclass java_sql_Time::theClass = nullptr;
+
+java_sql_Time::~java_sql_Time()
+{}
+
+jclass java_sql_Time::getMyClass() const
+{
+ return st_getMyClass();
+}
+jclass java_sql_Time::st_getMyClass()
+{
+ // the class needs only be fetched once, that is why it is static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Time");
+ return theClass;
+}
+java_sql_Time::java_sql_Time( const css::util::Time& _rOut ): java_util_Date( nullptr, nullptr )
+{
+ SDBThreadAttach t;
+ if( !t.pEnv )
+ return;
+ jvalue args[1];
+ // Convert parameters
+ // java.sql.Time supports only whole seconds...
+ OUString sDateStr = ::dbtools::DBTypeConversion::toTimeStringS(_rOut);
+ args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);
+
+ // Turn off Java-Call for the constructor
+ // initialise temporary variables
+ jobject tempObj;
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(Ljava/lang/String;)Ljava/sql/Time;";
+ mID = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
+ }
+ OSL_ENSURE(mID,"Unknown method id!");
+ tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ saveRef( t.pEnv, tempObj );
+ t.pEnv->DeleteLocalRef( tempObj );
+ // and clean
+}
+
+java_sql_Time::operator css::util::Time()
+{
+ return ::dbtools::DBTypeConversion::toTime(toString());
+}
+
+//************ Class: java.sql.Timestamp
+
+
+jclass java_sql_Timestamp::theClass = nullptr;
+
+java_sql_Timestamp::~java_sql_Timestamp()
+{}
+
+jclass java_sql_Timestamp::getMyClass() const
+{
+ return st_getMyClass();
+}
+
+jclass java_sql_Timestamp::st_getMyClass()
+{
+ // the class needs only be fetched once, that is why it is static
+ if( !theClass )
+ theClass = findMyClass("java/sql/Timestamp");
+ return theClass;
+}
+
+java_sql_Timestamp::java_sql_Timestamp(const css::util::DateTime& _rOut)
+ :java_util_Date( nullptr, nullptr )
+{
+ SDBThreadAttach t;
+ if( !t.pEnv )
+ return;
+ jvalue args[1];
+ // Convert parameters
+ OUString sDateStr = ::dbtools::DBTypeConversion::toDateTimeString(_rOut);
+
+ args[0].l = convertwchar_tToJavaString(t.pEnv,sDateStr);
+
+ // Turn off Java-Call for the constructor
+ // initialise temporary variables
+ jobject tempObj;
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "(Ljava/lang/String;)Ljava/sql/Timestamp;";
+ mID = t.pEnv->GetStaticMethodID( getMyClass(), "valueOf", cSignature );
+ }
+ OSL_ENSURE(mID,"Unknown method id!");
+ tempObj = t.pEnv->CallStaticObjectMethod( getMyClass(), mID, args[0].l );
+
+ saveRef( t.pEnv, tempObj );
+ t.pEnv->DeleteLocalRef( tempObj );
+ // and clean
+}
+
+
+java_sql_Timestamp::operator css::util::DateTime()
+{
+ return ::dbtools::DBTypeConversion::toDateTime(toString());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/connectivity/source/drivers/jdbc/jdbc.component b/connectivity/source/drivers/jdbc/jdbc.component
new file mode 100644
index 000000000..86a6a079b
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/jdbc.component
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
+
+<!-- Recent Java 6 VMs make calls to JNI Attach/DetachCurrentThread (which this
+ code does extensively) very expensive. A follow-up JVM fix reduced the
+ overhead significantly again for all threads but the main thread. So a
+ quick hack to improve performance of this component again is to confine it
+ in the affine apartment (where all code will run on a single, dedicated
+ thread that is guaranteed no to be the main thread). However, a better fix
+ would still be to redesign the code so that it does not call
+ Attach/DetachCurrentThread so frequently:
+-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ environment="@CPPU_ENV@:affine"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.sdbc.JDBCDriver"
+ constructor="connectivity_java_sql_Driver_get_implementation">
+ <service name="com.sun.star.sdbc.Driver"/>
+ </implementation>
+</component>
diff --git a/connectivity/source/drivers/jdbc/tools.cxx b/connectivity/source/drivers/jdbc/tools.cxx
new file mode 100644
index 000000000..4a4d5069e
--- /dev/null
+++ b/connectivity/source/drivers/jdbc/tools.cxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <string.h>
+#include <java/tools.hxx>
+#include <java/util/Property.hxx>
+#include <com/sun/star/sdbc/DriverPropertyInfo.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <connectivity/dbexception.hxx>
+#include <osl/diagnose.h>
+
+using namespace connectivity;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+void java_util_Properties::setProperty(const OUString& key, const OUString& value)
+{
+ SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java environment has been deleted!");
+
+ {
+ jvalue args[2];
+ // Convert Parameter
+ args[0].l = convertwchar_tToJavaString(t.pEnv,key);
+ args[1].l = convertwchar_tToJavaString(t.pEnv,value);
+ // Initialize temporary Variables
+ static const char * const cSignature = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;";
+ static const char * const cMethodName = "setProperty";
+ // Turn off Java-Call
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, cMethodName,cSignature, mID);
+ jobject out = t.pEnv->CallObjectMethod(object, mID, args[0].l,args[1].l);
+ ThrowSQLException(t.pEnv,nullptr);
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[1].l));
+ t.pEnv->DeleteLocalRef(static_cast<jstring>(args[0].l));
+ ThrowSQLException(t.pEnv,nullptr);
+ if(out)
+ t.pEnv->DeleteLocalRef(out);
+ } //t.pEnv
+ // WARNING: The caller will be owner of the returned pointers!!!
+}
+jclass java_util_Properties::theClass = nullptr;
+
+java_util_Properties::~java_util_Properties()
+{}
+
+jclass java_util_Properties::getMyClass() const
+{
+ // the class needs only be called once, that is why it is static
+ if( !theClass )
+ theClass = findMyClass("java/util/Properties");
+ return theClass;
+}
+
+
+java_util_Properties::java_util_Properties( ): java_lang_Object( nullptr, nullptr )
+{
+ SDBThreadAttach t;
+ if( !t.pEnv )
+ return;
+ // Turn off Java-Call for the constructor
+ // Initialize temporary Variables
+ static const char * const cSignature = "()V";
+ jobject tempObj;
+ static jmethodID mID(nullptr);
+ obtainMethodId_throwSQL(t.pEnv, "<init>",cSignature, mID);
+ tempObj = t.pEnv->NewObject( getMyClass(), mID);
+ saveRef( t.pEnv, tempObj );
+ t.pEnv->DeleteLocalRef( tempObj );
+}
+
+
+jstring connectivity::convertwchar_tToJavaString(JNIEnv *pEnv,const OUString& _rTemp)
+{
+ OSL_ENSURE(pEnv,"Environment is NULL!");
+ jstring pStr = pEnv->NewString(
+ reinterpret_cast<jchar const *>(_rTemp.getStr()), _rTemp.getLength());
+ pEnv->ExceptionClear();
+ OSL_ENSURE(pStr,"Could not create a jsstring object!");
+ return pStr;
+}
+
+
+std::unique_ptr<java_util_Properties> connectivity::createStringPropertyArray(const Sequence< PropertyValue >& info )
+{
+ std::unique_ptr<java_util_Properties> pProps(new java_util_Properties());
+ const PropertyValue* pBegin = info.getConstArray();
+ const PropertyValue* pEnd = pBegin + info.getLength();
+
+ for(;pBegin != pEnd;++pBegin)
+ {
+ // these are properties used internally by LibreOffice,
+ // and should not be passed to the JDBC driver
+ // (which probably does not know anything about them anyway).
+ if ( pBegin->Name != "JavaDriverClass"
+ && pBegin->Name != "JavaDriverClassPath"
+ && pBegin->Name != "SystemProperties"
+ && pBegin->Name != "CharSet"
+ && pBegin->Name != "AppendTableAliasName"
+ && pBegin->Name != "AppendTableAliasInSelect"
+ && pBegin->Name != "DisplayVersionColumns"
+ && pBegin->Name != "GeneratedValues"
+ && pBegin->Name != "UseIndexDirectionKeyword"
+ && pBegin->Name != "UseKeywordAsBeforeAlias"
+ && pBegin->Name != "AddIndexAppendix"
+ && pBegin->Name != "FormsCheckRequiredFields"
+ && pBegin->Name != "GenerateASBeforeCorrelationName"
+ && pBegin->Name != "EscapeDateTime"
+ && pBegin->Name != "ParameterNameSubstitution"
+ && pBegin->Name != "IsPasswordRequired"
+ && pBegin->Name != "IsAutoRetrievingEnabled"
+ && pBegin->Name != "AutoRetrievingStatement"
+ && pBegin->Name != "UseCatalogInSelect"
+ && pBegin->Name != "UseSchemaInSelect"
+ && pBegin->Name != "AutoIncrementCreation"
+ && pBegin->Name != "Extension"
+ && pBegin->Name != "NoNameLengthLimit"
+ && pBegin->Name != "EnableSQL92Check"
+ && pBegin->Name != "EnableOuterJoinEscape"
+ && pBegin->Name != "BooleanComparisonMode"
+ && pBegin->Name != "IgnoreCurrency"
+ && pBegin->Name != "TypeInfoSettings"
+ && pBegin->Name != "IgnoreDriverPrivileges"
+ && pBegin->Name != "ImplicitCatalogRestriction"
+ && pBegin->Name != "ImplicitSchemaRestriction"
+ && pBegin->Name != "SupportsTableCreation"
+ && pBegin->Name != "UseJava"
+ && pBegin->Name != "Authentication"
+ && pBegin->Name != "PreferDosLikeLineEnds"
+ && pBegin->Name != "PrimaryKeySupport"
+ && pBegin->Name != "RespectDriverResultSetType"
+ )
+ {
+ OUString aStr;
+ OSL_VERIFY( pBegin->Value >>= aStr );
+ pProps->setProperty(pBegin->Name,aStr);
+ }
+ }
+ return pProps;
+}
+
+OUString connectivity::JavaString2String(JNIEnv *pEnv,jstring Str)
+{
+ OUString aStr;
+ if(Str)
+ {
+ jboolean bCopy(true);
+ const jchar* pChar = pEnv->GetStringChars(Str,&bCopy);
+ jsize len = pEnv->GetStringLength(Str);
+ aStr = OUString(reinterpret_cast<sal_Unicode const *>(pChar), len);
+
+ if(bCopy)
+ pEnv->ReleaseStringChars(Str,pChar);
+ pEnv->DeleteLocalRef(Str);
+ }
+ return aStr;
+}
+
+jobject connectivity::convertTypeMapToJavaMap(const Reference< css::container::XNameAccess > & _rMap)
+{
+ if ( _rMap.is() )
+ {
+ css::uno::Sequence< OUString > aNames = _rMap->getElementNames();
+ if ( aNames.hasElements() )
+ ::dbtools::throwFeatureNotImplementedSQLException( "Type maps", nullptr );
+ }
+ return nullptr;
+}
+
+bool connectivity::isExceptionOccurred(JNIEnv *pEnv)
+{
+ if ( !pEnv )
+ return false;
+
+ jthrowable pThrowable = pEnv->ExceptionOccurred();
+ bool bRet = pThrowable != nullptr;
+ if ( pThrowable )
+ {
+ pEnv->ExceptionClear();
+ pEnv->DeleteLocalRef(pThrowable);
+ }
+
+ return bRet;
+}
+
+jobject connectivity::createByteInputStream(const css::uno::Reference< css::io::XInputStream >& x,sal_Int32 length)
+{
+ SDBThreadAttach t;
+ if( !t.pEnv || !x.is() )
+ return nullptr;
+ // Turn off Java-Call for the constructor
+ // Initialize temporary variables
+ jclass clazz = java_lang_Object::findMyClass("java/io/ByteArrayInputStream");
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "([B)V";
+ mID = t.pEnv->GetMethodID( clazz, "<init>", cSignature );
+ OSL_ENSURE( mID, cSignature );
+ if ( !mID )
+ throw SQLException();
+ } // if ( !_inout_MethodID )
+ jbyteArray pByteArray = t.pEnv->NewByteArray(length);
+ Sequence< sal_Int8 > aData;
+ x->readBytes(aData,length);
+ jboolean p = false;
+ memcpy(t.pEnv->GetByteArrayElements(pByteArray,&p),aData.getArray(),aData.getLength());
+ jobject out = t.pEnv->NewObject( clazz, mID,pByteArray);
+ t.pEnv->DeleteLocalRef(pByteArray);
+ return out;
+}
+
+jobject connectivity::createCharArrayReader(const css::uno::Reference< css::io::XInputStream >& x,sal_Int32 length)
+{
+ SDBThreadAttach t;
+ if( !t.pEnv || !x.is() )
+ return nullptr;
+ // Turn off Java-Call for the constructor
+ // Initialize temporary Variables
+ jclass clazz = java_lang_Object::findMyClass("java/io/CharArrayReader");
+ static jmethodID mID(nullptr);
+ if ( !mID )
+ {
+ static const char * const cSignature = "([C)V";
+ mID = t.pEnv->GetMethodID( clazz, "<init>", cSignature );
+ OSL_ENSURE( mID, cSignature );
+ if ( !mID )
+ throw SQLException();
+ } // if ( !_inout_MethodID )
+ jcharArray pCharArray = t.pEnv->NewCharArray(length);
+ Sequence< sal_Int8 > aData;
+ x->readBytes(aData,length);
+ jboolean p = false;
+ memcpy(t.pEnv->GetCharArrayElements(pCharArray,&p),aData.getArray(),aData.getLength());
+ jobject out = t.pEnv->NewObject( clazz, mID,pCharArray);
+ t.pEnv->DeleteLocalRef(pCharArray);
+ return out;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */