com.sun.gjc.spi.base.ConnectionHolder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2018-2021] Payara Foundation and/or affiliates
package com.sun.gjc.spi.base;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.gjc.common.DataSourceObjectBuilder;
import com.sun.gjc.spi.ManagedConnectionImpl;
import com.sun.gjc.util.MethodExecutor;
import com.sun.logging.LogDomains;
import jakarta.resource.ResourceException;
import java.sql.*;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Holds the java.sql.Connection object, which is to be
* passed to the application program.
*
* @author Binod P.G
* @version 1.0, 02/07/23
*/
public abstract class ConnectionHolder implements Connection {
private static final Logger _logger = LogDomains.getLogger(ManagedConnectionImpl.class, LogDomains.RSR_LOGGER);
protected Connection con;
protected ManagedConnectionImpl mc;
protected boolean wrappedAlready = false;
protected boolean isClosed = false;
protected boolean valid = true;
protected boolean active = false;
private jakarta.resource.spi.LazyAssociatableConnectionManager lazyAssocCm_;
private jakarta.resource.spi.LazyEnlistableConnectionManager lazyEnlistCm_;
private jakarta.resource.spi.ConnectionRequestInfo cxReqInfo_;
private jakarta.resource.spi.ManagedConnectionFactory mcf_;
protected int statementTimeout;
protected boolean statementTimeoutEnabled;
private MethodExecutor executor = null;
public static enum ConnectionType {
LAZY_ENLISTABLE, LAZY_ASSOCIATABLE, STANDARD
}
private ConnectionType myType_ = ConnectionType.STANDARD;
/**
* The active flag is false when the connection handle is
* created. When a method is invoked on this object, it asks
* the ManagedConnection if it can be the active connection
* handle out of the multiple connection handles. If the
* ManagedConnection reports that this connection handle
* can be active by setting this flag to true via the setActive
* function, the above method invocation succeeds; otherwise
* an exception is thrown.
*/
protected final static StringManager sm = StringManager.getManager(
DataSourceObjectBuilder.class);
/**
* Constructs a Connection holder.
*
* @param con java.sql.Connection
object.
*/
public ConnectionHolder(Connection con, ManagedConnectionImpl mc,
jakarta.resource.spi.ConnectionRequestInfo cxRequestInfo) {
this.con = con;
this.mc = mc;
mcf_ = mc.getMcf();
cxReqInfo_ = cxRequestInfo;
statementTimeout = mc.getStatementTimeout();
executor = new MethodExecutor();
if (statementTimeout > 0) {
statementTimeoutEnabled = true;
}
}
/**
* Returns the actual connection in this holder object.
*
* @return Connection object.
* @throws java.sql.SQLException
*/
public Connection getConnection() throws SQLException {
//To ensure that the actual connection is always returned and not a proxy
return con.unwrap(java.sql.Connection.class);
}
/**
* Sets the flag to indicate that, the connection is wrapped already or not.
*
* @param wrapFlag
*/
public void wrapped(boolean wrapFlag) {
this.wrappedAlready = wrapFlag;
}
/**
* Returns whether it is wrapped already or not.
*
* @return wrapped flag.
*/
public boolean isWrapped() {
return wrappedAlready;
}
/**
* Returns the ManagedConnection
instance responsible
* for this connection.
*
* @return ManagedConnection
instance.
*/
public ManagedConnectionImpl getManagedConnection() {
return mc;
}
/**
* Replace the actual java.sql.Connection
object with the one
* supplied. Also replace ManagedConnection
link.
*
* @param con Connection
object.
* @param mc ManagedConnection
object.
*/
public void associateConnection(Connection con, ManagedConnectionImpl mc) {
this.mc = mc;
this.con = con;
}
/**
* Dis-associate ManagedConnection and actual-connection from this user connection.
* Used when lazy-connection-association is ON.
*/
public void dissociateConnection() {
this.mc = null;
this.con = null;
}
/**
* Clears all warnings reported for the underlying connection object.
*
* @throws SQLException In case of a database error.
*/
@Override
public void clearWarnings() throws SQLException {
checkValidity();
con.clearWarnings();
}
/**
* Closes the logical connection.
*
* @throws SQLException In case of a database error.
*/
@Override
public void close() throws SQLException {
if (isClosed) {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "jdbc.duplicate_close_connection", this);
}
return;
}
isClosed = true;
if (mc != null) {
//mc might be null if this is a lazyAssociatable connection
//and has not been associated yet or has been disassociated
mc.connectionClosed(null, this);
}
}
/**
* Invalidates this object.
*/
public void invalidate() {
valid = false;
}
/**
* Closes the physical connection involved in this.
*
* @throws SQLException In case of a database error.
*/
void actualClose() throws SQLException {
con.close();
}
/**
* Commit the changes in the underlying Connection.
*
* @throws SQLException In case of a database error.
*/
@Override
public void commit() throws SQLException {
checkValidity();
con.commit();
}
/**
* Creates a statement from the underlying Connection
*
* @return Statement
object.
* @throws SQLException In case of a database error.
*/
@Override
public Statement createStatement() throws SQLException {
checkValidity();
jdbcPreInvoke();
Statement stmt = con.createStatement();
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a statement from the underlying Connection.
*
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @return Statement
object.
* @throws SQLException In case of a database error.
*/
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
checkValidity();
jdbcPreInvoke();
Statement stmt = con.createStatement(resultSetType, resultSetConcurrency);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a statement from the underlying Connection.
*
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @param resultSetHoldability ResultSet Holdability.
* @return Statement
object.
* @throws SQLException In case of a database error.
*/
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
checkValidity();
jdbcPreInvoke();
Statement stmt = con.createStatement(resultSetType, resultSetConcurrency,
resultSetHoldability);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Retrieves the current auto-commit mode for the underlying Connection
.
*
* @return The current state of connection's auto-commit mode.
* @throws SQLException In case of a database error.
*/
@Override
public boolean getAutoCommit() throws SQLException {
checkValidity();
return con.getAutoCommit();
}
/**
* Retrieves the underlying Connection
object's catalog name.
*
* @return Catalog Name.
* @throws SQLException In case of a database error.
*/
@Override
public String getCatalog() throws SQLException {
checkValidity();
return con.getCatalog();
}
/**
* Retrieves the current holdability of ResultSet
objects created
* using this connection object.
*
* @return holdability value.
* @throws SQLException In case of a database error.
*/
@Override
public int getHoldability() throws SQLException {
checkValidity();
return con.getHoldability();
}
/**
* Retrieves the DatabaseMetaData
object from the underlying
* Connection
object.
*
* @return DatabaseMetaData
object.
* @throws SQLException In case of a database error.
*/
@Override
public DatabaseMetaData getMetaData() throws SQLException {
checkValidity();
return con.getMetaData();
}
/**
* Retrieves this Connection
object's current transaction isolation level.
*
* @return Transaction level
* @throws SQLException In case of a database error.
*/
@Override
public int getTransactionIsolation() throws SQLException {
checkValidity();
return con.getTransactionIsolation();
}
/**
* Retrieves the Map
object associated with
* Connection
Object.
*
* @return TypeMap set in this object.
* @throws SQLException In case of a database error.
*/
@Override
public Map> getTypeMap() throws SQLException {
checkValidity();
return con.getTypeMap();
}
/**
* Retrieves the the first warning reported by calls on the underlying
* Connection
object.
*
* @return First SQLWarning
Object or null.
* @throws SQLException In case of a database error.
*/
@Override
public SQLWarning getWarnings() throws SQLException {
checkValidity();
return con.getWarnings();
}
/**
* Retrieves whether underlying Connection
object is closed.
*
* @return true if Connection
object is closed, false
* if it is closed.
* @throws SQLException In case of a database error.
*/
@Override
public boolean isClosed() throws SQLException {
return isClosed;
}
/**
* Set the isClosed flag based on whether the underlying Connection
* object is closed.
*
* @param flag true if Connection
object is closed, false if
* its not closed.
*/
public void setClosed(boolean flag) {
isClosed = flag;
}
/**
* Retrieves whether this Connection
object is read-only.
*
* @return true if Connection
is read-only, false other-wise
* @throws SQLException In case of a database error.
*/
@Override
public boolean isReadOnly() throws SQLException {
checkValidity();
return con.isReadOnly();
}
/**
* Converts the given SQL statement into the system's native SQL grammer.
*
* @param sql SQL statement , to be converted.
* @return Converted SQL string.
* @throws SQLException In case of a database error.
*/
@Override
public String nativeSQL(String sql) throws SQLException {
checkValidity();
return con.nativeSQL(sql);
}
/**
* Creates a CallableStatement
object for calling database
* stored procedures.
*
* @param sql SQL Statement
* @return CallableStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
checkValidity();
jdbcPreInvoke();
CallableStatement stmt = con.prepareCall(sql);
if (statementTimeoutEnabled) {
stmt.setQueryTimeout(statementTimeout);
}
return stmt;
}
/**
* Creates a CallableStatement
object for calling database
* stored procedures.
*
* @param sql SQL Statement
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @return CallableStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
checkValidity();
jdbcPreInvoke();
CallableStatement stmt = con.prepareCall(sql, resultSetType, resultSetConcurrency);
if (statementTimeoutEnabled) {
stmt.setQueryTimeout(statementTimeout);
}
return stmt;
}
/**
* Creates a CallableStatement
object for calling database
* stored procedures.
*
* @param sql SQL Statement
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @param resultSetHoldability ResultSet Holdability.
* @return CallableStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
checkValidity();
jdbcPreInvoke();
CallableStatement stmt = con.prepareCall(sql, resultSetType, resultSetConcurrency,
resultSetHoldability);
if (statementTimeoutEnabled) {
stmt.setQueryTimeout(statementTimeout);
}
return stmt;
}
/**
* Creates a PreparedStatement
object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @return PreparedStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public PreparedStatement prepareStatement(final String sql) throws SQLException {
checkValidity();
jdbcPreInvoke();
PreparedStatement stmt = con.prepareStatement(sql);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a PreparedStatement
object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be returned.
* @return PreparedStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public PreparedStatement prepareStatement(final String sql, int autoGeneratedKeys) throws SQLException {
checkValidity();
jdbcPreInvoke();
PreparedStatement stmt = con.prepareStatement(sql, autoGeneratedKeys);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a PreparedStatement
object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param columnIndexes an array of column indexes indicating the columns that should be
* returned from the inserted row or rows.
* @return PreparedStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public PreparedStatement prepareStatement(final String sql, int[] columnIndexes) throws SQLException {
checkValidity();
jdbcPreInvoke();
PreparedStatement stmt = con.prepareStatement(sql, columnIndexes);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a PreparedStatement
object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @return PreparedStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public PreparedStatement prepareStatement(final String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
checkValidity();
jdbcPreInvoke();
PreparedStatement stmt = con.prepareStatement(sql, resultSetType, resultSetConcurrency);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a PreparedStatement
object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @param resultSetHoldability ResultSet Holdability.
* @return PreparedStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public PreparedStatement prepareStatement(final String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
checkValidity();
jdbcPreInvoke();
PreparedStatement stmt = con.prepareStatement(sql, resultSetType,
resultSetConcurrency, resultSetHoldability);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Creates a PreparedStatement
object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param columnNames Name of bound columns.
* @return PreparedStatement
object.
* @throws SQLException In case of a database error.
*/
@Override
public PreparedStatement prepareStatement(final String sql, String[] columnNames) throws SQLException {
checkValidity();
jdbcPreInvoke();
PreparedStatement stmt = con.prepareStatement(sql, columnNames);
if (statementTimeoutEnabled) {
try {
stmt.setQueryTimeout(statementTimeout);
} catch (SQLException ex) {
stmt.close();
}
}
return stmt;
}
/**
* Removes the given Savepoint
object from the current transaction.
*
* @param savepoint Savepoint
object
* @throws SQLException In case of a database error.
*/
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
checkValidity();
con.releaseSavepoint(savepoint);
}
/**
* Rolls back the changes made in the current transaction.
*
* @throws SQLException In case of a database error.
*/
@Override
public void rollback() throws SQLException {
checkValidity();
con.rollback();
}
/**
* Rolls back the changes made after the savepoint.
*
* @throws SQLException In case of a database error.
*/
@Override
public void rollback(Savepoint savepoint) throws SQLException {
checkValidity();
con.rollback(savepoint);
}
/**
* Sets the auto-commmit mode of the Connection
object.
*
* @param autoCommit boolean value indicating the auto-commit mode.
* @throws SQLException In case of a database error.
*/
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
checkValidity();
con.setAutoCommit(autoCommit);
mc.setLastAutoCommitValue(autoCommit);
}
/**
* Sets the catalog name to the Connection
object
*
* @param catalog Catalog name.
* @throws SQLException In case of a database error.
*/
@Override
public void setCatalog(String catalog) throws SQLException {
checkValidity();
con.setCatalog(catalog);
}
/**
* Sets the holdability of ResultSet
objects created
* using this Connection
object.
*
* @param holdability A ResultSet
holdability constant
* @throws SQLException In case of a database error.
*/
@Override
public void setHoldability(int holdability) throws SQLException {
checkValidity();
con.setHoldability(holdability);
}
/**
* Puts the connection in read-only mode as a hint to the driver to
* perform database optimizations.
*
* @param readOnly true enables read-only mode, false disables it.
* @throws SQLException In case of a database error.
*/
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
checkValidity();
con.setReadOnly(readOnly);
}
/**
* Creates and unnamed savepoint and returns an object corresponding to that.
*
* @return Savepoint
object.
* @throws SQLException In case of a database error.
*/
@Override
public Savepoint setSavepoint() throws SQLException {
checkValidity();
return con.setSavepoint();
}
/**
* Creates a savepoint with the name and returns an object corresponding to that.
*
* @param name Name of the savepoint.
* @return Savepoint
object.
* @throws SQLException In case of a database error.
*/
@Override
public Savepoint setSavepoint(String name) throws SQLException {
checkValidity();
return con.setSavepoint(name);
}
/**
* Creates the transaction isolation level.
*
* @param level transaction isolation level.
* @throws SQLException In case of a database error.
*/
@Override
public void setTransactionIsolation(int level) throws SQLException {
checkValidity();
con.setTransactionIsolation(level);
mc.setLastTransactionIsolationLevel(level);
}
/**
* Checks the validity of this object
*/
protected void checkValidity() throws SQLException {
if (isClosed) throw new SQLException("Connection closed");
if (!valid) throw new SQLException("Invalid Connection");
if (active == false) {
mc.checkIfActive(this);
}
}
/**
* Sets the active flag to true
*
* @param actv boolean
*/
public void setActive(boolean actv) {
active = actv;
}
/*
* Here this is a no-op. In the LazyEnlistableConnectionHolder, it will
* actually fire the lazyEnlist method of LazyEnlistableManagedConnection
*/
protected void jdbcPreInvoke() throws SQLException {
if (myType_ == ConnectionType.LAZY_ASSOCIATABLE) {
performLazyAssociation();
} else if (myType_ == ConnectionType.LAZY_ENLISTABLE) {
performLazyEnlistment();
}
}
protected void performLazyEnlistment() throws SQLException {
try {
if(lazyEnlistCm_ != null) {
lazyEnlistCm_.lazyEnlist(mc);
}
} catch (ResourceException re) {
String msg = sm.getString(
"jdbc.cannot_enlist", re.getMessage() +
" Cannnot Enlist ManagedConnection");
SQLException sqle = new SQLException(msg);
sqle.initCause(re);
throw sqle;
}
}
protected void performLazyAssociation() throws SQLException {
if (mc == null) {
try {
if(lazyAssocCm_ != null) {
lazyAssocCm_.associateConnection(this, mcf_, cxReqInfo_);
}
} catch (ResourceException re) {
String msg = sm.getString(
"jdbc.cannot_assoc", re.getMessage() +
" Cannnot Associate ManagedConnection");
SQLException sqle = new SQLException(msg);
sqle.initCause(re);
throw sqle;
}
}
}
public void setConnectionType(ConnectionType type) {
myType_ = type;
}
public ConnectionType getConnectionType() {
return myType_;
}
public void setLazyAssociatableConnectionManager(
jakarta.resource.spi.LazyAssociatableConnectionManager cm) {
lazyAssocCm_ = cm;
}
public void setLazyEnlistableConnectionManager(
jakarta.resource.spi.LazyEnlistableConnectionManager cm) {
lazyEnlistCm_ = cm;
}
/*
public void setManagedConnection(ManagedConnection con) {
this.mc = con;
}
*/
/**
* Installs the given Map
object as the tyoe map for this
* Connection
object.
*
* @param map Map
a Map object to install.
* @throws SQLException In case of a database error.
*/
@Override
public void setTypeMap(java.util.Map> map) throws SQLException {
checkValidity();
con.setTypeMap(map);
}
protected MethodExecutor getMethodExecutor() {
return executor;
}
}