/* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. See terms of license at gnu.org. * */ package org.jboss.resource.adapter.jdbc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Savepoint; import java.sql.Statement; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.jboss.logging.Logger; /** * A wrapper for a connection. * * @author David Jencks * @author Adrian Brock * @version $Revision: 1.7 $ */ public class WrappedConnection implements Connection { private static final Logger log = Logger.getLogger(WrappedConnection.class); private BaseWrapperManagedConnection mc; private HashMap statements; private boolean closed = false; private int trackStatements; public WrappedConnection(final BaseWrapperManagedConnection mc) { this.mc = mc; if (mc != null) trackStatements = mc.getTrackStatements(); } void setManagedConnection(final BaseWrapperManagedConnection mc) { this.mc = mc; if (mc != null) trackStatements = mc.getTrackStatements(); } // implementation of java.sql.Connection interface /** * @param param1 * @exception java.sql.SQLException */ public void setReadOnly(boolean readOnly) throws SQLException { checkStatus(); mc.setJdbcReadOnly(readOnly); } /** * @return * @exception java.sql.SQLException */ public boolean isReadOnly() throws SQLException { checkStatus(); return mc.isJdbcReadOnly(); } /** * @exception java.sql.SQLException */ public void close() throws SQLException { closed = true; if (mc != null) { if (trackStatements != BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) { synchronized (this) { if (statements != null) { for (Iterator i = statements.entrySet().iterator(); i.hasNext(); ) { Map.Entry entry = (Map.Entry) i.next(); WrappedStatement ws = (WrappedStatement) entry.getKey(); if (trackStatements == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT) { Throwable stackTrace = (Throwable) entry.getValue(); // JBOSSHACK avoid extra exception layer log.warn("Closing a statement you left open, please do your own housekeeping", stackTrace); } try { ws.internalClose(); } catch (Throwable t) { log.warn("Exception trying to close statement:", t); } } } } } mc.closeHandle(this); } // end of if () mc = null; } /** * @return * @exception java.sql.SQLException */ public boolean isClosed() throws SQLException { return closed; } /** * @return * @exception java.sql.SQLException */ public Statement createStatement() throws SQLException { checkTransaction(); try { return new WrappedStatement(this, mc.getConnection().createStatement()); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @param param2 * @return * @exception java.sql.SQLException */ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { checkTransaction(); try { return new WrappedStatement(this, mc.getConnection().createStatement(resultSetType, resultSetConcurrency)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @param param2 * @param param3 * @return * @exception java.sql.SQLException */ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { checkTransaction(); try { return new WrappedStatement(this, mc.getConnection() .createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @return * @exception java.sql.SQLException */ public PreparedStatement prepareStatement(String sql) throws SQLException { checkTransaction(); try { return new WrappedPreparedStatement(this, mc.prepareStatement(sql)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @param param2 * @param param3 * @return * @exception java.sql.SQLException */ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { checkTransaction(); try { return new WrappedPreparedStatement(this, mc.getConnection() .prepareStatement(sql, resultSetType, resultSetConcurrency)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @param param2 * @param param3 * @param param4 * @return * @exception java.sql.SQLException */ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { checkTransaction(); try { return new WrappedPreparedStatement(this, mc.getConnection() .prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @param param2 * @return * @exception java.sql.SQLException */ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { checkTransaction(); try { return new WrappedPreparedStatement(this, mc.getConnection().prepareStatement(sql, autoGeneratedKeys)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @param param2 * @return * @exception java.sql.SQLException */ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { checkTransaction(); try { return new WrappedPreparedStatement(this, mc.getConnection().prepareStatement(sql, columnIndexes)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @param param2 * @return * @exception java.sql.SQLException */ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { checkTransaction(); try { return new WrappedPreparedStatement(this, mc.getConnection().prepareStatement(sql, columnNames)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @return * @exception java.sql.SQLException */ public CallableStatement prepareCall(String sql) throws SQLException { checkTransaction(); try { return new WrappedCallableStatement(this, mc.getConnection().prepareCall(sql)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @param param2 * @param param3 * @return * @exception java.sql.SQLException */ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { checkTransaction(); try { return new WrappedCallableStatement(this, mc.getConnection() .prepareCall(sql, resultSetType, resultSetConcurrency)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @param param2 * @param param3 * @param param4 * @return * @exception java.sql.SQLException */ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { checkTransaction(); try { return new WrappedCallableStatement(this, mc.getConnection() .prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); } catch (SQLException e) { checkException(e); return null; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @return * @exception java.sql.SQLException */ public String nativeSQL(String sql) throws SQLException { checkTransaction(); try { return mc.getConnection().nativeSQL(sql); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @exception java.sql.SQLException */ public void setAutoCommit(boolean autocommit) throws SQLException { checkStatus(); mc.setJdbcAutoCommit(autocommit); } /** * @return * @exception java.sql.SQLException */ public boolean getAutoCommit() throws SQLException { checkStatus(); return mc.isJdbcAutoCommit(); } /** * @exception java.sql.SQLException */ public void commit() throws SQLException { checkTransaction(); mc.jdbcCommit(); } /** * @exception java.sql.SQLException */ public void rollback() throws SQLException { checkStatus(); mc.jdbcRollback(); } /** * @param param1 * @exception java.sql.SQLException */ public void rollback(Savepoint savepoint) throws SQLException { checkTransaction(); mc.jdbcRollback(savepoint); } /** * @return * @exception java.sql.SQLException */ public DatabaseMetaData getMetaData() throws SQLException { checkTransaction(); try { return mc.getConnection().getMetaData(); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @exception java.sql.SQLException */ public void setCatalog(String catalog) throws SQLException { checkTransaction(); try { mc.getConnection().setCatalog(catalog); } catch (SQLException e) { checkException(e); } // end of try-catch } /** * @return * @exception java.sql.SQLException */ public String getCatalog() throws SQLException { checkTransaction(); try { return mc.getConnection().getCatalog(); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @exception java.sql.SQLException @todo check we are not in * a managed transaction. */ public void setTransactionIsolation(int isolationLevel) throws SQLException { checkStatus(); mc.setJdbcTransactionIsolation(isolationLevel); } /** * @return * @exception java.sql.SQLException */ public int getTransactionIsolation() throws SQLException { checkStatus(); return mc.getJdbcTransactionIsolation(); } /** * @return * @exception java.sql.SQLException */ public SQLWarning getWarnings() throws SQLException { checkTransaction(); return mc.getConnection().getWarnings(); } /** * @exception java.sql.SQLException */ public void clearWarnings() throws SQLException { checkTransaction(); mc.getConnection().clearWarnings(); } /** * @return * @exception java.sql.SQLException */ public Map getTypeMap() throws SQLException { checkTransaction(); try { return mc.getConnection().getTypeMap(); } catch (SQLException e) { checkException(e); return null; } // end of try-catch } /** * @param param1 * @exception java.sql.SQLException */ public void setTypeMap(Map typeMap) throws SQLException { checkTransaction(); try { mc.getConnection().setTypeMap(typeMap); } catch (SQLException e) { checkException(e); } // end of try-catch } /** * @param param1 * @exception java.sql.SQLException */ public void setHoldability(int holdability) throws SQLException { checkTransaction(); try { mc.getConnection().setHoldability(holdability); } catch (SQLException e) { checkException(e); } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @return * @exception java.sql.SQLException */ public int getHoldability() throws SQLException { checkTransaction(); try { return mc.getConnection().getHoldability(); } catch (SQLException e) { checkException(e); throw e; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @return * @exception java.sql.SQLException */ public Savepoint setSavepoint() throws SQLException { checkTransaction(); try { return mc.getConnection().setSavepoint(); } catch (SQLException e) { checkException(e); throw e; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @return * @exception java.sql.SQLException */ public Savepoint setSavepoint(String name) throws SQLException { checkTransaction(); try { return mc.getConnection().setSavepoint(name); } catch (SQLException e) { checkException(e); throw e; } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } /** * @param param1 * @exception java.sql.SQLException */ public void releaseSavepoint(Savepoint savepoint) throws SQLException { checkTransaction(); try { mc.getConnection().releaseSavepoint(savepoint); } catch (SQLException e) { checkException(e); } // end of try-catch /* * throw new SQLException("JDK1.4 method not available in JDK1.3"); */ } //Public non-jdbc methods public Connection getUnderlyingConnection() throws SQLException { checkTransaction(); return mc.getConnection(); } //package methods void checkTransaction() throws SQLException { checkStatus(); mc.checkTransaction(); } //protected methods /** * The checkStatus method checks that the handle has not been closed and * that it is associated with a managed connection. * * @exception SQLException if an error occurs */ protected void checkStatus() throws SQLException { if (closed) { throw new SQLException("Connection handle has been closed and is unusable"); } // end of if () if (mc == null) { throw new SQLException("Connection handle is not currently associated with a ManagedConnection"); } // end of if () } /** * The base checkException method rethrows the supplied exception, informing * the ManagedConnection of the error. Subclasses may override this to * filter exceptions based on their severity. * * @param e a SQLException value * @exception Exception if an error occurs */ protected void checkException(SQLException e) throws SQLException { if (mc != null) { mc.connectionError(e); } // end of if () throw e; } int getTrackStatements() { return trackStatements; } void registerStatement(WrappedStatement ws) { if (trackStatements == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) return; synchronized (this) { if (statements == null) statements = new HashMap(); statements.put(ws, new Throwable("STACKTRACE")); // JBOSSHACK avoid extra exception layer } } void unregisterStatement(WrappedStatement ws) { if (trackStatements == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) return; synchronized (this) { if (statements != null) statements.remove(ws); } } Logger getLogger() { return log; } }