Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java?rev=1833804&r1=1833803&r2=1833804&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java Tue Jun 19 10:30:31 2018 @@ -31,58 +31,79 @@ import org.apache.tomcat.dbcp.pool2.impl /** * A {@link DelegatingConnection} that pools {@link PreparedStatement}s. * <p> - * The {@link #prepareStatement} and {@link #prepareCall} methods, rather than - * creating a new PreparedStatement each time, may actually pull the statement - * from a pool of unused statements. - * The {@link PreparedStatement#close} method of the returned statement doesn't - * actually close the statement, but rather returns it to the pool. - * (See {@link PoolablePreparedStatement}, {@link PoolableCallableStatement}.) - * + * The {@link #prepareStatement} and {@link #prepareCall} methods, rather than creating a new PreparedStatement each + * time, may actually pull the statement from a pool of unused statements. The {@link PreparedStatement#close} method of + * the returned statement doesn't actually close the statement, but rather returns it to the pool. (See + * {@link PoolablePreparedStatement}, {@link PoolableCallableStatement}.) + * </p> * * @see PoolablePreparedStatement - * @author Rodney Waldhoff - * @author Dirk Verbeeck * @since 2.0 */ public class PoolingConnection extends DelegatingConnection<Connection> - implements KeyedPooledObjectFactory<PStmtKey,DelegatingPreparedStatement> { + implements KeyedPooledObjectFactory<PStmtKey, DelegatingPreparedStatement> { /** - * Pool of {@link PreparedStatement}s. and {@link CallableStatement}s + * Statement types. + * + * @since 2.0 protected enum. + * @since 2.4.0 public enum. */ - private KeyedObjectPool<PStmtKey,DelegatingPreparedStatement> _pstmtPool = null; + public enum StatementType { + + /** + * Callable statement. + */ + CALLABLE_STATEMENT, + + /** + * Prepared statement. + */ + PREPARED_STATEMENT + } + + /** Pool of {@link PreparedStatement}s. and {@link CallableStatement}s */ + private KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pstmtPool; /** * Constructor. - * @param c the underlying {@link Connection}. + * + * @param connection + * the underlying {@link Connection}. */ - public PoolingConnection(final Connection c) { - super(c); + public PoolingConnection(final Connection connection) { + super(connection); } - - public void setStatementPool( - final KeyedObjectPool<PStmtKey,DelegatingPreparedStatement> pool) { - _pstmtPool = pool; + /** + * {@link KeyedPooledObjectFactory} method for activating pooled statements. + * + * @param key + * ignored + * @param pooledObject + * wrapped pooled statement to be activated + */ + @Override + public void activateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) + throws Exception { + pooledObject.getObject().activate(); } - /** - * Close and free all {@link PreparedStatement}s or - * {@link CallableStatement}s from the pool, and close the underlying - * connection. + * Closes and frees all {@link PreparedStatement}s or {@link CallableStatement}s from the pool, and close the + * underlying connection. */ @Override public synchronized void close() throws SQLException { try { - if (null != _pstmtPool) { - final KeyedObjectPool<PStmtKey,DelegatingPreparedStatement> oldpool = _pstmtPool; - _pstmtPool = null; + if (null != pstmtPool) { + final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> oldpool = pstmtPool; + pstmtPool = null; try { oldpool.close(); - } catch(final RuntimeException e) { + } catch (final RuntimeException e) { throw e; - } catch(final Exception e) { + } catch (final Exception e) { throw new SQLException("Cannot close connection", e); } } @@ -96,348 +117,166 @@ public class PoolingConnection extends D } /** - * Create or obtain a {@link PreparedStatement} from the pool. - * @param sql the sql string used to define the PreparedStatement - * @return a {@link PoolablePreparedStatement} - */ - @Override - public PreparedStatement prepareStatement(final String sql) throws SQLException { - if (null == _pstmtPool) { - throw new SQLException( - "Statement pool is null - closed or invalid PoolingConnection."); - } - try { - return _pstmtPool.borrowObject(createKey(sql)); - } catch(final NoSuchElementException e) { - throw new SQLException("MaxOpenPreparedStatements limit reached", e); - } catch(final RuntimeException e) { - throw e; - } catch(final Exception e) { - throw new SQLException("Borrow prepareStatement from pool failed", e); - } - } - - @Override - public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException { - if (null == _pstmtPool) { - throw new SQLException( - "Statement pool is null - closed or invalid PoolingConnection."); - } - try { - return _pstmtPool.borrowObject(createKey(sql, autoGeneratedKeys)); - } - catch (final NoSuchElementException e) { - throw new SQLException("MaxOpenPreparedStatements limit reached", e); - } - catch (final RuntimeException e) { - throw e; - } - catch (final Exception e) { - throw new SQLException("Borrow prepareStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link PreparedStatement} from the pool. - * @param sql the sql string used to define the PreparedStatement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @return a {@link PoolablePreparedStatement} - * @throws SQLException An error occurred - */ - @Override - public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { - if (null == _pstmtPool) { - throw new SQLException( - "Statement pool is null - closed or invalid PoolingConnection."); - } - try { - return _pstmtPool.borrowObject(createKey(sql,resultSetType,resultSetConcurrency)); - } catch(final NoSuchElementException e) { - throw new SQLException("MaxOpenPreparedStatements limit reached", e); - } catch(final RuntimeException e) { - throw e; - } catch(final Exception e) { - throw new SQLException("Borrow prepareStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link CallableStatement} from the pool. - * @param sql the sql string used to define the CallableStatement - * @return a {@link PoolableCallableStatement} - * @throws SQLException An error occurred - */ - @Override - public CallableStatement prepareCall(final String sql) throws SQLException { - try { - return (CallableStatement) _pstmtPool.borrowObject(createKey(sql, StatementType.CALLABLE_STATEMENT)); - } catch (final NoSuchElementException e) { - throw new SQLException("MaxOpenCallableStatements limit reached", e); - } catch (final RuntimeException e) { - throw e; - } catch (final Exception e) { - throw new SQLException("Borrow callableStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link CallableStatement} from the pool. - * @param sql the sql string used to define the CallableStatement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @return a {@link PoolableCallableStatement} - * @throws SQLException An error occurred - */ - @Override - public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { - try { - return (CallableStatement) _pstmtPool.borrowObject(createKey(sql, resultSetType, - resultSetConcurrency, StatementType.CALLABLE_STATEMENT)); - } catch (final NoSuchElementException e) { - throw new SQLException("MaxOpenCallableStatements limit reached", e); - } catch (final RuntimeException e) { - throw e; - } catch (final Exception e) { - throw new SQLException("Borrow callableStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link PreparedStatement} from the pool. - * @param sql the sql string used to define the PreparedStatement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @param resultSetHoldability result set holdability - * @return a {@link PoolablePreparedStatement} - */ - @Override - public PreparedStatement prepareStatement(final String sql, final int resultSetType, - final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { - if (null == _pstmtPool) { - throw new SQLException( - "Statement pool is null - closed or invalid PoolingConnection."); - } - try { - return _pstmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); - } catch(final NoSuchElementException e) { - throw new SQLException("MaxOpenPreparedStatements limit reached", e); - } catch(final RuntimeException e) { - throw e; - } catch(final Exception e) { - throw new SQLException("Borrow prepareStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link PreparedStatement} from the pool. - * @param sql the sql string used to define the PreparedStatement - * @param columnIndexes column indexes - * @return a {@link PoolablePreparedStatement} - */ - @Override - public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) - throws SQLException { - if (null == _pstmtPool) { - throw new SQLException( - "Statement pool is null - closed or invalid PoolingConnection."); - } - try { - return _pstmtPool.borrowObject(createKey(sql, columnIndexes)); - } catch(final NoSuchElementException e) { - throw new SQLException("MaxOpenPreparedStatements limit reached", e); - } catch(final RuntimeException e) { - throw e; - } catch(final Exception e) { - throw new SQLException("Borrow prepareStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link PreparedStatement} from the pool. - * @param sql the sql string used to define the PreparedStatement - * @param columnNames column names - * @return a {@link PoolablePreparedStatement} - */ - @Override - public PreparedStatement prepareStatement(final String sql, final String columnNames[]) - throws SQLException { - if (null == _pstmtPool) { - throw new SQLException( - "Statement pool is null - closed or invalid PoolingConnection."); - } - try { - return _pstmtPool.borrowObject(createKey(sql, columnNames)); - } catch(final NoSuchElementException e) { - throw new SQLException("MaxOpenPreparedStatements limit reached", e); - } catch(final RuntimeException e) { - throw e; - } catch(final Exception e) { - throw new SQLException("Borrow prepareStatement from pool failed", e); - } - } - - /** - * Create or obtain a {@link CallableStatement} from the pool. - * @param sql the sql string used to define the CallableStatement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @param resultSetHoldability result set holdability - * @return a {@link PoolableCallableStatement} - * @throws SQLException if a {@link CallableStatement} cannot be obtained - * from the pool + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement */ - @Override - public CallableStatement prepareCall(final String sql, final int resultSetType, - final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { - try { - return (CallableStatement) _pstmtPool.borrowObject(createKey(sql, resultSetType, - resultSetConcurrency, resultSetHoldability, StatementType.CALLABLE_STATEMENT)); - } catch (final NoSuchElementException e) { - throw new SQLException("MaxOpenCallableStatements limit reached", e); - } catch (final RuntimeException e) { - throw e; - } catch (final Exception e) { - throw new SQLException("Borrow callableStatement from pool failed", e); - } - } - - protected PStmtKey createKey(final String sql, final int autoGeneratedKeys) { + protected PStmtKey createKey(final String sql) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, autoGeneratedKeys); + return new PStmtKey(normalizeSQL(sql), catalog); } - /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @return the key - */ - protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency) { + protected PStmtKey createKey(final String sql, final int autoGeneratedKeys) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency); + return new PStmtKey(normalizeSQL(sql), catalog, autoGeneratedKeys); } /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @param stmtType statement type - * @return the key + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param columnIndexes + * column indexes */ - protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, final StatementType stmtType) { + protected PStmtKey createKey(final String sql, final int columnIndexes[]) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, stmtType); + return new PStmtKey(normalizeSQL(sql), catalog, columnIndexes); } /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @return the key + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency */ - protected PStmtKey createKey(final String sql) { + protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog); + return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency); } /** - * Create a PStmtKey for the given arguments. - * @param sql the SQL string used to define the statement - * @param stmtType statement type - * @return the key + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @param resultSetHoldability + * result set holdability */ - protected PStmtKey createKey(final String sql, final StatementType stmtType) { + protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, stmtType, null); + return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, resultSetHoldability); } /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @param resultSetHoldability result set holdability - * @return a newly created key for the given arguments + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @param resultSetHoldability + * result set holdability + * @param stmtType + * statement type */ protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, - final int resultSetHoldability) { + final int resultSetHoldability, final StatementType stmtType) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, resultSetHoldability); + return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, resultSetHoldability, + stmtType); } /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @param resultSetType result set type - * @param resultSetConcurrency result set concurrency - * @param resultSetHoldability result set holdability - * @param stmtType statement type - * @return a newly created key for the given arguments + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @param stmtType + * statement type */ protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, - final int resultSetHoldability, final StatementType stmtType) { + final StatementType stmtType) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, resultSetHoldability, stmtType); + return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, stmtType); } /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @param columnIndexes column indexes - * @return a newly created key for the given arguments + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param stmtType + * statement type */ - protected PStmtKey createKey(final String sql, final int columnIndexes[]) { + protected PStmtKey createKey(final String sql, final StatementType stmtType) { String catalog = null; try { catalog = getCatalog(); } catch (final SQLException e) { // Ignored } - return new PStmtKey(normalizeSQL(sql), catalog, columnIndexes); + return new PStmtKey(normalizeSQL(sql), catalog, stmtType, null); } /** - * Create a PStmtKey for the given arguments. - * @param sql the sql string used to define the statement - * @param columnNames column names - * @return a newly created key for the given arguments + * Creates a PStmtKey for the given arguments. + * + * @param sql + * the SQL string used to define the statement + * @param columnNames + * column names */ protected PStmtKey createKey(final String sql, final String columnNames[]) { String catalog = null; @@ -450,119 +289,327 @@ public class PoolingConnection extends D } /** - * Normalize the given SQL statement, producing a - * canonical form that is semantically equivalent to the original. - * @param sql The SQL statement - * @return the trimmed SQL statement + * {@link KeyedPooledObjectFactory} method for destroying PoolablePreparedStatements and PoolableCallableStatements. + * Closes the underlying statement. + * + * @param key + * ignored + * @param pooledObject + * the wrapped pooled statement to be destroyed. */ - protected String normalizeSQL(final String sql) { - return sql.trim(); + @Override + public void destroyObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) + throws Exception { + pooledObject.getObject().getInnermostDelegate().close(); } /** - * {@link KeyedPooledObjectFactory} method for creating - * {@link PoolablePreparedStatement}s or {@link PoolableCallableStatement}s. - * The <code>stmtType</code> field in the key determines whether - * a PoolablePreparedStatement or PoolableCallableStatement is created. - * - * @param key the key for the {@link PreparedStatement} to be created - * @return the object - * @throws Exception An error occurred + * {@link KeyedPooledObjectFactory} method for creating {@link PoolablePreparedStatement}s or + * {@link PoolableCallableStatement}s. The <code>stmtType</code> field in the key determines whether a + * PoolablePreparedStatement or PoolableCallableStatement is created. + * + * @param key + * the key for the {@link PreparedStatement} to be created * @see #createKey(String, int, int, StatementType) */ + @SuppressWarnings("resource") @Override - public PooledObject<DelegatingPreparedStatement> makeObject(final PStmtKey key) - throws Exception { - if(null == key) { + public PooledObject<DelegatingPreparedStatement> makeObject(final PStmtKey key) throws Exception { + if (null == key) { throw new IllegalArgumentException("Prepared statement key is null or invalid."); } - if (key.getStmtType() == StatementType.PREPARED_STATEMENT ) { + if (key.getStmtType() == StatementType.PREPARED_STATEMENT) { final PreparedStatement statement = (PreparedStatement) key.createStatement(getDelegate()); - @SuppressWarnings({"rawtypes", "unchecked"}) // Unable to find way to avoid this - final - PoolablePreparedStatement pps = new PoolablePreparedStatement(statement, key, _pstmtPool, this); + @SuppressWarnings({"rawtypes", "unchecked" }) // Unable to find way to avoid this + final PoolablePreparedStatement pps = new PoolablePreparedStatement(statement, key, pstmtPool, this); return new DefaultPooledObject<DelegatingPreparedStatement>(pps); } final CallableStatement statement = (CallableStatement) key.createStatement(getDelegate()); - final PoolableCallableStatement pcs = new PoolableCallableStatement(statement, key, _pstmtPool, this); + final PoolableCallableStatement pcs = new PoolableCallableStatement(statement, key, pstmtPool, this); return new DefaultPooledObject<DelegatingPreparedStatement>(pcs); } /** - * {@link KeyedPooledObjectFactory} method for destroying - * PoolablePreparedStatements and PoolableCallableStatements. - * Closes the underlying statement. + * Normalizes the given SQL statement, producing a canonical form that is semantically equivalent to the original. + */ + protected String normalizeSQL(final String sql) { + return sql.trim(); + } + + /** + * {@link KeyedPooledObjectFactory} method for passivating {@link PreparedStatement}s or {@link CallableStatement}s. + * Invokes {@link PreparedStatement#clearParameters}. * - * @param key ignored - * @param p the wrapped pooled statement to be destroyed. - * @throws Exception An error occurred + * @param key + * ignored + * @param pooledObject + * a wrapped {@link PreparedStatement} */ @Override - public void destroyObject(final PStmtKey key, - final PooledObject<DelegatingPreparedStatement> p) + public void passivateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) throws Exception { - p.getObject().getInnermostDelegate().close(); + @SuppressWarnings("resource") + final DelegatingPreparedStatement dps = pooledObject.getObject(); + dps.clearParameters(); + dps.passivate(); } /** - * {@link KeyedPooledObjectFactory} method for validating - * pooled statements. Currently always returns true. + * Creates or obtains a {@link CallableStatement} from the pool. * - * @param key ignored - * @param p ignored - * @return {@code true} + * @param sql + * the SQL string used to define the CallableStatement + * @return a {@link PoolableCallableStatement} + * @throws SQLException + * Wraps an underlying exception. */ @Override - public boolean validateObject(final PStmtKey key, - final PooledObject<DelegatingPreparedStatement> p) { - return true; + public CallableStatement prepareCall(final String sql) throws SQLException { + try { + return (CallableStatement) pstmtPool.borrowObject(createKey(sql, StatementType.CALLABLE_STATEMENT)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenCallableStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow callableStatement from pool failed", e); + } } /** - * {@link KeyedPooledObjectFactory} method for activating - * pooled statements. + * Creates or obtains a {@link CallableStatement} from the pool. * - * @param key ignored - * @param p wrapped pooled statement to be activated - * @throws Exception An error occurred + * @param sql + * the SQL string used to define the CallableStatement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @return a {@link PoolableCallableStatement} + * @throws SQLException + * Wraps an underlying exception. */ @Override - public void activateObject(final PStmtKey key, - final PooledObject<DelegatingPreparedStatement> p) throws Exception { - p.getObject().activate(); + public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) + throws SQLException { + try { + return (CallableStatement) pstmtPool.borrowObject( + createKey(sql, resultSetType, resultSetConcurrency, StatementType.CALLABLE_STATEMENT)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenCallableStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow callableStatement from pool failed", e); + } } /** - * {@link KeyedPooledObjectFactory} method for passivating - * {@link PreparedStatement}s or {@link CallableStatement}s. - * Invokes {@link PreparedStatement#clearParameters}. + * Creates or obtains a {@link CallableStatement} from the pool. * - * @param key ignored - * @param p a wrapped {@link PreparedStatement} - * @throws Exception An error occurred + * @param sql + * the SQL string used to define the CallableStatement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @param resultSetHoldability + * result set holdability + * @return a {@link PoolableCallableStatement} + * @throws SQLException + * Wraps an underlying exception. */ @Override - public void passivateObject(final PStmtKey key, - final PooledObject<DelegatingPreparedStatement> p) throws Exception { - final DelegatingPreparedStatement dps = p.getObject(); - dps.clearParameters(); - dps.passivate(); + public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) throws SQLException { + try { + return (CallableStatement) pstmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency, + resultSetHoldability, StatementType.CALLABLE_STATEMENT)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenCallableStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow callableStatement from pool failed", e); + } + } + + /** + * Creates or obtains a {@link PreparedStatement} from the pool. + * + * @param sql + * the SQL string used to define the PreparedStatement + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql) throws SQLException { + if (null == pstmtPool) { + throw new SQLException("Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return pstmtPool.borrowObject(createKey(sql)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + @Override + public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException { + if (null == pstmtPool) { + throw new SQLException("Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return pstmtPool.borrowObject(createKey(sql, autoGeneratedKeys)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + /** + * Creates or obtains a {@link PreparedStatement} from the pool. + * + * @param sql + * the SQL string used to define the PreparedStatement + * @param columnIndexes + * column indexes + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException { + if (null == pstmtPool) { + throw new SQLException("Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return pstmtPool.borrowObject(createKey(sql, columnIndexes)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + /** + * Creates or obtains a {@link PreparedStatement} from the pool. + * + * @param sql + * the SQL string used to define the PreparedStatement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) + throws SQLException { + if (null == pstmtPool) { + throw new SQLException("Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return pstmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + /** + * Creates or obtains a {@link PreparedStatement} from the pool. + * + * @param sql + * the SQL string used to define the PreparedStatement + * @param resultSetType + * result set type + * @param resultSetConcurrency + * result set concurrency + * @param resultSetHoldability + * result set holdability + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) throws SQLException { + if (null == pstmtPool) { + throw new SQLException("Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return pstmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + /** + * Creates or obtains a {@link PreparedStatement} from the pool. + * + * @param sql + * the SQL string used to define the PreparedStatement + * @param columnNames + * column names + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException { + if (null == pstmtPool) { + throw new SQLException("Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return pstmtPool.borrowObject(createKey(sql, columnNames)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + /** + * Sets the prepared statement pool. + * + * @param pool + * the prepared statement pool. + */ + public void setStatementPool(final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pool) { + pstmtPool = pool; } @Override public String toString() { - if (_pstmtPool != null ) { - return "PoolingConnection: " + _pstmtPool.toString(); + if (pstmtPool != null) { + return "PoolingConnection: " + pstmtPool.toString(); } return "PoolingConnection: null"; } /** - * The possible statement types. - * @since 2.0 + * {@link KeyedPooledObjectFactory} method for validating pooled statements. Currently always returns true. + * + * @param key + * ignored + * @param pooledObject + * ignored + * @return {@code true} */ - protected enum StatementType { - CALLABLE_STATEMENT, - PREPARED_STATEMENT + @Override + public boolean validateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) { + return true; } }
Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java?rev=1833804&r1=1833803&r2=1833804&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java Tue Jun 19 10:30:31 2018 @@ -21,6 +21,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.logging.Logger; import javax.sql.DataSource; @@ -31,15 +32,11 @@ import org.apache.tomcat.dbcp.pool2.Obje import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool; /** - * A simple {@link DataSource} implementation that obtains - * {@link Connection}s from the specified {@link ObjectPool}. + * A simple {@link DataSource} implementation that obtains {@link Connection}s from the specified {@link ObjectPool}. * - * @param <C> The connection type + * @param <C> + * The connection type * - * @author Rodney Waldhoff - * @author Glenn L. Nielsen - * @author James House - * @author Dirk Verbeeck * @since 2.0 */ public class PoolingDataSource<C extends Connection> implements DataSource, AutoCloseable { @@ -47,40 +44,43 @@ public class PoolingDataSource<C extends private static final Log log = LogFactory.getLog(PoolingDataSource.class); /** Controls access to the underlying connection */ - private boolean accessToUnderlyingConnectionAllowed = false; + private boolean accessToUnderlyingConnectionAllowed; + /** + * Constructs a new instance backed by the given connection pool. + * + * @param pool + * the given connection pool. + */ public PoolingDataSource(final ObjectPool<C> pool) { - if (null == pool) { - throw new NullPointerException("Pool must not be null."); - } - _pool = pool; - // Verify that _pool's factory refers back to it. If not, log a warning and try to fix. - if (_pool instanceof GenericObjectPool<?>) { - final PoolableConnectionFactory pcf = (PoolableConnectionFactory) ((GenericObjectPool<?>) _pool).getFactory(); - if (pcf == null) { - throw new NullPointerException("PoolableConnectionFactory must not be null."); - } - if (pcf.getPool() != _pool) { + Objects.requireNonNull(pool, "Pool must not be null."); + this.pool = pool; + // Verify that pool's factory refers back to it. If not, log a warning and try to fix. + if (this.pool instanceof GenericObjectPool<?>) { + final PoolableConnectionFactory pcf = (PoolableConnectionFactory) ((GenericObjectPool<?>) this.pool) + .getFactory(); + Objects.requireNonNull(pcf, "PoolableConnectionFactory must not be null."); + if (pcf.getPool() != this.pool) { log.warn(Utils.getMessage("poolingDataSource.factoryConfig")); @SuppressWarnings("unchecked") // PCF must have a pool of PCs - final - ObjectPool<PoolableConnection> p = (ObjectPool<PoolableConnection>) _pool; + final ObjectPool<PoolableConnection> p = (ObjectPool<PoolableConnection>) this.pool; pcf.setPool(p); } } } /** - * Close and free all {@link Connection}s from the pool. + * Closes and free all {@link Connection}s from the pool. + * * @since 2.1 */ @Override public void close() throws Exception { try { - _pool.close(); - } catch(final RuntimeException rte) { + pool.close(); + } catch (final RuntimeException rte) { throw new RuntimeException(Utils.getMessage("pool.close.fail"), rte); - } catch(final Exception e) { + } catch (final Exception e) { throw new SQLException(Utils.getMessage("pool.close.fail"), e); } } @@ -95,11 +95,11 @@ public class PoolingDataSource<C extends } /** - * Sets the value of the accessToUnderlyingConnectionAllowed property. - * It controls if the PoolGuard allows access to the underlying connection. - * (Default: false) + * Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to + * the underlying connection. (Default: false) * - * @param allow Access to the underlying connection is granted when true. + * @param allow + * Access to the underlying connection is granted when true. */ public void setAccessToUnderlyingConnectionAllowed(final boolean allow) { this.accessToUnderlyingConnectionAllowed = allow; @@ -122,38 +122,40 @@ public class PoolingDataSource<C extends throw new SQLFeatureNotSupportedException(); } - //--- DataSource methods ----------------------------------------- + // --- DataSource methods ----------------------------------------- /** - * Return a {@link java.sql.Connection} from my pool, - * according to the contract specified by {@link ObjectPool#borrowObject}. + * Returns a {@link java.sql.Connection} from my pool, according to the contract specified by + * {@link ObjectPool#borrowObject}. */ @Override public Connection getConnection() throws SQLException { try { - final C conn = _pool.borrowObject(); + final C conn = pool.borrowObject(); if (conn == null) { return null; } return new PoolGuardConnectionWrapper<>(conn); - } catch(final SQLException e) { + } catch (final SQLException e) { throw e; - } catch(final NoSuchElementException e) { + } catch (final NoSuchElementException e) { throw new SQLException("Cannot get a connection, pool error " + e.getMessage(), e); - } catch(final RuntimeException e) { + } catch (final RuntimeException e) { throw e; - } catch(final InterruptedException e) { + } catch (final InterruptedException e) { // Reset the interrupt status so it is visible to callers Thread.currentThread().interrupt(); throw new SQLException("Cannot get a connection, general error", e); - } catch(final Exception e) { + } catch (final Exception e) { throw new SQLException("Cannot get a connection, general error", e); } } /** * Throws {@link UnsupportedOperationException} - * @throws UnsupportedOperationException This is unsupported + * + * @throws UnsupportedOperationException + * always thrown */ @Override public Connection getConnection(final String uname, final String passwd) throws SQLException { @@ -162,18 +164,20 @@ public class PoolingDataSource<C extends /** * Returns my log writer. + * * @return my log writer * @see DataSource#getLogWriter */ @Override public PrintWriter getLogWriter() { - return _logWriter; + return logWriter; } /** * Throws {@link UnsupportedOperationException}. - * @throws UnsupportedOperationException As this - * implementation does not support this feature. + * + * @throws UnsupportedOperationException + * As this implementation does not support this feature. */ @Override public int getLoginTimeout() { @@ -182,8 +186,9 @@ public class PoolingDataSource<C extends /** * Throws {@link UnsupportedOperationException}. - * @throws UnsupportedOperationException As this - * implementation does not support this feature. + * + * @throws UnsupportedOperationException + * As this implementation does not support this feature. */ @Override public void setLoginTimeout(final int seconds) { @@ -192,29 +197,29 @@ public class PoolingDataSource<C extends /** * Sets my log writer. + * * @see DataSource#setLogWriter */ @Override public void setLogWriter(final PrintWriter out) { - _logWriter = out; + logWriter = out; } /** My log writer. */ - private PrintWriter _logWriter = null; + private PrintWriter logWriter = null; - private final ObjectPool<C> _pool; + private final ObjectPool<C> pool; protected ObjectPool<C> getPool() { - return _pool; + return pool; } /** - * PoolGuardConnectionWrapper is a Connection wrapper that makes sure a - * closed connection cannot be used anymore. + * PoolGuardConnectionWrapper is a Connection wrapper that makes sure a closed connection cannot be used anymore. + * * @since 2.0 */ - private class PoolGuardConnectionWrapper<D extends Connection> - extends DelegatingConnection<D> { + private class PoolGuardConnectionWrapper<D extends Connection> extends DelegatingConnection<D> { PoolGuardConnectionWrapper(final D delegate) { super(delegate); @@ -225,10 +230,7 @@ public class PoolingDataSource<C extends */ @Override public D getDelegate() { - if (isAccessToUnderlyingConnectionAllowed()) { - return super.getDelegate(); - } - return null; + return isAccessToUnderlyingConnectionAllowed() ? super.getDelegate() : null; } /** @@ -236,10 +238,7 @@ public class PoolingDataSource<C extends */ @Override public Connection getInnermostDelegate() { - if (isAccessToUnderlyingConnectionAllowed()) { - return super.getInnermostDelegate(); - } - return null; + return isAccessToUnderlyingConnectionAllowed() ? super.getInnermostDelegate() : null; } @Override @@ -252,10 +251,7 @@ public class PoolingDataSource<C extends @Override public boolean isClosed() throws SQLException { - if (getDelegateInternal() == null) { - return true; - } - return super.isClosed(); + return getDelegateInternal() == null ? true : super.isClosed(); } } } Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java?rev=1833804&r1=1833803&r2=1833804&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java Tue Jun 19 10:30:31 2018 @@ -30,107 +30,120 @@ import java.util.logging.Logger; import org.apache.tomcat.dbcp.pool2.ObjectPool; - /** - * A {@link Driver} implementation that obtains - * {@link Connection}s from a registered - * {@link ObjectPool}. + * A {@link Driver} implementation that obtains {@link Connection}s from a registered {@link ObjectPool}. * - * @author Rodney Waldhoff - * @author Dirk Verbeeck * @since 2.0 */ public class PoolingDriver implements Driver { - /** - * Register myself with the {@link DriverManager}. - */ + + /** Register myself with the {@link DriverManager}. */ static { try { DriverManager.registerDriver(new PoolingDriver()); - } catch(final Exception e) { + } catch (final Exception e) { + // ignore } } - /** - * The map of registered pools. - */ - protected static final HashMap<String,ObjectPool<? extends Connection>> pools = - new HashMap<>(); + /** The map of registered pools. */ + protected static final HashMap<String, ObjectPool<? extends Connection>> pools = new HashMap<>(); - /** - * Controls access to the underlying connection - */ + /** Controls access to the underlying connection */ private final boolean accessToUnderlyingConnectionAllowed; + /** + * Constructs a new driver with <code>accessToUnderlyingConnectionAllowed</code> enabled. + */ public PoolingDriver() { this(true); } /** * For unit testing purposes. - * @param accessToUnderlyingConnectionAllowed The new flag */ protected PoolingDriver(final boolean accessToUnderlyingConnectionAllowed) { this.accessToUnderlyingConnectionAllowed = accessToUnderlyingConnectionAllowed; } - /** * Returns the value of the accessToUnderlyingConnectionAllowed property. * - * @return <code>true</code> if access to the underlying is allowed, - * <code>false</code> otherwise. + * @return true if access to the underlying is allowed, false otherwise. */ protected boolean isAccessToUnderlyingConnectionAllowed() { return accessToUnderlyingConnectionAllowed; } - public synchronized ObjectPool<? extends Connection> getConnectionPool(final String name) - throws SQLException { + /** + * Gets the connection pool for the given name. + * + * @param name + * The pool name + * @return The pool + * @throws SQLException + * Thrown when the named pool is not registered. + */ + public synchronized ObjectPool<? extends Connection> getConnectionPool(final String name) throws SQLException { final ObjectPool<? extends Connection> pool = pools.get(name); if (null == pool) { - throw new SQLException("Pool not registered."); + throw new SQLException("Pool not registered: " + name); } return pool; } - public synchronized void registerPool(final String name, - final ObjectPool<? extends Connection> pool) { - pools.put(name,pool); + /** + * Registers a named pool. + * + * @param name + * The pool name. + * @param pool + * The pool. + */ + public synchronized void registerPool(final String name, final ObjectPool<? extends Connection> pool) { + pools.put(name, pool); } + /** + * Closes a named pool. + * + * @param name + * The pool name. + * @throws SQLException + * Thrown when a problem is caught closing the pool. + */ public synchronized void closePool(final String name) throws SQLException { + @SuppressWarnings("resource") final ObjectPool<? extends Connection> pool = pools.get(name); if (pool != null) { pools.remove(name); try { pool.close(); - } - catch (final Exception e) { + } catch (final Exception e) { throw new SQLException("Error closing pool " + name, e); } } } - public synchronized String[] getPoolNames(){ + /** + * Gets the pool names. + * + * @return the pool names. + */ + public synchronized String[] getPoolNames() { final Set<String> names = pools.keySet(); return names.toArray(new String[names.size()]); } @Override public boolean acceptsURL(final String url) throws SQLException { - try { - return url.startsWith(URL_PREFIX); - } catch(final NullPointerException e) { - return false; - } + return url == null ? false : url.startsWith(URL_PREFIX); } @Override public Connection connect(final String url, final Properties info) throws SQLException { - if(acceptsURL(url)) { - final ObjectPool<? extends Connection> pool = - getConnectionPool(url.substring(URL_PREFIX_LEN)); + if (acceptsURL(url)) { + final ObjectPool<? extends Connection> pool = getConnectionPool(url.substring(URL_PREFIX_LEN)); try { final Connection conn = pool.borrowObject(); @@ -138,13 +151,13 @@ public class PoolingDriver implements Dr return null; } return new PoolGuardConnectionWrapper(pool, conn); - } catch(final SQLException e) { + } catch (final SQLException e) { throw e; - } catch(final NoSuchElementException e) { + } catch (final NoSuchElementException e) { throw new SQLException("Cannot get a connection, pool error: " + e.getMessage(), e); - } catch(final RuntimeException e) { + } catch (final RuntimeException e) { throw e; - } catch(final Exception e) { + } catch (final Exception e) { throw new SQLException("Cannot get a connection, general error: " + e.getMessage(), e); } } @@ -159,24 +172,23 @@ public class PoolingDriver implements Dr /** * Invalidates the given connection. * - * @param conn connection to invalidate - * @throws SQLException if the connection is not a - * <code>PoolGuardConnectionWrapper</code> or an error occurs invalidating - * the connection + * @param conn + * connection to invalidate + * @throws SQLException + * if the connection is not a <code>PoolGuardConnectionWrapper</code> or an error occurs invalidating + * the connection */ public void invalidateConnection(final Connection conn) throws SQLException { if (conn instanceof PoolGuardConnectionWrapper) { // normal case final PoolGuardConnectionWrapper pgconn = (PoolGuardConnectionWrapper) conn; @SuppressWarnings("unchecked") - final - ObjectPool<Connection> pool = (ObjectPool<Connection>) pgconn.pool; + final ObjectPool<Connection> pool = (ObjectPool<Connection>) pgconn.pool; try { pool.invalidateObject(pgconn.getDelegateInternal()); + } catch (final Exception e) { + // Ignore. } - catch (final Exception e) { - } - } - else { + } else { throw new SQLException("Invalid connection class"); } } @@ -202,7 +214,7 @@ public class PoolingDriver implements Dr } /** My URL prefix */ - protected static final String URL_PREFIX = "jdbc:apache:commons:dbcp:"; + public static final String URL_PREFIX = "jdbc:apache:commons:dbcp:"; protected static final int URL_PREFIX_LEN = URL_PREFIX.length(); // version numbers @@ -210,16 +222,15 @@ public class PoolingDriver implements Dr protected static final int MINOR_VERSION = 0; /** - * PoolGuardConnectionWrapper is a Connection wrapper that makes sure a - * closed connection cannot be used anymore. + * PoolGuardConnectionWrapper is a Connection wrapper that makes sure a closed connection cannot be used anymore. + * * @since 2.0 */ private class PoolGuardConnectionWrapper extends DelegatingConnection<Connection> { private final ObjectPool<? extends Connection> pool; - PoolGuardConnectionWrapper(final ObjectPool<? extends Connection> pool, - final Connection delegate) { + PoolGuardConnectionWrapper(final ObjectPool<? extends Connection> pool, final Connection delegate) { super(delegate); this.pool = pool; } Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/SwallowedExceptionLogger.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/SwallowedExceptionLogger.java?rev=1833804&r1=1833803&r2=1833804&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/SwallowedExceptionLogger.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/SwallowedExceptionLogger.java Tue Jun 19 10:30:31 2018 @@ -21,29 +21,31 @@ import org.apache.tomcat.dbcp.pool2.Swal /** * Class for logging swallowed exceptions. + * * @since 2.0 */ -public class SwallowedExceptionLogger implements SwallowedExceptionListener{ +public class SwallowedExceptionLogger implements SwallowedExceptionListener { private final Log log; private final boolean logExpiredConnections; /** - * Create a SwallowedExceptionLogger with the given logger. By default, - * expired connection logging is turned on. + * Create a SwallowedExceptionLogger with the given logger. By default, expired connection logging is turned on. * - * @param log logger + * @param log + * logger */ public SwallowedExceptionLogger(final Log log) { this(log, true); } /** - * Create a SwallowedExceptionLogger with the given logger and expired - * connection logging property. + * Create a SwallowedExceptionLogger with the given logger and expired connection logging property. * - * @param log logger - * @param logExpiredConnections false suppresses logging of expired connection events + * @param log + * logger + * @param logExpiredConnections + * false suppresses logging of expired connection events */ public SwallowedExceptionLogger(final Log log, final boolean logExpiredConnections) { this.log = log; @@ -53,8 +55,7 @@ public class SwallowedExceptionLogger im @Override public void onSwallowException(final Exception e) { if (logExpiredConnections || !(e instanceof LifetimeExceededException)) { - log.warn(Utils.getMessage( - "swallowedExceptionLogger.onSwallowedException"), e); + log.warn(Utils.getMessage("swallowedExceptionLogger.onSwallowedException"), e); } } } Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java?rev=1833804&r1=1833803&r2=1833804&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/Utils.java Tue Jun 19 10:30:31 2018 @@ -28,15 +28,18 @@ import java.util.Set; /** * Utility methods. + * * @since 2.0 */ public final class Utils { - private static final ResourceBundle messages = ResourceBundle.getBundle( - Utils.class.getPackage().getName() + ".LocalStrings"); + private static final ResourceBundle messages = ResourceBundle + .getBundle(Utils.class.getPackage().getName() + ".LocalStrings"); - public static final boolean IS_SECURITY_ENABLED = - System.getSecurityManager() != null; + /** + * Whether the security manager is enabled. + */ + public static final boolean IS_SECURITY_ENABLED = System.getSecurityManager() != null; /** Any SQL_STATE starting with this value is considered a fatal disconnect */ public static final String DISCONNECTION_SQL_CODE_PREFIX = "08"; @@ -44,12 +47,12 @@ public final class Utils { /** * SQL codes of fatal connection errors. * <ul> - * <li>57P01 (ADMIN SHUTDOWN)</li> - * <li>57P02 (CRASH SHUTDOWN)</li> - * <li>57P03 (CANNOT CONNECT NOW)</li> - * <li>01002 (SQL92 disconnect error)</li> - * <li>JZ0C0 (Sybase disconnect error)</li> - * <li>JZ0C1 (Sybase disconnect error)</li> + * <li>57P01 (ADMIN SHUTDOWN)</li> + * <li>57P02 (CRASH SHUTDOWN)</li> + * <li>57P03 (CANNOT CONNECT NOW)</li> + * <li>01002 (SQL92 disconnect error)</li> + * <li>JZ0C0 (Sybase disconnect error)</li> + * <li>JZ0C1 (Sybase disconnect error)</li> * </ul> */ public static final Set<String> DISCONNECTION_SQL_CODES; @@ -71,12 +74,13 @@ public final class Utils { /** * Closes the ResultSet (which may be null). * - * @param rset a ResultSet, may be {@code null} + * @param resultSet + * a ResultSet, may be {@code null} */ - public static void closeQuietly(final ResultSet rset) { - if (rset != null) { + public static void closeQuietly(final ResultSet resultSet) { + if (resultSet != null) { try { - rset.close(); + resultSet.close(); } catch (final Exception e) { // ignored } @@ -86,12 +90,13 @@ public final class Utils { /** * Closes the Connection (which may be null). * - * @param conn a Connection, may be {@code null} + * @param connection + * a Connection, may be {@code null} */ - public static void closeQuietly(final Connection conn) { - if (conn != null) { + public static void closeQuietly(final Connection connection) { + if (connection != null) { try { - conn.close(); + connection.close(); } catch (final Exception e) { // ignored } @@ -101,42 +106,67 @@ public final class Utils { /** * Closes the Statement (which may be null). * - * @param stmt a Statement, may be {@code null} + * @param statement + * a Statement, may be {@code null}. */ - public static void closeQuietly(final Statement stmt) { - if (stmt != null) { + public static void closeQuietly(final Statement statement) { + if (statement != null) { try { - stmt.close(); + statement.close(); } catch (final Exception e) { // ignored } } } - /** - * Obtain the correct i18n message for the given key. - * @param key The message key - * @return the message + * Gets the correct i18n message for the given key. + * + * @param key + * The key to look up an i18n message. + * @return The i18n message. */ public static String getMessage(final String key) { return getMessage(key, (Object[]) null); } - /** - * Obtain the correct i18n message for the given key with placeholders - * replaced by the supplied arguments. - * @param key The message key - * @param args The arguments - * @return the message + * Gets the correct i18n message for the given key with placeholders replaced by the supplied arguments. + * + * @param key + * A message key. + * @param args + * The message arguments. + * @return An i18n message. */ public static String getMessage(final String key, final Object... args) { - final String msg = messages.getString(key); + final String msg = messages.getString(key); if (args == null || args.length == 0) { return msg; } final MessageFormat mf = new MessageFormat(msg); return mf.format(args, new StringBuffer(), null).toString(); } + + /** + * Converts the given String to a char[]. + * + * @param value + * may be null. + * @return a char[] or null. + */ + public static char[] toCharArray(final String value) { + return value != null ? value.toCharArray() : null; + } + + /** + * Converts the given char[] to a String. + * + * @param value + * may be null. + * @return a String or null. + */ + public static String toString(final char[] value) { + return value == null ? null : String.valueOf(value); + } } Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java?rev=1833804&r1=1833803&r2=1833804&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java Tue Jun 19 10:30:31 2018 @@ -17,26 +17,25 @@ package org.apache.tomcat.dbcp.dbcp2.cpdsadapter; +import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.apache.tomcat.dbcp.dbcp2.DelegatingCallableStatement; import org.apache.tomcat.dbcp.dbcp2.DelegatingConnection; import org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement; /** - * This class is the <code>Connection</code> that will be returned - * from <code>PooledConnectionImpl.getConnection()</code>. - * Most methods are wrappers around the JDBC 1.x <code>Connection</code>. - * A few exceptions include preparedStatement and close. - * In accordance with the JDBC specification this Connection cannot - * be used after closed() is called. Any further usage will result in an + * This class is the <code>Connection</code> that will be returned from + * <code>PooledConnectionImpl.getConnection()</code>. Most methods are wrappers around the JDBC 1.x + * <code>Connection</code>. A few exceptions include preparedStatement and close. In accordance with the JDBC + * specification this Connection cannot be used after closed() is called. Any further usage will result in an * SQLException. + * <p> + * ConnectionImpl extends DelegatingConnection to enable access to the underlying connection. + * </p> * - * ConnectionImpl extends DelegatingConnection to enable access to the - * underlying connection. - * - * @author John D. McNally * @since 2.0 */ class ConnectionImpl extends DelegatingConnection<Connection> { @@ -44,32 +43,34 @@ class ConnectionImpl extends DelegatingC private final boolean accessToUnderlyingConnectionAllowed; /** The object that instantiated this object */ - private final PooledConnectionImpl pooledConnection; + private final PooledConnectionImpl pooledConnection; /** * Creates a <code>ConnectionImpl</code>. * - * @param pooledConnection The PooledConnection that is calling the ctor. - * @param connection The JDBC 1.x Connection to wrap. - * @param accessToUnderlyingConnectionAllowed if true, then access is allowed to the underlying connection + * @param pooledConnection + * The PooledConnection that is calling the ctor. + * @param connection + * The JDBC 1.x Connection to wrap. + * @param accessToUnderlyingConnectionAllowed + * if true, then access is allowed to the underlying connection */ - ConnectionImpl(final PooledConnectionImpl pooledConnection, - final Connection connection, + ConnectionImpl(final PooledConnectionImpl pooledConnection, final Connection connection, final boolean accessToUnderlyingConnectionAllowed) { super(connection); this.pooledConnection = pooledConnection; - this.accessToUnderlyingConnectionAllowed = - accessToUnderlyingConnectionAllowed; + this.accessToUnderlyingConnectionAllowed = accessToUnderlyingConnectionAllowed; } /** - * Marks the Connection as closed, and notifies the pool that the - * pooled connection is available. - * In accordance with the JDBC specification this Connection cannot - * be used after closed() is called. Any further usage will result in an - * SQLException. + * Marks the Connection as closed, and notifies the pool that the pooled connection is available. + * <p> + * In accordance with the JDBC specification this Connection cannot be used after closed() is called. Any further + * usage will result in an SQLException. + * </p> * - * @throws SQLException The database connection couldn't be closed. + * @throws SQLException + * The database connection couldn't be closed. */ @Override public void close() throws SQLException { @@ -84,106 +85,179 @@ class ConnectionImpl extends DelegatingC } /** - * If pooling of <code>PreparedStatement</code>s is turned on in the - * {@link DriverAdapterCPDS}, a pooled object may be returned, otherwise - * delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. + * If pooling of <code>CallableStatement</code>s is turned on in the {@link DriverAdapterCPDS}, a pooled object may + * be returned, otherwise delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. * - * @param sql SQL statement to be prepared - * @return the prepared statement - * @throws SQLException if this connection is closed or an error occurs - * in the wrapped connection. + * @param sql + * an SQL statement that may contain one or more '?' parameter placeholders. Typically this statement is + * specified using JDBC call escape syntax. + * @return a default <code>CallableStatement</code> object containing the pre-compiled SQL statement. + * @exception SQLException + * Thrown if a database access error occurs or this method is called on a closed connection. + * @since 2.4.0 */ @Override - public PreparedStatement prepareStatement(final String sql) throws SQLException { + public CallableStatement prepareCall(final String sql) throws SQLException { checkOpen(); try { - return new DelegatingPreparedStatement - (this, pooledConnection.prepareStatement(sql)); - } - catch (final SQLException e) { + return new DelegatingCallableStatement(this, pooledConnection.prepareCall(sql)); + } catch (final SQLException e) { handleException(e); // Does not return return null; } } /** - * If pooling of <code>PreparedStatement</code>s is turned on in the - * {@link DriverAdapterCPDS}, a pooled object may be returned, otherwise - * delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. + * If pooling of <code>CallableStatement</code>s is turned on in the {@link DriverAdapterCPDS}, a pooled object may + * be returned, otherwise delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. * - * @throws SQLException if this connection is closed or an error occurs - * in the wrapped connection. + * @param sql + * a <code>String</code> object that is the SQL statement to be sent to the database; may contain on or + * more '?' parameters. + * @param resultSetType + * a result set type; one of <code>ResultSet.TYPE_FORWARD_ONLY</code>, + * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. + * @param resultSetConcurrency + * a concurrency type; one of <code>ResultSet.CONCUR_READ_ONLY</code> or + * <code>ResultSet.CONCUR_UPDATABLE</code>. + * @return a <code>CallableStatement</code> object containing the pre-compiled SQL statement that will produce + * <code>ResultSet</code> objects with the given type and concurrency. + * @throws SQLException + * Thrown if a database access error occurs, this method is called on a closed connection or the given + * parameters are not <code>ResultSet</code> constants indicating type and concurrency. + * @since 2.4.0 */ @Override - public PreparedStatement prepareStatement(final String sql, final int resultSetType, - final int resultSetConcurrency) + public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { checkOpen(); try { - return new DelegatingPreparedStatement - (this, pooledConnection.prepareStatement - (sql,resultSetType,resultSetConcurrency)); - } - catch (final SQLException e) { - handleException(e); + return new DelegatingCallableStatement(this, + pooledConnection.prepareCall(sql, resultSetType, resultSetConcurrency)); + } catch (final SQLException e) { + handleException(e); // Does not return return null; } } + /** + * If pooling of <code>CallableStatement</code>s is turned on in the {@link DriverAdapterCPDS}, a pooled object may + * be returned, otherwise delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. + * + * @param sql + * a <code>String</code> object that is the SQL statement to be sent to the database; may contain on or + * more '?' parameters. + * @param resultSetType + * one of the following <code>ResultSet</code> constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>, + * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>. + * @param resultSetConcurrency + * one of the following <code>ResultSet</code> constants: <code>ResultSet.CONCUR_READ_ONLY</code> or + * <code>ResultSet.CONCUR_UPDATABLE</code>. + * @param resultSetHoldability + * one of the following <code>ResultSet</code> constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> + * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>. + * @return a new <code>CallableStatement</code> object, containing the pre-compiled SQL statement, that will + * generate <code>ResultSet</code> objects with the given type, concurrency, and holdability. + * @throws SQLException + * Thrown if a database access error occurs, this method is called on a closed connection or the given + * parameters are not <code>ResultSet</code> constants indicating type, concurrency, and holdability. + * @since 2.4.0 + */ @Override - public PreparedStatement prepareStatement(final String sql, final int resultSetType, - final int resultSetConcurrency, - final int resultSetHoldability) - throws SQLException { + public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) throws SQLException { checkOpen(); try { - return new DelegatingPreparedStatement(this, - pooledConnection.prepareStatement(sql, resultSetType, - resultSetConcurrency, resultSetHoldability)); + return new DelegatingCallableStatement(this, + pooledConnection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); + } catch (final SQLException e) { + handleException(e); // Does not return + return null; } - catch (final SQLException e) { - handleException(e); + } + + /** + * If pooling of <code>PreparedStatement</code>s is turned on in the {@link DriverAdapterCPDS}, a pooled object may + * be returned, otherwise delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. + * + * @param sql + * SQL statement to be prepared + * @return the prepared statement + * @throws SQLException + * if this connection is closed or an error occurs in the wrapped connection. + */ + @Override + public PreparedStatement prepareStatement(final String sql) throws SQLException { + checkOpen(); + try { + return new DelegatingPreparedStatement(this, pooledConnection.prepareStatement(sql)); + } catch (final SQLException e) { + handleException(e); // Does not return return null; } } + /** + * If pooling of <code>PreparedStatement</code>s is turned on in the {@link DriverAdapterCPDS}, a pooled object may + * be returned, otherwise delegate to the wrapped JDBC 1.x {@link java.sql.Connection}. + * + * @throws SQLException + * if this connection is closed or an error occurs in the wrapped connection. + */ @Override - public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) + public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { checkOpen(); try { return new DelegatingPreparedStatement(this, - pooledConnection.prepareStatement(sql, autoGeneratedKeys)); - } - catch (final SQLException e) { + pooledConnection.prepareStatement(sql, resultSetType, resultSetConcurrency)); + } catch (final SQLException e) { handleException(e); return null; } } @Override - public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) - throws SQLException { + public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) throws SQLException { checkOpen(); try { return new DelegatingPreparedStatement(this, - pooledConnection.prepareStatement(sql, columnIndexes)); + pooledConnection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); + } catch (final SQLException e) { + handleException(e); + return null; } - catch (final SQLException e) { + } + + @Override + public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException { + checkOpen(); + try { + return new DelegatingPreparedStatement(this, pooledConnection.prepareStatement(sql, autoGeneratedKeys)); + } catch (final SQLException e) { handleException(e); return null; } } @Override - public PreparedStatement prepareStatement(final String sql, final String columnNames[]) - throws SQLException { + public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException { checkOpen(); try { - return new DelegatingPreparedStatement(this, - pooledConnection.prepareStatement(sql, columnNames)); + return new DelegatingPreparedStatement(this, pooledConnection.prepareStatement(sql, columnIndexes)); + } catch (final SQLException e) { + handleException(e); + return null; } - catch (final SQLException e) { + } + + @Override + public PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException { + checkOpen(); + try { + return new DelegatingPreparedStatement(this, pooledConnection.prepareStatement(sql, columnNames)); + } catch (final SQLException e) { handleException(e); return null; } @@ -195,6 +269,7 @@ class ConnectionImpl extends DelegatingC /** * If false, getDelegate() and getInnermostDelegate() will return null. + * * @return true if access is allowed to the underlying connection * @see ConnectionImpl */ @@ -204,6 +279,7 @@ class ConnectionImpl extends DelegatingC /** * Get the delegated connection, if allowed. + * * @return the internal connection, or null if access is not allowed. * @see #isAccessToUnderlyingConnectionAllowed() */ @@ -217,6 +293,7 @@ class ConnectionImpl extends DelegatingC /** * Get the innermost connection, if allowed. + * * @return the innermost internal connection, or null if access is not allowed. * @see #isAccessToUnderlyingConnectionAllowed() */ --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org