/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. 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.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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.
*/
package com.sun.gjc.spi;
import java.sql.*;
import java.util.Hashtable;
import java.util.Map;
import java.util.Enumeration;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.gjc.common.DataSourceObjectBuilder;
import javax.resource.ResourceException;
/**
* Holds the java.sql.Connection object, which is to be
* passed to the application program.
*
* @version 1.0, 02/07/23
* @author Binod P.G
*/
public class ConnectionHolder implements Connection{
protected Connection con;
protected ManagedConnection mc;
protected boolean wrappedAlready = false;
protected boolean isClosed = false;
protected boolean valid = true;
protected boolean active = false;
private javax.resource.spi.LazyAssociatableConnectionManager lazyAssocCm_;
private javax.resource.spi.LazyEnlistableConnectionManager lazyEnlistCm_;
private javax.resource.spi.ConnectionRequestInfo cxReqInfo_;
private javax.resource.spi.ManagedConnectionFactory mcf_;
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.
*/
static protected StringManager sm = StringManager.getManager(
DataSourceObjectBuilder.class);
/**
* Constructs a Connection holder.
*
* @param con <code>java.sql.Connection</code> object.
*/
public ConnectionHolder(Connection con, ManagedConnection mc,
javax.resource.spi.ConnectionRequestInfo cxRequestInfo ) {
this.con = con;
this.mc = mc;
mcf_ = mc.mcf;
cxReqInfo_ = cxRequestInfo;
}
/**
* Returns the actual connection in this holder object.
*
* @return Connection object.
*/
Connection getConnection() {
return con;
}
/**
* Sets the flag to indicate that, the connection is wrapped already or not.
*
* @param wrapFlag
*/
void wrapped(boolean wrapFlag){
this.wrappedAlready = wrapFlag;
}
/**
* Returns whether it is wrapped already or not.
*
* @return wrapped flag.
*/
boolean isWrapped(){
return wrappedAlready;
}
/**
* Returns the <code>ManagedConnection</code> instance responsible
* for this connection.
*
* @return <code>ManagedConnection</code> instance.
*/
ManagedConnection getManagedConnection() {
return mc;
}
/**
* Replace the actual <code>java.sql.Connection</code> object with the one
* supplied. Also replace <code>ManagedConnection</code> link.
*
* @param con <code>Connection</code> object.
* @param mc <code> ManagedConnection</code> object.
*/
void associateConnection(Connection con, ManagedConnection mc) {
this.mc = mc;
this.con = con;
}
/**
* Clears all warnings reported for the underlying connection object.
*
* @throws SQLException In case of a database error.
*/
public void clearWarnings() throws SQLException{
checkValidity();
con.clearWarnings();
}
/**
* Closes the logical connection.
*
* @throws SQLException In case of a database error.
*/
public void close() throws SQLException{
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.
*/
public void commit() throws SQLException {
checkValidity();
con.commit();
}
/**
* Creates a statement from the underlying Connection
*
* @return <code>Statement</code> object.
* @throws SQLException In case of a database error.
*/
public Statement createStatement() throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.createStatement();
}
/**
* Creates a statement from the underlying Connection.
*
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @return <code>Statement</code> object.
* @throws SQLException In case of a database error.
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.createStatement(resultSetType, resultSetConcurrency);
}
/**
* Creates a statement from the underlying Connection.
*
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @param resultSetHoldability ResultSet Holdability.
* @return <code>Statement</code> object.
* @throws SQLException In case of a database error.
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency,
int resultSetHoldabilty) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.createStatement(resultSetType, resultSetConcurrency,
resultSetHoldabilty);
}
/**
* Retrieves the current auto-commit mode for the underlying <code> Connection</code>.
*
* @return The current state of connection's auto-commit mode.
* @throws SQLException In case of a database error.
*/
public boolean getAutoCommit() throws SQLException {
checkValidity();
return con.getAutoCommit();
}
/**
* Retrieves the underlying <code>Connection</code> object's catalog name.
*
* @return Catalog Name.
* @throws SQLException In case of a database error.
*/
public String getCatalog() throws SQLException {
checkValidity();
return con.getCatalog();
}
/**
* Retrieves the current holdability of <code>ResultSet</code> objects created
* using this connection object.
*
* @return holdability value.
* @throws SQLException In case of a database error.
*/
public int getHoldability() throws SQLException {
checkValidity();
return con.getHoldability();
}
/**
* Retrieves the <code>DatabaseMetaData</code>object from the underlying
* <code> Connection </code> object.
*
* @return <code>DatabaseMetaData</code> object.
* @throws SQLException In case of a database error.
*/
public DatabaseMetaData getMetaData() throws SQLException {
checkValidity();
return con.getMetaData();
}
/**
* Retrieves this <code>Connection</code> object's current transaction isolation level.
*
* @return Transaction level
* @throws SQLException In case of a database error.
*/
public int getTransactionIsolation() throws SQLException {
checkValidity();
return con.getTransactionIsolation();
}
/**
* Retrieves the <code>Map</code> object associated with
* <code> Connection</code> Object.
*
* @return TypeMap set in this object.
* @throws SQLException In case of a database error.
*/
public Map getTypeMap() throws SQLException {
checkValidity();
return con.getTypeMap();
}
/**
* Retrieves the the first warning reported by calls on the underlying
* <code>Connection</code> object.
*
* @return First <code> SQLWarning</code> Object or null.
* @throws SQLException In case of a database error.
*/
public SQLWarning getWarnings() throws SQLException {
checkValidity();
return con.getWarnings();
}
/**
* Retrieves whether underlying <code>Connection</code> object is closed.
*
* @return true if <code>Connection</code> object is closed, false
* if it is closed.
* @throws SQLException In case of a database error.
*/
public boolean isClosed() throws SQLException {
return isClosed;
}
/**
* Retrieves whether this <code>Connection</code> object is read-only.
*
* @return true if <code> Connection </code> is read-only, false other-wise
* @throws SQLException In case of a database error.
*/
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.
*/
public String nativeSQL(String sql) throws SQLException {
checkValidity();
return con.nativeSQL(sql);
}
/**
* Creates a <code> CallableStatement </code> object for calling database
* stored procedures.
*
* @param sql SQL Statement
* @return <code> CallableStatement</code> object.
* @throws SQLException In case of a database error.
*/
public CallableStatement prepareCall(String sql) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.prepareCall(sql);
}
/**
* Creates a <code> CallableStatement </code> object for calling database
* stored procedures.
*
* @param sql SQL Statement
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @return <code> CallableStatement</code> object.
* @throws SQLException In case of a database error.
*/
public CallableStatement prepareCall(String sql,int resultSetType,
int resultSetConcurrency) throws SQLException{
checkValidity();
jdbcPreInvoke();
return con.prepareCall(sql, resultSetType, resultSetConcurrency);
}
/**
* Creates a <code> CallableStatement </code> 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 <code> CallableStatement</code> object.
* @throws SQLException In case of a database error.
*/
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldabilty) throws SQLException{
checkValidity();
jdbcPreInvoke();
return con.prepareCall(sql, resultSetType, resultSetConcurrency,
resultSetHoldabilty);
}
/**
* Creates a <code> PreparedStatement </code> object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @return <code> PreparedStatement</code> object.
* @throws SQLException In case of a database error.
*/
public PreparedStatement prepareStatement(String sql) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.prepareStatement(sql);
}
/**
* Creates a <code> PreparedStatement </code> object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param autoGeneratedKeys a flag indicating AutoGeneratedKeys need to be returned.
* @return <code> PreparedStatement</code> object.
* @throws SQLException In case of a database error.
*/
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.prepareStatement(sql,autoGeneratedKeys);
}
/**
* Creates a <code> PreparedStatement </code> 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 <code> PreparedStatement</code> object.
* @throws SQLException In case of a database error.
*/
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.prepareStatement(sql,columnIndexes);
}
/**
* Creates a <code> PreparedStatement </code> object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param resultSetType Type of the ResultSet
* @param resultSetConcurrency ResultSet Concurrency.
* @return <code> PreparedStatement</code> object.
* @throws SQLException In case of a database error.
*/
public PreparedStatement prepareStatement(String sql,int resultSetType,
int resultSetConcurrency) throws SQLException{
checkValidity();
jdbcPreInvoke();
return con.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
/**
* Creates a <code> PreparedStatement </code> 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 <code> PreparedStatement</code> object.
* @throws SQLException In case of a database error.
*/
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency,
int resultSetHoldabilty) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.prepareStatement(sql, resultSetType, resultSetConcurrency,
resultSetHoldabilty);
}
/**
* Creates a <code> PreparedStatement </code> object for sending
* paramterized SQL statements to database
*
* @param sql SQL Statement
* @param columnNames Name of bound columns.
* @return <code> PreparedStatement</code> object.
* @throws SQLException In case of a database error.
*/
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
checkValidity();
jdbcPreInvoke();
return con.prepareStatement(sql,columnNames);
}
/**
* Removes the given <code>Savepoint</code> object from the current transaction.
*
* @param savepoint <code>Savepoint</code> object
* @throws SQLException In case of a database error.
*/
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.
*/
public void rollback() throws SQLException {
checkValidity();
con.rollback();
}
/**
* Rolls back the changes made after the savepoint.
*
* @throws SQLException In case of a database error.
*/
public void rollback(Savepoint savepoint) throws SQLException {
checkValidity();
con.rollback(savepoint);
}
/**
* Sets the auto-commmit mode of the <code>Connection</code> object.
*
* @param autoCommit boolean value indicating the auto-commit mode.
* @throws SQLException In case of a database error.
*/
public void setAutoCommit(boolean autoCommit) throws SQLException {
checkValidity();
con.setAutoCommit(autoCommit);
mc.setLastAutoCommitValue(autoCommit);
}
/**
* Sets the catalog name to the <code>Connection</code> object
*
* @param catalog Catalog name.
* @throws SQLException In case of a database error.
*/
public void setCatalog(String catalog) throws SQLException {
checkValidity();
con.setCatalog(catalog);
}
/**
* Sets the holdability of <code>ResultSet</code> objects created
* using this <code>Connection</code> object.
*
* @param holdability A <code>ResultSet</code> holdability constant
* @throws SQLException In case of a database error.
*/
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.
*/
public void setReadOnly(boolean readOnly) throws SQLException {
checkValidity();
con.setReadOnly(readOnly);
}
/**
* Creates and unnamed savepoint and returns an object corresponding to that.
*
* @return <code>Savepoint</code> object.
* @throws SQLException In case of a database error.
*/
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 <code>Savepoint</code> object.
* @throws SQLException In case of a database error.
*/
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.
*/
public void setTransactionIsolation(int level) throws SQLException {
checkValidity();
con.setTransactionIsolation(level);
}
/**
* Installs the given <code>Map</code> object as the tyoe map for this
* <code> Connection </code> object.
*
* @param map <code>Map</code> a Map object to install.
* @throws SQLException In case of a database error.
*/
public void setTypeMap(Map map) throws SQLException {
checkValidity();
con.setTypeMap(map);
}
/**
* 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
*/
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 {
this.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 {
try {
this.lazyAssocCm_.associateConnection( this, mcf_, cxReqInfo_);
} 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;
}
}
public void setConnectionType( ConnectionType type ) {
myType_ = type;
}
public ConnectionType getConnectionType() {
return myType_;
}
public void setLazyAssociatableConnectionManager(
javax.resource.spi.LazyAssociatableConnectionManager cm ) {
lazyAssocCm_ = cm;
}
public void setLazyEnlistableConnectionManager(
javax.resource.spi.LazyEnlistableConnectionManager cm ) {
lazyEnlistCm_ = cm;
}
public void setManagedConnection( ManagedConnection con ) {
this.mc = con;
}
}
|