1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 package com.sun.star.comp.sdbc; 22 23 import org.apache.openoffice.comp.sdbc.dbtools.comphelper.CompHelper; 24 import org.apache.openoffice.comp.sdbc.dbtools.comphelper.PropertySet; 25 import org.apache.openoffice.comp.sdbc.dbtools.comphelper.PropertySetAdapter.PropertyGetter; 26 import org.apache.openoffice.comp.sdbc.dbtools.comphelper.PropertySetAdapter.PropertySetter; 27 import org.apache.openoffice.comp.sdbc.dbtools.util.PropertyIds; 28 import org.apache.openoffice.comp.sdbc.dbtools.util.Resources; 29 30 import com.sun.star.beans.PropertyVetoException; 31 import com.sun.star.comp.sdbc.ConnectionLog.ObjectType; 32 import com.sun.star.lang.IllegalArgumentException; 33 import com.sun.star.lang.WrappedTargetException; 34 import com.sun.star.logging.LogLevel; 35 import com.sun.star.sdbc.ResultSetConcurrency; 36 import com.sun.star.sdbc.ResultSetType; 37 import com.sun.star.sdbc.SQLException; 38 import com.sun.star.sdbc.SQLWarning; 39 import com.sun.star.sdbc.XCloseable; 40 import com.sun.star.sdbc.XGeneratedResultSet; 41 import com.sun.star.sdbc.XMultipleResults; 42 import com.sun.star.sdbc.XResultSet; 43 import com.sun.star.sdbc.XStatement; 44 import com.sun.star.sdbc.XWarningsSupplier; 45 import com.sun.star.uno.Any; 46 import com.sun.star.uno.Type; 47 import com.sun.star.util.XCancellable; 48 49 public abstract class JavaSQLStatementBase extends PropertySet 50 implements XGeneratedResultSet, XMultipleResults, XCloseable, XCancellable, XWarningsSupplier { 51 52 protected JavaSQLConnection connection; 53 protected ConnectionLog logger; 54 protected java.sql.Statement jdbcStatement; 55 protected boolean escapeProcessing = true; 56 protected int resultSetType = ResultSetType.FORWARD_ONLY; 57 protected int resultSetConcurrency = ResultSetConcurrency.READ_ONLY; 58 protected String sqlStatement = ""; 59 protected XStatement generatedStatement; 60 JavaSQLStatementBase(JavaSQLConnection connection)61 public JavaSQLStatementBase(JavaSQLConnection connection) { 62 this.connection = connection; 63 this.logger = new ConnectionLog(connection.getLogger(), ObjectType.STATEMENT); 64 registerProperties(); 65 } 66 getStatementObjectId()67 public int getStatementObjectId() { 68 return logger.getObjectId(); 69 } 70 71 // XComponent 72 73 @Override postDisposing()74 protected synchronized void postDisposing() { 75 super.postDisposing(); 76 logger.log(LogLevel.FINE, Resources.STR_LOG_CLOSING_STATEMENT); 77 if (jdbcStatement != null) { 78 try { 79 jdbcStatement.close(); 80 } catch (java.sql.SQLException sqlException) { 81 logger.log(LogLevel.WARNING, sqlException); 82 } 83 } 84 CompHelper.disposeComponent(generatedStatement); 85 } 86 createStatement()87 protected abstract void createStatement() throws SQLException; 88 89 // XPropertySet 90 registerProperties()91 private void registerProperties() { 92 registerProperty(PropertyIds.CURSORNAME.name, PropertyIds.CURSORNAME.id, Type.STRING, (short)0, 93 new PropertyGetter() { 94 @Override 95 public Object getValue() throws WrappedTargetException { 96 return getCursorName(); 97 } 98 }, 99 new PropertySetter() { 100 @Override 101 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 102 setCursorName((String)value); 103 } 104 } 105 ); 106 registerProperty(PropertyIds.ESCAPEPROCESSING.name, PropertyIds.ESCAPEPROCESSING.id, Type.BOOLEAN, (short)0, 107 new PropertyGetter() { 108 @Override 109 public Object getValue() throws WrappedTargetException { 110 return getEscapeProcessing(); 111 } 112 }, 113 new PropertySetter() { 114 @Override 115 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 116 setEscapeProcessing((boolean)value); 117 } 118 } 119 ); 120 registerProperty(PropertyIds.FETCHDIRECTION.name, PropertyIds.FETCHDIRECTION.id, Type.LONG, (short)0, 121 new PropertyGetter() { 122 @Override 123 public Object getValue() throws WrappedTargetException { 124 return getFetchDirection(); 125 } 126 }, 127 new PropertySetter() { 128 @Override 129 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 130 setFetchDirection((int)value); 131 } 132 } 133 ); 134 registerProperty(PropertyIds.FETCHSIZE.name, PropertyIds.FETCHSIZE.id, Type.LONG, (short)0, 135 new PropertyGetter() { 136 @Override 137 public Object getValue() throws WrappedTargetException { 138 return getFetchSize(); 139 } 140 }, 141 new PropertySetter() { 142 @Override 143 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 144 setFetchSize((int)value); 145 } 146 } 147 ); 148 registerProperty(PropertyIds.MAXFIELDSIZE.name, PropertyIds.MAXFIELDSIZE.id, Type.LONG, (short)0, 149 new PropertyGetter() { 150 @Override 151 public Object getValue() throws WrappedTargetException { 152 return getMaxFieldSize(); 153 } 154 }, 155 new PropertySetter() { 156 @Override 157 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 158 setMaxFieldSize((int)value); 159 } 160 } 161 ); 162 registerProperty(PropertyIds.MAXROWS.name, PropertyIds.MAXROWS.id, Type.LONG, (short)0, 163 new PropertyGetter() { 164 @Override 165 public Object getValue() throws WrappedTargetException { 166 return getMaxRows(); 167 } 168 }, 169 new PropertySetter() { 170 @Override 171 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 172 setMaxRows((int)value); 173 } 174 } 175 ); 176 registerProperty(PropertyIds.QUERYTIMEOUT.name, PropertyIds.QUERYTIMEOUT.id, Type.LONG, (short)0, 177 new PropertyGetter() { 178 @Override 179 public Object getValue() throws WrappedTargetException { 180 return getQueryTimeOut(); 181 } 182 }, 183 new PropertySetter() { 184 @Override 185 public void setValue(Object value) throws WrappedTargetException{ 186 setQueryTimeOut((int)value); 187 } 188 } 189 ); 190 registerProperty(PropertyIds.RESULTSETCONCURRENCY.name, PropertyIds.RESULTSETCONCURRENCY.id, Type.LONG, (short)0, 191 new PropertyGetter() { 192 @Override 193 public Object getValue() throws WrappedTargetException { 194 return getResultSetConcurrency(); 195 } 196 }, 197 new PropertySetter() { 198 @Override 199 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 200 setResultSetConcurrency((int)value); 201 } 202 } 203 ); 204 registerProperty(PropertyIds.RESULTSETTYPE.name, PropertyIds.RESULTSETTYPE.id, Type.LONG, (short)0, 205 new PropertyGetter() { 206 @Override 207 public Object getValue() throws WrappedTargetException { 208 return getResultSetType(); 209 } 210 }, 211 new PropertySetter() { 212 @Override 213 public void setValue(Object value) throws PropertyVetoException, IllegalArgumentException, WrappedTargetException { 214 setResultSetType((int)value); 215 } 216 } 217 ); 218 } 219 getCursorName()220 private String getCursorName() throws WrappedTargetException { 221 try { 222 createStatement(); 223 // FIXME: C++'s jdbcStatement.getCursorName() doesn't exist in JDBC. We always return a blank string. 224 return ""; 225 } catch (SQLException exception) { 226 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 227 } 228 } 229 setCursorName(String value)230 private synchronized void setCursorName(String value) throws WrappedTargetException { 231 try { 232 createStatement(); 233 jdbcStatement.setCursorName(value); 234 } catch (java.sql.SQLException | SQLException exception) { 235 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 236 } 237 } 238 getEscapeProcessing()239 private boolean getEscapeProcessing() throws WrappedTargetException { 240 try { 241 createStatement(); 242 return escapeProcessing; 243 } catch (SQLException exception) { 244 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 245 } 246 } 247 setEscapeProcessing(boolean value)248 private synchronized void setEscapeProcessing(boolean value) throws WrappedTargetException { 249 escapeProcessing = value; 250 try { 251 createStatement(); 252 logger.log(LogLevel.FINE, Resources.STR_LOG_SET_ESCAPE_PROCESSING, value); 253 jdbcStatement.setEscapeProcessing(value); 254 } catch (java.sql.SQLException | SQLException exception) { 255 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 256 } 257 } 258 getFetchDirection()259 private int getFetchDirection() throws WrappedTargetException { 260 try { 261 createStatement(); 262 return jdbcStatement.getFetchDirection(); 263 } catch (java.sql.SQLException | SQLException exception) { 264 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 265 } 266 } 267 setFetchDirection(int value)268 private synchronized void setFetchDirection(int value) throws WrappedTargetException { 269 try { 270 createStatement(); 271 logger.log(LogLevel.FINER, Resources.STR_LOG_FETCH_DIRECTION, value); 272 jdbcStatement.setFetchDirection(value); 273 } catch (java.sql.SQLException | SQLException exception) { 274 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 275 } 276 } 277 getFetchSize()278 private int getFetchSize() throws WrappedTargetException { 279 try { 280 createStatement(); 281 return jdbcStatement.getFetchSize(); 282 } catch (java.sql.SQLException | SQLException exception) { 283 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 284 } 285 } 286 setFetchSize(int value)287 private synchronized void setFetchSize(int value) throws WrappedTargetException { 288 try { 289 createStatement(); 290 logger.log(LogLevel.FINER, Resources.STR_LOG_FETCH_SIZE, value); 291 jdbcStatement.setFetchSize(value); 292 } catch (java.sql.SQLException | SQLException exception) { 293 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 294 } 295 } 296 getMaxFieldSize()297 private int getMaxFieldSize() throws WrappedTargetException { 298 try { 299 createStatement(); 300 return jdbcStatement.getMaxFieldSize(); 301 } catch (java.sql.SQLException | SQLException exception) { 302 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 303 } 304 } 305 setMaxFieldSize(int value)306 private synchronized void setMaxFieldSize(int value) throws WrappedTargetException { 307 try { 308 createStatement(); 309 jdbcStatement.setMaxFieldSize(value); 310 } catch (java.sql.SQLException | SQLException exception) { 311 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 312 } 313 } 314 getMaxRows()315 private int getMaxRows() throws WrappedTargetException { 316 try { 317 createStatement(); 318 return jdbcStatement.getMaxRows(); 319 } catch (java.sql.SQLException | SQLException exception) { 320 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 321 } 322 } 323 setMaxRows(int value)324 private synchronized void setMaxRows(int value) throws WrappedTargetException { 325 try { 326 createStatement(); 327 jdbcStatement.setMaxRows(value); 328 } catch (java.sql.SQLException | SQLException exception) { 329 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 330 } 331 } 332 getQueryTimeOut()333 private int getQueryTimeOut() throws WrappedTargetException { 334 try { 335 createStatement(); 336 return jdbcStatement.getQueryTimeout(); 337 } catch (java.sql.SQLException | SQLException exception) { 338 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 339 } 340 } 341 setQueryTimeOut(int value)342 private synchronized void setQueryTimeOut(int value) throws WrappedTargetException { 343 try { 344 createStatement(); 345 jdbcStatement.setQueryTimeout(value); 346 } catch (java.sql.SQLException | SQLException exception) { 347 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 348 } 349 } 350 getResultSetConcurrency()351 private int getResultSetConcurrency() throws WrappedTargetException { 352 try { 353 createStatement(); 354 return jdbcStatement.getResultSetConcurrency(); 355 } catch (java.sql.SQLException | SQLException exception) { 356 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 357 } 358 } 359 setResultSetConcurrency(int value)360 private synchronized void setResultSetConcurrency(int value) throws WrappedTargetException { 361 checkDisposed(); 362 try { 363 logger.log(LogLevel.FINE, Resources.STR_LOG_RESULT_SET_CONCURRENCY, value); 364 resultSetConcurrency = value; 365 jdbcStatement.close(); 366 } catch (java.sql.SQLException exception) { 367 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 368 } finally { 369 jdbcStatement = null; 370 } 371 } 372 getResultSetType()373 private int getResultSetType() throws WrappedTargetException { 374 try { 375 createStatement(); 376 return jdbcStatement.getResultSetType(); 377 } catch (java.sql.SQLException | SQLException exception) { 378 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 379 } 380 } 381 setResultSetType(int value)382 private synchronized void setResultSetType(int value) throws WrappedTargetException { 383 checkDisposed(); 384 try { 385 logger.log(LogLevel.FINE, Resources.STR_LOG_RESULT_SET_TYPE, value); 386 resultSetType = value; 387 jdbcStatement.close(); 388 } catch (java.sql.SQLException exception) { 389 throw new WrappedTargetException("SQL error", this, Tools.toUnoException(this, exception)); 390 } finally { 391 jdbcStatement = null; 392 } 393 } 394 395 // XCancellable 396 397 @Override cancel()398 public void cancel() { 399 try { 400 createStatement(); 401 jdbcStatement.cancel(); 402 } catch (SQLException sqlException) { 403 logger.log(LogLevel.SEVERE, sqlException); 404 } catch (java.sql.SQLException jdbcException) { 405 logger.log(LogLevel.SEVERE, jdbcException); 406 } 407 } 408 409 // XCloseable 410 411 @Override close()412 public synchronized void close() throws SQLException { 413 checkDisposed(); 414 dispose(); 415 } 416 417 // XWarningsSupplier 418 419 @Override clearWarnings()420 public synchronized void clearWarnings() throws SQLException { 421 try { 422 createStatement(); 423 jdbcStatement.clearWarnings(); 424 } catch (java.sql.SQLException sqlException) { 425 throw Tools.toUnoException(this, sqlException); 426 } 427 } 428 429 @Override getWarnings()430 public synchronized Object getWarnings() throws SQLException { 431 try { 432 createStatement(); 433 java.sql.SQLWarning javaWarning = jdbcStatement.getWarnings(); 434 if (javaWarning != null) { 435 java.lang.Throwable nextException = javaWarning.getCause(); 436 SQLWarning warning = new SQLWarning(javaWarning.getMessage()); 437 warning.Context = this; 438 warning.SQLState = javaWarning.getSQLState(); 439 warning.ErrorCode = javaWarning.getErrorCode(); 440 warning.NextException = nextException != null ? Tools.toUnoException(this, nextException) : Any.VOID; 441 return warning; 442 } 443 return Any.VOID; 444 } catch (java.sql.SQLException sqlException) { 445 throw Tools.toUnoException(this, sqlException); 446 } 447 } 448 449 // XGeneratedResultSet 450 451 @Override getGeneratedValues()452 public synchronized com.sun.star.sdbc.XResultSet getGeneratedValues() throws SQLException { 453 logger.log(LogLevel.FINE, Resources.STR_LOG_GENERATED_VALUES); 454 createStatement(); 455 java.sql.ResultSet jdbcResultSet = null; 456 try { 457 jdbcResultSet = jdbcStatement.getGeneratedKeys(); 458 } catch (java.sql.SQLException jdbcException) { 459 } 460 461 XResultSet resultSet = null; 462 if (jdbcResultSet != null) { 463 resultSet = new JavaSQLResultSet(jdbcResultSet, connection, this); 464 } else { 465 if (connection != null && connection.isAutoRetrievingEnabled()) { 466 String statement = connection.getTransformedGeneratedStatement(sqlStatement); 467 if (!statement.isEmpty()) { 468 logger.log(LogLevel.FINER, Resources.STR_LOG_GENERATED_VALUES_FALLBACK, statement); 469 CompHelper.disposeComponent(generatedStatement); 470 generatedStatement = connection.createStatement(); 471 resultSet = generatedStatement.executeQuery(statement); 472 } 473 } 474 } 475 return resultSet; 476 } 477 478 // XMultipleResults 479 480 @Override getMoreResults()481 public boolean getMoreResults() throws SQLException { 482 try { 483 createStatement(); 484 return jdbcStatement.getMoreResults(); 485 } catch (java.sql.SQLException sqlException) { 486 throw Tools.toUnoException(this, sqlException); 487 } 488 } 489 490 @Override getResultSet()491 public XResultSet getResultSet() throws SQLException { 492 try { 493 createStatement(); 494 java.sql.ResultSet jdbcResultSet = jdbcStatement.getResultSet(); 495 if (jdbcResultSet != null) { 496 return new JavaSQLResultSet(jdbcResultSet, connection, this); 497 } else { 498 return null; 499 } 500 } catch (java.sql.SQLException sqlException) { 501 throw Tools.toUnoException(this, sqlException); 502 } 503 } 504 505 @Override getUpdateCount()506 public int getUpdateCount() throws SQLException { 507 try { 508 createStatement(); 509 int count = jdbcStatement.getUpdateCount(); 510 logger.log(LogLevel.FINER, Resources.STR_LOG_UPDATE_COUNT, count); 511 return count; 512 } catch (java.sql.SQLException sqlException) { 513 throw Tools.toUnoException(this, sqlException); 514 } 515 } 516 } 517