You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2024/12/03 12:12:46 UTC
(tomcat) 01/03: Update fork of Commons DBCP to 2.13.0
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 30c42b2f0936ecd7b7dd2b44d82c2710b07764cb
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Dec 3 11:53:06 2024 +0000
Update fork of Commons DBCP to 2.13.0
---
MERGE.txt | 4 +-
.../apache/tomcat/dbcp/dbcp2/AbandonedTrace.java | 2 +-
.../apache/tomcat/dbcp/dbcp2/BasicDataSource.java | 182 ++-
.../tomcat/dbcp/dbcp2/BasicDataSourceFactory.java | 36 +-
java/org/apache/tomcat/dbcp/dbcp2/Constants.java | 20 +-
.../apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java | 10 +
.../tomcat/dbcp/dbcp2/DelegatingConnection.java | 44 +-
.../dbcp/dbcp2/DelegatingDatabaseMetaData.java | 1382 ++++----------------
.../dbcp/dbcp2/DelegatingPreparedStatement.java | 5 +-
.../tomcat/dbcp/dbcp2/DelegatingStatement.java | 5 +-
.../tomcat/dbcp/dbcp2/DriverConnectionFactory.java | 10 +-
.../dbcp/dbcp2/PoolableCallableStatement.java | 2 +-
.../tomcat/dbcp/dbcp2/PoolableConnection.java | 53 +-
.../dbcp/dbcp2/PoolableConnectionFactory.java | 149 ++-
.../dbcp/dbcp2/PoolableConnectionMXBean.java | 124 ++
.../dbcp/dbcp2/PoolablePreparedStatement.java | 2 +-
.../tomcat/dbcp/dbcp2/PoolingConnection.java | 6 +-
.../tomcat/dbcp/dbcp2/PoolingDataSource.java | 13 +-
.../apache/tomcat/dbcp/dbcp2/PoolingDriver.java | 15 +-
java/org/apache/tomcat/dbcp/dbcp2/Utils.java | 47 +-
.../dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java | 2 +-
.../dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java | 4 +-
.../dbcp2/cpdsadapter/PooledConnectionImpl.java | 8 +-
.../dbcp2/datasources/InstanceKeyDataSource.java | 26 +-
.../datasources/InstanceKeyDataSourceFactory.java | 90 +-
.../datasources/KeyedCPDSConnectionFactory.java | 3 +-
.../dbcp2/datasources/PerUserPoolDataSource.java | 304 ++---
.../tomcat/dbcp/dbcp2/datasources/PoolKey.java | 2 +
.../dbcp2/datasources/PooledConnectionAndInfo.java | 9 -
.../dbcp2/datasources/SharedPoolDataSource.java | 34 +-
.../datasources/SharedPoolDataSourceFactory.java | 8 +
.../tomcat/dbcp/dbcp2/datasources/UserPassKey.java | 4 -
.../dbcp/dbcp2/managed/BasicManagedDataSource.java | 15 +-
.../dbcp2/managed/LocalXAConnectionFactory.java | 17 +-
.../dbcp/dbcp2/managed/ManagedConnection.java | 14 +-
.../dbcp2/managed/PoolableManagedConnection.java | 41 +-
.../managed/PoolableManagedConnectionFactory.java | 4 +-
.../dbcp/dbcp2/managed/TransactionContext.java | 1 -
.../dbcp2/managed/TransactionContextListener.java | 7 +-
.../dbcp/dbcp2/managed/XAConnectionFactory.java | 8 +-
.../tomcat/dbcp/dbcp2/managed/package-info.java | 2 +-
.../org/apache/tomcat/dbcp/dbcp2/package-info.java | 2 +-
webapps/docs/changelog.xml | 3 +
43 files changed, 1174 insertions(+), 1545 deletions(-)
diff --git a/MERGE.txt b/MERGE.txt
index 352231a2ae..8fc200f810 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -44,7 +44,7 @@ FileUpload
Unused code is removed
Branch: 1.x
Sub-tree:
-src/main/java/org/apache/commons/fileupload2
+src/main/java/org/apache/commons/fileupload
The SHA1 ID / tag for the most recent commit to be merged to Tomcat is:
7a8c3241cfa8d036452cd4fc3f92d57cff189bca (2023-09-16)
@@ -66,4 +66,4 @@ Sub-tree
src/main/java/org/apache/commons/dbcp2
src/main/resources/org/apache/commons/dbcp2
The SHA1 ID / tag for the most recent commit to be merged to Tomcat is:
-rel/commons-dbcp-2.12.0 (2024-03-04)
+rel/commons-dbcp-2.13.0 (2024-12-02)
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java b/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
index bff2021fd7..d4130ae581 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
@@ -158,7 +158,7 @@ public class AbandonedTrace implements TrackedUse, AutoCloseable {
* AbandonedTrace parent object.
*/
private void init(final AbandonedTrace parent) {
- AbandonedTrace.add(parent, this);
+ add(parent, this);
}
/**
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
index 790141e622..043369b22b 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
@@ -27,12 +27,14 @@ import java.sql.SQLFeatureNotSupportedException;
import java.time.Duration;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.logging.Logger;
+import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -55,7 +57,6 @@ import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPoolConfig;
/**
* Basic implementation of {@code javax.sql.DataSource} that is configured via JavaBeans properties.
- *
* <p>
* This is not the only way to combine the <em>commons-dbcp2</em> and <em>commons-pool2</em> packages, but provides a
* one-stop solution for basic requirements.
@@ -318,6 +319,13 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
private volatile Set<String> disconnectionSqlCodes;
+ /**
+ * A collection of SQL State codes that are not considered fatal disconnection codes.
+ *
+ * @since 2.13.0
+ */
+ private volatile Set<String> disconnectionIgnoreSqlCodes;
+
private boolean fastFailValidation;
/**
@@ -601,6 +609,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeoutDuration());
connectionFactory.setFastFailValidation(fastFailValidation);
connectionFactory.setDisconnectionSqlCodes(disconnectionSqlCodes);
+ connectionFactory.setDisconnectionIgnoreSqlCodes(disconnectionIgnoreSqlCodes);
validateConnectionFactory(connectionFactory);
} catch (final RuntimeException e) {
throw e;
@@ -813,7 +822,33 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
}
/**
- * Gets the set of SQL_STATE codes considered to signal fatal conditions.
+ * Gets the set of SQL State codes that are not considered fatal disconnection codes.
+ * <p>
+ * This method returns the set of SQL State codes that have been specified to be ignored
+ * when determining if a {@link SQLException} signals a disconnection. These codes will not
+ * trigger a disconnection even if they match other disconnection criteria.
+ * </p>
+ *
+ * @return a set of SQL State codes that should be ignored for disconnection checks, or an empty set if none have been specified.
+ * @since 2.13.0
+ */
+ public Set<String> getDisconnectionIgnoreSqlCodes() {
+ final Set<String> result = disconnectionIgnoreSqlCodes;
+ return result == null ? Collections.emptySet() : result;
+ }
+
+ /**
+ * Provides the same data as {@link #getDisconnectionIgnoreSqlCodes()} but in an array, so it is accessible via JMX.
+ *
+ * @since 2.13.0
+ */
+ @Override
+ public String[] getDisconnectionIgnoreSqlCodesAsArray() {
+ return getDisconnectionIgnoreSqlCodes().toArray(Utils.EMPTY_STRING_ARRAY);
+ }
+
+ /**
+ * Gets the set of SQL State codes considered to signal fatal conditions.
*
* @return fatal disconnection state codes
* @see #setDisconnectionSqlCodes(Collection)
@@ -910,10 +945,11 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
/**
* True means that validation will fail immediately for connections that have previously thrown SQLExceptions with
- * SQL_STATE indicating fatal disconnection errors.
+ * SQL State indicating fatal disconnection errors.
*
* @return true if connections created by this datasource will fast fail validation.
* @see #setDisconnectionSqlCodes(Collection)
+ * @see #setDisconnectionIgnoreSqlCodes(Collection)
* @since 2.1
*/
@Override
@@ -1405,7 +1441,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Gets the JDBC connection {code userName} property.
*
* @return the {code userName} passed to the JDBC driver to establish connections
- * @deprecated Replaced with DataSourceMXBean.getUserName()
+ * @deprecated Use {@link #getUserName()}.
*/
@Deprecated
@Override
@@ -1567,10 +1603,10 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
}
/**
- * Logs the given throwable.
- * @param message TODO
- * @param throwable the throwable.
+ * Logs the given message and throwable.
*
+ * @param message value to be log.
+ * @param throwable the throwable.
* @since 2.7.0
*/
protected void log(final String message, final Throwable throwable) {
@@ -1688,8 +1724,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* the underlying connection. (Default: false)
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param allow Access to the underlying connection is granted when true.
@@ -1745,8 +1781,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the collection of SQL statements to be executed when a physical connection is first created.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param connectionInitSqls Collection of SQL statements to execute on connection creation
@@ -1761,8 +1797,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the list of SQL statements to be executed when a physical connection is first created.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param connectionInitSqls List of SQL statements to execute on connection creation
@@ -1812,8 +1848,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets default auto-commit state of connections returned by this datasource.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param defaultAutoCommit default auto-commit value
@@ -1826,8 +1862,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the default catalog.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param defaultCatalog the default catalog
@@ -1863,8 +1899,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets defaultReadonly property.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param defaultReadOnly default read-only value
@@ -1877,8 +1913,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the default schema.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param defaultSchema the default catalog
@@ -1892,8 +1928,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the default transaction isolation state for returned connections.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param defaultTransactionIsolation the default transaction isolation state
@@ -1904,11 +1940,41 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
}
/**
- * Sets the SQL_STATE codes considered to signal fatal conditions.
+ * Sets the SQL State codes that should be ignored when determining fatal disconnection conditions.
+ * <p>
+ * This method allows you to specify a collection of SQL State codes that will be excluded from
+ * disconnection checks. These codes will not trigger the "fatally disconnected" status even if they
+ * match the typical disconnection criteria. This can be useful in scenarios where certain SQL State
+ * codes (e.g., specific codes starting with "08") are known to be non-fatal in your environment.
+ * </p>
+ * <p>
+ * The effect of this method is similar to the one described in {@link #setDisconnectionSqlCodes(Collection)},
+ * but instead of setting codes that signal fatal disconnections, it defines codes that should be ignored
+ * during such checks.
+ * </p>
+ * <p>
+ * Note: This method currently has no effect once the pool has been initialized. The pool is initialized the first
+ * time one of the following methods is invoked: {@code getConnection, setLogwriter, setLoginTimeout,
+ * getLoginTimeout, getLogWriter}.
+ * </p>
+ *
+ * @param disconnectionIgnoreSqlCodes SQL State codes that should be ignored in disconnection checks
+ * @throws IllegalArgumentException if any SQL state codes overlap with those in {@link #disconnectionSqlCodes}.
+ * @since 2.13.0
+ */
+ public void setDisconnectionIgnoreSqlCodes(final Collection<String> disconnectionIgnoreSqlCodes) {
+ Utils.checkSqlCodes(disconnectionIgnoreSqlCodes, this.disconnectionSqlCodes);
+ final Set<String> collect = Utils.isEmpty(disconnectionIgnoreSqlCodes) ? null
+ : disconnectionIgnoreSqlCodes.stream().filter(s -> !isEmpty(s)).collect(toLinkedHashSet());
+ this.disconnectionIgnoreSqlCodes = Utils.isEmpty(collect) ? null : collect;
+ }
+
+ /**
+ * Sets the SQL State codes considered to signal fatal conditions.
* <p>
* Overrides the defaults in {@link Utils#getDisconnectionSqlCodes()} (plus anything starting with
* {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}). If this property is non-null and {@link #getFastFailValidation()}
- * is {@code true}, whenever connections created by this datasource generate exceptions with SQL_STATE codes in this
+ * is {@code true}, whenever connections created by this datasource generate exceptions with SQL State codes in this
* list, they will be marked as "fatally disconnected" and subsequent validations will fail fast (no attempt at
* isValid or validation query).
* </p>
@@ -1921,12 +1987,14 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter}.
* </p>
*
- * @param disconnectionSqlCodes SQL_STATE codes considered to signal fatal conditions
+ * @param disconnectionSqlCodes SQL State codes considered to signal fatal conditions
* @since 2.1
+ * @throws IllegalArgumentException if any SQL state codes overlap with those in {@link #disconnectionIgnoreSqlCodes}.
*/
public void setDisconnectionSqlCodes(final Collection<String> disconnectionSqlCodes) {
+ Utils.checkSqlCodes(disconnectionSqlCodes, this.disconnectionIgnoreSqlCodes);
final Set<String> collect = Utils.isEmpty(disconnectionSqlCodes) ? null
- : disconnectionSqlCodes.stream().filter(s -> !isEmpty(s)).collect(Collectors.toSet());
+ : disconnectionSqlCodes.stream().filter(s -> !isEmpty(s)).collect(toLinkedHashSet());
this.disconnectionSqlCodes = Utils.isEmpty(collect) ? null : collect;
}
@@ -1934,8 +2002,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the JDBC Driver instance to use for this pool.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param driver The JDBC Driver instance to use for this pool.
@@ -1948,8 +2016,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the class loader to be used to load the JDBC driver.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param driverClassLoader the class loader with which to load the JDBC driver
@@ -1962,8 +2030,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the JDBC driver class name.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param driverClassName the class name of the JDBC driver
@@ -2021,8 +2089,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the initial size of the connection pool.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param initialSize the number of connections created when the pool is initialized
@@ -2114,8 +2182,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* infinite lifetime.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param maxConnDuration The maximum permitted lifetime of a connection.
@@ -2130,8 +2198,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* infinite lifetime.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param maxConnLifetimeMillis The maximum permitted lifetime of a connection in milliseconds.
@@ -2158,8 +2226,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the value of the {@code maxOpenPreparedStatements} property.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param maxOpenStatements the new maximum number of prepared statements
@@ -2256,8 +2324,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the {code password}.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param password new value for the password
@@ -2270,8 +2338,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets whether to pool statements or not.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param poolingStatements pooling on or off
@@ -2442,8 +2510,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the {code connection string}.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param connectionString the new value for the JDBC connection connectionString
@@ -2456,8 +2524,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the {code userName}.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param userName the new value for the JDBC connection user name
@@ -2470,8 +2538,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* Sets the {code validationQuery}.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param validationQuery the new value for the validation query
@@ -2485,8 +2553,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* response from the database when executing a validation query. Use a value less than or equal to 0 for no timeout.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param validationQueryTimeoutDuration new validation query timeout value in seconds
@@ -2501,8 +2569,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
* response from the database when executing a validation query. Use a value less than or equal to 0 for no timeout.
* <p>
* Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * time one of the following methods is invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)},
+ * {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()}, {@link #getLogWriter()}.
* </p>
*
* @param validationQueryTimeoutSeconds new validation query timeout value in seconds
@@ -2545,6 +2613,10 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
}
}
+ private Collector<String, ?, LinkedHashSet<String>> toLinkedHashSet() {
+ return Collectors.toCollection(LinkedHashSet::new);
+ }
+
@Override
public <T> T unwrap(final Class<T> iface) throws SQLException {
if (isWrapperFor(iface)) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
index 8e736624a9..56c9b19ba6 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
@@ -120,6 +120,18 @@ public class BasicDataSourceFactory implements ObjectFactory {
*/
private static final String PROP_DISCONNECTION_SQL_CODES = "disconnectionSqlCodes";
+ /**
+ * Property key for specifying the SQL State codes that should be ignored during disconnection checks.
+ * <p>
+ * The value for this property must be a comma-separated string of SQL State codes, where each code represents
+ * a state that will be excluded from being treated as a fatal disconnection. The expected format is a series
+ * of SQL State codes separated by commas, with no spaces between them (e.g., "08003,08004").
+ * </p>
+ * @since 2.13.0
+ */
+ private static final String PROP_DISCONNECTION_IGNORE_SQL_CODES = "disconnectionIgnoreSqlCodes";
+
+
/*
* Block with obsolete properties from DBCP 1.x. Warn users that these are ignored and they should use the 2.x
* properties.
@@ -149,8 +161,8 @@ public class BasicDataSourceFactory implements ObjectFactory {
PROP_CLEAR_STATEMENT_POOL_ON_RETURN,
PROP_MAX_OPEN_PREPARED_STATEMENTS, PROP_CONNECTION_PROPERTIES, PROP_MAX_CONN_LIFETIME_MILLIS,
PROP_LOG_EXPIRED_CONNECTIONS, PROP_ROLLBACK_ON_RETURN, PROP_ENABLE_AUTO_COMMIT_ON_RETURN,
- PROP_DEFAULT_QUERY_TIMEOUT, PROP_FAST_FAIL_VALIDATION, PROP_DISCONNECTION_SQL_CODES, PROP_JMX_NAME,
- PROP_REGISTER_CONNECTION_MBEAN, PROP_CONNECTION_FACTORY_CLASS_NAME);
+ PROP_DEFAULT_QUERY_TIMEOUT, PROP_FAST_FAIL_VALIDATION, PROP_DISCONNECTION_SQL_CODES, PROP_DISCONNECTION_IGNORE_SQL_CODES,
+ PROP_JMX_NAME, PROP_REGISTER_CONNECTION_MBEAN, PROP_CONNECTION_FACTORY_CLASS_NAME);
/**
* Obsolete properties from DBCP 1.x. with warning strings suggesting new properties. LinkedHashMap will guarantee
@@ -227,17 +239,23 @@ public class BasicDataSourceFactory implements ObjectFactory {
getOptional(properties, PROP_DEFAULT_TRANSACTION_ISOLATION).ifPresent(value -> {
value = value.toUpperCase(Locale.ROOT);
int level = PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION;
- if ("NONE".equals(value)) {
+ switch (value) {
+ case "NONE":
level = Connection.TRANSACTION_NONE;
- } else if ("READ_COMMITTED".equals(value)) {
+ break;
+ case "READ_COMMITTED":
level = Connection.TRANSACTION_READ_COMMITTED;
- } else if ("READ_UNCOMMITTED".equals(value)) {
+ break;
+ case "READ_UNCOMMITTED":
level = Connection.TRANSACTION_READ_UNCOMMITTED;
- } else if ("REPEATABLE_READ".equals(value)) {
+ break;
+ case "REPEATABLE_READ":
level = Connection.TRANSACTION_REPEATABLE_READ;
- } else if ("SERIALIZABLE".equals(value)) {
+ break;
+ case "SERIALIZABLE":
level = Connection.TRANSACTION_SERIALIZABLE;
- } else {
+ break;
+ default:
try {
level = Integer.parseInt(value);
} catch (final NumberFormatException e) {
@@ -246,6 +264,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
System.err.println("using default value of database driver");
level = PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION;
}
+ break;
}
dataSource.setDefaultTransactionIsolation(level);
});
@@ -302,6 +321,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
acceptDurationOfSeconds(properties, PROP_DEFAULT_QUERY_TIMEOUT, dataSource::setDefaultQueryTimeout);
acceptBoolean(properties, PROP_FAST_FAIL_VALIDATION, dataSource::setFastFailValidation);
getOptional(properties, PROP_DISCONNECTION_SQL_CODES).ifPresent(v -> dataSource.setDisconnectionSqlCodes(parseList(v, ',')));
+ getOptional(properties, PROP_DISCONNECTION_IGNORE_SQL_CODES).ifPresent(v -> dataSource.setDisconnectionIgnoreSqlCodes(parseList(v, ',')));
acceptString(properties, PROP_CONNECTION_FACTORY_CLASS_NAME, dataSource::setConnectionFactoryClassName);
// DBCP-215
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Constants.java b/java/org/apache/tomcat/dbcp/dbcp2/Constants.java
index da83187dad..e96e0e53a4 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Constants.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Constants.java
@@ -23,13 +23,29 @@ package org.apache.tomcat.dbcp.dbcp2;
*/
public class Constants {
+ /**
+ * Constant used to build JMX strings.
+ */
public static final String JMX_CONNECTION_POOL_BASE_EXT = ",connectionpool=";
+
+ /**
+ * Constant used to build JMX strings.
+ */
public static final String JMX_CONNECTION_POOL_PREFIX = "connections";
- public static final String JMX_CONNECTION_BASE_EXT = JMX_CONNECTION_POOL_BASE_EXT + JMX_CONNECTION_POOL_PREFIX
- + ",connection=";
+ /**
+ * Constant used to build JMX strings.
+ */
+ public static final String JMX_CONNECTION_BASE_EXT = JMX_CONNECTION_POOL_BASE_EXT + JMX_CONNECTION_POOL_PREFIX + ",connection=";
+ /**
+ * Constant used to build JMX strings.
+ */
public static final String JMX_STATEMENT_POOL_BASE_EXT = JMX_CONNECTION_BASE_EXT;
+
+ /**
+ * Constant used to build JMX strings.
+ */
public static final String JMX_STATEMENT_POOL_PREFIX = ",statementpool=statements";
/**
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java b/java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java
index de2afe062c..2f40c52b81 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java
@@ -85,6 +85,16 @@ public interface DataSourceMXBean {
*/
int getDefaultTransactionIsolation();
+ /**
+ * See {@link BasicDataSource#getDisconnectionIgnoreSqlCodesAsArray()}.
+ *
+ * @return {@link BasicDataSource#getDisconnectionIgnoreSqlCodesAsArray()}.
+ * @since 2.13.0
+ */
+ default String[] getDisconnectionIgnoreSqlCodesAsArray() {
+ return Utils.EMPTY_STRING_ARRAY;
+ }
+
/**
* See {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}.
*
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
index 3d9624dc94..cf47cb1e86 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
@@ -95,6 +95,9 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
}
+ /**
+ * Marks this instance as used and delegates to a wrapped {@link DelegatingConnection#activate()}.
+ */
protected void activate() {
closed = false;
setLastUsed();
@@ -103,6 +106,11 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
}
+ /**
+ * Throws a SQLException if this connection is not open.
+ *
+ * @throws SQLException Thrown if this connection is not open.
+ */
protected void checkOpen() throws SQLException {
if (closed) {
if (null != connection) {
@@ -314,7 +322,13 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
/**
- * Returns the state caching flag.
+ * Gets whether to cache properties. The cached properties are:
+ * <ul>
+ * <li>auto-commit</li>
+ * <li>catalog</li>
+ * <li>schema</li>
+ * <li>read-only</li>
+ * </ul>
*
* @return the state caching flag
*/
@@ -573,6 +587,11 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
return closed || connection == null || connection.isClosed();
}
+ /**
+ * Tests the raw internal closed state.
+ *
+ * @return the raw internal closed state.
+ */
protected boolean isClosedInternal() {
return closed;
}
@@ -644,6 +663,11 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
}
+ /**
+ * Clears the list of objects being traced by this object.
+ *
+ * @throws SQLException Thrown if not all traced objects were closed.
+ */
protected void passivate() throws SQLException {
// The JDBC specification requires that a Connection close any open
// Statements when it is closed.
@@ -812,10 +836,15 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
/**
- * Sets the state caching flag.
+ * Sets whether to cache properties. The cached properties are:
+ * <ul>
+ * <li>auto-commit</li>
+ * <li>catalog</li>
+ * <li>schema</li>
+ * <li>read-only</li>
+ * </ul>
*
- * @param cacheState
- * The new value for the state caching flag
+ * @param cacheState The new value for the state caching flag
*/
public void setCacheState(final boolean cacheState) {
this.cacheState = cacheState;
@@ -859,6 +888,11 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
}
}
+ /**
+ * Sets the raw internal closed state.
+ *
+ * @param closed the raw internal closed state.
+ */
protected void setClosedInternal(final boolean closed) {
this.closed = closed;
}
@@ -960,7 +994,7 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
try {
Jdbc41Bridge.setSchema(connection, schema);
if (cacheState) {
- cachedSchema = connection.getSchema();
+ cachedSchema = Jdbc41Bridge.getSchema(connection);
}
} catch (final SQLException e) {
cachedSchema = null;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
index 79543e401b..21b27f18e0 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
@@ -22,14 +22,15 @@ import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
import java.util.Objects;
+import java.util.concurrent.Callable;
/**
* <p>
* A base delegating implementation of {@link DatabaseMetaData}.
* </p>
* <p>
- * Methods that create {@link ResultSet} objects are wrapped to create {@link DelegatingResultSet} objects and the
- * remaining methods simply call the corresponding method on the "delegate" provided in the constructor.
+ * Methods that create {@link ResultSet} objects are wrapped to create {@link DelegatingResultSet} objects and the remaining methods simply call the
+ * corresponding method on the "delegate" provided in the constructor.
* </p>
*
* @since 2.0
@@ -45,190 +46,115 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
/**
* Constructs a new instance for the given delegating connection and database meta data.
*
- * @param connection
- * the delegating connection
- * @param databaseMetaData
- * the database meta data
+ * @param connection the delegating connection
+ * @param databaseMetaData the database meta data
*/
- public DelegatingDatabaseMetaData(final DelegatingConnection<?> connection,
- final DatabaseMetaData databaseMetaData) {
+ public DelegatingDatabaseMetaData(final DelegatingConnection<?> connection, final DatabaseMetaData databaseMetaData) {
this.connection = Objects.requireNonNull(connection, "connection");
this.databaseMetaData = Objects.requireNonNull(databaseMetaData, "databaseMetaData");
}
@Override
public boolean allProceduresAreCallable() throws SQLException {
- try {
- return databaseMetaData.allProceduresAreCallable();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::allProceduresAreCallable);
}
@Override
public boolean allTablesAreSelectable() throws SQLException {
- try {
- return databaseMetaData.allTablesAreSelectable();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::allTablesAreSelectable);
}
@Override
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
- try {
- return databaseMetaData.autoCommitFailureClosesAllResultSets();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::autoCommitFailureClosesAllResultSets);
}
@Override
public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
- try {
- return databaseMetaData.dataDefinitionCausesTransactionCommit();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::dataDefinitionCausesTransactionCommit);
}
@Override
public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
- try {
- return databaseMetaData.dataDefinitionIgnoredInTransactions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::dataDefinitionIgnoredInTransactions);
}
@Override
public boolean deletesAreDetected(final int type) throws SQLException {
- try {
- return databaseMetaData.deletesAreDetected(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.deletesAreDetected(type));
}
@Override
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
- try {
- return databaseMetaData.doesMaxRowSizeIncludeBlobs();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::doesMaxRowSizeIncludeBlobs);
}
@Override
public boolean generatedKeyAlwaysReturned() throws SQLException {
connection.checkOpen();
+ return getB(() -> Jdbc41Bridge.generatedKeyAlwaysReturned(databaseMetaData));
+ }
+
+ private <T> T get(final Callable<T> s) throws SQLException {
+ return get(s, null);
+ }
+
+ private <T> T get(final Callable<T> s, final T defaultValue) throws SQLException {
try {
- return Jdbc41Bridge.generatedKeyAlwaysReturned(databaseMetaData);
- } catch (final SQLException e) {
- handleException(e);
- return false;
+ return s.call();
+ } catch (final Exception e) {
+ if (e instanceof SQLException) {
+ handleException((SQLException) e);
+ }
+ return defaultValue;
}
}
@Override
- public ResultSet getAttributes(final String catalog, final String schemaPattern, final String typeNamePattern,
- final String attributeNamePattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getAttributes(final String catalog, final String schemaPattern, final String typeNamePattern, final String attributeNamePattern)
+ throws SQLException {
+ return getRS(() -> databaseMetaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern));
+ }
+
+ private boolean getB(final Callable<Boolean> s) throws SQLException {
+ return get(s, false);
}
@Override
- public ResultSet getBestRowIdentifier(final String catalog, final String schema, final String table,
- final int scope, final boolean nullable) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getBestRowIdentifier(catalog, schema, table, scope, nullable));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getBestRowIdentifier(final String catalog, final String schema, final String table, final int scope, final boolean nullable)
+ throws SQLException {
+ return getRS(() -> databaseMetaData.getBestRowIdentifier(catalog, schema, table, scope, nullable));
}
@Override
public ResultSet getCatalogs() throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getCatalogs());
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(databaseMetaData::getCatalogs);
}
@Override
public String getCatalogSeparator() throws SQLException {
- try {
- return databaseMetaData.getCatalogSeparator();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getCatalogSeparator);
}
@Override
public String getCatalogTerm() throws SQLException {
- try {
- return databaseMetaData.getCatalogTerm();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getCatalogTerm);
}
@Override
public ResultSet getClientInfoProperties() throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getClientInfoProperties());
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(databaseMetaData::getClientInfoProperties);
}
@Override
- public ResultSet getColumnPrivileges(final String catalog, final String schema, final String table,
- final String columnNamePattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getColumnPrivileges(catalog, schema, table, columnNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getColumnPrivileges(final String catalog, final String schema, final String table, final String columnNamePattern) throws SQLException {
+ return getRS(() -> databaseMetaData.getColumnPrivileges(catalog, schema, table, columnNamePattern));
}
@Override
- public ResultSet getColumns(final String catalog, final String schemaPattern, final String tableNamePattern,
- final String columnNamePattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getColumns(final String catalog, final String schemaPattern, final String tableNamePattern, final String columnNamePattern)
+ throws SQLException {
+ return getRS(() -> databaseMetaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern));
}
@Override
@@ -237,66 +163,34 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
}
@Override
- public ResultSet getCrossReference(final String parentCatalog, final String parentSchema, final String parentTable,
- final String foreignCatalog, final String foreignSchema, final String foreignTable) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getCrossReference(parentCatalog,
- parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getCrossReference(final String parentCatalog, final String parentSchema, final String parentTable, final String foreignCatalog,
+ final String foreignSchema, final String foreignTable) throws SQLException {
+ return getRS(() -> databaseMetaData.getCrossReference(parentCatalog, parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable));
}
@Override
public int getDatabaseMajorVersion() throws SQLException {
- try {
- return databaseMetaData.getDatabaseMajorVersion();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getDatabaseMajorVersion);
}
@Override
public int getDatabaseMinorVersion() throws SQLException {
- try {
- return databaseMetaData.getDatabaseMinorVersion();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getDatabaseMinorVersion);
}
@Override
public String getDatabaseProductName() throws SQLException {
- try {
- return databaseMetaData.getDatabaseProductName();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getDatabaseProductName);
}
@Override
public String getDatabaseProductVersion() throws SQLException {
- try {
- return databaseMetaData.getDatabaseProductVersion();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getDatabaseProductVersion);
}
@Override
public int getDefaultTransactionIsolation() throws SQLException {
- try {
- return databaseMetaData.getDefaultTransactionIsolation();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getDefaultTransactionIsolation);
}
/**
@@ -320,119 +214,63 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
@Override
public String getDriverName() throws SQLException {
- try {
- return databaseMetaData.getDriverName();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getDriverName);
}
@Override
public String getDriverVersion() throws SQLException {
- try {
- return databaseMetaData.getDriverVersion();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getDriverVersion);
}
@Override
- public ResultSet getExportedKeys(final String catalog, final String schema, final String table)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getExportedKeys(catalog, schema, table));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getExportedKeys(final String catalog, final String schema, final String table) throws SQLException {
+ return getRS(() -> databaseMetaData.getExportedKeys(catalog, schema, table));
}
@Override
public String getExtraNameCharacters() throws SQLException {
- try {
- return databaseMetaData.getExtraNameCharacters();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getExtraNameCharacters);
}
@Override
- public ResultSet getFunctionColumns(final String catalog, final String schemaPattern,
- final String functionNamePattern, final String columnNamePattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getFunctionColumns(catalog,
- schemaPattern, functionNamePattern, columnNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getFunctionColumns(final String catalog, final String schemaPattern, final String functionNamePattern, final String columnNamePattern)
+ throws SQLException {
+ return getRS(() -> databaseMetaData.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern));
}
@Override
- public ResultSet getFunctions(final String catalog, final String schemaPattern, final String functionNamePattern)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getFunctions(catalog, schemaPattern, functionNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getFunctions(final String catalog, final String schemaPattern, final String functionNamePattern) throws SQLException {
+ return getRS(() -> databaseMetaData.getFunctions(catalog, schemaPattern, functionNamePattern));
+ }
+
+ private int getI(final Callable<Integer> s) throws SQLException {
+ return get(s, 0);
}
@Override
public String getIdentifierQuoteString() throws SQLException {
- try {
- return databaseMetaData.getIdentifierQuoteString();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getIdentifierQuoteString);
}
@Override
- public ResultSet getImportedKeys(final String catalog, final String schema, final String table)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getImportedKeys(catalog, schema, table));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getImportedKeys(final String catalog, final String schema, final String table) throws SQLException {
+ return getRS(() -> databaseMetaData.getImportedKeys(catalog, schema, table));
}
@Override
- public ResultSet getIndexInfo(final String catalog, final String schema, final String table, final boolean unique,
- final boolean approximate) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getIndexInfo(catalog, schema, table, unique, approximate));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getIndexInfo(final String catalog, final String schema, final String table, final boolean unique, final boolean approximate)
+ throws SQLException {
+ return getRS(() -> databaseMetaData.getIndexInfo(catalog, schema, table, unique, approximate));
}
/**
- * If my underlying {@link ResultSet} is not a {@code DelegatingResultSet}, returns it, otherwise recursively
- * invokes this method on my delegate.
+ * If my underlying {@link ResultSet} is not a {@code DelegatingResultSet}, returns it, otherwise recursively invokes this method on my delegate.
* <p>
- * Hence this method will return the first delegate that is not a {@code DelegatingResultSet}, or {@code null} when
- * no non-{@code DelegatingResultSet} delegate can be found by traversing this chain.
+ * Hence this method will return the first delegate that is not a {@code DelegatingResultSet}, or {@code null} when no non-{@code DelegatingResultSet}
+ * delegate can be found by traversing this chain.
* </p>
* <p>
- * This method is useful when you may have nested {@code DelegatingResultSet}s, and you want to make sure to obtain
- * a "genuine" {@link ResultSet}.
+ * This method is useful when you may have nested {@code DelegatingResultSet}s, and you want to make sure to obtain a "genuine" {@link ResultSet}.
* </p>
*
* @return the innermost database meta data.
@@ -450,142 +288,76 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
@Override
public int getJDBCMajorVersion() throws SQLException {
- try {
- return databaseMetaData.getJDBCMajorVersion();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getJDBCMajorVersion);
}
@Override
public int getJDBCMinorVersion() throws SQLException {
- try {
- return databaseMetaData.getJDBCMinorVersion();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getJDBCMinorVersion);
+ }
+
+ private long getL(final Callable<Long> s) throws SQLException {
+ return get(s, 0L);
}
@Override
public int getMaxBinaryLiteralLength() throws SQLException {
- try {
- return databaseMetaData.getMaxBinaryLiteralLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxBinaryLiteralLength);
}
@Override
public int getMaxCatalogNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxCatalogNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxCatalogNameLength);
}
@Override
public int getMaxCharLiteralLength() throws SQLException {
- try {
- return databaseMetaData.getMaxCharLiteralLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxCharLiteralLength);
}
@Override
public int getMaxColumnNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxColumnNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxColumnNameLength);
}
@Override
public int getMaxColumnsInGroupBy() throws SQLException {
- try {
- return databaseMetaData.getMaxColumnsInGroupBy();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxColumnsInGroupBy);
}
@Override
public int getMaxColumnsInIndex() throws SQLException {
- try {
- return databaseMetaData.getMaxColumnsInIndex();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxColumnsInIndex);
}
@Override
public int getMaxColumnsInOrderBy() throws SQLException {
- try {
- return databaseMetaData.getMaxColumnsInOrderBy();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxColumnsInOrderBy);
}
@Override
public int getMaxColumnsInSelect() throws SQLException {
- try {
- return databaseMetaData.getMaxColumnsInSelect();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxColumnsInSelect);
}
@Override
public int getMaxColumnsInTable() throws SQLException {
- try {
- return databaseMetaData.getMaxColumnsInTable();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxColumnsInTable);
}
@Override
public int getMaxConnections() throws SQLException {
- try {
- return databaseMetaData.getMaxConnections();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxConnections);
}
@Override
public int getMaxCursorNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxCursorNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxCursorNameLength);
}
@Override
public int getMaxIndexLength() throws SQLException {
- try {
- return databaseMetaData.getMaxIndexLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxIndexLength);
}
/**
@@ -593,397 +365,198 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
*/
@Override
public long getMaxLogicalLobSize() throws SQLException {
- try {
- return databaseMetaData.getMaxLogicalLobSize();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getL(databaseMetaData::getMaxLogicalLobSize);
}
@Override
public int getMaxProcedureNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxProcedureNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxProcedureNameLength);
}
@Override
public int getMaxRowSize() throws SQLException {
- try {
- return databaseMetaData.getMaxRowSize();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxRowSize);
}
@Override
public int getMaxSchemaNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxSchemaNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxSchemaNameLength);
}
@Override
public int getMaxStatementLength() throws SQLException {
- try {
- return databaseMetaData.getMaxStatementLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxStatementLength);
}
@Override
public int getMaxStatements() throws SQLException {
- try {
- return databaseMetaData.getMaxStatements();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxStatements);
}
@Override
public int getMaxTableNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxTableNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxTableNameLength);
}
@Override
public int getMaxTablesInSelect() throws SQLException {
- try {
- return databaseMetaData.getMaxTablesInSelect();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxTablesInSelect);
}
@Override
public int getMaxUserNameLength() throws SQLException {
- try {
- return databaseMetaData.getMaxUserNameLength();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getMaxUserNameLength);
}
@Override
public String getNumericFunctions() throws SQLException {
- try {
- return databaseMetaData.getNumericFunctions();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getNumericFunctions);
}
@Override
public ResultSet getPrimaryKeys(final String catalog, final String schema, final String table) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getPrimaryKeys(catalog, schema, table));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(() -> databaseMetaData.getPrimaryKeys(catalog, schema, table));
}
@Override
- public ResultSet getProcedureColumns(final String catalog, final String schemaPattern,
- final String procedureNamePattern, final String columnNamePattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getProcedureColumns(catalog,
- schemaPattern, procedureNamePattern, columnNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getProcedureColumns(final String catalog, final String schemaPattern, final String procedureNamePattern, final String columnNamePattern)
+ throws SQLException {
+ return getRS(() -> databaseMetaData.getProcedureColumns(catalog, schemaPattern, procedureNamePattern, columnNamePattern));
}
@Override
- public ResultSet getProcedures(final String catalog, final String schemaPattern, final String procedureNamePattern)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getProcedures(catalog, schemaPattern, procedureNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getProcedures(final String catalog, final String schemaPattern, final String procedureNamePattern) throws SQLException {
+ return getRS(() -> databaseMetaData.getProcedures(catalog, schemaPattern, procedureNamePattern));
}
@Override
public String getProcedureTerm() throws SQLException {
- try {
- return databaseMetaData.getProcedureTerm();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getProcedureTerm);
}
@Override
- public ResultSet getPseudoColumns(final String catalog, final String schemaPattern, final String tableNamePattern,
- final String columnNamePattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, Jdbc41Bridge.getPseudoColumns(databaseMetaData,
- catalog, schemaPattern, tableNamePattern, columnNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getPseudoColumns(final String catalog, final String schemaPattern, final String tableNamePattern, final String columnNamePattern)
+ throws SQLException {
+ return getRS(() -> Jdbc41Bridge.getPseudoColumns(databaseMetaData, catalog, schemaPattern, tableNamePattern, columnNamePattern));
}
@Override
public int getResultSetHoldability() throws SQLException {
- try {
- return databaseMetaData.getResultSetHoldability();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getResultSetHoldability);
}
@Override
public RowIdLifetime getRowIdLifetime() throws SQLException {
- try {
- return databaseMetaData.getRowIdLifetime();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getRowIdLifetime);
+ }
+
+ @SuppressWarnings("resource")
+ private ResultSet getRS(final Callable<ResultSet> s) throws SQLException {
+ connection.checkOpen();
+ return DelegatingResultSet.wrapResultSet(connection, get(s));
}
@Override
public ResultSet getSchemas() throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getSchemas());
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(databaseMetaData::getSchemas);
}
@Override
public ResultSet getSchemas(final String catalog, final String schemaPattern) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getSchemas(catalog, schemaPattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(() -> databaseMetaData.getSchemas(catalog, schemaPattern));
}
@Override
public String getSchemaTerm() throws SQLException {
- try {
- return databaseMetaData.getSchemaTerm();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getSchemaTerm);
}
@Override
public String getSearchStringEscape() throws SQLException {
- try {
- return databaseMetaData.getSearchStringEscape();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getSearchStringEscape);
}
@Override
public String getSQLKeywords() throws SQLException {
- try {
- return databaseMetaData.getSQLKeywords();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getSQLKeywords);
}
@Override
public int getSQLStateType() throws SQLException {
- try {
- return databaseMetaData.getSQLStateType();
- } catch (final SQLException e) {
- handleException(e);
- return 0;
- }
+ return getI(databaseMetaData::getSQLStateType);
}
@Override
public String getStringFunctions() throws SQLException {
- try {
- return databaseMetaData.getStringFunctions();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getStringFunctions);
}
@Override
- public ResultSet getSuperTables(final String catalog, final String schemaPattern, final String tableNamePattern)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getSuperTables(catalog, schemaPattern, tableNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getSuperTables(final String catalog, final String schemaPattern, final String tableNamePattern) throws SQLException {
+ return getRS(() -> databaseMetaData.getSuperTables(catalog, schemaPattern, tableNamePattern));
}
@Override
- public ResultSet getSuperTypes(final String catalog, final String schemaPattern, final String typeNamePattern)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getSuperTypes(catalog, schemaPattern, typeNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getSuperTypes(final String catalog, final String schemaPattern, final String typeNamePattern) throws SQLException {
+ return getRS(() -> databaseMetaData.getSuperTypes(catalog, schemaPattern, typeNamePattern));
}
@Override
public String getSystemFunctions() throws SQLException {
- try {
- return databaseMetaData.getSystemFunctions();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getSystemFunctions);
}
@Override
- public ResultSet getTablePrivileges(final String catalog, final String schemaPattern, final String tableNamePattern)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getTablePrivileges(final String catalog, final String schemaPattern, final String tableNamePattern) throws SQLException {
+ return getRS(() -> databaseMetaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern));
}
@Override
- public ResultSet getTables(final String catalog, final String schemaPattern, final String tableNamePattern,
- final String[] types) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getTables(catalog, schemaPattern, tableNamePattern, types));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getTables(final String catalog, final String schemaPattern, final String tableNamePattern, final String[] types) throws SQLException {
+ return getRS(() -> databaseMetaData.getTables(catalog, schemaPattern, tableNamePattern, types));
}
@Override
public ResultSet getTableTypes() throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getTableTypes());
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(databaseMetaData::getTableTypes);
}
@Override
public String getTimeDateFunctions() throws SQLException {
- try {
- return databaseMetaData.getTimeDateFunctions();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getTimeDateFunctions);
}
@Override
public ResultSet getTypeInfo() throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection, databaseMetaData.getTypeInfo());
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return getRS(databaseMetaData::getTypeInfo);
}
@Override
- public ResultSet getUDTs(final String catalog, final String schemaPattern, final String typeNamePattern,
- final int[] types) throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getUDTs(catalog, schemaPattern, typeNamePattern, types));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getUDTs(final String catalog, final String schemaPattern, final String typeNamePattern, final int[] types) throws SQLException {
+ return getRS(() -> databaseMetaData.getUDTs(catalog, schemaPattern, typeNamePattern, types));
}
@Override
public String getURL() throws SQLException {
- try {
- return databaseMetaData.getURL();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getURL);
}
@Override
public String getUserName() throws SQLException {
- try {
- return databaseMetaData.getUserName();
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ return get(databaseMetaData::getUserName);
}
@Override
- public ResultSet getVersionColumns(final String catalog, final String schema, final String table)
- throws SQLException {
- connection.checkOpen();
- try {
- return DelegatingResultSet.wrapResultSet(connection,
- databaseMetaData.getVersionColumns(catalog, schema, table));
- } catch (final SQLException e) {
- handleException(e);
- throw new AssertionError();
- }
+ public ResultSet getVersionColumns(final String catalog, final String schema, final String table) throws SQLException {
+ return getRS(() -> databaseMetaData.getVersionColumns(catalog, schema, table));
}
+ /**
+ * Delegates to the connection's {@link DelegatingConnection#handleException(SQLException)}.
+ *
+ * @param e the exception to throw or delegate.
+ * @throws SQLException the exception to throw.
+ */
protected void handleException(final SQLException e) throws SQLException {
if (connection == null) {
throw e;
@@ -993,32 +566,17 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
@Override
public boolean insertsAreDetected(final int type) throws SQLException {
- try {
- return databaseMetaData.insertsAreDetected(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.insertsAreDetected(type));
}
@Override
public boolean isCatalogAtStart() throws SQLException {
- try {
- return databaseMetaData.isCatalogAtStart();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::isCatalogAtStart);
}
@Override
public boolean isReadOnly() throws SQLException {
- try {
- return databaseMetaData.isReadOnly();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::isReadOnly);
}
@Override
@@ -1034,632 +592,318 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
@Override
public boolean locatorsUpdateCopy() throws SQLException {
- try {
- return databaseMetaData.locatorsUpdateCopy();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::locatorsUpdateCopy);
}
@Override
public boolean nullPlusNonNullIsNull() throws SQLException {
- try {
- return databaseMetaData.nullPlusNonNullIsNull();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::nullPlusNonNullIsNull);
}
@Override
public boolean nullsAreSortedAtEnd() throws SQLException {
- try {
- return databaseMetaData.nullsAreSortedAtEnd();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::nullsAreSortedAtEnd);
}
@Override
public boolean nullsAreSortedAtStart() throws SQLException {
- try {
- return databaseMetaData.nullsAreSortedAtStart();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::nullsAreSortedAtStart);
}
@Override
public boolean nullsAreSortedHigh() throws SQLException {
- try {
- return databaseMetaData.nullsAreSortedHigh();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::nullsAreSortedHigh);
}
@Override
public boolean nullsAreSortedLow() throws SQLException {
- try {
- return databaseMetaData.nullsAreSortedLow();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::nullsAreSortedLow);
}
@Override
public boolean othersDeletesAreVisible(final int type) throws SQLException {
- try {
- return databaseMetaData.othersDeletesAreVisible(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.othersDeletesAreVisible(type));
}
@Override
public boolean othersInsertsAreVisible(final int type) throws SQLException {
- try {
- return databaseMetaData.othersInsertsAreVisible(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.othersInsertsAreVisible(type));
}
@Override
public boolean othersUpdatesAreVisible(final int type) throws SQLException {
- try {
- return databaseMetaData.othersUpdatesAreVisible(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.othersUpdatesAreVisible(type));
}
@Override
public boolean ownDeletesAreVisible(final int type) throws SQLException {
- try {
- return databaseMetaData.ownDeletesAreVisible(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.ownDeletesAreVisible(type));
}
@Override
public boolean ownInsertsAreVisible(final int type) throws SQLException {
- try {
- return databaseMetaData.ownInsertsAreVisible(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.ownInsertsAreVisible(type));
}
@Override
public boolean ownUpdatesAreVisible(final int type) throws SQLException {
- try {
- return databaseMetaData.ownUpdatesAreVisible(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.ownUpdatesAreVisible(type));
}
@Override
public boolean storesLowerCaseIdentifiers() throws SQLException {
- try {
- return databaseMetaData.storesLowerCaseIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::storesLowerCaseIdentifiers);
}
@Override
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
- try {
- return databaseMetaData.storesLowerCaseQuotedIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::storesLowerCaseQuotedIdentifiers);
}
@Override
public boolean storesMixedCaseIdentifiers() throws SQLException {
- try {
- return databaseMetaData.storesMixedCaseIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::storesMixedCaseIdentifiers);
}
@Override
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
- try {
- return databaseMetaData.storesMixedCaseQuotedIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::storesMixedCaseQuotedIdentifiers);
}
@Override
public boolean storesUpperCaseIdentifiers() throws SQLException {
- try {
- return databaseMetaData.storesUpperCaseIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::storesUpperCaseIdentifiers);
+
}
@Override
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
- try {
- return databaseMetaData.storesUpperCaseQuotedIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::storesUpperCaseQuotedIdentifiers);
}
@Override
public boolean supportsAlterTableWithAddColumn() throws SQLException {
- try {
- return databaseMetaData.supportsAlterTableWithAddColumn();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsAlterTableWithAddColumn);
}
@Override
public boolean supportsAlterTableWithDropColumn() throws SQLException {
- try {
- return databaseMetaData.supportsAlterTableWithDropColumn();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsAlterTableWithDropColumn);
}
@Override
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
- try {
- return databaseMetaData.supportsANSI92EntryLevelSQL();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsANSI92EntryLevelSQL);
}
@Override
public boolean supportsANSI92FullSQL() throws SQLException {
- try {
- return databaseMetaData.supportsANSI92FullSQL();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsANSI92FullSQL);
}
@Override
public boolean supportsANSI92IntermediateSQL() throws SQLException {
- try {
- return databaseMetaData.supportsANSI92IntermediateSQL();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsANSI92IntermediateSQL);
}
@Override
public boolean supportsBatchUpdates() throws SQLException {
- try {
- return databaseMetaData.supportsBatchUpdates();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsBatchUpdates);
}
@Override
public boolean supportsCatalogsInDataManipulation() throws SQLException {
- try {
- return databaseMetaData.supportsCatalogsInDataManipulation();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCatalogsInDataManipulation);
}
@Override
public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
- try {
- return databaseMetaData.supportsCatalogsInIndexDefinitions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCatalogsInIndexDefinitions);
}
@Override
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
- try {
- return databaseMetaData.supportsCatalogsInPrivilegeDefinitions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCatalogsInPrivilegeDefinitions);
}
@Override
public boolean supportsCatalogsInProcedureCalls() throws SQLException {
- try {
- return databaseMetaData.supportsCatalogsInProcedureCalls();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCatalogsInProcedureCalls);
}
@Override
public boolean supportsCatalogsInTableDefinitions() throws SQLException {
- try {
- return databaseMetaData.supportsCatalogsInTableDefinitions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCatalogsInTableDefinitions);
}
@Override
public boolean supportsColumnAliasing() throws SQLException {
- try {
- return databaseMetaData.supportsColumnAliasing();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsColumnAliasing);
}
@Override
public boolean supportsConvert() throws SQLException {
- try {
- return databaseMetaData.supportsConvert();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsConvert);
}
@Override
public boolean supportsConvert(final int fromType, final int toType) throws SQLException {
- try {
- return databaseMetaData.supportsConvert(fromType, toType);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.supportsConvert(fromType, toType));
}
@Override
public boolean supportsCoreSQLGrammar() throws SQLException {
- try {
- return databaseMetaData.supportsCoreSQLGrammar();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCoreSQLGrammar);
}
@Override
public boolean supportsCorrelatedSubqueries() throws SQLException {
- try {
- return databaseMetaData.supportsCorrelatedSubqueries();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsCorrelatedSubqueries);
}
@Override
public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
- try {
- return databaseMetaData.supportsDataDefinitionAndDataManipulationTransactions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsDataDefinitionAndDataManipulationTransactions);
}
@Override
public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
- try {
- return databaseMetaData.supportsDataManipulationTransactionsOnly();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsDataManipulationTransactionsOnly);
}
@Override
public boolean supportsDifferentTableCorrelationNames() throws SQLException {
- try {
- return databaseMetaData.supportsDifferentTableCorrelationNames();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsDifferentTableCorrelationNames);
}
@Override
public boolean supportsExpressionsInOrderBy() throws SQLException {
- try {
- return databaseMetaData.supportsExpressionsInOrderBy();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsExpressionsInOrderBy);
}
@Override
public boolean supportsExtendedSQLGrammar() throws SQLException {
- try {
- return databaseMetaData.supportsExtendedSQLGrammar();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsExtendedSQLGrammar);
}
@Override
public boolean supportsFullOuterJoins() throws SQLException {
- try {
- return databaseMetaData.supportsFullOuterJoins();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsFullOuterJoins);
}
@Override
public boolean supportsGetGeneratedKeys() throws SQLException {
- try {
- return databaseMetaData.supportsGetGeneratedKeys();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsGetGeneratedKeys);
}
@Override
public boolean supportsGroupBy() throws SQLException {
- try {
- return databaseMetaData.supportsGroupBy();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsGroupBy);
}
@Override
public boolean supportsGroupByBeyondSelect() throws SQLException {
- try {
- return databaseMetaData.supportsGroupByBeyondSelect();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsGroupByBeyondSelect);
}
@Override
public boolean supportsGroupByUnrelated() throws SQLException {
- try {
- return databaseMetaData.supportsGroupByUnrelated();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsGroupByUnrelated);
}
@Override
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
- try {
- return databaseMetaData.supportsIntegrityEnhancementFacility();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsIntegrityEnhancementFacility);
}
@Override
public boolean supportsLikeEscapeClause() throws SQLException {
- try {
- return databaseMetaData.supportsLikeEscapeClause();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsLikeEscapeClause);
}
@Override
public boolean supportsLimitedOuterJoins() throws SQLException {
- try {
- return databaseMetaData.supportsLimitedOuterJoins();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsLimitedOuterJoins);
}
@Override
public boolean supportsMinimumSQLGrammar() throws SQLException {
- try {
- return databaseMetaData.supportsMinimumSQLGrammar();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsMinimumSQLGrammar);
}
@Override
public boolean supportsMixedCaseIdentifiers() throws SQLException {
- try {
- return databaseMetaData.supportsMixedCaseIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsMixedCaseIdentifiers);
}
@Override
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
- try {
- return databaseMetaData.supportsMixedCaseQuotedIdentifiers();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsMixedCaseQuotedIdentifiers);
}
@Override
public boolean supportsMultipleOpenResults() throws SQLException {
- try {
- return databaseMetaData.supportsMultipleOpenResults();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsMultipleOpenResults);
}
@Override
public boolean supportsMultipleResultSets() throws SQLException {
- try {
- return databaseMetaData.supportsMultipleResultSets();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsMultipleResultSets);
}
@Override
public boolean supportsMultipleTransactions() throws SQLException {
- try {
- return databaseMetaData.supportsMultipleTransactions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsMultipleTransactions);
}
@Override
public boolean supportsNamedParameters() throws SQLException {
- try {
- return databaseMetaData.supportsNamedParameters();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsNamedParameters);
}
@Override
public boolean supportsNonNullableColumns() throws SQLException {
- try {
- return databaseMetaData.supportsNonNullableColumns();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsNonNullableColumns);
}
@Override
public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
- try {
- return databaseMetaData.supportsOpenCursorsAcrossCommit();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsOpenCursorsAcrossCommit);
}
@Override
public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
- try {
- return databaseMetaData.supportsOpenCursorsAcrossRollback();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsOpenCursorsAcrossRollback);
}
@Override
public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
- try {
- return databaseMetaData.supportsOpenStatementsAcrossCommit();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsOpenStatementsAcrossCommit);
}
@Override
public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
- try {
- return databaseMetaData.supportsOpenStatementsAcrossRollback();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsOpenStatementsAcrossRollback);
}
@Override
public boolean supportsOrderByUnrelated() throws SQLException {
- try {
- return databaseMetaData.supportsOrderByUnrelated();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsOrderByUnrelated);
}
@Override
public boolean supportsOuterJoins() throws SQLException {
- try {
- return databaseMetaData.supportsOuterJoins();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsOuterJoins);
}
@Override
public boolean supportsPositionedDelete() throws SQLException {
- try {
- return databaseMetaData.supportsPositionedDelete();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsPositionedDelete);
}
@Override
public boolean supportsPositionedUpdate() throws SQLException {
- try {
- return databaseMetaData.supportsPositionedUpdate();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsPositionedUpdate);
}
/**
@@ -1667,232 +911,117 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
*/
@Override
public boolean supportsRefCursors() throws SQLException {
- try {
- return databaseMetaData.supportsRefCursors();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsRefCursors);
}
@Override
public boolean supportsResultSetConcurrency(final int type, final int concurrency) throws SQLException {
- try {
- return databaseMetaData.supportsResultSetConcurrency(type, concurrency);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.supportsResultSetConcurrency(type, concurrency));
}
@Override
public boolean supportsResultSetHoldability(final int holdability) throws SQLException {
- try {
- return databaseMetaData.supportsResultSetHoldability(holdability);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.supportsResultSetHoldability(holdability));
}
@Override
public boolean supportsResultSetType(final int type) throws SQLException {
- try {
- return databaseMetaData.supportsResultSetType(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.supportsResultSetType(type));
}
@Override
public boolean supportsSavepoints() throws SQLException {
- try {
- return databaseMetaData.supportsSavepoints();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSavepoints);
}
@Override
public boolean supportsSchemasInDataManipulation() throws SQLException {
- try {
- return databaseMetaData.supportsSchemasInDataManipulation();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSchemasInDataManipulation);
}
@Override
public boolean supportsSchemasInIndexDefinitions() throws SQLException {
- try {
- return databaseMetaData.supportsSchemasInIndexDefinitions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSchemasInIndexDefinitions);
}
@Override
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
- try {
- return databaseMetaData.supportsSchemasInPrivilegeDefinitions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSchemasInPrivilegeDefinitions);
}
@Override
public boolean supportsSchemasInProcedureCalls() throws SQLException {
- try {
- return databaseMetaData.supportsSchemasInProcedureCalls();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSchemasInProcedureCalls);
}
@Override
public boolean supportsSchemasInTableDefinitions() throws SQLException {
- try {
- return databaseMetaData.supportsSchemasInTableDefinitions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSchemasInTableDefinitions);
}
@Override
public boolean supportsSelectForUpdate() throws SQLException {
- try {
- return databaseMetaData.supportsSelectForUpdate();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSelectForUpdate);
}
@Override
public boolean supportsStatementPooling() throws SQLException {
- try {
- return databaseMetaData.supportsStatementPooling();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsStatementPooling);
}
@Override
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
- try {
- return databaseMetaData.supportsStoredFunctionsUsingCallSyntax();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsStoredFunctionsUsingCallSyntax);
}
@Override
public boolean supportsStoredProcedures() throws SQLException {
- try {
- return databaseMetaData.supportsStoredProcedures();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsStoredProcedures);
}
@Override
public boolean supportsSubqueriesInComparisons() throws SQLException {
- try {
- return databaseMetaData.supportsSubqueriesInComparisons();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSubqueriesInComparisons);
}
@Override
public boolean supportsSubqueriesInExists() throws SQLException {
- try {
- return databaseMetaData.supportsSubqueriesInExists();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSubqueriesInExists);
}
@Override
public boolean supportsSubqueriesInIns() throws SQLException {
- try {
- return databaseMetaData.supportsSubqueriesInIns();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSubqueriesInIns);
}
@Override
public boolean supportsSubqueriesInQuantifieds() throws SQLException {
- try {
- return databaseMetaData.supportsSubqueriesInQuantifieds();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsSubqueriesInQuantifieds);
}
@Override
public boolean supportsTableCorrelationNames() throws SQLException {
- try {
- return databaseMetaData.supportsTableCorrelationNames();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsTableCorrelationNames);
}
@Override
public boolean supportsTransactionIsolationLevel(final int level) throws SQLException {
- try {
- return databaseMetaData.supportsTransactionIsolationLevel(level);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.supportsTransactionIsolationLevel(level));
}
@Override
public boolean supportsTransactions() throws SQLException {
- try {
- return databaseMetaData.supportsTransactions();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsTransactions);
}
@Override
public boolean supportsUnion() throws SQLException {
- try {
- return databaseMetaData.supportsUnion();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsUnion);
}
@Override
public boolean supportsUnionAll() throws SQLException {
- try {
- return databaseMetaData.supportsUnionAll();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::supportsUnionAll);
}
@Override
@@ -1908,31 +1037,16 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
@Override
public boolean updatesAreDetected(final int type) throws SQLException {
- try {
- return databaseMetaData.updatesAreDetected(type);
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(() -> databaseMetaData.updatesAreDetected(type));
}
@Override
public boolean usesLocalFilePerTable() throws SQLException {
- try {
- return databaseMetaData.usesLocalFilePerTable();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::usesLocalFilePerTable);
}
@Override
public boolean usesLocalFiles() throws SQLException {
- try {
- return databaseMetaData.usesLocalFiles();
- } catch (final SQLException e) {
- handleException(e);
- return false;
- }
+ return getB(databaseMetaData::usesLocalFiles);
}
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingPreparedStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingPreparedStatement.java
index 8c0cc3200a..0864bdad89 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingPreparedStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingPreparedStatement.java
@@ -32,12 +32,12 @@ import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLType;
import java.sql.SQLXML;
-import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
+import java.util.Objects;
/**
* A base delegating implementation of {@link PreparedStatement}.
@@ -712,7 +712,6 @@ public class DelegatingPreparedStatement extends DelegatingStatement implements
*/
@Override
public synchronized String toString() {
- final Statement statement = getDelegate();
- return statement == null ? "NULL" : statement.toString();
+ return Objects.toString(getDelegate(), "NULL");
}
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
index abfedf3590..faf06e18be 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
@@ -23,6 +23,7 @@ import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* A base delegating implementation of {@link Statement}.
@@ -93,7 +94,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
protected void checkOpen() throws SQLException {
if (isClosed()) {
- throw new SQLException(this.getClass().getName() + " with address: \"" + this.toString() + "\" is closed.");
+ throw new SQLException(this.getClass().getName() + " with address: \"" + toString() + "\" is closed.");
}
}
@@ -795,7 +796,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
*/
@Override
public synchronized String toString() {
- return statement == null ? "NULL" : statement.toString();
+ return Objects.toString(statement, "NULL");
}
@Override
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
index a5752919b2..b14cc26958 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
@@ -53,6 +53,8 @@ public class DriverConnectionFactory implements ConnectionFactory {
}
/**
+ * Gets the connection String.
+ *
* @return The connection String.
* @since 2.6.0
*/
@@ -61,7 +63,9 @@ public class DriverConnectionFactory implements ConnectionFactory {
}
/**
- * @return The Driver.
+ * Gets the JDBC Driver.
+ *
+ * @return The JDBC Driver.
* @since 2.6.0
*/
public Driver getDriver() {
@@ -69,7 +73,9 @@ public class DriverConnectionFactory implements ConnectionFactory {
}
/**
- * @return The Properties.
+ * Gets the properties.
+ *
+ * @return The properties.
* @since 2.6.0
*/
public Properties getProperties() {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
index 0bb84c0347..d2a2161362 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
@@ -76,7 +76,7 @@ public class PoolableCallableStatement extends DelegatingCallableStatement {
@Override
public void activate() throws SQLException {
setClosedInternal(false);
- AbandonedTrace.add(getConnectionInternal(), this);
+ add(getConnectionInternal(), this);
super.activate();
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
index 0459d176db..532091d957 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
@@ -71,11 +71,19 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
private boolean fatalSqlExceptionThrown;
/**
- * SQL_STATE codes considered to signal fatal conditions. Overrides the defaults in
+ * SQL State codes considered to signal fatal conditions. Overrides the defaults in
* {@link Utils#getDisconnectionSqlCodes()} (plus anything starting with {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}).
*/
private final Collection<String> disconnectionSqlCodes;
+ /**
+ * A collection of SQL State codes that are not considered fatal disconnection codes.
+ *
+ * @since 2.13.0
+ */
+ private final Collection<String> disconnectionIgnoreSqlCodes;
+
+
/** Whether or not to fast fail validation after fatal connection errors */
private final boolean fastFailValidation;
@@ -102,18 +110,43 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
* @param jmxObjectName
* JMX name
* @param disconnectSqlCodes
- * SQL_STATE codes considered fatal disconnection errors
+ * SQL State codes considered fatal disconnection errors
* @param fastFailValidation
* true means fatal disconnection errors cause subsequent validations to fail immediately (no attempt to
* run query or isValid)
*/
+ public PoolableConnection(final Connection conn, final ObjectPool<PoolableConnection> pool,
+ final ObjectName jmxObjectName, final Collection<String> disconnectSqlCodes,
+ final boolean fastFailValidation) {
+ this(conn, pool, jmxObjectName, disconnectSqlCodes, null, fastFailValidation);
+ }
+
+ /**
+ * Creates a new {@link PoolableConnection} instance.
+ *
+ * @param conn
+ * my underlying connection
+ * @param pool
+ * the pool to which I should return when closed
+ * @param jmxObjectName
+ * JMX name
+ * @param disconnectSqlCodes
+ * SQL State codes considered fatal disconnection errors
+ * @param disconnectionIgnoreSqlCodes
+ * SQL State codes that should be ignored when determining fatal disconnection errors
+ * @param fastFailValidation
+ * true means fatal disconnection errors cause subsequent validations to fail immediately (no attempt to
+ * run query or isValid)
+ * @since 2.13.0
+ */
public PoolableConnection(final Connection conn, final ObjectPool<PoolableConnection> pool,
final ObjectName jmxObjectName, final Collection<String> disconnectSqlCodes,
- final boolean fastFailValidation) {
+ final Collection<String> disconnectionIgnoreSqlCodes, final boolean fastFailValidation) {
super(conn);
this.pool = pool;
this.jmxObjectName = ObjectNameWrapper.wrap(jmxObjectName);
this.disconnectionSqlCodes = disconnectSqlCodes;
+ this.disconnectionIgnoreSqlCodes = disconnectionIgnoreSqlCodes;
this.fastFailValidation = fastFailValidation;
if (jmxObjectName != null) {
@@ -139,7 +172,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
}
/**
- * Returns me to my pool.
+ * Returns this instance to my containing pool.
*/
@Override
public void close() throws SQLException {
@@ -212,7 +245,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
}
/**
- * Expose the {@link #toString()} method via a bean getter, so it can be read as a property via JMX.
+ * Gets the value of the {@link #toString()} method via a bean getter, so it can be read as a property via JMX.
*/
@Override
public String getToString() {
@@ -255,7 +288,8 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
* If {@link #disconnectionSqlCodes} has been set, sql states are compared to those in the configured list of fatal
* exception codes. If this property is not set, codes are compared against the default codes in
* {@link Utils#getDisconnectionSqlCodes()} and in this case anything starting with #{link
- * Utils.DISCONNECTION_SQL_CODE_PREFIX} is considered a disconnection.
+ * Utils.DISCONNECTION_SQL_CODE_PREFIX} is considered a disconnection. Additionally, any SQL state
+ * listed in {@link #disconnectionIgnoreSqlCodes} will be ignored and not treated as fatal.
* </p>
*
* @param e SQLException to be examined
@@ -265,8 +299,11 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
boolean fatalException = false;
final String sqlState = e.getSQLState();
if (sqlState != null) {
+ if (disconnectionIgnoreSqlCodes != null && disconnectionIgnoreSqlCodes.contains(sqlState)) {
+ return false;
+ }
fatalException = disconnectionSqlCodes == null
- ? sqlState.startsWith(Utils.DISCONNECTION_SQL_CODE_PREFIX) || Utils.getDisconnectionSqlCodes().contains(sqlState)
+ ? sqlState.startsWith(Utils.DISCONNECTION_SQL_CODE_PREFIX) || Utils.isDisconnectionSqlCode(sqlState)
: disconnectionSqlCodes.contains(sqlState);
}
return fatalException;
@@ -317,7 +354,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
}
/**
- * Actually close my underlying {@link Connection}.
+ * Closes the underlying {@link Connection}.
*/
@Override
public void reallyClose() throws SQLException {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
index 4ebede76c5..35bda67bee 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
@@ -64,6 +64,8 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
private Collection<String> disconnectionSqlCodes;
+ private Collection<String> disconnectionIgnoreSqlCodes;
+
private boolean fastFailValidation = true;
private volatile ObjectPool<PoolableConnection> pool;
@@ -147,14 +149,14 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
@Override
public void destroyObject(final PooledObject<PoolableConnection> p, final DestroyMode mode) throws SQLException {
if (mode == DestroyMode.ABANDONED) {
- p.getObject().getInnermostDelegate().abort(Runnable::run);
+ Jdbc41Bridge.abort(p.getObject().getInnermostDelegate(), Runnable::run);
} else {
p.getObject().reallyClose();
}
}
/**
- * Gets the cache state.
+ * Gets the cache state to propagate in {@link #makeObject()}.
*
* @return The cache state.
* @since 2.6.0.
@@ -173,11 +175,18 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
return connectionFactory;
}
+ /**
+ * Gets how many connections were created in {@link #makeObject()}.
+ *
+ * @return the connection count.
+ */
protected AtomicLong getConnectionIndex() {
return connectionIndex;
}
/**
+ * Gets the collection of initialization SQL statements.
+ *
* @return The collection of initialization SQL statements.
* @since 2.6.0
*/
@@ -186,7 +195,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return The data source JMX ObjectName
+ * Gets data source JMX ObjectName.
+ *
+ * @return The data source JMX ObjectName.
* @since 2.6.0.
*/
public ObjectName getDataSourceJmxName() {
@@ -194,7 +205,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return The data source JMS ObjectName.
+ * Gets the data source JMX ObjectName.
+ *
+ * @return The data source JMX ObjectName.
* @since 2.6.0
*/
public ObjectName getDataSourceJmxObjectName() {
@@ -202,7 +215,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default auto-commit value.
+ * Gets the Default auto-commit value.
+ *
+ * @return The default auto-commit value.
* @since 2.6.0
*/
public Boolean getDefaultAutoCommit() {
@@ -210,7 +225,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default catalog.
+ * Gets the default catalog.
+ *
+ * @return The default catalog.
* @since 2.6.0
*/
public String getDefaultCatalog() {
@@ -218,7 +235,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default query timeout in seconds.
+ * Gets the default query timeout in seconds.
+ *
+ * @return The default query timeout in seconds.
* @deprecated Use {@link #getDefaultQueryTimeoutDuration()}.
*/
@Deprecated
@@ -229,7 +248,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
/**
* Gets the default query timeout Duration.
*
- * @return Default query timeout Duration.
+ * @return The default query timeout Duration.
* @since 2.10.0
*/
public Duration getDefaultQueryTimeoutDuration() {
@@ -237,7 +256,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default query timeout in seconds.
+ * Gets the default query timeout in seconds.
+ *
+ * @return The default query timeout in seconds.
* @since 2.6.0
* @deprecated Use {@link #getDefaultQueryTimeoutDuration()}.
*/
@@ -247,7 +268,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default read-only-value.
+ * Gets the default read-only-value.
+ *
+ * @return The default read-only-value.
* @since 2.6.0
*/
public Boolean getDefaultReadOnly() {
@@ -255,7 +278,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default schema.
+ * Gets the default schema.
+ *
+ * @return The default schema.
* @since 2.6.0
*/
public String getDefaultSchema() {
@@ -263,7 +288,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Default transaction isolation.
+ * Gets the default transaction isolation.
+ *
+ * @return The default transaction isolation.
* @since 2.6.0
*/
public int getDefaultTransactionIsolation() {
@@ -271,11 +298,26 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * SQL_STATE codes considered to signal fatal conditions.
+ * Gets the collection of SQL State codes that are not considered fatal disconnection codes.
+ * <p>
+ * This method returns the collection of SQL State codes that have been set to be ignored when
+ * determining if a {@link SQLException} signals a disconnection. These codes are excluded from
+ * being treated as fatal even if they match the typical disconnection criteria.
+ * </p>
+ *
+ * @return a {@link Collection} of SQL State codes that should be ignored for disconnection checks.
+ * @since 2.13.0
+ */
+ public Collection<String> getDisconnectionIgnoreSqlCodes() {
+ return disconnectionIgnoreSqlCodes;
+ }
+
+ /**
+ * Gets SQL State codes considered to signal fatal conditions.
* <p>
* Overrides the defaults in {@link Utils#getDisconnectionSqlCodes()} (plus anything starting with
* {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}). If this property is non-null and {@link #isFastFailValidation()} is
- * {@code true}, whenever connections created by this factory generate exceptions with SQL_STATE codes in this list,
+ * {@code true}, whenever connections created by this factory generate exceptions with SQL State codes in this list,
* they will be marked as "fatally disconnected" and subsequent validations will fail fast (no attempt at isValid or
* validation query).
* </p>
@@ -283,7 +325,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
* If {@link #isFastFailValidation()} is {@code false} setting this property has no effect.
* </p>
*
- * @return SQL_STATE codes overriding defaults
+ * @return SQL State codes overriding defaults
* @since 2.1
*/
public Collection<String> getDisconnectionSqlCodes() {
@@ -310,9 +352,15 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
return maxConnDuration.toMillis();
}
+ /**
+ * Gets the maximum number of open prepared statements.
+ *
+ * @return The maximum number of open prepared statements.
+ */
protected int getMaxOpenPreparedStatements() {
return maxOpenPreparedStatements;
}
+
/**
* Returns the {@link ObjectPool} in which {@link Connection}s are pooled.
*
@@ -321,14 +369,20 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
public synchronized ObjectPool<PoolableConnection> getPool() {
return pool;
}
+
/**
+ * Tests whether to pool statements.
+ *
* @return Whether to pool statements.
* @since 2.6.0.
*/
public boolean getPoolStatements() {
return poolStatements;
}
+
/**
+ * Gets the validation query.
+ *
* @return Validation query.
* @since 2.6.0
*/
@@ -358,6 +412,13 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
return (int) validationQueryTimeoutDuration.getSeconds();
}
+ /**
+ * Initializes the given connection with the collection of SQL statements set in {@link #setConnectionInitSql(Collection)}.
+ *
+ * @param conn the connection to initialize.
+ * @throws SQLException if a database access error occurs or this method is called on a closed connection.
+ * @see #setConnectionInitSql(Collection)
+ */
protected void initializeConnection(final Connection conn) throws SQLException {
final Collection<String> sqls = connectionInitSqls;
if (conn.isClosed()) {
@@ -373,7 +434,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Whether to auto-commit on return.
+ * Tests whether to set auto-commit on {@link #passivateObject(PooledObject)}.
+ *
+ * @return Whether to set auto-commit on {@link #passivateObject(PooledObject)}.
* @since 2.6.0
*/
public boolean isAutoCommitOnReturn() {
@@ -381,7 +444,9 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
- * @return Whether to auto-commit on return.
+ * Tests whether to set auto-commit on {@link #passivateObject(PooledObject)}.
+ *
+ * @return Whether to set auto-commit on {@link #passivateObject(PooledObject)}.
* @deprecated Use {@link #isAutoCommitOnReturn()}.
*/
@Deprecated
@@ -391,7 +456,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
/**
* True means that validation will fail immediately for connections that have previously thrown SQLExceptions with
- * SQL_STATE indicating fatal disconnection errors.
+ * SQL State indicating fatal disconnection errors.
*
* @return true if connections created by this factory will fast fail validation.
* @see #setDisconnectionSqlCodes(Collection)
@@ -403,6 +468,8 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
+ * Tests whether to rollback on return.
+ *
* @return Whether to rollback on return.
*/
public boolean isRollbackOnReturn() {
@@ -464,7 +531,8 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
}
- final PoolableConnection pc = new PoolableConnection(conn, pool, connJmxName, disconnectionSqlCodes, fastFailValidation);
+ final PoolableConnection pc = new PoolableConnection(conn, pool, connJmxName,
+ disconnectionSqlCodes, disconnectionIgnoreSqlCodes, fastFailValidation);
pc.setCacheState(cacheState);
return new DefaultPooledObject<>(pc);
@@ -500,10 +568,20 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
conn.passivate();
}
+ /**
+ * Sets whether to set auto-commit on {@link #passivateObject(PooledObject)}.
+ *
+ * @param autoCommitOnReturn whether to set auto-commit.
+ */
public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
this.autoCommitOnReturn = autoCommitOnReturn;
}
+ /**
+ * Sets the cache state to propagate in {@link #makeObject()}.
+ *
+ * @param cacheState the cache state to propagate.
+ */
public void setCacheState(final boolean cacheState) {
this.cacheState = cacheState;
}
@@ -602,18 +680,37 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
}
/**
+ * Sets the disconnection SQL codes to ignore.
+ *
+ * @param disconnectionIgnoreSqlCodes
+ * The collection of SQL State codes to be ignored.
+ * @see #getDisconnectionIgnoreSqlCodes()
+ * @throws IllegalArgumentException if any SQL state codes overlap with those in {@link #disconnectionSqlCodes}.
+ * @since 2.13.0
+ */
+ public void setDisconnectionIgnoreSqlCodes(final Collection<String> disconnectionIgnoreSqlCodes) {
+ Utils.checkSqlCodes(disconnectionIgnoreSqlCodes, this.disconnectionSqlCodes);
+ this.disconnectionIgnoreSqlCodes = disconnectionIgnoreSqlCodes;
+ }
+
+ /**
+ * Sets the disconnection SQL codes.
+ *
* @param disconnectionSqlCodes
* The disconnection SQL codes.
* @see #getDisconnectionSqlCodes()
* @since 2.1
+ * @throws IllegalArgumentException if any SQL state codes overlap with those in {@link #disconnectionIgnoreSqlCodes}.
*/
public void setDisconnectionSqlCodes(final Collection<String> disconnectionSqlCodes) {
+ Utils.checkSqlCodes(disconnectionSqlCodes, this.disconnectionIgnoreSqlCodes);
this.disconnectionSqlCodes = disconnectionSqlCodes;
}
/**
- * @param autoCommitOnReturn Whether to auto-commit on return.
- * @deprecated Use {@link #setAutoCommitOnReturn(boolean)}.
+ * Sets whether to set auto-commit on {@link #passivateObject(PooledObject)}.
+ *
+ * @param autoCommitOnReturn whether to set auto-commit.
*/
@Deprecated
public void setEnableAutoCommitOnReturn(final boolean autoCommitOnReturn) {
@@ -690,10 +787,20 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
this.pool = pool;
}
+ /**
+ * Sets whether to pool statements.
+ *
+ * @param poolStatements whether to pool statements.
+ */
public void setPoolStatements(final boolean poolStatements) {
this.poolStatements = poolStatements;
}
+ /**
+ * Sets whether to rollback on return.
+ *
+ * @param rollbackOnReturn whether to rollback on return.
+ */
public void setRollbackOnReturn(final boolean rollbackOnReturn) {
this.rollbackOnReturn = rollbackOnReturn;
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionMXBean.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionMXBean.java
index f72c565607..e3b4bf8bf5 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionMXBean.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionMXBean.java
@@ -16,6 +16,7 @@
*/
package org.apache.tomcat.dbcp.dbcp2;
+import java.sql.Connection;
import java.sql.SQLException;
/**
@@ -25,43 +26,166 @@ import java.sql.SQLException;
*/
public interface PoolableConnectionMXBean {
+ /**
+ * Clears the cached state. Call when you know that the underlying connection may have been accessed directly.
+ */
void clearCachedState();
+ /**
+ * See {@link Connection#clearWarnings()}.
+ *
+ * @throws SQLException See {@link Connection#clearWarnings()}.
+ */
void clearWarnings() throws SQLException;
+ /**
+ * Returns this instance to my containing pool.
+ *
+ * @throws SQLException Throw if this instance cannot be returned.
+ */
void close() throws SQLException;
+ /**
+ * See {@link Connection#getAutoCommit()}.
+ *
+ * @return See {@link Connection#getAutoCommit()}.
+ * @throws SQLException See {@link Connection#getAutoCommit()}.
+ */
boolean getAutoCommit() throws SQLException;
+ /**
+ * Gets whether to cache properties. The cached properties are:
+ * <ul>
+ * <li>auto-commit</li>
+ * <li>catalog</li>
+ * <li>schema</li>
+ * <li>read-only</li>
+ * </ul>
+ *
+ * @return The value for the state caching flag.
+ */
boolean getCacheState();
+ /**
+ * See {@link Connection#getCatalog()}.
+ *
+ * @return See {@link Connection#getCatalog()}.
+ * @throws SQLException See {@link Connection#getCatalog()}.
+ */
String getCatalog() throws SQLException;
+ /**
+ * See {@link Connection#getHoldability()}.
+ *
+ * @return See {@link Connection#getHoldability()}.
+ * @throws SQLException See {@link Connection#getHoldability()}.
+ */
int getHoldability() throws SQLException;
+ /**
+ * See {@link Connection#getSchema()}.
+ *
+ * @return See {@link Connection#getSchema()}.
+ * @throws SQLException See {@link Connection#getSchema()}.
+ */
String getSchema() throws SQLException;
+ /**
+ * Gets the value of the {@link Object#toString()} method via a bean getter, so it can be read as a property via JMX.
+ *
+ * @return the value of the {@link Object#toString()}.
+ */
String getToString();
+ /**
+ * See {@link Connection#getTransactionIsolation()}.
+ *
+ * @return See {@link Connection#getTransactionIsolation()}.
+ * @throws SQLException See {@link Connection#getTransactionIsolation()}.
+ */
int getTransactionIsolation() throws SQLException;
+ /**
+ * See {@link Connection#isClosed()}.
+ *
+ * @return See {@link Connection#isClosed()}.
+ * @throws SQLException See {@link Connection#isClosed()}.
+ */
boolean isClosed() throws SQLException;
+ /**
+ * See {@link Connection#isReadOnly()}.
+ *
+ * @return See {@link Connection#isReadOnly()}.
+ * @throws SQLException See {@link Connection#isReadOnly()}.
+ */
boolean isReadOnly() throws SQLException;
+ /**
+ * Closes the underlying {@link Connection}.
+ *
+ * @throws SQLException Thrown if the connection can be closed.
+ */
void reallyClose() throws SQLException;
+ /**
+ * See {@link Connection#setAutoCommit(boolean)}.
+ *
+ * @param autoCommit See {@link Connection#setAutoCommit(boolean)}.
+ * @throws SQLException See {@link Connection#setAutoCommit(boolean)}.
+ */
void setAutoCommit(boolean autoCommit) throws SQLException;
+ /**
+ * Sets whether to cache properties. The cached properties are:
+ * <ul>
+ * <li>auto-commit</li>
+ * <li>catalog</li>
+ * <li>schema</li>
+ * <li>read-only</li>
+ * </ul>
+ *
+ * @param cacheState The new value for the state caching flag
+ */
void setCacheState(boolean cacheState);
+ /**
+ * See {@link Connection#setCatalog(String)}.
+ *
+ * @param catalog See {@link Connection#setCatalog(String)}.
+ * @throws SQLException See {@link Connection#setCatalog(String)}.
+ */
void setCatalog(String catalog) throws SQLException;
+ /**
+ * See {@link Connection#setHoldability(int)}.
+ *
+ * @param holdability {@link Connection#setHoldability(int)}.
+ * @throws SQLException See {@link Connection#setHoldability(int)}.
+ */
void setHoldability(int holdability) throws SQLException;
+ /**
+ * See {@link Connection#setReadOnly(boolean)}.
+ *
+ * @param readOnly See {@link Connection#setReadOnly(boolean)}.
+ * @throws SQLException See {@link Connection#setReadOnly(boolean)}.
+ */
void setReadOnly(boolean readOnly) throws SQLException;
+ /**
+ * See {@link Connection#setSchema(String)}.
+ *
+ * @param schema See {@link Connection#setSchema(String)}.
+ * @throws SQLException See {@link Connection#setSchema(String)}.
+ */
void setSchema(String schema) throws SQLException;
+ /**
+ * See {@link Connection#setTransactionIsolation(int)}.
+ *
+ * @param level See {@link Connection#setTransactionIsolation(int)}.
+ * @throws SQLException See {@link Connection#setTransactionIsolation(int)}.
+ */
void setTransactionIsolation(int level) throws SQLException;
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
index 6da7a269f9..9ff65986cc 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
@@ -74,7 +74,7 @@ public class PoolablePreparedStatement<K> extends DelegatingPreparedStatement {
@Override
public void activate() throws SQLException {
setClosedInternal(false);
- AbandonedTrace.add(getConnectionInternal(), this);
+ add(getConnectionInternal(), this);
super.activate();
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
index fc609e6a98..fdee6560e2 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
@@ -122,7 +122,11 @@ public class PoolingConnection extends DelegatingConnection<Connection>
}
} finally {
try {
- getDelegateInternal().close();
+ @SuppressWarnings("resource")
+ final Connection delegateInternal = getDelegateInternal();
+ if (delegateInternal != null) {
+ delegateInternal.close();
+ }
} finally {
setClosedInternal(true);
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
index 7293a115ac..b7473e4f88 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
@@ -99,13 +99,12 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
* the given connection pool.
*/
public PoolingDataSource(final ObjectPool<C> pool) {
- Objects.requireNonNull(pool, "Pool must not be null.");
+ Objects.requireNonNull(pool, "pool");
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.");
+ final PoolableConnectionFactory pcf = (PoolableConnectionFactory) ((GenericObjectPool<?>) this.pool).getFactory();
+ Objects.requireNonNull(pcf, "this.pool.getFactory()");
if (pcf.getPool() != this.pool) {
log.warn(Utils.getMessage("poolingDataSource.factoryConfig"));
@SuppressWarnings("unchecked") // PCF must have a pool of PCs
@@ -165,7 +164,6 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
throw new UnsupportedOperationException();
}
- // --- DataSource methods -----------------------------------------
/**
* Throws {@link UnsupportedOperationException}.
@@ -194,6 +192,11 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
throw new SQLFeatureNotSupportedException();
}
+ /**
+ * Gets the backing object pool.
+ *
+ * @return the backing object pool.
+ */
protected ObjectPool<C> getPool() {
return pool;
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
index d758825198..b7bb3551cb 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
@@ -87,14 +87,24 @@ public class PoolingDriver implements Driver {
/** The map of registered pools. */
protected static final HashMap<String, ObjectPool<? extends Connection>> pools = new HashMap<>();
- /** My URL prefix */
+ /**
+ * The Apache Commons connection string prefix {@value}.
+ */
public static final String URL_PREFIX = "jdbc:apache:commons:dbcp:";
+ /**
+ * The String length of {@link #URL_PREFIX}.
+ */
protected static final int URL_PREFIX_LEN = URL_PREFIX.length();
- // version numbers
+ /**
+ * Major version number.
+ */
protected static final int MAJOR_VERSION = 1;
+ /**
+ * Minor version number.
+ */
protected static final int MINOR_VERSION = 0;
/** Controls access to the underlying connection */
@@ -146,7 +156,6 @@ public class PoolingDriver implements Driver {
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));
-
try {
final Connection conn = pool.borrowObject();
if (conn == null) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Utils.java b/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
index 470ba74d10..fffdb187f3 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
@@ -41,7 +41,9 @@ public final class Utils {
private static final ResourceBundle messages = ResourceBundle
.getBundle(Utils.class.getPackage().getName() + ".LocalStrings");
- /** Any SQL_STATE starting with this value is considered a fatal disconnect */
+ /**
+ * Any SQL_STATE starting with this value is considered a fatal disconnect.
+ */
public static final String DISCONNECTION_SQL_CODE_PREFIX = "08";
/**
@@ -72,6 +74,27 @@ public final class Utils {
DISCONNECTION_SQL_CODES.add("JZ0C1"); // Sybase disconnect error
}
+ /**
+ * Checks for conflicts between two collections.
+ * <p>
+ * If any overlap is found between the two provided collections, an {@link IllegalArgumentException} is thrown.
+ * </p>
+ *
+ * @param codes1 The first collection of SQL state codes.
+ * @param codes2 The second collection of SQL state codes.
+ * @throws IllegalArgumentException if any codes overlap between the two collections.
+ * @since 2.13.0
+ */
+ static void checkSqlCodes(final Collection<String> codes1, final Collection<String> codes2) {
+ if (codes1 != null && codes2 != null) {
+ final Set<String> test = new HashSet<>(codes1);
+ test.retainAll(codes2);
+ if (!test.isEmpty()) {
+ throw new IllegalArgumentException(test + " cannot be in both disconnectionSqlCodes and disconnectionIgnoreSqlCodes.");
+ }
+ }
+ }
+
/**
* Clones the given char[] if not null.
*
@@ -171,7 +194,7 @@ public final class Utils {
* <li>JZ0C0 (Sybase disconnect error)</li>
* <li>JZ0C1 (Sybase disconnect error)</li>
* </ul>
- * @return SQL codes of fatal connection errors.
+ * @return A copy SQL codes of fatal connection errors.
* @since 2.10.0
*/
public static Set<String> getDisconnectionSqlCodes() {
@@ -204,6 +227,17 @@ public final class Utils {
return mf.format(args, new StringBuffer(), null).toString();
}
+ /**
+ * Checks if the given SQL state corresponds to a fatal connection error.
+ *
+ * @param sqlState the SQL state to check.
+ * @return true if the SQL state is a fatal connection error, false otherwise.
+ * @since 2.13.0
+ */
+ static boolean isDisconnectionSqlCode(final String sqlState) {
+ return DISCONNECTION_SQL_CODES.contains(sqlState);
+ }
+
static boolean isEmpty(final Collection<?> collection) {
return collection == null || collection.isEmpty();
}
@@ -228,11 +262,18 @@ public final class Utils {
return value == null ? null : String.valueOf(value);
}
+ /**
+ * Throws a LifetimeExceededException if the given pooled object's lifetime has exceeded a maximum duration.
+ *
+ * @param p The pooled object to test.
+ * @param maxDuration The maximum lifetime.
+ * @throws LifetimeExceededException Thrown if the given pooled object's lifetime has exceeded a maximum duration.
+ */
public static void validateLifetime(final PooledObject<?> p, final Duration maxDuration) throws LifetimeExceededException {
if (maxDuration.compareTo(Duration.ZERO) > 0) {
final Duration lifetimeDuration = Duration.between(p.getCreateInstant(), Instant.now());
if (lifetimeDuration.compareTo(maxDuration) > 0) {
- throw new LifetimeExceededException(Utils.getMessage("connectionFactory.lifetimeExceeded", lifetimeDuration, maxDuration));
+ throw new LifetimeExceededException(getMessage("connectionFactory.lifetimeExceeded", lifetimeDuration, maxDuration));
}
}
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
index 3007a6cdcb..77d07da6b5 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
@@ -698,7 +698,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
* <p>
* When a negative value is supplied,
* {@code ceil({@link BasicDataSource#getNumIdle})/abs({@link #getNumTestsPerEvictionRun})} tests will be run.
- * I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the idle objects will be tested per run.
+ * I.e., when the value is <em>-n</em>, roughly one <em>n</em>th of the idle objects will be tested per run.
* </p>
*
* @param numTestsPerEvictionRun number of statements to examine per run
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
index 68e871ea14..69e14e3871 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
@@ -16,10 +16,12 @@
*/
package org.apache.tomcat.dbcp.dbcp2.cpdsadapter;
+import java.sql.PreparedStatement;
+
import org.apache.tomcat.dbcp.dbcp2.PStmtKey;
/**
- * A key uniquely identifying a {@link java.sql.PreparedStatement PreparedStatement}.
+ * A key uniquely identifying a {@link PreparedStatement}.
*
* @since 2.0
* @deprecated Use {@link PStmtKey}.
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
index 15e45c2bb0..e19b932152 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
@@ -44,7 +44,7 @@ import org.apache.tomcat.dbcp.pool2.PooledObject;
import org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject;
/**
- * Implementation of {@link PooledConnection} that is returned by {@link DriverAdapterCPDS}.
+ * Implements {@link PooledConnection} that is returned by {@link DriverAdapterCPDS}.
*
* @since 2.0
*/
@@ -119,6 +119,9 @@ final class PooledConnectionImpl
pooledObject.getObject().activate();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void addConnectionEventListener(final ConnectionEventListener listener) {
if (!eventListeners.contains(listener)) {
@@ -671,6 +674,9 @@ final class PooledConnectionImpl
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void removeConnectionEventListener(final ConnectionEventListener listener) {
eventListeners.remove(listener);
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
index 6ea4ed2a9d..d7f4325fcf 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
@@ -1109,18 +1109,15 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
/**
* <p>
- * Sets the maximum permitted lifetime of a connection. A value of zero or less indicates an
- * infinite lifetime.
+ * Sets the maximum permitted lifetime of a connection. A value of zero or less indicates an infinite lifetime.
* </p>
* <p>
- * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first time one of the following methods is
+ * invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)}, {@link #setLoginTimeout(Duration)}, {@link #getLoginTimeoutDuration()},
+ * {@link #getLogWriter()}.
* </p>
*
- * @param maxConnLifetimeMillis
- * The maximum permitted lifetime of a connection. A value of zero or less indicates an
- * infinite lifetime.
+ * @param maxConnLifetimeMillis The maximum permitted lifetime of a connection. A value of zero or less indicates an infinite lifetime.
* @since 2.9.0
*/
public void setMaxConnLifetime(final Duration maxConnLifetimeMillis) {
@@ -1129,18 +1126,15 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
/**
* <p>
- * Sets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an
- * infinite lifetime.
+ * Sets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an infinite lifetime.
* </p>
* <p>
- * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first time one of the following methods is
+ * invoked: {@link #getConnection()}, {@link #setLogWriter(PrintWriter)}, {@link #setLoginTimeout(Duration)}, {@link #getLoginTimeoutDuration()},
+ * {@link #getLogWriter()}.
* </p>
*
- * @param maxConnLifetimeMillis
- * The maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an
- * infinite lifetime.
+ * @param maxConnLifetimeMillis The maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an infinite lifetime.
* @deprecated Use {@link #setMaxConnLifetime(Duration)}.
*/
@Deprecated
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
index 325fad1b78..4185a050ed 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
@@ -77,7 +77,6 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
* Data to deserialize to create the configuration parameter.
*
* @return The Object created by deserializing the data.
- *
* @throws ClassNotFoundException
* If a class cannot be found during the deserialization of a configuration parameter.
* @throws IOException
@@ -117,6 +116,10 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
}
}
+ private Boolean booleanValueOf(RefAddr refAddr) {
+ return Boolean.valueOf(toString(refAddr));
+ }
+
/**
* Creates an instance of the subclass and sets any properties contained in the Reference.
*
@@ -124,7 +127,6 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
* The properties to be set on the created DataSource
*
* @return A configured DataSource of the appropriate type.
- *
* @throws ClassNotFoundException
* If a class cannot be found during the deserialization of a configuration parameter.
* @throws IOException
@@ -145,7 +147,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
final Reference ref = (Reference) refObj;
if (isCorrectClass(ref.getClassName())) {
final RefAddr refAddr = ref.get("instanceKey");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
// object was bound to JNDI via Referenceable API.
obj = INSTANCE_MAP.get(refAddr.getContent());
} else {
@@ -171,6 +173,10 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
return obj;
}
+ private boolean hasContent(final RefAddr refAddr) {
+ return refAddr != null && refAddr.getContent() != null;
+ }
+
/**
* Tests if className is the value returned from getClass().getName().toString().
*
@@ -197,143 +203,151 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
throws IOException, ClassNotFoundException {
RefAddr refAddr = ref.get("dataSourceName");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDataSourceName(toString(refAddr));
}
refAddr = ref.get("description");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDescription(toString(refAddr));
}
refAddr = ref.get("jndiEnvironment");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
final byte[] serialized = (byte[]) refAddr.getContent();
ikds.setJndiEnvironment((Properties) deserialize(serialized));
}
refAddr = ref.get("loginTimeout");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setLoginTimeout(Duration.ofSeconds(parseInt(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setLoginTimeout(toDurationFromSeconds(refAddr));
}
// Pool properties
refAddr = ref.get("blockWhenExhausted");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultBlockWhenExhausted(parseBoolean(refAddr));
}
refAddr = ref.get("evictionPolicyClassName");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultEvictionPolicyClassName(toString(refAddr));
}
// Pool properties
refAddr = ref.get("lifo");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultLifo(parseBoolean(refAddr));
}
refAddr = ref.get("maxIdlePerKey");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultMaxIdle(parseInt(refAddr));
}
refAddr = ref.get("maxTotalPerKey");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultMaxTotal(parseInt(refAddr));
}
refAddr = ref.get("maxWaitMillis");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setDefaultMaxWait(Duration.ofMillis(parseLong(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setDefaultMaxWait(toDurationFromMillis(refAddr));
}
refAddr = ref.get("minEvictableIdleTimeMillis");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setDefaultMinEvictableIdle(Duration.ofMillis(parseLong(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setDefaultMinEvictableIdle(toDurationFromMillis(refAddr));
}
refAddr = ref.get("minIdlePerKey");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultMinIdle(parseInt(refAddr));
}
refAddr = ref.get("numTestsPerEvictionRun");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultNumTestsPerEvictionRun(parseInt(refAddr));
}
refAddr = ref.get("softMinEvictableIdleTimeMillis");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setDefaultSoftMinEvictableIdle(Duration.ofMillis(parseLong(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setDefaultSoftMinEvictableIdle(toDurationFromMillis(refAddr));
}
refAddr = ref.get("testOnCreate");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultTestOnCreate(parseBoolean(refAddr));
}
refAddr = ref.get("testOnBorrow");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultTestOnBorrow(parseBoolean(refAddr));
}
refAddr = ref.get("testOnReturn");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultTestOnReturn(parseBoolean(refAddr));
}
refAddr = ref.get("testWhileIdle");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultTestWhileIdle(parseBoolean(refAddr));
}
refAddr = ref.get("timeBetweenEvictionRunsMillis");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setDefaultDurationBetweenEvictionRuns(Duration.ofMillis(parseLong(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setDefaultDurationBetweenEvictionRuns(toDurationFromMillis(refAddr));
}
// Connection factory properties
refAddr = ref.get("validationQuery");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setValidationQuery(toString(refAddr));
}
refAddr = ref.get("validationQueryTimeout");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setValidationQueryTimeout(Duration.ofSeconds(parseInt(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setValidationQueryTimeout(toDurationFromSeconds(refAddr));
}
refAddr = ref.get("rollbackAfterValidation");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setRollbackAfterValidation(parseBoolean(refAddr));
}
refAddr = ref.get("maxConnLifetimeMillis");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setMaxConnLifetime(Duration.ofMillis(parseLong(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setMaxConnLifetime(toDurationFromMillis(refAddr));
}
// Connection properties
refAddr = ref.get("defaultAutoCommit");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setDefaultAutoCommit(Boolean.valueOf(toString(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setDefaultAutoCommit(booleanValueOf(refAddr));
}
refAddr = ref.get("defaultTransactionIsolation");
- if (refAddr != null && refAddr.getContent() != null) {
+ if (hasContent(refAddr)) {
ikds.setDefaultTransactionIsolation(parseInt(refAddr));
}
refAddr = ref.get("defaultReadOnly");
- if (refAddr != null && refAddr.getContent() != null) {
- ikds.setDefaultReadOnly(Boolean.valueOf(toString(refAddr)));
+ if (hasContent(refAddr)) {
+ ikds.setDefaultReadOnly(booleanValueOf(refAddr));
}
}
+ private Duration toDurationFromMillis(RefAddr refAddr) {
+ return Duration.ofMillis(parseLong(refAddr));
+ }
+
+ private Duration toDurationFromSeconds(RefAddr refAddr) {
+ return Duration.ofSeconds(parseInt(refAddr));
+ }
+
String toString(final RefAddr refAddr) {
return refAddr.getContent().toString();
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
index a5ddd34b68..6743c15d18 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
@@ -38,8 +38,7 @@ import org.apache.tomcat.dbcp.pool2.PooledObject;
import org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject;
/**
- * A {@link KeyedPooledObjectFactory} that creates {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnection
- * PoolableConnection}s.
+ * A {@link KeyedPooledObjectFactory} that creates {@link PoolableConnection}s.
*
* @since 2.0
*/
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java
index 5614e5948e..3d9dc292e1 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java
@@ -24,6 +24,7 @@ import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.function.Supplier;
import javax.naming.NamingException;
import javax.naming.Reference;
@@ -35,6 +36,7 @@ import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.dbcp.dbcp2.SwallowedExceptionLogger;
import org.apache.tomcat.dbcp.dbcp2.Utils;
import org.apache.tomcat.dbcp.pool2.ObjectPool;
+import org.apache.tomcat.dbcp.pool2.impl.EvictionPolicy;
import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool;
/**
@@ -67,23 +69,94 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
return new HashMap<>();
}
+ /**
+ * Maps user names to a data source property: BlockWhenExhausted.
+ */
private Map<String, Boolean> perUserBlockWhenExhausted;
+
+ /**
+ * Maps user names to a data source property: EvictionPolicyClassName.
+ */
private Map<String, String> perUserEvictionPolicyClassName;
+
+ /**
+ * Maps user names to a data source property: Lifo.
+ */
private Map<String, Boolean> perUserLifo;
+
+ /**
+ * Maps user names to a data source property: MaxIdle.
+ */
private Map<String, Integer> perUserMaxIdle;
+
+ /**
+ * Maps user names to a data source property: MaxTotal.
+ */
private Map<String, Integer> perUserMaxTotal;
+
+ /**
+ * Maps user names to a data source property: MaxWaitDuration.
+ */
private Map<String, Duration> perUserMaxWaitDuration;
+
+ /**
+ * Maps user names to a data source property: MinEvictableIdleDuration.
+ */
private Map<String, Duration> perUserMinEvictableIdleDuration;
+
+ /**
+ * Maps user names to a data source property: MinIdle.
+ */
private Map<String, Integer> perUserMinIdle;
+
+ /**
+ * Maps user names to a data source property: NumTestsPerEvictionRun.
+ */
private Map<String, Integer> perUserNumTestsPerEvictionRun;
+
+ /**
+ * Maps user names to a data source property: SoftMinEvictableIdleDuration.
+ */
private Map<String, Duration> perUserSoftMinEvictableIdleDuration;
+
+ /**
+ * Maps user names to a data source property: TestOnCreate.
+ */
private Map<String, Boolean> perUserTestOnCreate;
+
+ /**
+ * Maps user names to a data source property: TestOnBorrow.
+ */
private Map<String, Boolean> perUserTestOnBorrow;
+
+ /**
+ * Maps user names to a data source property: TestOnReturn.
+ */
private Map<String, Boolean> perUserTestOnReturn;
+
+ /**
+ * Maps user names to a data source property: TestWhileIdle.
+ */
private Map<String, Boolean> perUserTestWhileIdle;
+
+ /**
+ * Maps user names to a data source property: DurationBetweenEvictionRuns.
+ */
private Map<String, Duration> perUserDurationBetweenEvictionRuns;
+
+ /**
+ * Maps user names to a data source property: DefaultAutoCommit.
+ */
private Map<String, Boolean> perUserDefaultAutoCommit;
+
+ /**
+ * Maps user names to a data source property: DefaultTransactionIsolation.
+ */
private Map<String, Integer> perUserDefaultTransactionIsolation;
+
+ /**
+ * Maps user names to a data source property: DefaultReadOnly.
+ */
private Map<String, Boolean> perUserDefaultReadOnly;
/**
@@ -92,7 +165,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
private transient Map<PoolKey, PooledConnectionManager> managers = createMap();
/**
- * Default no-arg constructor for Serialization.
+ * Constructs a new instance.
*/
public PerUserPoolDataSource() {
}
@@ -103,6 +176,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @see org.apache.tomcat.dbcp.pool2.ObjectPool#clear()
* @since 2.3.0
*/
+ @SuppressWarnings("resource") // does not allocate a pool
public void clear() {
managers.values().forEach(manager -> {
try {
@@ -140,13 +214,34 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
}
+ /**
+ * Gets the user specific default value in a map for the specified user's pool.
+ *
+ * @param userName The user name key.
+ * @return The user specific value.
+ */
+ private <V> V get(final Map<String, V> map, final String userName) {
+ return map != null ? map.get(userName) : null;
+ }
+
+ /**
+ * Gets the user specific default value in a map for the specified user's pool.
+ *
+ * @param userName The user name key.
+ * @return The user specific value.
+ */
+ private <V> V get(final Map<String, V> map, final String userName, final Supplier<V> defaultSupplier) {
+ final V v = get(map, userName);
+ return v != null ? v : defaultSupplier.get();
+ }
+
@Override
protected PooledConnectionManager getConnectionManager(final UserPassKey upKey) {
return managers.get(getPoolKey(upKey.getUserName()));
}
/**
- * Gets the underlying pool but does NOT allocate it.
+ * Gets the underlying pre-allocated pool (does NOT allocate).
*
* @param manager A CPDSConnectionFactory.
* @return the underlying pool.
@@ -206,14 +301,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public boolean getPerUserBlockWhenExhausted(final String userName) {
- Boolean value = null;
- if (perUserBlockWhenExhausted != null) {
- value = perUserBlockWhenExhausted.get(userName);
- }
- if (value == null) {
- return getDefaultBlockWhenExhausted();
- }
- return value.booleanValue();
+ return get(perUserBlockWhenExhausted, userName, this::getDefaultBlockWhenExhausted);
}
/**
@@ -224,11 +312,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public Boolean getPerUserDefaultAutoCommit(final String userName) {
- Boolean value = null;
- if (perUserDefaultAutoCommit != null) {
- value = perUserDefaultAutoCommit.get(userName);
- }
- return value;
+ return get(perUserDefaultAutoCommit, userName);
}
/**
@@ -239,11 +323,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public Boolean getPerUserDefaultReadOnly(final String userName) {
- Boolean value = null;
- if (perUserDefaultReadOnly != null) {
- value = perUserDefaultReadOnly.get(userName);
- }
- return value;
+ return get(perUserDefaultReadOnly, userName);
}
/**
@@ -255,11 +335,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public Integer getPerUserDefaultTransactionIsolation(final String userName) {
- Integer value = null;
- if (perUserDefaultTransactionIsolation != null) {
- value = perUserDefaultTransactionIsolation.get(userName);
- }
- return value;
+ return get(perUserDefaultTransactionIsolation, userName);
}
/**
@@ -272,33 +348,22 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @since 2.10.0
*/
public Duration getPerUserDurationBetweenEvictionRuns(final String userName) {
- Duration value = null;
- if (perUserDurationBetweenEvictionRuns != null) {
- value = perUserDurationBetweenEvictionRuns.get(userName);
- }
- if (value == null) {
- return getDefaultDurationBetweenEvictionRuns();
- }
- return value;
+ return get(perUserDurationBetweenEvictionRuns, userName, this::getDefaultDurationBetweenEvictionRuns);
}
/**
* Gets the user specific value for {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified user's
* pool or the default if no user specific value is defined.
+ * <p>
+ * The class must implement {@link EvictionPolicy}.
+ * </p>
*
* @param userName
* The user name key.
* @return The user specific value.
*/
public String getPerUserEvictionPolicyClassName(final String userName) {
- String value = null;
- if (perUserEvictionPolicyClassName != null) {
- value = perUserEvictionPolicyClassName.get(userName);
- }
- if (value == null) {
- return getDefaultEvictionPolicyClassName();
- }
- return value;
+ return get(perUserEvictionPolicyClassName, userName, this::getDefaultEvictionPolicyClassName);
}
/**
@@ -310,14 +375,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public boolean getPerUserLifo(final String userName) {
- Boolean value = null;
- if (perUserLifo != null) {
- value = perUserLifo.get(userName);
- }
- if (value == null) {
- return getDefaultLifo();
- }
- return value.booleanValue();
+ return get(perUserLifo, userName, this::getDefaultLifo);
}
/**
@@ -329,14 +387,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public int getPerUserMaxIdle(final String userName) {
- Integer value = null;
- if (perUserMaxIdle != null) {
- value = perUserMaxIdle.get(userName);
- }
- if (value == null) {
- return getDefaultMaxIdle();
- }
- return value.intValue();
+ return get(perUserMaxIdle, userName, this::getDefaultMaxIdle);
}
/**
@@ -348,14 +399,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public int getPerUserMaxTotal(final String userName) {
- Integer value = null;
- if (perUserMaxTotal != null) {
- value = perUserMaxTotal.get(userName);
- }
- if (value == null) {
- return getDefaultMaxTotal();
- }
- return value.intValue();
+ return get(perUserMaxTotal, userName, this::getDefaultMaxTotal);
}
/**
@@ -368,14 +412,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @since 2.10.0
*/
public Duration getPerUserMaxWaitDuration(final String userName) {
- Duration value = null;
- if (perUserMaxWaitDuration != null) {
- value = perUserMaxWaitDuration.get(userName);
- }
- if (value == null) {
- return getDefaultMaxWait();
- }
- return value;
+ return get(perUserMaxWaitDuration, userName, this::getDefaultMaxWait);
}
/**
@@ -402,14 +439,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @since 2.10.0
*/
public Duration getPerUserMinEvictableIdleDuration(final String userName) {
- Duration value = null;
- if (perUserMinEvictableIdleDuration != null) {
- value = perUserMinEvictableIdleDuration.get(userName);
- }
- if (value == null) {
- return getDefaultMinEvictableIdleDuration();
- }
- return value;
+ return get(perUserMinEvictableIdleDuration, userName, this::getDefaultMinEvictableIdleDuration);
}
/**
@@ -435,14 +465,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public int getPerUserMinIdle(final String userName) {
- Integer value = null;
- if (perUserMinIdle != null) {
- value = perUserMinIdle.get(userName);
- }
- if (value == null) {
- return getDefaultMinIdle();
- }
- return value.intValue();
+ return get(perUserMinIdle, userName, this::getDefaultMinIdle);
}
/**
@@ -454,14 +477,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public int getPerUserNumTestsPerEvictionRun(final String userName) {
- Integer value = null;
- if (perUserNumTestsPerEvictionRun != null) {
- value = perUserNumTestsPerEvictionRun.get(userName);
- }
- if (value == null) {
- return getDefaultNumTestsPerEvictionRun();
- }
- return value.intValue();
+ return get(perUserNumTestsPerEvictionRun, userName, this::getDefaultNumTestsPerEvictionRun);
}
/**
@@ -474,14 +490,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @since 2.10.0
*/
public Duration getPerUserSoftMinEvictableIdleDuration(final String userName) {
- Duration value = null;
- if (perUserSoftMinEvictableIdleDuration != null) {
- value = perUserSoftMinEvictableIdleDuration.get(userName);
- }
- if (value == null) {
- return getDefaultSoftMinEvictableIdleDuration();
- }
- return value;
+ return get(perUserSoftMinEvictableIdleDuration, userName, this::getDefaultSoftMinEvictableIdleDuration);
}
/**
@@ -507,14 +516,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public boolean getPerUserTestOnBorrow(final String userName) {
- Boolean value = null;
- if (perUserTestOnBorrow != null) {
- value = perUserTestOnBorrow.get(userName);
- }
- if (value == null) {
- return getDefaultTestOnBorrow();
- }
- return value.booleanValue();
+ return get(perUserTestOnBorrow, userName, this::getDefaultTestOnBorrow);
}
/**
@@ -526,14 +528,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public boolean getPerUserTestOnCreate(final String userName) {
- Boolean value = null;
- if (perUserTestOnCreate != null) {
- value = perUserTestOnCreate.get(userName);
- }
- if (value == null) {
- return getDefaultTestOnCreate();
- }
- return value.booleanValue();
+ return get(perUserTestOnCreate, userName, this::getDefaultTestOnCreate);
}
/**
@@ -545,14 +540,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public boolean getPerUserTestOnReturn(final String userName) {
- Boolean value = null;
- if (perUserTestOnReturn != null) {
- value = perUserTestOnReturn.get(userName);
- }
- if (value == null) {
- return getDefaultTestOnReturn();
- }
- return value.booleanValue();
+ return get(perUserTestOnReturn, userName, this::getDefaultTestOnReturn);
}
/**
@@ -564,14 +552,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
* @return The user specific value.
*/
public boolean getPerUserTestWhileIdle(final String userName) {
- Boolean value = null;
- if (perUserTestWhileIdle != null) {
- value = perUserTestWhileIdle.get(userName);
- }
- if (value == null) {
- return getDefaultTestWhileIdle();
- }
- return value.booleanValue();
+ return get(perUserTestWhileIdle, userName, this::getDefaultTestWhileIdle);
}
/**
@@ -600,10 +581,9 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
return mgr == null ? null : mgr.getPool();
}
+ @SuppressWarnings("resource") // does not allocate a pool
@Override
- protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String password)
- throws SQLException {
-
+ protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String password) throws SQLException {
final PoolKey key = getPoolKey(userName);
ObjectPool<PooledConnectionAndInfo> pool;
PooledConnectionManager manager;
@@ -619,7 +599,6 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
}
pool = getCPDSConnectionFactoryPool(manager);
}
-
PooledConnectionAndInfo info = null;
try {
info = pool.borrowObject();
@@ -682,39 +661,36 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
}
/**
- * Supports Serialization interface.
+ * Deserializes an instance from an ObjectInputStream.
*
- * @param in
- * a {@link java.io.ObjectInputStream} value
- * @throws IOException
- * if an error occurs
- * @throws ClassNotFoundException
- * if an error occurs
+ * @param in The source ObjectInputStream.
+ * @throws IOException Any of the usual Input/Output related exceptions.
+ * @throws ClassNotFoundException A class of a serialized object cannot be found.
*/
+ @SuppressWarnings("resource")
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ this.managers = readObjectImpl().managers;
+ }
+
+ private PerUserPoolDataSource readObjectImpl() throws IOException, ClassNotFoundException {
try {
- in.defaultReadObject();
- final PerUserPoolDataSource oldDS = (PerUserPoolDataSource) new PerUserPoolDataSourceFactory()
- .getObjectInstance(getReference(), null, null, null);
- this.managers = oldDS.managers;
+ return (PerUserPoolDataSource) new PerUserPoolDataSourceFactory().getObjectInstance(getReference(), null, null, null);
} catch (final NamingException e) {
throw new IOException("NamingException: " + e);
}
}
- private synchronized void registerPool(final String userName, final String password)
- throws NamingException, SQLException {
-
+ private synchronized void registerPool(final String userName, final String password) throws NamingException, SQLException {
final ConnectionPoolDataSource cpds = testCPDS(userName, password);
-
// Set up the factory we will use (passing the pool associates
// the factory with the pool, so we do not have to do so
// explicitly)
final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, getValidationQuery(), getValidationQueryTimeoutDuration(),
- isRollbackAfterValidation(), userName, password);
+ isRollbackAfterValidation(), userName, password);
factory.setMaxConn(getMaxConnDuration());
-
// Create an object pool to contain our PooledConnections
+ @SuppressWarnings("resource")
final GenericObjectPool<PooledConnectionAndInfo> pool = new GenericObjectPool<>(factory);
factory.setPool(pool);
pool.setBlockWhenExhausted(getPerUserBlockWhenExhausted(userName));
@@ -732,13 +708,13 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
pool.setTestOnReturn(getPerUserTestOnReturn(userName));
pool.setTestWhileIdle(getPerUserTestWhileIdle(userName));
pool.setDurationBetweenEvictionRuns(getPerUserDurationBetweenEvictionRuns(userName));
-
pool.setSwallowedExceptionListener(new SwallowedExceptionLogger(log));
-
- final PooledConnectionManager old = managers.put(getPoolKey(userName), factory);
- if (old != null) {
+ final PoolKey poolKey = getPoolKey(userName);
+ if (managers.containsKey(poolKey)) {
+ pool.close();
throw new IllegalStateException("Pool already contains an entry for this user/password: " + userName);
}
+ managers.put(poolKey, factory);
}
private <K, V> Map<K, V> replaceAll(final Map<K, V> currentMap, final Map<K, V> newMap) {
@@ -855,7 +831,9 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
/**
* Sets a user specific value for {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified user's
* pool.
- *
+ * <p>
+ * The class must implement {@link EvictionPolicy}.
+ * </p>
* @param userName
* The user name key.
* @param value
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java
index 9cc08ab23b..43deef603e 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java
@@ -20,6 +20,8 @@ import java.io.Serializable;
import java.util.Objects;
/**
+ * The key type for entries in a {@link PerUserPoolDataSource}.
+ *
* @since 2.0
*/
final class PoolKey implements Serializable {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java
index 18aa8c144e..ecbe1b451b 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java
@@ -30,15 +30,6 @@ final class PooledConnectionAndInfo {
private final UserPassKey userPassKey;
- /**
- * Constructs a new instance.
- *
- * @since 2.4.0
- */
- PooledConnectionAndInfo(final PooledConnection pooledConnection, final char[] userName, final char[] userPassword) {
- this(pooledConnection, new UserPassKey(userName, userPassword));
- }
-
PooledConnectionAndInfo(final PooledConnection pooledConnection, final UserPassKey userPassKey) {
this.pooledConnection = pooledConnection;
this.userPassKey = userPassKey;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
index e3907066d5..63e8423403 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
@@ -51,10 +51,19 @@ public class SharedPoolDataSource extends InstanceKeyDataSource {
private static final long serialVersionUID = -1458539734480586454L;
- // Pool properties
+ /**
+ * Max total defaults to {@link GenericKeyedObjectPoolConfig#DEFAULT_MAX_TOTAL}.
+ */
private int maxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
+ /**
+ * Maps user credentials to pooled connection with credentials.
+ */
private transient KeyedObjectPool<UserPassKey, PooledConnectionAndInfo> pool;
+
+ /**
+ * A {@link KeyedPooledObjectFactory} that creates {@link PoolableConnection}s.
+ */
private transient KeyedCPDSConnectionFactory factory;
/**
@@ -89,9 +98,6 @@ public class SharedPoolDataSource extends InstanceKeyDataSource {
return this.maxTotal;
}
- // ----------------------------------------------------------------------
- // Instrumentation Methods
-
/**
* Gets the number of active connections in the pool.
*
@@ -142,20 +148,20 @@ public class SharedPoolDataSource extends InstanceKeyDataSource {
}
/**
- * Supports Serialization interface.
+ * Deserializes an instance from an ObjectInputStream.
*
- * @param in
- * a {@link java.io.ObjectInputStream} value
- * @throws IOException
- * if an error occurs
- * @throws ClassNotFoundException
- * if an error occurs
+ * @param in The source ObjectInputStream.
+ * @throws IOException Any of the usual Input/Output related exceptions.
+ * @throws ClassNotFoundException A class of a serialized object cannot be found.
*/
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ this.pool = readObjectImpl();
+ }
+
+ private KeyedObjectPool<UserPassKey, PooledConnectionAndInfo> readObjectImpl() throws IOException, ClassNotFoundException {
try {
- in.defaultReadObject();
- final SharedPoolDataSource oldDS = (SharedPoolDataSource) new SharedPoolDataSourceFactory().getObjectInstance(getReference(), null, null, null);
- this.pool = oldDS.pool;
+ return ((SharedPoolDataSource) new SharedPoolDataSourceFactory().getObjectInstance(getReference(), null, null, null)).pool;
} catch (final NamingException e) {
throw new IOException("NamingException: " + e);
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java
index b3feafe0e7..ca405f8405 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java
@@ -25,8 +25,16 @@ import javax.naming.Reference;
* @since 2.0
*/
public class SharedPoolDataSourceFactory extends InstanceKeyDataSourceFactory {
+
private static final String SHARED_POOL_CLASSNAME = SharedPoolDataSource.class.getName();
+ /**
+ * Constructs a new instance.
+ */
+ public SharedPoolDataSourceFactory() {
+ // empty
+ }
+
@Override
protected InstanceKeyDataSource getNewInstance(final Reference ref) {
final SharedPoolDataSource spds = new SharedPoolDataSource();
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
index 02ed24bbcd..4c4a2afd97 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
@@ -42,10 +42,6 @@ final class UserPassKey implements Serializable {
private final CharArray name;
private final CharArray password;
- UserPassKey(final char[] userName, final char[] password) {
- this(new CharArray(userName), new CharArray(password));
- }
-
UserPassKey(final CharArray userName, final CharArray userPassword) {
this.name = userName;
this.password = userPassword;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java
index 436a073f06..e456811bca 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.java
@@ -128,8 +128,7 @@ public class BasicManagedDataSource extends BasicDataSource {
throws SQLException {
PoolableConnectionFactory connectionFactory = null;
try {
- connectionFactory = new PoolableManagedConnectionFactory((XAConnectionFactory) driverConnectionFactory,
- getRegisteredJmxName());
+ connectionFactory = new PoolableManagedConnectionFactory((XAConnectionFactory) driverConnectionFactory, getRegisteredJmxName());
connectionFactory.setValidationQuery(getValidationQuery());
connectionFactory.setValidationQueryTimeout(getValidationQueryTimeoutDuration());
connectionFactory.setConnectionInitSql(getConnectionInitSqls());
@@ -148,6 +147,7 @@ public class BasicManagedDataSource extends BasicDataSource {
connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeoutDuration());
connectionFactory.setFastFailValidation(getFastFailValidation());
connectionFactory.setDisconnectionSqlCodes(getDisconnectionSqlCodes());
+ connectionFactory.setDisconnectionIgnoreSqlCodes(getDisconnectionIgnoreSqlCodes());
validateConnectionFactory(connectionFactory);
} catch (final RuntimeException e) {
throw e;
@@ -236,17 +236,14 @@ public class BasicManagedDataSource extends BasicDataSource {
}
/**
- * <p>
* Sets the XADataSource instance used by the XAConnectionFactory.
- * </p>
* <p>
- * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first
- * time one of the following methods is invoked: <code>getConnection, setLogwriter,
- * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+ * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first time one of the following methods is
+ * invoked: {@link #getConnection()}, {@link #setLogWriter(java.io.PrintWriter)}, {@link #setLoginTimeout(int)}, {@link #getLoginTimeout()},
+ * {@link #getLogWriter()}.
* </p>
*
- * @param xaDataSourceInstance
- * XADataSource instance
+ * @param xaDataSourceInstance XADataSource instance
*/
public synchronized void setXaDataSourceInstance(final XADataSource xaDataSourceInstance) {
this.xaDataSourceInstance = xaDataSourceInstance;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java
index d32b701567..8c70d24478 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.java
@@ -201,18 +201,18 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
connection.setAutoCommit(originalAutoCommit);
// tell the transaction manager we are read only
- return XAResource.XA_RDONLY;
+ return XA_RDONLY;
}
} catch (final SQLException ignored) {
// no big deal
}
// this is a local (one phase) only connection, so we can't prepare
- return XAResource.XA_OK;
+ return XA_OK;
}
/**
- * Always returns a zero length Xid array. The LocalXAConnectionFactory can not support recovery, so no xids
+ * Always returns a zero length Xid array. The LocalXAConnectionFactory cannot support recovery, so no xids
* will ever be found.
*
* @param flag
@@ -280,7 +280,7 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
*/
@Override
public synchronized void start(final Xid xid, final int flag) throws XAException {
- if (flag == XAResource.TMNOFLAGS) {
+ if (flag == TMNOFLAGS) {
// first time in this transaction
// make sure we aren't already in another tx
@@ -305,7 +305,7 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
}
this.currentXid = xid;
- } else if (flag == XAResource.TMRESUME) {
+ } else if (flag == TMRESUME) {
if (!xid.equals(this.currentXid)) {
throw new XAException("Attempting to resume in different transaction: expected " + this.currentXid
+ ", but was " + xid);
@@ -369,6 +369,8 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
}
/**
+ * Gets the connection factory.
+ *
* @return The connection factory.
* @since 2.6.0
*/
@@ -376,6 +378,11 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
return connectionFactory;
}
+ /**
+ * Gets the transaction registry.
+ *
+ * @return The transaction registry.
+ */
@Override
public TransactionRegistry getTransactionRegistry() {
return transactionRegistry;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java
index 579231d362..1f958e1e46 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/ManagedConnection.java
@@ -122,7 +122,7 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
@Override
public void commit() throws SQLException {
if (transactionContext != null) {
- throw new SQLException("Commit can not be set while enrolled in a transaction");
+ throw new SQLException("Commit cannot be set while enrolled in a transaction");
}
super.commit();
}
@@ -148,6 +148,8 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
}
/**
+ * Gets the transaction context.
+ *
* @return The transaction context.
* @since 2.6.0
*/
@@ -156,6 +158,8 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
}
/**
+ * Gets the transaction registry.
+ *
* @return The transaction registry.
* @since 2.6.0
*/
@@ -175,7 +179,7 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
@Override
public void rollback() throws SQLException {
if (transactionContext != null) {
- throw new SQLException("Commit can not be set while enrolled in a transaction");
+ throw new SQLException("Commit cannot be set while enrolled in a transaction");
}
super.rollback();
}
@@ -183,7 +187,7 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
@Override
public void setAutoCommit(final boolean autoCommit) throws SQLException {
if (transactionContext != null) {
- throw new SQLException("Auto-commit can not be set while enrolled in a transaction");
+ throw new SQLException("Auto-commit cannot be set while enrolled in a transaction");
}
super.setAutoCommit(autoCommit);
}
@@ -191,7 +195,7 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
@Override
public void setReadOnly(final boolean readOnly) throws SQLException {
if (transactionContext != null) {
- throw new SQLException("Read-only can not be set while enrolled in a transaction");
+ throw new SQLException("Read-only cannot be set while enrolled in a transaction");
}
super.setReadOnly(readOnly);
}
@@ -240,7 +244,7 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
if (transactionContext != null && !transactionContext.isTransactionComplete()) {
if (transactionContext.isActive()) {
if (transactionContext != transactionRegistry.getActiveTransactionContext()) {
- throw new SQLException("Connection can not be used while enlisted in another transaction");
+ throw new SQLException("Connection cannot be used while enlisted in another transaction");
}
return;
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java
index f9958d7a81..05d5a132a3 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnection.java
@@ -33,7 +33,7 @@ public class PoolableManagedConnection extends PoolableConnection {
private final TransactionRegistry transactionRegistry;
/**
- * Create a PoolableManagedConnection.
+ * Creates a PoolableManagedConnection.
*
* @param transactionRegistry
* transaction registry
@@ -42,13 +42,12 @@ public class PoolableManagedConnection extends PoolableConnection {
* @param pool
* connection pool
*/
- public PoolableManagedConnection(final TransactionRegistry transactionRegistry, final Connection conn,
- final ObjectPool<PoolableConnection> pool) {
+ public PoolableManagedConnection(final TransactionRegistry transactionRegistry, final Connection conn, final ObjectPool<PoolableConnection> pool) {
this(transactionRegistry, conn, pool, null, true);
}
/**
- * Create a PoolableManagedConnection.
+ * Creates a PoolableManagedConnection.
*
* @param transactionRegistry
* transaction registry
@@ -57,19 +56,43 @@ public class PoolableManagedConnection extends PoolableConnection {
* @param pool
* connection pool
* @param disconnectSqlCodes
- * SQL_STATE codes considered fatal disconnection errors
+ * SQL State codes considered fatal disconnection errors
* @param fastFailValidation
* true means fatal disconnection errors cause subsequent validations to fail immediately (no attempt to
* run query or isValid)
*/
- public PoolableManagedConnection(final TransactionRegistry transactionRegistry, final Connection conn,
- final ObjectPool<PoolableConnection> pool, final Collection<String> disconnectSqlCodes,
- final boolean fastFailValidation) {
- super(conn, pool, null, disconnectSqlCodes, fastFailValidation);
+ public PoolableManagedConnection(final TransactionRegistry transactionRegistry, final Connection conn, final ObjectPool<PoolableConnection> pool,
+ final Collection<String> disconnectSqlCodes, final boolean fastFailValidation) {
+ this(transactionRegistry, conn, pool, disconnectSqlCodes, null, fastFailValidation);
+ }
+
+ /**
+ * Creates a PoolableManagedConnection.
+ *
+ * @param transactionRegistry
+ * transaction registry
+ * @param conn
+ * underlying connection
+ * @param pool
+ * connection pool
+ * @param disconnectSqlCodes
+ * SQL State codes considered fatal disconnection errors
+ * @param disconnectionIgnoreSqlCodes
+ * SQL State codes considered fatal disconnection errors
+ * @param fastFailValidation
+ * true means fatal disconnection errors cause subsequent validations to fail immediately (no attempt to
+ * run query or isValid)
+ * @since 2.13.0
+ */
+ public PoolableManagedConnection(final TransactionRegistry transactionRegistry, final Connection conn, final ObjectPool<PoolableConnection> pool,
+ final Collection<String> disconnectSqlCodes, final Collection<String> disconnectionIgnoreSqlCodes, final boolean fastFailValidation) {
+ super(conn, pool, null, disconnectSqlCodes, disconnectionIgnoreSqlCodes, fastFailValidation);
this.transactionRegistry = transactionRegistry;
}
/**
+ * Gets the transaction registry.
+ *
* @return The transaction registry.
* @since 2.6.0
*/
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java
index 28c2046cd1..bbd5a4e2c6 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/PoolableManagedConnectionFactory.java
@@ -58,6 +58,8 @@ public class PoolableManagedConnectionFactory extends PoolableConnectionFactory
}
/**
+ * Gets the transaction registry.
+ *
* @return The transaction registry.
* @since 2.6.0
*/
@@ -103,7 +105,7 @@ public class PoolableManagedConnectionFactory extends PoolableConnectionFactory
((PoolingConnection) conn).setCacheState(getCacheState());
}
final PoolableManagedConnection pmc = new PoolableManagedConnection(transactionRegistry, conn, getPool(),
- getDisconnectionSqlCodes(), isFastFailValidation());
+ getDisconnectionSqlCodes(), getDisconnectionIgnoreSqlCodes(), isFastFailValidation());
pmc.setCacheState(getCacheState());
return new DefaultPooledObject<>(pmc);
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java
index 1a8823483f..a1d84745dc 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContext.java
@@ -162,7 +162,6 @@ public class TransactionContext {
* Gets the transaction complete flag to true.
*
* @return The transaction complete flag.
- *
* @since 2.4.0
*/
public boolean isTransactionComplete() {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContextListener.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContextListener.java
index 10dd34a02b..c447ecb01d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContextListener.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/TransactionContextListener.java
@@ -22,13 +22,14 @@ package org.apache.tomcat.dbcp.dbcp2.managed;
* @since 2.0
*/
public interface TransactionContextListener {
+
/**
- * Occurs after the transaction commits or rolls back.
+ * Called after a transaction commits or rolls back.
*
* @param transactionContext
- * the transaction context that completed
+ * the transaction context that completed.
* @param committed
- * true if the transaction committed; false otherwise
+ * true if the transaction committed; false otherwise.
*/
void afterCompletion(TransactionContext transactionContext, boolean committed);
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java
index b9913fbb42..07b6dec7d8 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/XAConnectionFactory.java
@@ -30,16 +30,16 @@ import org.apache.tomcat.dbcp.dbcp2.ConnectionFactory;
* @since 2.0
*/
public interface XAConnectionFactory extends ConnectionFactory {
+
/**
- * Create a new {@link java.sql.Connection} in an implementation specific fashion.
+ * Creates a new {@link Connection} in an implementation specific fashion.
* <p>
* An implementation can assume that the caller of this will wrap the connection in a proxy that protects access to
* the setAutoCommit, commit and rollback when enrolled in a XA transaction.
* </p>
*
- * @return a new {@link java.sql.Connection}
- * @throws java.sql.SQLException
- * if a database error occurs creating the connection
+ * @return a new {@link Connection}
+ * @throws SQLException if a database error occurs creating the connection
*/
@Override
Connection createConnection() throws SQLException;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/managed/package-info.java b/java/org/apache/tomcat/dbcp/dbcp2/managed/package-info.java
index a439660a21..ca00170f9c 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/managed/package-info.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/package-info.java
@@ -19,7 +19,7 @@
* <p>
* This package provides support for pooling of ManagedConnections. A managed
* connection is responsible for managing a database connection in a
- * transactional environment (typically called <i>Container Managed</i>).
+ * transactional environment (typically called <em>Container Managed</em>).
* A managed connection operates like any other connection when no global
* transaction (a.k.a. XA transaction or JTA Transaction) is in progress.
* When a global transaction is active a single physical connection to the
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/package-info.java b/java/org/apache/tomcat/dbcp/dbcp2/package-info.java
index 58a517589d..cfccb0df96 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/package-info.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/package-info.java
@@ -19,7 +19,7 @@
* <p>
* Database Connection Pool API.
* </p>
- * <b>Overview in Dialog Form</b>
+ * <strong>Overview in Dialog Form</strong>
* <p>
* Q: How do I use the DBCP package?
* </p>
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6a1d6f7824..d341f87b3f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -301,6 +301,9 @@
<bug>69465</bug>: Fix warnings during native image compilation using the
Tomcat embedded JARs. (markt)
</fix>
+ <update>
+ Update Tomcat's fork of Commons DBCP to 2.13.0. (markt)
+ </update>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org