/** * Alipay.com Inc. * Copyright (c) 2004-2012 All Rights Reserved. */ package com.alipay.zdal.datasource.resource.adapter.jdbc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import com.alipay.zdal.datasource.ZDataSource; /** * A wrapper for a statement. * * @todo remove the org.jboss.ejb.plugins.cmp.jdbc.WrappedStatement dependency * * @author ���� * @version $Id: WrappedStatement.java, v 0.1 2014-1-6 ����05:31:18 Exp $ */ public class WrappedStatement implements Statement, StatementAccess { private final WrappedConnection lc; private final Statement s; protected String dataSourceName = ""; /** The result sets */ private HashMap resultSets; /** Whether we are closed */ private boolean closed = false; /** The state lock */ private final Object lock = new Object(); /** ���ÿ����Ĕ���Դ*/ protected ZDataSource zdatasource = null; public ZDataSource getZdatasource() { return zdatasource; } public void setZdatasource(ZDataSource zdatasource) { this.zdatasource = zdatasource; } /** * @param lc * @param s * @param zdatasource */ public WrappedStatement(final WrappedConnection lc, Statement s, ZDataSource zdatasource) { this.lc = lc; this.s = s; this.zdatasource = zdatasource; lc.registerStatement(this); } /** * @param lc * @param s * @param dataSourceName * @param zdatasource */ public WrappedStatement(final WrappedConnection lc, Statement s, String dataSourceName, ZDataSource zdatasource) { this.lc = lc; this.s = s; this.dataSourceName = dataSourceName; this.zdatasource = zdatasource; lc.registerStatement(this); } public void close() throws SQLException { synchronized (lock) { if (closed) { return; } closed = true; } lc.unregisterStatement(this); internalClose(); } /** * @see java.sql.Statement#execute(java.lang.String) */ public boolean execute(String sql) throws SQLException { return this.executeInternal(sql, -1, null, null); } /** * @see java.sql.Statement#execute(java.lang.String, int) */ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { return this.executeInternal(sql, autoGeneratedKeys, null, null); } /** * @see java.sql.Statement#execute(java.lang.String, int[]) */ public boolean execute(String sql, int[] columnIndexes) throws SQLException { return this.executeInternal(sql, -1, columnIndexes, null); } /** * @see java.sql.Statement#execute(java.lang.String, java.lang.String[]) */ public boolean execute(String sql, String[] columnNames) throws SQLException { return this.executeInternal(sql, -1, null, columnNames); } /** * * @param sql * @param autoGeneratedKeys * @param columnIndexes * @param columnNames * @return * @throws SQLException */ private boolean executeInternal(String sql, int autoGeneratedKeys, int[] columnIndexes, String[] columnNames) throws SQLException { checkTransaction(); try { checkConfiguredQueryTimeout(); if (autoGeneratedKeys == -1 && columnIndexes == null && columnNames == null) { return s.execute(sql); } else if (autoGeneratedKeys != -1) { return s.execute(sql, autoGeneratedKeys); } else if (columnIndexes != null) { return s.execute(sql, columnIndexes); } else { return s.execute(sql, columnNames); } } catch (Throwable t) { throw checkException(t); } finally { } } public Connection getConnection() throws SQLException { return lc; } public SQLWarning getWarnings() throws SQLException { checkState(); try { return s.getWarnings(); } catch (Throwable t) { throw checkException(t); } } public void clearWarnings() throws SQLException { checkState(); try { s.clearWarnings(); } catch (Throwable t) { throw checkException(t); } } /** * @see java.sql.Statement#executeQuery(java.lang.String) */ public ResultSet executeQuery(String sql) throws SQLException { checkTransaction(); try { checkConfiguredQueryTimeout(); ResultSet result = s.executeQuery(sql); return registerResultSet(result); } catch (Throwable t) { throw checkException(t); } finally { } } /** * @see java.sql.Statement#executeUpdate(java.lang.String) */ public int executeUpdate(String sql) throws SQLException { return this.executeUpdateInternal(sql, -1, null, null); } /** * @see java.sql.Statement#executeUpdate(java.lang.String, int) */ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { return this.executeUpdateInternal(sql, autoGeneratedKeys, null, null); } /** * @see java.sql.Statement#executeUpdate(java.lang.String, int[]) */ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { return this.executeUpdateInternal(sql, -1, columnIndexes, null); } /** * @see java.sql.Statement#executeUpdate(java.lang.String, java.lang.String[]) */ public int executeUpdate(String sql, String[] columnNames) throws SQLException { return this.executeUpdateInternal(sql, -1, null, columnNames); } /** * * @param sql * @param autoGeneratedKeys * @param columnIndexes * @param columnNames * @return * @throws SQLException */ private int executeUpdateInternal(String sql, int autoGeneratedKeys, int[] columnIndexes, String[] columnNames) throws SQLException { checkTransaction(); try { checkConfiguredQueryTimeout(); if (autoGeneratedKeys == -1 && columnIndexes == null && columnNames == null) { return s.executeUpdate(sql); } else if (autoGeneratedKeys != -1) { return s.executeUpdate(sql, autoGeneratedKeys); } else if (columnIndexes != null) { return s.executeUpdate(sql, columnIndexes); } else { return s.executeUpdate(sql, columnNames); } } catch (Throwable t) { throw checkException(t); } finally { } } public int getMaxFieldSize() throws SQLException { checkState(); try { return s.getMaxFieldSize(); } catch (Throwable t) { throw checkException(t); } } public void setMaxFieldSize(int max) throws SQLException { checkState(); try { s.setMaxFieldSize(max); } catch (Throwable t) { throw checkException(t); } } public int getMaxRows() throws SQLException { checkState(); try { return s.getMaxRows(); } catch (Throwable t) { throw checkException(t); } } public void setMaxRows(int max) throws SQLException { checkState(); try { s.setMaxRows(max); } catch (Throwable t) { throw checkException(t); } } public void setEscapeProcessing(boolean enable) throws SQLException { checkState(); try { s.setEscapeProcessing(enable); } catch (Throwable t) { throw checkException(t); } } public int getQueryTimeout() throws SQLException { checkState(); try { return s.getQueryTimeout(); } catch (Throwable t) { throw checkException(t); } } public void setQueryTimeout(int timeout) throws SQLException { checkState(); try { s.setQueryTimeout(timeout); } catch (Throwable t) { throw checkException(t); } } public void cancel() throws SQLException { checkState(); try { s.cancel(); } catch (Throwable t) { throw checkException(t); } } public void setCursorName(String name) throws SQLException { checkState(); try { s.setCursorName(name); } catch (Throwable t) { throw checkException(t); } } public ResultSet getResultSet() throws SQLException { checkState(); try { ResultSet result = s.getResultSet(); if (result == null) { return null; } else { return registerResultSet(result); } } catch (Throwable t) { throw checkException(t); } } public int getUpdateCount() throws SQLException { checkState(); try { return s.getUpdateCount(); } catch (Throwable t) { throw checkException(t); } } public boolean getMoreResults() throws SQLException { checkState(); try { return s.getMoreResults(); } catch (Throwable t) { throw checkException(t); } } public boolean getMoreResults(int current) throws SQLException { checkState(); try { return s.getMoreResults(current); } catch (Throwable t) { throw checkException(t); } } public void setFetchDirection(int direction) throws SQLException { checkState(); try { s.setFetchDirection(direction); } catch (Throwable t) { throw checkException(t); } } public int getFetchDirection() throws SQLException { checkState(); try { return s.getFetchDirection(); } catch (Throwable t) { throw checkException(t); } } public void setFetchSize(int rows) throws SQLException { checkState(); try { s.setFetchSize(rows); } catch (Throwable t) { throw checkException(t); } } public int getFetchSize() throws SQLException { checkState(); try { return s.getFetchSize(); } catch (Throwable t) { throw checkException(t); } } public int getResultSetConcurrency() throws SQLException { checkState(); try { return s.getResultSetConcurrency(); } catch (Throwable t) { throw checkException(t); } } public int getResultSetType() throws SQLException { checkState(); try { return s.getResultSetType(); } catch (Throwable t) { throw checkException(t); } } /** * @see java.sql.Statement#addBatch(java.lang.String) */ public void addBatch(String sql) throws SQLException { // doSqlValve(sql); checkState(); try { s.addBatch(sql); } catch (Throwable t) { throw checkException(t); } finally { } } /** * @see java.sql.Statement#clearBatch() */ public void clearBatch() throws SQLException { checkState(); try { s.clearBatch(); } catch (Throwable t) { throw checkException(t); } } /** * @see java.sql.Statement#executeBatch() */ public int[] executeBatch() throws SQLException { checkState(); try { checkConfiguredQueryTimeout(); return s.executeBatch(); } catch (Throwable t) { throw checkException(t); } } public ResultSet getGeneratedKeys() throws SQLException { checkState(); try { ResultSet resultSet = s.getGeneratedKeys(); return registerResultSet(resultSet); } catch (Throwable t) { throw checkException(t); } } public int getResultSetHoldability() throws SQLException { checkState(); try { return s.getResultSetHoldability(); } catch (Throwable t) { throw checkException(t); } } public Statement getUnderlyingStatement() throws SQLException { checkState(); return s; } protected SQLException checkException(Throwable t) throws SQLException { throw lc.checkException(t); } protected void checkTransaction() throws SQLException { checkState(); lc.checkTransaction(); } protected void checkConfiguredQueryTimeout() throws SQLException { lc.checkConfiguredQueryTimeout(this); } protected void internalClose() throws SQLException { synchronized (lock) { closed = true; } try { closeResultSets(); } finally { s.close(); } } /** * * @throws SQLException */ void checkState() throws SQLException { synchronized (lock) { if (closed) { throw new SQLException("The statement is closed."); } } } /** * * @param resultSet * @return */ protected ResultSet registerResultSet(ResultSet resultSet) { if (resultSet != null) { resultSet = new WrappedResultSet(this, resultSet); } if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) { return resultSet; } synchronized (this) { if (resultSets == null) { resultSets = new HashMap(); } if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT) { resultSets.put(resultSet, new Throwable("STACKTRACE")); } else { resultSets.put(resultSet, null); } } return resultSet; } /** * * @param resultSet */ protected void unregisterResultSet(WrappedResultSet resultSet) { if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) { return; } synchronized (this) { if (resultSets != null) { resultSets.remove(resultSet); } } } /** * */ protected void closeResultSets() { if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) { return; } synchronized (this) { if (resultSets == null) { return; } for (Iterator i = resultSets.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); WrappedResultSet resultSet = (WrappedResultSet) entry.getKey(); if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT) { Throwable stackTrace = (Throwable) entry.getValue(); lc.getLogger() .warn("Closing a result set you left open! Please close it yourself.", stackTrace); } try { resultSet.internalClose(); } catch (Throwable t) { lc.getLogger().warn( "Error closing a result set you left open! Please close it yourself.", t); } } resultSets.clear(); } } // jdk 6 public boolean isClosed() throws SQLException { return closed; } public boolean isWrapperFor(Class<?> iface) throws SQLException { return iface.isInstance(s); } public <T> T unwrap(Class<T> iface) throws SQLException { return (T) (iface.isInstance(s) ? s : null); } public boolean isPoolable() throws SQLException { return false; } public void setPoolable(boolean poolable) throws SQLException { } protected String getDataSourceName() { return dataSourceName; } protected void setDataSourceName(String dataSourceName) { this.dataSourceName = dataSourceName; } }