1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include "java/sql/CallableStatement.hxx" 31 #include "java/tools.hxx" 32 #include "java/sql/Array.hxx" 33 #include "java/sql/Clob.hxx" 34 #include "java/sql/Blob.hxx" 35 #include "java/sql/Connection.hxx" 36 #include "java/sql/Ref.hxx" 37 #include "java/sql/Timestamp.hxx" 38 #include <cppuhelper/typeprovider.hxx> 39 #include <comphelper/sequence.hxx> 40 41 #include <string.h> 42 43 using namespace connectivity; 44 using namespace ::com::sun::star::uno; 45 using namespace ::com::sun::star::beans; 46 // using namespace ::com::sun::star::sdbcx; 47 using namespace ::com::sun::star::sdbc; 48 using namespace ::com::sun::star::container; 49 using namespace ::com::sun::star::lang; 50 51 52 IMPLEMENT_SERVICE_INFO(java_sql_CallableStatement,"com.sun.star.sdbcx.ACallableStatement","com.sun.star.sdbc.CallableStatement"); 53 54 //************************************************************** 55 //************ Class: java.sql.CallableStatement 56 //************************************************************** 57 java_sql_CallableStatement::java_sql_CallableStatement( JNIEnv * pEnv, java_sql_Connection& _rCon,const ::rtl::OUString& sql ) 58 : java_sql_PreparedStatement( pEnv, _rCon, sql ) 59 { 60 } 61 // ----------------------------------------------------------------------------- 62 java_sql_CallableStatement::~java_sql_CallableStatement() 63 { 64 } 65 // ----------------------------------------------------------------------------- 66 67 Any SAL_CALL java_sql_CallableStatement::queryInterface( const Type & rType ) throw(RuntimeException) 68 { 69 Any aRet = java_sql_PreparedStatement::queryInterface(rType); 70 return aRet.hasValue() ? aRet : ::cppu::queryInterface(rType,static_cast< starsdbc::XRow*>(this),static_cast< starsdbc::XOutParameters*>(this)); 71 } 72 // ------------------------------------------------------------------------- 73 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL java_sql_CallableStatement::getTypes( ) throw(::com::sun::star::uno::RuntimeException) 74 { 75 ::cppu::OTypeCollection aTypes( ::getCppuType( (const ::com::sun::star::uno::Reference< starsdbc::XRow > *)0 ), 76 ::getCppuType( (const ::com::sun::star::uno::Reference< starsdbc::XOutParameters > *)0 )); 77 78 return ::comphelper::concatSequences(aTypes.getTypes(),java_sql_PreparedStatement::getTypes()); 79 } 80 // ------------------------------------------------------------------------- 81 sal_Bool SAL_CALL java_sql_CallableStatement::wasNull( ) throw(starsdbc::SQLException, RuntimeException) 82 { 83 static jmethodID mID(NULL); 84 return callBooleanMethod( "wasNull", mID ); 85 } 86 87 sal_Bool SAL_CALL java_sql_CallableStatement::getBoolean( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 88 { 89 static jmethodID mID(NULL); 90 return callBooleanMethodWithIntArg( "getBoolean", mID,columnIndex ); 91 } 92 sal_Int8 SAL_CALL java_sql_CallableStatement::getByte( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 93 { 94 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 95 createStatement(t.pEnv); 96 static jmethodID mID(NULL); 97 jbyte (JNIEnv::*pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallByteMethod; 98 return callMethodWithIntArg<jbyte>(pCallMethod,"getByte","(I)B",mID,columnIndex); 99 } 100 Sequence< sal_Int8 > SAL_CALL java_sql_CallableStatement::getBytes( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 101 { 102 ::osl::MutexGuard aGuard( m_aMutex ); 103 checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed); 104 Sequence< sal_Int8 > aSeq; 105 106 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 107 createStatement(t.pEnv); 108 static jmethodID mID(NULL); 109 jbyteArray out = (jbyteArray)callObjectMethodWithIntArg(t.pEnv,"getBytes","(I)[B", mID, columnIndex); 110 if (out) 111 { 112 jboolean p = sal_False; 113 aSeq.realloc(t.pEnv->GetArrayLength(out)); 114 memcpy(aSeq.getArray(),t.pEnv->GetByteArrayElements(out,&p),aSeq.getLength()); 115 t.pEnv->DeleteLocalRef(out); 116 } 117 return aSeq; 118 } 119 ::com::sun::star::util::Date SAL_CALL java_sql_CallableStatement::getDate( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 120 { 121 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 122 createStatement(t.pEnv); 123 static jmethodID mID(NULL); 124 jobject out = callObjectMethodWithIntArg(t.pEnv,"getDate","(I)Ljava/sql/Date;", mID, columnIndex); 125 return out ? static_cast <com::sun::star::util::Date>(java_sql_Date( t.pEnv, out )) : ::com::sun::star::util::Date(); 126 } 127 double SAL_CALL java_sql_CallableStatement::getDouble( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 128 { 129 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 130 createStatement(t.pEnv); 131 static jmethodID mID(NULL); 132 double (JNIEnv::*pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallDoubleMethod; 133 return callMethodWithIntArg<double>(pCallMethod,"getDouble","(I)D",mID,columnIndex); 134 } 135 136 float SAL_CALL java_sql_CallableStatement::getFloat( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 137 { 138 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 139 createStatement(t.pEnv); 140 static jmethodID mID(NULL); 141 jfloat (JNIEnv::*pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallFloatMethod; 142 return callMethodWithIntArg<jfloat>(pCallMethod,"getFloat","(I)F",mID,columnIndex); 143 } 144 145 sal_Int32 SAL_CALL java_sql_CallableStatement::getInt( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 146 { 147 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 148 createStatement(t.pEnv); 149 static jmethodID mID(NULL); 150 return callIntMethodWithIntArg("getInt",mID,columnIndex); 151 } 152 153 sal_Int64 SAL_CALL java_sql_CallableStatement::getLong( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 154 { 155 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 156 createStatement(t.pEnv); 157 static jmethodID mID(NULL); 158 jlong (JNIEnv::*pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallLongMethod; 159 return callMethodWithIntArg<jlong>(pCallMethod,"getLong","(I)J",mID,columnIndex); 160 } 161 162 Any SAL_CALL java_sql_CallableStatement::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(starsdbc::SQLException, RuntimeException) 163 { 164 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 165 createStatement(t.pEnv); 166 static jmethodID mID(NULL); 167 /*jobject out = */callObjectMethodWithIntArg(t.pEnv,"getObject","(I)Ljava/lang/Object;", mID, columnIndex); 168 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 169 return Any(); //out==0 ? 0 : new java_lang_Object( t.pEnv, out ); 170 } 171 172 sal_Int16 SAL_CALL java_sql_CallableStatement::getShort( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 173 { 174 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 175 createStatement(t.pEnv); 176 static jmethodID mID(NULL); 177 jshort (JNIEnv::*pCallMethod)( jobject obj, jmethodID methodID, ... ) = &JNIEnv::CallShortMethod; 178 return callMethodWithIntArg<jshort>(pCallMethod,"getShort","(I)S",mID,columnIndex); 179 } 180 181 ::rtl::OUString SAL_CALL java_sql_CallableStatement::getString( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 182 { 183 ::osl::MutexGuard aGuard( m_aMutex ); 184 checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed); 185 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 186 createStatement(t.pEnv); 187 static jmethodID mID(NULL); 188 return callStringMethodWithIntArg("getString",mID,columnIndex); 189 } 190 191 ::com::sun::star::util::Time SAL_CALL java_sql_CallableStatement::getTime( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 192 { 193 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 194 createStatement(t.pEnv); 195 static jmethodID mID(NULL); 196 jobject out = callObjectMethodWithIntArg(t.pEnv,"getTime","(I)Ljava/sql/Time;", mID, columnIndex); 197 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 198 return out ? static_cast <com::sun::star::util::Time> (java_sql_Time( t.pEnv, out )) : ::com::sun::star::util::Time(); 199 } 200 201 ::com::sun::star::util::DateTime SAL_CALL java_sql_CallableStatement::getTimestamp( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 202 { 203 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 204 createStatement(t.pEnv); 205 static jmethodID mID(NULL); 206 jobject out = callObjectMethodWithIntArg(t.pEnv,"getTimestamp","(I)Ljava/sql/Timestamp;", mID, columnIndex); 207 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 208 return out ? static_cast <com::sun::star::util::DateTime> (java_sql_Timestamp( t.pEnv, out )) : ::com::sun::star::util::DateTime(); 209 } 210 211 void SAL_CALL java_sql_CallableStatement::registerOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) throw(starsdbc::SQLException, RuntimeException) 212 { 213 ::osl::MutexGuard aGuard( m_aMutex ); 214 checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed); 215 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 216 217 { 218 createStatement(t.pEnv); 219 220 // temporaere Variable initialisieren 221 static const char * cSignature = "(IILjava/lang/String;)V"; 222 static const char * cMethodName = "registerOutParameter"; 223 // Java-Call absetzen 224 static jmethodID mID(NULL); 225 obtainMethodId(t.pEnv, cMethodName,cSignature, mID); 226 // Parameter konvertieren 227 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,typeName)); 228 t.pEnv->CallVoidMethod( object, mID, parameterIndex,sqlType,str.get()); 229 ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); 230 } 231 } 232 void SAL_CALL java_sql_CallableStatement::registerNumericOutParameter( sal_Int32 parameterIndex, sal_Int32 sqlType, sal_Int32 scale ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) 233 { 234 ::osl::MutexGuard aGuard( m_aMutex ); 235 checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed); 236 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 237 238 { 239 createStatement(t.pEnv); 240 // temporaere Variable initialisieren 241 static const char * cSignature = "(III)V"; 242 static const char * cMethodName = "registerOutParameter"; 243 // Java-Call absetzen 244 static jmethodID mID(NULL); 245 obtainMethodId(t.pEnv, cMethodName,cSignature, mID); 246 t.pEnv->CallVoidMethod( object, mID, parameterIndex,sqlType,scale); 247 ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); 248 } 249 } 250 251 jclass java_sql_CallableStatement::theClass = 0; 252 253 jclass java_sql_CallableStatement::getMyClass() const 254 { 255 // die Klasse muss nur einmal geholt werden, daher statisch 256 if( !theClass ) 257 theClass = findMyClass("java/sql/CallableStatement"); 258 return theClass; 259 } 260 261 Reference< ::com::sun::star::io::XInputStream > SAL_CALL java_sql_CallableStatement::getBinaryStream( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 262 { 263 Reference< starsdbc::XBlob > xBlob = getBlob(columnIndex); 264 return xBlob.is() ? xBlob->getBinaryStream() : Reference< ::com::sun::star::io::XInputStream >(); 265 } 266 Reference< ::com::sun::star::io::XInputStream > SAL_CALL java_sql_CallableStatement::getCharacterStream( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 267 { 268 Reference< starsdbc::XClob > xClob = getClob(columnIndex); 269 return xClob.is() ? xClob->getCharacterStream() : Reference< ::com::sun::star::io::XInputStream >(); 270 } 271 272 Reference< starsdbc::XArray > SAL_CALL java_sql_CallableStatement::getArray( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 273 { 274 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 275 createStatement(t.pEnv); 276 static jmethodID mID(NULL); 277 jobject out = callObjectMethodWithIntArg(t.pEnv,"getArray","(I)Ljava/sql/Array;", mID, columnIndex); 278 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 279 return out==0 ? 0 : new java_sql_Array( t.pEnv, out ); 280 } 281 282 Reference< starsdbc::XClob > SAL_CALL java_sql_CallableStatement::getClob( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 283 { 284 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 285 createStatement(t.pEnv); 286 static jmethodID mID(NULL); 287 jobject out = callObjectMethodWithIntArg(t.pEnv,"getClob","(I)Ljava/sql/Clob;", mID, columnIndex); 288 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 289 return out==0 ? 0 : new java_sql_Clob( t.pEnv, out ); 290 } 291 Reference< starsdbc::XBlob > SAL_CALL java_sql_CallableStatement::getBlob( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 292 { 293 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 294 createStatement(t.pEnv); 295 static jmethodID mID(NULL); 296 jobject out = callObjectMethodWithIntArg(t.pEnv,"getBlob","(I)Ljava/sql/Blob;", mID, columnIndex); 297 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 298 return out==0 ? 0 : new java_sql_Blob( t.pEnv, out ); 299 } 300 301 Reference< starsdbc::XRef > SAL_CALL java_sql_CallableStatement::getRef( sal_Int32 columnIndex ) throw(starsdbc::SQLException, RuntimeException) 302 { 303 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 304 createStatement(t.pEnv); 305 static jmethodID mID(NULL); 306 jobject out = callObjectMethodWithIntArg(t.pEnv,"getRef","(I)Ljava/sql/Ref;", mID, columnIndex); 307 // ACHTUNG: der Aufrufer wird Eigentuemer des zurueckgelieferten Zeigers !!! 308 return out==0 ? 0 : new java_sql_Ref( t.pEnv, out ); 309 } 310 // ----------------------------------------------------------------------------- 311 void SAL_CALL java_sql_CallableStatement::acquire() throw() 312 { 313 java_sql_PreparedStatement::acquire(); 314 } 315 // ----------------------------------------------------------------------------- 316 void SAL_CALL java_sql_CallableStatement::release() throw() 317 { 318 java_sql_PreparedStatement::release(); 319 } 320 // ----------------------------------------------------------------------------- 321 void java_sql_CallableStatement::createStatement(JNIEnv* /*_pEnv*/) 322 { 323 ::osl::MutexGuard aGuard( m_aMutex ); 324 checkDisposed(java_sql_Statement_BASE::rBHelper.bDisposed); 325 326 327 SDBThreadAttach t; OSL_ENSURE(t.pEnv,"Java Enviroment geloescht worden!"); 328 if( t.pEnv && !object ){ 329 // temporaere Variable initialisieren 330 static const char * cSignature = "(Ljava/lang/String;II)Ljava/sql/CallableStatement;"; 331 static const char * cMethodName = "prepareCall"; 332 // Java-Call absetzen 333 jobject out = NULL; 334 // Parameter konvertieren 335 jdbc::LocalRef< jstring > str( t.env(),convertwchar_tToJavaString(t.pEnv,m_sSqlStatement)); 336 337 static jmethodID mID(NULL); 338 if ( !mID ) 339 mID = t.pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature ); 340 if( mID ){ 341 out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID, str.get() ,m_nResultSetType,m_nResultSetConcurrency); 342 } //mID 343 else 344 { 345 static const char * cSignature2 = "(Ljava/lang/String;)Ljava/sql/CallableStatement;"; 346 static jmethodID mID2 = t.pEnv->GetMethodID( m_pConnection->getMyClass(), cMethodName, cSignature2 );OSL_ENSURE(mID2,"Unknown method id!"); 347 if( mID2 ){ 348 out = t.pEnv->CallObjectMethod( m_pConnection->getJavaObject(), mID2, str.get() ); 349 } //mID 350 } 351 ThrowLoggedSQLException( m_aLogger, t.pEnv, *this ); 352 353 if ( out ) 354 object = t.pEnv->NewGlobalRef( out ); 355 } //t.pEnv 356 } 357 // ----------------------------------------------------------------------------- 358 359 360