All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.dbcp2.DelegatingStatement Maven / Gradle / Ivy

There is a newer version: 2.12.0
Show newest version
/*
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.dbcp2;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.List;

/**
 * A base delegating implementation of {@link Statement}.
 * 

* All of the methods from the {@link Statement} interface * simply check to see that the {@link Statement} is active, * and call the corresponding method on the "delegate" * provided in my constructor. *

* Extends AbandonedTrace to implement Statement tracking and * logging of code which created the Statement. Tracking the * Statement ensures that the Connection which created it can * close any open Statement's on Connection close. * * @author Rodney Waldhoff * @author Glenn L. Nielsen * @author James House * @author Dirk Verbeeck * @since 2.0 */ public class DelegatingStatement extends AbandonedTrace implements Statement { /** My delegate. */ private Statement _stmt = null; /** The connection that created me. **/ private DelegatingConnection _conn = null; /** * Create a wrapper for the Statement which traces this * Statement to the Connection which created it and the * code which created it. * * @param s the {@link Statement} to delegate all calls to. * @param c the {@link DelegatingConnection} that created this statement. */ public DelegatingStatement(final DelegatingConnection c, final Statement s) { super(c); _stmt = s; _conn = c; } /** * Returns my underlying {@link Statement}. * @return my underlying {@link Statement}. * @see #getInnermostDelegate */ public Statement getDelegate() { return _stmt; } /** * If my underlying {@link Statement} is not a * {@code DelegatingStatement}, returns it, * otherwise recursively invokes this method on * my delegate. *

* Hence this method will return the first * delegate that is not a {@code DelegatingStatement} * or {@code null} when no non-{@code DelegatingStatement} * delegate can be found by traversing this chain. *

* This method is useful when you may have nested * {@code DelegatingStatement}s, and you want to make * sure to obtain a "genuine" {@link Statement}. * @see #getDelegate */ public Statement getInnermostDelegate() { Statement s = _stmt; while(s != null && s instanceof DelegatingStatement) { s = ((DelegatingStatement)s).getDelegate(); if(this == s) { return null; } } return s; } /** Sets my delegate. */ public void setDelegate(final Statement s) { _stmt = s; } private boolean _closed = false; protected boolean isClosedInternal() { return _closed; } protected void setClosedInternal(final boolean closed) { this._closed = closed; } protected void checkOpen() throws SQLException { if(isClosed()) { throw new SQLException (this.getClass().getName() + " with address: \"" + this.toString() + "\" is closed."); } } /** * Close this DelegatingStatement, and close * any ResultSets that were not explicitly closed. */ @Override public void close() throws SQLException { if (isClosed()) { return; } try { try { if (_conn != null) { _conn.removeTrace(this); _conn = null; } // The JDBC spec requires that a statement close any open // ResultSet's when it is closed. // FIXME The PreparedStatement we're wrapping should handle this for us. // See bug 17301 for what could happen when ResultSets are closed twice. final List resultSets = getTrace(); if( resultSets != null) { final ResultSet[] set = resultSets.toArray(new ResultSet[resultSets.size()]); for (final ResultSet element : set) { element.close(); } clearTrace(); } if (_stmt != null) { _stmt.close(); } } catch (final SQLException e) { handleException(e); } } finally { _closed = true; _stmt = null; } } protected void handleException(final SQLException e) throws SQLException { if (_conn != null) { _conn.handleException(e); } else { throw e; } } protected void activate() throws SQLException { if(_stmt instanceof DelegatingStatement) { ((DelegatingStatement)_stmt).activate(); } } protected void passivate() throws SQLException { if(_stmt instanceof DelegatingStatement) { ((DelegatingStatement)_stmt).passivate(); } } @Override public Connection getConnection() throws SQLException { checkOpen(); return getConnectionInternal(); // return the delegating connection that created this } protected DelegatingConnection getConnectionInternal() { return _conn; } @Override public ResultSet executeQuery(final String sql) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return DelegatingResultSet.wrapResultSet(this,_stmt.executeQuery(sql)); } catch (final SQLException e) { handleException(e); throw new AssertionError(); } } @Override public ResultSet getResultSet() throws SQLException { checkOpen(); try { return DelegatingResultSet.wrapResultSet(this,_stmt.getResultSet()); } catch (final SQLException e) { handleException(e); throw new AssertionError(); } } @Override public int executeUpdate(final String sql) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.executeUpdate(sql); } catch (final SQLException e) { handleException(e); return 0; } } @Override public int getMaxFieldSize() throws SQLException { checkOpen(); try { return _stmt.getMaxFieldSize(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public void setMaxFieldSize(final int max) throws SQLException { checkOpen(); try { _stmt.setMaxFieldSize(max); } catch (final SQLException e) { handleException(e); } } @Override public int getMaxRows() throws SQLException { checkOpen(); try { return _stmt.getMaxRows(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public void setMaxRows(final int max) throws SQLException { checkOpen(); try { _stmt.setMaxRows(max); } catch (final SQLException e) { handleException(e); } } @Override public void setEscapeProcessing(final boolean enable) throws SQLException { checkOpen(); try { _stmt.setEscapeProcessing(enable); } catch (final SQLException e) { handleException(e); } } @Override public int getQueryTimeout() throws SQLException { checkOpen(); try { return _stmt.getQueryTimeout(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public void setQueryTimeout(final int seconds) throws SQLException { checkOpen(); try { _stmt.setQueryTimeout(seconds); } catch (final SQLException e) { handleException(e); } } @Override public void cancel() throws SQLException { checkOpen(); try { _stmt.cancel(); } catch (final SQLException e) { handleException(e); } } @Override public SQLWarning getWarnings() throws SQLException { checkOpen(); try { return _stmt.getWarnings(); } catch (final SQLException e) { handleException(e); throw new AssertionError(); } } @Override public void clearWarnings() throws SQLException { checkOpen(); try { _stmt.clearWarnings(); } catch (final SQLException e) { handleException(e); } } @Override public void setCursorName(final String name) throws SQLException { checkOpen(); try { _stmt.setCursorName(name); } catch (final SQLException e) { handleException(e); } } @Override public boolean execute(final String sql) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.execute(sql); } catch (final SQLException e) { handleException(e); return false; } } @Override public int getUpdateCount() throws SQLException { checkOpen(); try { return _stmt.getUpdateCount(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public boolean getMoreResults() throws SQLException { checkOpen(); try { return _stmt.getMoreResults(); } catch (final SQLException e) { handleException(e); return false; } } @Override public void setFetchDirection(final int direction) throws SQLException { checkOpen(); try { _stmt.setFetchDirection(direction); } catch (final SQLException e) { handleException(e); } } @Override public int getFetchDirection() throws SQLException { checkOpen(); try { return _stmt.getFetchDirection(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public void setFetchSize(final int rows) throws SQLException { checkOpen(); try { _stmt.setFetchSize(rows); } catch (final SQLException e) { handleException(e); } } @Override public int getFetchSize() throws SQLException { checkOpen(); try { return _stmt.getFetchSize(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public int getResultSetConcurrency() throws SQLException { checkOpen(); try { return _stmt.getResultSetConcurrency(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public int getResultSetType() throws SQLException { checkOpen(); try { return _stmt.getResultSetType(); } catch (final SQLException e) { handleException(e); return 0; } } @Override public void addBatch(final String sql) throws SQLException { checkOpen(); try { _stmt.addBatch(sql); } catch (final SQLException e) { handleException(e); } } @Override public void clearBatch() throws SQLException { checkOpen(); try { _stmt.clearBatch(); } catch (final SQLException e) { handleException(e); } } @Override public int[] executeBatch() throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.executeBatch(); } catch (final SQLException e) { handleException(e); throw new AssertionError(); } } /** * Returns a String representation of this object. * * @return String */ @Override public String toString() { return _stmt == null ? "NULL" : _stmt.toString(); } @Override public boolean getMoreResults(final int current) throws SQLException { checkOpen(); try { return _stmt.getMoreResults(current); } catch (final SQLException e) { handleException(e); return false; } } @Override public ResultSet getGeneratedKeys() throws SQLException { checkOpen(); try { return DelegatingResultSet.wrapResultSet(this, _stmt.getGeneratedKeys()); } catch (final SQLException e) { handleException(e); throw new AssertionError(); } } @Override public int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.executeUpdate(sql, autoGeneratedKeys); } catch (final SQLException e) { handleException(e); return 0; } } @Override public int executeUpdate(final String sql, final int columnIndexes[]) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.executeUpdate(sql, columnIndexes); } catch (final SQLException e) { handleException(e); return 0; } } @Override public int executeUpdate(final String sql, final String columnNames[]) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.executeUpdate(sql, columnNames); } catch (final SQLException e) { handleException(e); return 0; } } @Override public boolean execute(final String sql, final int autoGeneratedKeys) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.execute(sql, autoGeneratedKeys); } catch (final SQLException e) { handleException(e); return false; } } @Override public boolean execute(final String sql, final int columnIndexes[]) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.execute(sql, columnIndexes); } catch (final SQLException e) { handleException(e); return false; } } @Override public boolean execute(final String sql, final String columnNames[]) throws SQLException { checkOpen(); if (_conn != null) { _conn.setLastUsed(); } try { return _stmt.execute(sql, columnNames); } catch (final SQLException e) { handleException(e); return false; } } @Override public int getResultSetHoldability() throws SQLException { checkOpen(); try { return _stmt.getResultSetHoldability(); } catch (final SQLException e) { handleException(e); return 0; } } /* * Note was protected prior to JDBC 4 */ @Override public boolean isClosed() throws SQLException { return _closed; } @Override public boolean isWrapperFor(final Class iface) throws SQLException { if (iface.isAssignableFrom(getClass())) { return true; } else if (iface.isAssignableFrom(_stmt.getClass())) { return true; } else { return _stmt.isWrapperFor(iface); } } @Override public T unwrap(final Class iface) throws SQLException { if (iface.isAssignableFrom(getClass())) { return iface.cast(this); } else if (iface.isAssignableFrom(_stmt.getClass())) { return iface.cast(_stmt); } else { return _stmt.unwrap(iface); } } @Override public void setPoolable(final boolean poolable) throws SQLException { checkOpen(); try { _stmt.setPoolable(poolable); } catch (final SQLException e) { handleException(e); } } @Override public boolean isPoolable() throws SQLException { checkOpen(); try { return _stmt.isPoolable(); } catch (final SQLException e) { handleException(e); return false; } } @Override public void closeOnCompletion() throws SQLException { checkOpen(); try { _stmt.closeOnCompletion(); } catch (final SQLException e) { handleException(e); } } @Override public boolean isCloseOnCompletion() throws SQLException { checkOpen(); try { return _stmt.isCloseOnCompletion(); } catch (final SQLException e) { handleException(e); return false; } } @Override protected void finalize() throws Throwable { // This is required because of statement pooling. The poolable // statements will always be strongly held by the statement pool. If the // delegating statements that wrap the poolable statement are not // strongly held they will be garbage collected but at that point the // poolable statements need to be returned to the pool else there will // be a leak of statements from the pool. Closing this statement will // close all the wrapped statements and return any poolable statements // to the pool. close(); super.finalize(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy