Home » commons-dbcp-1.2.2-src » org.apache.commons » dbcp » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.commons.dbcp;
   19   
   20   import java.sql.Connection;
   21   import java.sql.ResultSet;
   22   import java.sql.SQLException;
   23   import java.sql.SQLWarning;
   24   import java.sql.Statement;
   25   import java.util.List;
   26   
   27   /**
   28    * A base delegating implementation of {@link Statement}.
   29    * <p>
   30    * All of the methods from the {@link Statement} interface
   31    * simply check to see that the {@link Statement} is active,
   32    * and call the corresponding method on the "delegate"
   33    * provided in my constructor.
   34    * <p>
   35    * Extends AbandonedTrace to implement Statement tracking and
   36    * logging of code which created the Statement. Tracking the
   37    * Statement ensures that the Connection which created it can
   38    * close any open Statement's on Connection close.
   39    *
   40    * @author Rodney Waldhoff
   41    * @author Glenn L. Nielsen
   42    * @author James House
   43    * @author Dirk Verbeeck
   44    * @version $Revision: 500687 $ $Date: 2007-01-27 16:33:47 -0700 (Sat, 27 Jan 2007) $
   45    */
   46   public class DelegatingStatement extends AbandonedTrace implements Statement {
   47       /** My delegate. */
   48       protected Statement _stmt = null;
   49       /** The connection that created me. **/
   50       protected DelegatingConnection _conn = null;
   51   
   52       /**
   53        * Create a wrapper for the Statement which traces this
   54        * Statement to the Connection which created it and the
   55        * code which created it.
   56        *
   57        * @param s the {@link Statement} to delegate all calls to.
   58        * @param c the {@link DelegatingConnection} that created this statement.
   59        */
   60       public DelegatingStatement(DelegatingConnection c, Statement s) {
   61           super(c);
   62           _stmt = s;
   63           _conn = c;
   64       }
   65   
   66       /**
   67        * Returns my underlying {@link Statement}.
   68        * @return my underlying {@link Statement}.
   69        * @see #getInnermostDelegate
   70        */
   71       public Statement getDelegate() {
   72           return _stmt;
   73       }
   74   
   75       public boolean equals(Object obj) {
   76           Statement delegate = getInnermostDelegate();
   77           if (delegate == null) {
   78               return false;
   79           }
   80           if (obj instanceof DelegatingStatement) {
   81               DelegatingStatement s = (DelegatingStatement) obj;
   82               return delegate.equals(s.getInnermostDelegate());
   83           }
   84           else {
   85               return delegate.equals(obj);
   86           }
   87       }
   88   
   89       public int hashCode() {
   90           Object obj = getInnermostDelegate();
   91           if (obj == null) {
   92               return 0;
   93           }
   94           return obj.hashCode();
   95       }
   96       
   97       /**
   98        * If my underlying {@link Statement} is not a
   99        * <tt>DelegatingStatement</tt>, returns it,
  100        * otherwise recursively invokes this method on
  101        * my delegate.
  102        * <p>
  103        * Hence this method will return the first
  104        * delegate that is not a <tt>DelegatingStatement</tt>
  105        * or <tt>null</tt> when no non-<tt>DelegatingStatement</tt>
  106        * delegate can be found by transversing this chain.
  107        * <p>
  108        * This method is useful when you may have nested
  109        * <tt>DelegatingStatement</tt>s, and you want to make
  110        * sure to obtain a "genuine" {@link Statement}.
  111        * @see #getDelegate
  112        */
  113       public Statement getInnermostDelegate() {
  114           Statement s = _stmt;
  115           while(s != null && s instanceof DelegatingStatement) {
  116               s = ((DelegatingStatement)s).getDelegate();
  117               if(this == s) {
  118                   return null;
  119               }
  120           }
  121           return s;
  122       }
  123   
  124       /** Sets my delegate. */
  125       public void setDelegate(Statement s) {
  126           _stmt = s;
  127       }
  128   
  129       protected boolean _closed = false;
  130   
  131       protected boolean isClosed() {
  132           return _closed;
  133       }
  134   
  135       protected void checkOpen() throws SQLException {
  136           if(isClosed()) {
  137               throw new SQLException
  138                   (this.getClass().getName() + " with address: \"" + 
  139                   this.toString() + "\" is closed.");
  140           }
  141       }
  142   
  143       /**
  144        * Close this DelegatingStatement, and close
  145        * any ResultSets that were not explicitly closed.
  146        */
  147       public void close() throws SQLException {
  148           try {
  149               try {
  150                   if (_conn != null) {
  151                       _conn.removeTrace(this);
  152                       _conn = null;
  153                   }
  154           
  155                   // The JDBC spec requires that a statment close any open
  156                   // ResultSet's when it is closed.
  157                   // FIXME The PreparedStatement we're wrapping should handle this for us.
  158                   // See bug 17301 for what could happen when ResultSets are closed twice.
  159                   List resultSets = getTrace();
  160                   if( resultSets != null) {
  161                       ResultSet[] set = (ResultSet[]) resultSets.toArray(new ResultSet[resultSets.size()]);
  162                       for (int i = 0; i < set.length; i++) {
  163                           set[i].close();
  164                       }
  165                       clearTrace();
  166                   }
  167           
  168                   _stmt.close();
  169               }
  170               catch (SQLException e) {
  171                   handleException(e);
  172               }
  173           }
  174           finally {
  175               _closed = true;
  176           }
  177       }
  178   
  179       protected void handleException(SQLException e) throws SQLException {
  180           if (_conn != null) {
  181               _conn.handleException(e);
  182           }
  183           else {
  184               throw e;
  185           }
  186       }
  187   
  188       protected void activate() throws SQLException {
  189           if(_stmt instanceof DelegatingStatement) {
  190               ((DelegatingStatement)_stmt).activate();
  191           }
  192       }
  193   
  194       protected void passivate() throws SQLException {
  195           if(_stmt instanceof DelegatingStatement) {
  196               ((DelegatingStatement)_stmt).passivate();
  197           }
  198       }
  199   
  200       public Connection getConnection() throws SQLException {
  201           checkOpen();
  202           return _conn; // return the delegating connection that created this
  203       }
  204   
  205       public ResultSet executeQuery(String sql) throws SQLException {
  206           checkOpen();
  207           try {
  208               return DelegatingResultSet.wrapResultSet(this,_stmt.executeQuery(sql));
  209           }
  210           catch (SQLException e) {
  211               handleException(e);
  212               return null;
  213           }
  214       }
  215   
  216       public ResultSet getResultSet() throws SQLException {
  217           checkOpen();
  218           try {
  219               return DelegatingResultSet.wrapResultSet(this,_stmt.getResultSet());
  220           }
  221           catch (SQLException e) {
  222               handleException(e);
  223               return null;
  224           }
  225       }
  226   
  227       public int executeUpdate(String sql) throws SQLException
  228       { checkOpen(); try { return _stmt.executeUpdate(sql); } catch (SQLException e) { handleException(e); return 0; } }
  229   
  230       public int getMaxFieldSize() throws SQLException
  231       { checkOpen(); try { return _stmt.getMaxFieldSize(); } catch (SQLException e) { handleException(e); return 0; } }
  232   
  233       public void setMaxFieldSize(int max) throws SQLException
  234       { checkOpen(); try { _stmt.setMaxFieldSize(max); } catch (SQLException e) { handleException(e); } }
  235   
  236       public int getMaxRows() throws SQLException
  237       { checkOpen(); try { return _stmt.getMaxRows(); } catch (SQLException e) { handleException(e); return 0; } }
  238   
  239       public void setMaxRows(int max) throws SQLException
  240       { checkOpen(); try { _stmt.setMaxRows(max); } catch (SQLException e) { handleException(e); } }
  241   
  242       public void setEscapeProcessing(boolean enable) throws SQLException
  243       { checkOpen(); try { _stmt.setEscapeProcessing(enable); } catch (SQLException e) { handleException(e); } }
  244   
  245       public int getQueryTimeout() throws SQLException
  246       { checkOpen(); try { return _stmt.getQueryTimeout(); } catch (SQLException e) { handleException(e); return 0; } }
  247   
  248       public void setQueryTimeout(int seconds) throws SQLException
  249       { checkOpen(); try { _stmt.setQueryTimeout(seconds); } catch (SQLException e) { handleException(e); } }
  250   
  251       public void cancel() throws SQLException
  252       { checkOpen(); try { _stmt.cancel(); } catch (SQLException e) { handleException(e); } }
  253   
  254       public SQLWarning getWarnings() throws SQLException
  255       { checkOpen(); try { return _stmt.getWarnings(); } catch (SQLException e) { handleException(e); return null; } }
  256   
  257       public void clearWarnings() throws SQLException
  258       { checkOpen(); try { _stmt.clearWarnings(); } catch (SQLException e) { handleException(e); } }
  259   
  260       public void setCursorName(String name) throws SQLException
  261       { checkOpen(); try { _stmt.setCursorName(name); } catch (SQLException e) { handleException(e); } }
  262   
  263       public boolean execute(String sql) throws SQLException
  264       { checkOpen(); try { return _stmt.execute(sql); } catch (SQLException e) { handleException(e); return false; } }
  265   
  266       public int getUpdateCount() throws SQLException
  267       { checkOpen(); try { return _stmt.getUpdateCount(); } catch (SQLException e) { handleException(e); return 0; } }
  268   
  269       public boolean getMoreResults() throws SQLException
  270       { checkOpen(); try { return _stmt.getMoreResults(); } catch (SQLException e) { handleException(e); return false; } }
  271   
  272       public void setFetchDirection(int direction) throws SQLException
  273       { checkOpen(); try { _stmt.setFetchDirection(direction); } catch (SQLException e) { handleException(e); } }
  274   
  275       public int getFetchDirection() throws SQLException
  276       { checkOpen(); try { return _stmt.getFetchDirection(); } catch (SQLException e) { handleException(e); return 0; } }
  277   
  278       public void setFetchSize(int rows) throws SQLException
  279       { checkOpen(); try { _stmt.setFetchSize(rows); } catch (SQLException e) { handleException(e); } }
  280   
  281       public int getFetchSize() throws SQLException
  282       { checkOpen(); try { return _stmt.getFetchSize(); } catch (SQLException e) { handleException(e); return 0; } }
  283   
  284       public int getResultSetConcurrency() throws SQLException
  285       { checkOpen(); try { return _stmt.getResultSetConcurrency(); } catch (SQLException e) { handleException(e); return 0; } }
  286   
  287       public int getResultSetType() throws SQLException
  288       { checkOpen(); try { return _stmt.getResultSetType(); } catch (SQLException e) { handleException(e); return 0; } }
  289   
  290       public void addBatch(String sql) throws SQLException
  291       { checkOpen(); try { _stmt.addBatch(sql); } catch (SQLException e) { handleException(e); } }
  292   
  293       public void clearBatch() throws SQLException
  294       { checkOpen(); try { _stmt.clearBatch(); } catch (SQLException e) { handleException(e); } }
  295   
  296       public int[] executeBatch() throws SQLException
  297       { checkOpen(); try { return _stmt.executeBatch(); } catch (SQLException e) { handleException(e); return null; } }
  298   
  299       /**
  300        * Returns a String representation of this object.
  301        *
  302        * @return String
  303        * @since 1.2.2
  304        */
  305       public String toString() {
  306       return _stmt.toString();
  307       }
  308   
  309       // ------------------- JDBC 3.0 -----------------------------------------
  310       // Will be commented by the build process on a JDBC 2.0 system
  311   
  312   /* JDBC_3_ANT_KEY_BEGIN */
  313   
  314       public boolean getMoreResults(int current) throws SQLException
  315       { checkOpen(); try { return _stmt.getMoreResults(current); } catch (SQLException e) { handleException(e); return false; } }
  316   
  317       public ResultSet getGeneratedKeys() throws SQLException
  318       { checkOpen(); try { return _stmt.getGeneratedKeys(); } catch (SQLException e) { handleException(e); return null; } }
  319   
  320       public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
  321       { checkOpen(); try { return _stmt.executeUpdate(sql, autoGeneratedKeys); } catch (SQLException e) { handleException(e); return 0; } }
  322   
  323       public int executeUpdate(String sql, int columnIndexes[]) throws SQLException
  324       { checkOpen(); try { return _stmt.executeUpdate(sql, columnIndexes); } catch (SQLException e) { handleException(e); return 0; } }
  325   
  326       public int executeUpdate(String sql, String columnNames[]) throws SQLException
  327       { checkOpen(); try { return _stmt.executeUpdate(sql, columnNames); } catch (SQLException e) { handleException(e); return 0; } }
  328   
  329       public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
  330       { checkOpen(); try { return _stmt.execute(sql, autoGeneratedKeys); } catch (SQLException e) { handleException(e); return false; } }
  331   
  332       public boolean execute(String sql, int columnIndexes[]) throws SQLException
  333       { checkOpen(); try { return _stmt.execute(sql, columnIndexes); } catch (SQLException e) { handleException(e); return false; } }
  334   
  335       public boolean execute(String sql, String columnNames[]) throws SQLException
  336       { checkOpen(); try { return _stmt.execute(sql, columnNames); } catch (SQLException e) { handleException(e); return false; } }
  337   
  338       public int getResultSetHoldability() throws SQLException
  339       { checkOpen(); try { return _stmt.getResultSetHoldability(); } catch (SQLException e) { handleException(e); return 0; } }
  340   
  341   /* JDBC_3_ANT_KEY_END */
  342   }

Save This Page
Home » commons-dbcp-1.2.2-src » org.apache.commons » dbcp » [javadoc | source]