Taken from https://issues.apache.org/jira/browse/DBCP-191 Index: src/test/org/apache/commons/dbcp/TesterPreparedStatement.java =================================================================== --- src/test/org/apache/commons/dbcp/TesterPreparedStatement.java (revision 558600) +++ src/test/org/apache/commons/dbcp/TesterPreparedStatement.java (working copy) @@ -28,6 +28,13 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Calendar; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.io.InputStream; +import java.io.Reader; +import java.sql.NClob; +import java.sql.RowId; +import java.sql.SQLXML; +/* JDBC_4_ANT_KEY_END */ /** * A dummy {@link PreparedStatement}, for testing purposes. @@ -288,7 +295,79 @@ public java.sql.ParameterMetaData getParameterMetaData() throws SQLException { throw new SQLException("Not implemented."); } - /* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ + public void setRowId(int parameterIndex, RowId value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setNString(int parameterIndex, String value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setNClob(int parameterIndex, NClob value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setSQLXML(int parameterIndex, SQLXML value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setAsciiStream(int parameterIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setBinaryStream(int parameterIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setAsciiStream(int parameterIndex, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setBinaryStream(int parameterIndex, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setNCharacterStream(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setClob(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } +/* JDBC_4_ANT_KEY_END */ } Index: src/test/org/apache/commons/dbcp/TesterResultSet.java =================================================================== --- src/test/org/apache/commons/dbcp/TesterResultSet.java (revision 558600) +++ src/test/org/apache/commons/dbcp/TesterResultSet.java (working copy) @@ -28,6 +28,13 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.Calendar; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.io.InputStream; +import java.io.Reader; +import java.sql.NClob; +import java.sql.RowId; +import java.sql.SQLXML; +/* JDBC_4_ANT_KEY_END */ /** * A dummy {@link ResultSet}, for testing purposes. @@ -759,7 +766,207 @@ throws SQLException { throw new SQLException("Not implemented."); } - /* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ + public boolean isWrapperFor(Class<?> iface) throws SQLException { + throw new SQLException("Not implemented."); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + throw new SQLException("Not implemented."); + } + + public RowId getRowId(int columnIndex) throws SQLException { + throw new SQLException("Not implemented."); + } + + public RowId getRowId(String columnLabel) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateRowId(int columnIndex, RowId value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateRowId(String columnLabel, RowId value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public int getHoldability() throws SQLException { + throw new SQLException("Not implemented."); + } + + public boolean isClosed() throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNString(int columnIndex, String value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNString(String columnLabel, String value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNClob(int columnIndex, NClob value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNClob(String columnLabel, NClob value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public NClob getNClob(int columnIndex) throws SQLException { + throw new SQLException("Not implemented."); + } + + public NClob getNClob(String columnLabel) throws SQLException { + throw new SQLException("Not implemented."); + } + + public SQLXML getSQLXML(int columnIndex) throws SQLException { + throw new SQLException("Not implemented."); + } + + public SQLXML getSQLXML(String columnLabel) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateSQLXML(int columnIndex, SQLXML value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateSQLXML(String columnLabel, SQLXML value) throws SQLException { + throw new SQLException("Not implemented."); + } + + public String getNString(int columnIndex) throws SQLException { + throw new SQLException("Not implemented."); + } + + public String getNString(String columnLabel) throws SQLException { + throw new SQLException("Not implemented."); + } + + public Reader getNCharacterStream(int columnIndex) throws SQLException { + throw new SQLException("Not implemented."); + } + + public Reader getNCharacterStream(String columnLabel) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNCharacterStream(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateAsciiStream(int columnIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBinaryStream(int columnIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateCharacterStream(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateAsciiStream(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBinaryStream(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("Not implemented."); + } +/* JDBC_4_ANT_KEY_END */ } Index: src/test/org/apache/commons/dbcp/TesterConnection.java =================================================================== --- src/test/org/apache/commons/dbcp/TesterConnection.java (revision 558600) +++ src/test/org/apache/commons/dbcp/TesterConnection.java (working copy) @@ -25,6 +25,16 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.Map; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.NClob; +import java.sql.SQLClientInfoException; +import java.sql.SQLXML; +import java.sql.Struct; +import java.util.Properties; +/* JDBC_4_ANT_KEY_END */ /** * A dummy {@link Connection}, for testing purposes. @@ -274,6 +284,59 @@ throws SQLException { return prepareStatement(sql); } +/* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ -/* JDBC_3_ANT_KEY_END */ + public boolean isWrapperFor(Class<?> iface) throws SQLException { + throw new SQLException("Not implemented."); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + throw new SQLException("Not implemented."); + } + + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + throw new SQLException("Not implemented."); + } + + public Blob createBlob() throws SQLException { + throw new SQLException("Not implemented."); + } + + public Clob createClob() throws SQLException { + throw new SQLException("Not implemented."); + } + + public NClob createNClob() throws SQLException { + throw new SQLException("Not implemented."); + } + + public SQLXML createSQLXML() throws SQLException { + throw new SQLException("Not implemented."); + } + + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + throw new SQLException("Not implemented."); + } + + public boolean isValid(int timeout) throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setClientInfo(String name, String value) throws SQLClientInfoException { + throw new SQLClientInfoException(); + } + + public void setClientInfo(Properties properties) throws SQLClientInfoException { + throw new SQLClientInfoException(); + } + + public Properties getClientInfo() throws SQLException { + throw new SQLException("Not implemented."); + } + + public String getClientInfo(String name) throws SQLException { + throw new SQLException("Not implemented."); + } +/* JDBC_4_ANT_KEY_END */ } Index: src/test/org/apache/commons/dbcp/TesterStatement.java =================================================================== --- src/test/org/apache/commons/dbcp/TesterStatement.java (revision 558600) +++ src/test/org/apache/commons/dbcp/TesterStatement.java (working copy) @@ -268,5 +268,26 @@ throw new SQLException("Not implemented."); } /* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ + public boolean isWrapperFor(Class<?> iface) throws SQLException { + throw new SQLException("Not implemented."); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + throw new SQLException("Not implemented."); + } + + public boolean isClosed() throws SQLException { + throw new SQLException("Not implemented."); + } + + public void setPoolable(boolean poolable) throws SQLException { + throw new SQLException("Not implemented."); + } + + public boolean isPoolable() throws SQLException { + throw new SQLException("Not implemented."); + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java =================================================================== --- src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java (revision 558600) +++ src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java (working copy) @@ -32,6 +32,11 @@ import java.io.InputStream; import java.io.Reader; import java.sql.SQLException; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.sql.NClob; +import java.sql.RowId; +import java.sql.SQLXML; +/* JDBC_4_ANT_KEY_END */ /** * A base delegating implementation of {@link CallableStatement}. @@ -332,6 +337,337 @@ public URL getURL(String parameterName) throws SQLException { checkOpen(); try { return _stmt.getURL(parameterName); } catch (SQLException e) { handleException(e); return null; } } +/* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ -/* JDBC_3_ANT_KEY_END */ + public RowId getRowId(int parameterIndex) throws SQLException { + checkOpen(); + try { + return _stmt.getRowId(parameterIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public RowId getRowId(String parameterName) throws SQLException { + checkOpen(); + try { + return _stmt.getRowId(parameterName); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public void setRowId(String parameterName, RowId value) throws SQLException { + checkOpen(); + try { + _stmt.setRowId(parameterName, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNString(String parameterName, String value) throws SQLException { + checkOpen(); + try { + _stmt.setNString(parameterName, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNCharacterStream(String parameterName, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setNCharacterStream(parameterName, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNClob(String parameterName, NClob value) throws SQLException { + checkOpen(); + try { + _stmt.setNClob(parameterName, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setClob(String parameterName, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setClob(parameterName, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException { + checkOpen(); + try { + _stmt.setBlob(parameterName, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNClob(String parameterName, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setNClob(parameterName, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public NClob getNClob(int parameterIndex) throws SQLException { + checkOpen(); + try { + return _stmt.getNClob(parameterIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public NClob getNClob(String parameterName) throws SQLException { + checkOpen(); + try { + return _stmt.getNClob(parameterName); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public void setSQLXML(String parameterName, SQLXML value) throws SQLException { + checkOpen(); + try { + _stmt.setSQLXML(parameterName, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public SQLXML getSQLXML(int parameterIndex) throws SQLException { + checkOpen(); + try { + return _stmt.getSQLXML(parameterIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public SQLXML getSQLXML(String parameterName) throws SQLException { + checkOpen(); + try { + return _stmt.getSQLXML(parameterName); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public String getNString(int parameterIndex) throws SQLException { + checkOpen(); + try { + return _stmt.getNString(parameterIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public String getNString(String parameterName) throws SQLException { + checkOpen(); + try { + return _stmt.getNString(parameterName); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Reader getNCharacterStream(int parameterIndex) throws SQLException { + checkOpen(); + try { + return _stmt.getNCharacterStream(parameterIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Reader getNCharacterStream(String parameterName) throws SQLException { + checkOpen(); + try { + return _stmt.getNCharacterStream(parameterName); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Reader getCharacterStream(int parameterIndex) throws SQLException { + checkOpen(); + try { + return _stmt.getCharacterStream(parameterIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Reader getCharacterStream(String parameterName) throws SQLException { + checkOpen(); + try { + return _stmt.getCharacterStream(parameterName); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public void setBlob(String parameterName, Blob blob) throws SQLException { + checkOpen(); + try { + _stmt.setBlob(parameterName, blob); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setClob(String parameterName, Clob clob) throws SQLException { + checkOpen(); + try { + _stmt.setClob(parameterName, clob); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setAsciiStream(String parameterName, InputStream inputStream, long length) throws SQLException { + checkOpen(); + try { + _stmt.setAsciiStream(parameterName, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBinaryStream(String parameterName, InputStream inputStream, long length) throws SQLException { + checkOpen(); + try { + _stmt.setBinaryStream(parameterName, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setCharacterStream(parameterName, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setAsciiStream(String parameterName, InputStream inputStream) throws SQLException { + checkOpen(); + try { + _stmt.setAsciiStream(parameterName, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBinaryStream(String parameterName, InputStream inputStream) throws SQLException { + checkOpen(); + try { + _stmt.setBinaryStream(parameterName, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setCharacterStream(String parameterName, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setCharacterStream(parameterName, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNCharacterStream(String parameterName, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setNCharacterStream(parameterName, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setClob(String parameterName, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setClob(parameterName, reader); + } + catch (SQLException e) { + handleException(e); + } } + + public void setBlob(String parameterName, InputStream inputStream) throws SQLException { + checkOpen(); + try { + _stmt.setBlob(parameterName, inputStream); + } + catch (SQLException e) { + handleException(e); + } } + + public void setNClob(String parameterName, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setNClob(parameterName, reader); + } + catch (SQLException e) { + handleException(e); + } + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java =================================================================== --- src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java (revision 558600) +++ src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java (working copy) @@ -25,6 +25,19 @@ import java.sql.Statement; import java.sql.SQLWarning; import java.sql.SQLException; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.sql.Array; +import java.sql.Blob; +import java.sql.ClientInfoStatus; +import java.sql.Clob; +import java.sql.NClob; +import java.sql.SQLClientInfoException; +import java.sql.SQLXML; +import java.sql.Struct; +import java.util.Collections; +import java.util.Map; +import java.util.Properties; +/* JDBC_4_ANT_KEY_END */ /** * This class is the <code>Connection</code> that will be returned @@ -42,6 +55,11 @@ private static final String CLOSED = "Attempted to use Connection after closed() was called."; +/* JDBC_4_ANT_KEY_BEGIN */ + private static final Map<String, ClientInfoStatus> EMPTY_FAILED_PROPERTIES = + Collections.<String, ClientInfoStatus>emptyMap(); +/* JDBC_4_ANT_KEY_END */ + /** The JDBC database connection. */ private Connection connection; @@ -453,6 +471,86 @@ assertOpen(); return connection.prepareStatement(sql, columnNames); } +/* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ -/* JDBC_3_ANT_KEY_END */ + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return connection.isWrapperFor(iface); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + return connection.unwrap(iface); + } + + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + assertOpen(); + return connection.createArrayOf(typeName, elements); + } + + public Blob createBlob() throws SQLException { + assertOpen(); + return connection.createBlob(); + } + + public Clob createClob() throws SQLException { + assertOpen(); + return connection.createClob(); + } + + public NClob createNClob() throws SQLException { + assertOpen(); + return connection.createNClob(); + } + + public SQLXML createSQLXML() throws SQLException { + assertOpen(); + return connection.createSQLXML(); + } + + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + assertOpen(); + return connection.createStruct(typeName, attributes); + } + + public boolean isValid(int timeout) throws SQLException { + assertOpen(); + return connection.isValid(timeout); + } + + public void setClientInfo(String name, String value) throws SQLClientInfoException { + try { + assertOpen(); + connection.setClientInfo(name, value); + } + catch (SQLClientInfoException e) { + throw e; + } + catch (SQLException e) { + throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e); + } + } + + public void setClientInfo(Properties properties) throws SQLClientInfoException { + try { + assertOpen(); + connection.setClientInfo(properties); + } + catch (SQLClientInfoException e) { + throw e; + } + catch (SQLException e) { + throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e); + } + } + + public Properties getClientInfo() throws SQLException { + assertOpen(); + return connection.getClientInfo(); + } + + public String getClientInfo(String name) throws SQLException { + assertOpen(); + return connection.getClientInfo(name); + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/cpdsadapter/PooledConnectionImpl.java =================================================================== --- src/java/org/apache/commons/dbcp/cpdsadapter/PooledConnectionImpl.java (revision 558600) +++ src/java/org/apache/commons/dbcp/cpdsadapter/PooledConnectionImpl.java (working copy) @@ -26,6 +26,7 @@ import javax.sql.ConnectionEvent; import javax.sql.ConnectionEventListener; import javax.sql.PooledConnection; +import javax.sql.StatementEventListener; import org.apache.commons.dbcp.DelegatingConnection; import org.apache.commons.dbcp.DelegatingPreparedStatement; @@ -66,6 +67,11 @@ private Vector eventListeners; /** + * StatementEventListeners + */ + private Vector statementEventListeners; + + /** * flag set to true, once close() is called. */ boolean isClosed; @@ -101,6 +107,12 @@ } } + public void addStatementEventListener(StatementEventListener listener) { + if (!statementEventListeners.contains(listener)) { + statementEventListeners.add(listener); + } + } + /** * Closes the physical connection and marks this * <code>PooledConnection</code> so that it may not be used @@ -169,6 +181,10 @@ eventListeners.remove(listener); } + public void removeStatementEventListener(StatementEventListener listener) { + statementEventListeners.remove(listener); + } + /** * Closes the physical connection and checks that the logical connection * was closed as well. Index: src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java =================================================================== --- src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java (revision 558600) +++ src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java (working copy) @@ -27,6 +27,13 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Calendar; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.io.InputStream; +import java.io.Reader; +import java.sql.NClob; +import java.sql.RowId; +import java.sql.SQLXML; +/* JDBC_4_ANT_KEY_END */ /** * A base delegating implementation of {@link PreparedStatement}. @@ -221,6 +228,187 @@ public java.sql.ParameterMetaData getParameterMetaData() throws SQLException { checkOpen(); try { return _stmt.getParameterMetaData(); } catch (SQLException e) { handleException(e); return null; } } +/* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ -/* JDBC_3_ANT_KEY_END */ + public void setRowId(int parameterIndex, RowId value) throws SQLException { + checkOpen(); + try { + _stmt.setRowId(parameterIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNString(int parameterIndex, String value) throws SQLException { + checkOpen(); + try { + _stmt.setNString(parameterIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + checkOpen(); + try { + _stmt.setNCharacterStream(parameterIndex, value, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNClob(int parameterIndex, NClob value) throws SQLException { + checkOpen(); + try { + _stmt.setNClob(parameterIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setClob(parameterIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + checkOpen(); + try { + _stmt.setBlob(parameterIndex, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setNClob(parameterIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setSQLXML(int parameterIndex, SQLXML value) throws SQLException { + checkOpen(); + try { + _stmt.setSQLXML(parameterIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setAsciiStream(int parameterIndex, InputStream inputStream, long length) throws SQLException { + checkOpen(); + try { + _stmt.setAsciiStream(parameterIndex, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBinaryStream(int parameterIndex, InputStream inputStream, long length) throws SQLException { + checkOpen(); + try { + _stmt.setBinaryStream(parameterIndex, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + checkOpen(); + try { + _stmt.setCharacterStream(parameterIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setAsciiStream(int parameterIndex, InputStream inputStream) throws SQLException { + checkOpen(); + try { + _stmt.setAsciiStream(parameterIndex, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBinaryStream(int parameterIndex, InputStream inputStream) throws SQLException { + checkOpen(); + try { + _stmt.setBinaryStream(parameterIndex, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setCharacterStream(parameterIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNCharacterStream(int parameterIndex, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setNCharacterStream(parameterIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setClob(int parameterIndex, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setClob(parameterIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + checkOpen(); + try { + _stmt.setBlob(parameterIndex, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + checkOpen(); + try { + _stmt.setNClob(parameterIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/DelegatingResultSet.java =================================================================== --- src/java/org/apache/commons/dbcp/DelegatingResultSet.java (revision 558600) +++ src/java/org/apache/commons/dbcp/DelegatingResultSet.java (working copy) @@ -34,6 +34,11 @@ import java.sql.Clob; import java.sql.Array; import java.util.Calendar; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.sql.NClob; +import java.sql.RowId; +import java.sql.SQLXML; +/* JDBC_4_ANT_KEY_END */ /** * A base delegating implementation of {@link ResultSet}. @@ -585,6 +590,459 @@ public void updateArray(String columnName, java.sql.Array x) throws SQLException { try { _res.updateArray(columnName, x); } catch (SQLException e) { handleException(e); } } +/* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ -/* JDBC_3_ANT_KEY_END */ + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return _res.isWrapperFor(iface); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + return _res.unwrap(iface); + } + + public RowId getRowId(int columnIndex) throws SQLException { + try { + return _res.getRowId(columnIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public RowId getRowId(String columnLabel) throws SQLException { + try { + return _res.getRowId(columnLabel); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public void updateRowId(int columnIndex, RowId value) throws SQLException { + try { + _res.updateRowId(columnIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateRowId(String columnLabel, RowId value) throws SQLException { + try { + _res.updateRowId(columnLabel, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public int getHoldability() throws SQLException { + try { + return _res.getHoldability(); + } + catch (SQLException e) { + handleException(e); + return 0; + } + } + + public boolean isClosed() throws SQLException { + try { + return _res.isClosed(); + } + catch (SQLException e) { + handleException(e); + return false; + } + } + + public void updateNString(int columnIndex, String value) throws SQLException { + try { + _res.updateNString(columnIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNString(String columnLabel, String value) throws SQLException { + try { + _res.updateNString(columnLabel, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNClob(int columnIndex, NClob value) throws SQLException { + try { + _res.updateNClob(columnIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNClob(String columnLabel, NClob value) throws SQLException { + try { + _res.updateNClob(columnLabel, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public NClob getNClob(int columnIndex) throws SQLException { + try { + return _res.getNClob(columnIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public NClob getNClob(String columnLabel) throws SQLException { + try { + return _res.getNClob(columnLabel); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public SQLXML getSQLXML(int columnIndex) throws SQLException { + try { + return _res.getSQLXML(columnIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public SQLXML getSQLXML(String columnLabel) throws SQLException { + try { + return _res.getSQLXML(columnLabel); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public void updateSQLXML(int columnIndex, SQLXML value) throws SQLException { + try { + _res.updateSQLXML(columnIndex, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateSQLXML(String columnLabel, SQLXML value) throws SQLException { + try { + _res.updateSQLXML(columnLabel, value); + } + catch (SQLException e) { + handleException(e); + } + } + + public String getNString(int columnIndex) throws SQLException { + try { + return _res.getNString(columnIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public String getNString(String columnLabel) throws SQLException { + try { + return _res.getNString(columnLabel); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Reader getNCharacterStream(int columnIndex) throws SQLException { + try { + return _res.getNCharacterStream(columnIndex); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Reader getNCharacterStream(String columnLabel) throws SQLException { + try { + return _res.getNCharacterStream(columnLabel); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public void updateNCharacterStream(int columnIndex, Reader reader, long length) throws SQLException { + try { + _res.updateNCharacterStream(columnIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + try { + _res.updateNCharacterStream(columnLabel, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateAsciiStream(int columnIndex, InputStream inputStream, long length) throws SQLException { + try { + _res.updateAsciiStream(columnIndex, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBinaryStream(int columnIndex, InputStream inputStream, long length) throws SQLException { + try { + _res.updateBinaryStream(columnIndex, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateCharacterStream(int columnIndex, Reader reader, long length) throws SQLException { + try { + _res.updateCharacterStream(columnIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateAsciiStream(String columnLabel, InputStream inputStream, long length) throws SQLException { + try { + _res.updateAsciiStream(columnLabel, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBinaryStream(String columnLabel, InputStream inputStream, long length) throws SQLException { + try { + _res.updateBinaryStream(columnLabel, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + try { + _res.updateCharacterStream(columnLabel, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + try { + _res.updateBlob(columnIndex, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + try { + _res.updateBlob(columnLabel, inputStream, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + try { + _res.updateClob(columnIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + try { + _res.updateClob(columnLabel, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + try { + _res.updateNClob(columnIndex, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + try { + _res.updateNClob(columnLabel, reader, length); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException { + try { + _res.updateNCharacterStream(columnIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + try { + _res.updateNCharacterStream(columnLabel, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException { + try { + _res.updateAsciiStream(columnIndex, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException { + try { + _res.updateBinaryStream(columnIndex, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException { + try { + _res.updateCharacterStream(columnIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException { + try { + _res.updateAsciiStream(columnLabel, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException { + try { + _res.updateBinaryStream(columnLabel, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + try { + _res.updateCharacterStream(columnLabel, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + try { + _res.updateBlob(columnIndex, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + try { + _res.updateBlob(columnLabel, inputStream); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateClob(int columnIndex, Reader reader) throws SQLException { + try { + _res.updateClob(columnIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateClob(String columnLabel, Reader reader) throws SQLException { + try { + _res.updateClob(columnLabel, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + try { + _res.updateNClob(columnIndex, reader); + } + catch (SQLException e) { + handleException(e); + } + } + + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + try { + _res.updateNClob(columnLabel, reader); + } + catch (SQLException e) { + handleException(e); + } + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/PoolingDataSource.java =================================================================== --- src/java/org/apache/commons/dbcp/PoolingDataSource.java (revision 558600) +++ src/java/org/apache/commons/dbcp/PoolingDataSource.java (working copy) @@ -84,6 +84,14 @@ public void setAccessToUnderlyingConnectionAllowed(boolean allow) { this.accessToUnderlyingConnectionAllowed = allow; } + + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return false; + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + throw new SQLException("PoolingDataSource is not a wrapper."); + } //--- DataSource methods ----------------------------------------- Index: src/java/org/apache/commons/dbcp/DelegatingConnection.java =================================================================== --- src/java/org/apache/commons/dbcp/DelegatingConnection.java (revision 558600) +++ src/java/org/apache/commons/dbcp/DelegatingConnection.java (working copy) @@ -26,6 +26,19 @@ import java.sql.Statement; import java.util.List; import java.util.Map; +/* JDBC_4_ANT_KEY_BEGIN */ +import java.sql.Array; +import java.sql.Blob; +import java.sql.ClientInfoStatus; +import java.sql.Clob; +import java.sql.NClob; +import java.sql.SQLClientInfoException; +import java.sql.SQLXML; +import java.sql.Struct; +import java.util.Collections; +import java.util.Map; +import java.util.Properties; +/* JDBC_4_ANT_KEY_END */ /** * A base delegating implementation of {@link Connection}. @@ -50,6 +63,10 @@ */ public class DelegatingConnection extends AbandonedTrace implements Connection { +/* JDBC_4_ANT_KEY_BEGIN */ + private static final Map<String, ClientInfoStatus> EMPTY_FAILED_PROPERTIES = + Collections.<String, ClientInfoStatus>emptyMap(); +/* JDBC_4_ANT_KEY_END */ /** My delegate {@link Connection}. */ protected Connection _conn = null; @@ -495,4 +512,139 @@ } } /* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ + + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return _conn.isWrapperFor(iface); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + return _conn.unwrap(iface); + } + + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + checkOpen(); + try { + return _conn.createArrayOf(typeName, elements); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Blob createBlob() throws SQLException { + checkOpen(); + try { + return _conn.createBlob(); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Clob createClob() throws SQLException { + checkOpen(); + try { + return _conn.createClob(); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public NClob createNClob() throws SQLException { + checkOpen(); + try { + return _conn.createNClob(); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public SQLXML createSQLXML() throws SQLException { + checkOpen(); + try { + return _conn.createSQLXML(); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + checkOpen(); + try { + return _conn.createStruct(typeName, attributes); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public boolean isValid(int timeout) throws SQLException { + checkOpen(); + try { + return _conn.isValid(timeout); + } + catch (SQLException e) { + handleException(e); + return false; + } + } + + public void setClientInfo(String name, String value) throws SQLClientInfoException { + try { + checkOpen(); + _conn.setClientInfo(name, value); + } + catch (SQLClientInfoException e) { + throw e; + } + catch (SQLException e) { + throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e); + } + } + + public void setClientInfo(Properties properties) throws SQLClientInfoException { + try { + checkOpen(); + _conn.setClientInfo(properties); + } + catch (SQLClientInfoException e) { + throw e; + } + catch (SQLException e) { + throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e); + } + } + + public Properties getClientInfo() throws SQLException { + checkOpen(); + try { + return _conn.getClientInfo(); + } + catch (SQLException e) { + handleException(e); + return null; + } + } + + public String getClientInfo(String name) throws SQLException { + checkOpen(); + try { + return _conn.getClientInfo(name); + } + catch (SQLException e) { + handleException(e); + return null; + } + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/DelegatingStatement.java =================================================================== --- src/java/org/apache/commons/dbcp/DelegatingStatement.java (revision 558600) +++ src/java/org/apache/commons/dbcp/DelegatingStatement.java (working copy) @@ -128,10 +128,6 @@ protected boolean _closed = false; - protected boolean isClosed() { - return _closed; - } - protected void checkOpen() throws SQLException { if(isClosed()) { throw new SQLException @@ -346,4 +342,39 @@ { checkOpen(); try { return _stmt.getResultSetHoldability(); } catch (SQLException e) { handleException(e); return 0; } } /* JDBC_3_ANT_KEY_END */ +/* JDBC_4_ANT_KEY_BEGIN */ + + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return _conn.isWrapperFor(iface); + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + return _conn.unwrap(iface); + } + + public boolean isClosed() throws SQLException { + return _closed; + } + + public void setPoolable(boolean poolable) throws SQLException { + checkOpen(); + try { + _stmt.setPoolable(poolable); + } + catch (SQLException e) { + handleException(e); + } + } + + public boolean isPoolable() throws SQLException { + checkOpen(); + try { + return _stmt.isPoolable(); + } + catch (SQLException e) { + handleException(e); + return false; + } + } +/* JDBC_4_ANT_KEY_END */ } Index: src/java/org/apache/commons/dbcp/BasicDataSource.java =================================================================== --- src/java/org/apache/commons/dbcp/BasicDataSource.java (revision 558600) +++ src/java/org/apache/commons/dbcp/BasicDataSource.java (working copy) @@ -1115,7 +1115,14 @@ } } + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return false; + } + public <T> T unwrap(Class<T> iface) throws SQLException { + throw new SQLException("BasicDataSource is not a wrapper."); + } + // ------------------------------------------------------ Protected Methods Index: src/java/org/apache/commons/dbcp/datasources/InstanceKeyDataSource.java =================================================================== --- src/java/org/apache/commons/dbcp/datasources/InstanceKeyDataSource.java (revision 558600) +++ src/java/org/apache/commons/dbcp/datasources/InstanceKeyDataSource.java (working copy) @@ -154,6 +154,14 @@ */ public abstract void close() throws Exception; + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return false; + } + + public <T> T unwrap(Class<T> iface) throws SQLException { + throw new SQLException("InstanceKeyDataSource is not a wrapper."); + } + // ------------------------------------------------------------------- // Properties Index: project.properties =================================================================== --- project.properties (revision 558600) +++ project.properties (working copy) @@ -30,8 +30,8 @@ maven.xdoc.developmentProcessUrl=http://jakarta.apache.org/commons/charter.html # JDK level -maven.compile.source=1.3 -maven.compile.target=1.3 +maven.compile.source=1.6 +maven.compile.target=1.6 # Merge in a file containing just Built-By attribute maven.jar.manifest=${basedir}/manifestMods.txt