/*
* 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;
}
}