/*
* Use of this J2EE Connectors Sample Source Code file is governed by
* the following modified BSD license:
*
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND
* ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES
* SUFFERED BY LICENSEE AS A RESULT OF OR RELATING TO USE, MODIFICATION
* OR DISTRIBUTION OF THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/
package com.sun.connector.cciblackbox;
import javax.resource.*;
import javax.resource.spi.*;
import javax.resource.spi.security.PasswordCredential;
import javax.resource.spi.IllegalStateException;
import javax.resource.spi.SecurityException;
import javax.resource.NotSupportedException;
import javax.transaction.xa.XAResource;
import java.io.*;
import java.util.*;
import javax.security.auth.Subject;
import javax.sql.PooledConnection;
import javax.sql.XAConnection;
import java.sql.SQLException;
import java.sql.Connection;
/**
* This class represents a physical connection to an underlying EIS.
* @author Sheetal Vartak
*/
public class CciManagedConnection implements ManagedConnection {
private XAConnection xacon;
private java.sql.Connection con;
private CciConnectionEventListener cciListener;
private PasswordCredential passCred;
private ManagedConnectionFactory mcf;
private PrintWriter logWriter;
private boolean supportsXA;
private boolean supportsLocalTx;
private boolean destroyed;
private Set connectionSet; // set of CciConnection
CciManagedConnection(ManagedConnectionFactory mcf,
PasswordCredential passCred,
XAConnection xacon,
Connection con,
boolean supportsXA,
boolean supportsLocalTx) {
this.mcf = mcf;
this.passCred = passCred;
this.xacon = xacon;
this.con = con;
this.supportsXA = supportsXA;
this.supportsLocalTx = supportsLocalTx;
connectionSet = new HashSet();
cciListener = new CciConnectionEventListener(this);
if (xacon != null) {
xacon.addConnectionEventListener(cciListener);
}
}
public void setXAConnection(XAConnection xa) {
this.xacon = xa;
}
public void setConnection(java.sql.Connection con) {
this.con = con;
}
public void setSupportsXA(boolean xa) {
this.supportsXA = xa;
}
public void setSupportsLocalTx(boolean xa) {
this.supportsLocalTx = xa;
}
public void setManagedConnectionFactory(ManagedConnectionFactory xa) {
this.mcf = xa;
}
public XAConnection getXAConnection() {
return this.xacon;
}
public java.sql.Connection getConnection() {
return this.con;
}
public boolean getSupportsXA() {
return this.supportsXA;
}
public boolean getSupportsLocalTx() {
return this.supportsLocalTx;
}
public ManagedConnectionFactory getManagedConnectionFactory() {
return this.mcf;
}
// XXX should throw better exception
private void throwResourceException(SQLException ex)
throws ResourceException {
ResourceException re =
new ResourceException("SQLException: " + ex.getMessage());
re.setLinkedException(ex);
throw re;
}
public Object getConnection(Subject subject,
ConnectionRequestInfo connectionRequestInfo)
throws ResourceException {
PasswordCredential pc =
Util.getPasswordCredential(mcf, subject, connectionRequestInfo);
if (!Util.isPasswordCredentialEqual(pc, passCred)) {
throw new SecurityException("Principal does not match." +
"Reauthentication not supported");
}
checkIfDestroyed();
CciConnection cciCon = new CciConnection(this);
addCciConnection(cciCon);
return cciCon;
}
public void destroy() throws ResourceException {
try {
if (destroyed) return;
destroyed = true;
Iterator it = connectionSet.iterator();
while (it.hasNext()) {
CciConnection cciCon = (CciConnection) it.next();
cciCon.invalidate();
}
connectionSet.clear();
con.close();
if (xacon != null) xacon.close();
} catch (SQLException ex) {
throwResourceException(ex);
}
}
public void cleanup() throws ResourceException {
try {
checkIfDestroyed();
Iterator it = connectionSet.iterator();
while (it.hasNext()) {
CciConnection cciCon = (CciConnection) it.next();
cciCon.invalidate();
}
connectionSet.clear();
if (xacon != null) {
con.close();
con = xacon.getConnection();
} else {
con.setAutoCommit(true);
}
} catch (SQLException ex) {
throwResourceException(ex);
}
}
public void associateConnection(Object connection)
throws ResourceException {
checkIfDestroyed();
if (connection instanceof CciConnection) {
CciConnection cciCon = (CciConnection) connection;
cciCon.associateConnection(this);
} else {
throw new IllegalStateException("Invalid connection object: " +
connection);
}
}
public void addConnectionEventListener(ConnectionEventListener listener) {
cciListener.addConnectorListener(listener);
}
public void removeConnectionEventListener
(ConnectionEventListener listener) {
cciListener.removeConnectorListener(listener);
}
public XAResource getXAResource() throws ResourceException {
if (!supportsXA) {
throw new NotSupportedException("XA transaction not supported");
}
try {
checkIfDestroyed();
return xacon.getXAResource();
} catch (SQLException ex) {
throwResourceException(ex);
return null;
}
}
public javax.resource.spi.LocalTransaction getLocalTransaction()
throws ResourceException {
if (!supportsLocalTx) {
throw new NotSupportedException("Local transaction not supported");
} else {
checkIfDestroyed();
return new SpiLocalTransactionImpl(this);
}
}
public ManagedConnectionMetaData getMetaData() throws ResourceException {
checkIfDestroyed();
return new CciManagedConnectionMetaDataImpl(this);
}
public void setLogWriter(PrintWriter out) throws ResourceException {
this.logWriter = out;
}
public PrintWriter getLogWriter() throws ResourceException {
return logWriter;
}
public Connection getJdbcConnection() throws ResourceException {
checkIfDestroyed();
return con;
}
boolean isDestroyed() {
return destroyed;
}
PasswordCredential getPasswordCredential() {
return passCred;
}
public void sendEvent(int eventType, Exception ex) {
cciListener.sendEvent(eventType, ex, null);
}
public void sendEvent(int eventType, Exception ex,
Object connectionHandle) {
cciListener.sendEvent(eventType, ex, connectionHandle);
}
public void removeCciConnection(CciConnection cciCon) {
connectionSet.remove(cciCon);
}
public void addCciConnection(CciConnection cciCon) {
connectionSet.add(cciCon);
}
private void checkIfDestroyed() throws ResourceException {
if (destroyed) {
throw new IllegalStateException("Managed connection is closed");
}
}
}