User: mulder
Date: 00/06/02 06:48:43
Added: src/main/org/jboss/minerva/factories
JDBCConnectionFactory.java XAConnectionFactory.java
package.html
Log:
Initial entry of Minerva JDBC Pools into CVS.
Pools, DataSources, and other non-jBoss-dependent code is under
org.jboss.minerva.*
JavaDoc source HTML files are included - the package comments are in
the package.html files in the various packages, and the overview
comments are in org/jboss/minerva/minerva.html
MBeans to load a pool into jBoss are in org.jboss.jdbc
A new logging Writer is on org.jboss.logging.
Revision Changes Path
1.1
jboss/src/main/org/jboss/minerva/factories/JDBCConnectionFactory.java
Index: JDBCConnectionFactory.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.minerva.factories;
import java.sql.*;
import java.util.Properties;
import org.jboss.minerva.pools.*;
import org.jboss.minerva.jdbc.*;
/**
* Object factory that creates java.sql.Connections. This is meant for use
* outside a J2EE/JTA environment - servlets alone, client/server, etc. If
* you're interested in creating transactional-aware connections, see
* XAConnectionFactory, which complies with the JDBC 2.0 standard extension.
* @see org.jboss.minerva.factories.XAConnectionFactory
* @version $Revision: 1.1 $
* @author Aaron Mulder ([EMAIL PROTECTED])
*/
public class JDBCConnectionFactory extends PoolObjectFactory {
private String url;
private Properties props;
private String userName;
private String password;
/**
* Creates a new factory. You must configure it with JDBC properties
* before you can use it.
*/
public JDBCConnectionFactory() {
}
/**
* Sets the JDBC URL used to create new connections.
*/
public void setConnectURL(String url) {this.url = url;}
/**
* Gets the JDBC URL used to create new connections.
*/
public String getConnectURL() {return url;}
/**
* Sets the JDBC Propeties used to create new connections.
* This is optional, and will only be used if present.
*/
public void setConnectProperties(Properties props) {this.props = props;}
/**
* Gets the JDBC Properties used to create new connections.
*/
public Properties getConnectProperties() {return props;}
/**
* Sets the JDBC user name used to create new connections.
* This is optional, and will only be used if present.
*/
public void setUser(String userName) {this.userName = userName;}
/**
* Gets the JDBC user name used to create new connections.
*/
public String getUser() {return userName;}
/**
* Sets the JDBC password used to create new connections.
* This is optional, and will only be used if present.
*/
public void setPassword(String password) {this.password = password;}
/**
* Gets the JDBC password used to create new connections.
*/
public String getPassword() {return password;}
/**
* Validates that connection properties were set (at least a URL).
*/
public void poolStarted(ObjectPool pool) {
super.poolStarted(pool);
if(url == null)
throw new IllegalStateException("Must specify JDBC connection URL to
"+getClass().getName());
}
/**
* Creates a new JDBC Connection.
*/
public Object createObject() {
try {
if(userName != null && userName.length() > 0)
return DriverManager.getConnection(url, userName, password);
else if(props != null)
return DriverManager.getConnection(url, props);
else
return DriverManager.getConnection(url);
} catch(SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* Wraps the connection with a ConnectionInPool.
* @see org.jboss.minerva.jdbc.ConnectionInPool
*/
public Object prepareObject(Object pooledObject) {
Connection con = (Connection)pooledObject;
ConnectionInPool wrapper = new ConnectionInPool(con);
return wrapper;
}
/**
* Returns the original connection from a ConnectionInPool.
* @see org.jboss.minerva.jdbc.ConnectionInPool
*/
public Object translateObject(Object clientObject) {
return ((ConnectionInPool)clientObject).getUnderlyingConnection();
}
/**
* Closes all outstanding work for the connection, rolls it back, and
* returns the underlying connection to the pool.
*/
public Object returnObject(Object clientObject) {
ConnectionInPool wrapper = (ConnectionInPool)clientObject;
Connection con = wrapper.getUnderlyingConnection();
try {
wrapper.reset();
} catch(SQLException e) {}
return con;
}
/**
* Closes a connection.
*/
public void deleteObject(Object pooledObject) {
Connection con = (Connection)pooledObject;
try {
con.rollback();
} catch(SQLException e) {}
try {
con.close();
} catch(SQLException e) {}
}
}
1.1
jboss/src/main/org/jboss/minerva/factories/XAConnectionFactory.java
Index: XAConnectionFactory.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.minerva.factories;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.transaction.*;
import javax.transaction.xa.*;
import org.jboss.minerva.pools.*;
import org.jboss.minerva.xa.*;
/**
* Object factory for JDBC 2.0 standard extension XAConnections. You pool the
* XAConnections instead of the java.sql.Connections since with vendor
* conformant drivers, you don't have direct access to the java.sql.Connection,
* and any work done isn't associated with the java.sql.Connection anyway.
* <P><B>Note:</B> This implementation requires that the TransactionManager
* be bound to a JNDI name.</P>
* @version $Revision: 1.1 $
* @author Aaron Mulder ([EMAIL PROTECTED])
*/
public class XAConnectionFactory extends PoolObjectFactory {
private InitialContext ctx;
private XADataSource source;
private String userName;
private String password;
private String tmJndiName;
private ConnectionEventListener listener;
private TransactionListener transListener;
private ObjectPool pool;
/**
* Creates a new factory. You must set the XADataSource and
* TransactionManager JNDI name before the factory can be used.
*/
public XAConnectionFactory() throws NamingException {
ctx = new InitialContext();
listener = new ConnectionEventListener() {
public void connectionErrorOccurred(ConnectionEvent evt) {
closeConnection(evt, XAResource.TMFAIL);
}
public void connectionClosed(ConnectionEvent evt) {
closeConnection(evt, XAResource.TMSUCCESS);
}
private void closeConnection(ConnectionEvent evt, int status) {
XAConnection con = (XAConnection)evt.getSource();
try {
TransactionManager tm =
(TransactionManager)ctx.lookup(tmJndiName);
if(tm.getStatus() != Status.STATUS_NO_TRANSACTION)
tm.getTransaction().delistResource(con.getXAResource(),
status);
} catch(Exception e) {
e.printStackTrace();
throw new RuntimeException("Unable to deregister with
TransactionManager: "+e);
}
con.removeConnectionEventListener(listener);
if(!(con instanceof XAConnectionImpl))
pool.releaseObject(con);
}
};
transListener = new TransactionListener() {
public void transactionFinished(XAConnectionImpl con) {
con.clearTransactionListener();
pool.releaseObject(con);
}
};
}
/**
* Sets the user name used to generate XAConnections. This is optional,
* and will only be used if present.
*/
public void setUser(String userName) {this.userName = userName;}
/**
* Gets the user name used to generate XAConnections.
*/
public String getUser() {return userName;}
/**
* Sets the password used to generate XAConnections. This is optional,
* and will only be used if present.
*/
public void setPassword(String password) {this.password = password;}
/**
* Gets the password used to generate XAConnections.
*/
public String getPassword() {return password;}
/**
* Sets the XADataSource used to generate XAConnections. This may be
* supplied by the vendor, or it may use the wrappers for non-compliant
* drivers (see XADataSourceImpl).
* @see org.jboss.minerva.xa.XADataSourceImpl
*/
public void setDataSource(XADataSource dataSource) {source = dataSource;}
/**
* Gets the XADataSource used to generate XAConnections.
*/
public XADataSource getDataSource() {return source;}
/**
* Sets the JNDI name that the TransactionManager is registered under.
*/
public void setTransactionManagerJNDIName(String name) {tmJndiName = name;}
/**
* Gets the JNDI name that the TransactionManager is registered under.
*/
public String getTransactionManagerJNDIName() {return tmJndiName;}
/**
* Verifies that the data source and transaction manager are accessible.
*/
public void poolStarted(ObjectPool pool) {
super.poolStarted(pool);
this.pool = pool;
if(source == null)
throw new IllegalStateException("Must specify XADataSource to
"+getClass().getName());
if(tmJndiName == null)
throw new IllegalStateException("Must specify TransactionManager JNDI
Name to "+getClass().getName());
if(ctx == null)
throw new IllegalStateException("Must specify InitialContext to
"+getClass().getName());
try {
TransactionManager tm = (TransactionManager)ctx.lookup(tmJndiName);
} catch(NamingException e) {
throw new IllegalStateException("Cannot lookup TransactionManager using
specified context and name!");
}
}
/**
* Creates a new XAConnection from the provided XADataSource.
*/
public Object createObject() {
try {
if(userName != null && userName.length() > 0)
return source.getXAConnection(userName, password);
else
return source.getXAConnection();
} catch(SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* Registers the XAConnection's XAResource with the current transaction (if
* there is one). Sets listeners that will handle deregistering and
* returning the XAConnection to the pool via callbacks.
*/
public Object prepareObject(Object pooledObject) {
XAConnection con = (XAConnection)pooledObject;
try {
TransactionManager tm = (TransactionManager)ctx.lookup(tmJndiName);
if(tm.getStatus() != Status.STATUS_NO_TRANSACTION) {
tm.getTransaction().enlistResource(con.getXAResource());
System.out.println("Enlisted with transaction.");
}
System.out.println("No transaction right now.");
} catch(Exception e) {
e.printStackTrace();
throw new RuntimeException("Unable to register with TransactionManager:
"+e);
}
con.addConnectionEventListener(listener);
if(con instanceof XAConnectionImpl)
((XAConnectionImpl)con).setTransactionListener(transListener);
return con;
}
/**
* Closes a connection.
*/
public void deleteObject(Object pooledObject) {
XAConnection con = (XAConnection)pooledObject;
try {
con.close();
} catch(SQLException e) {}
}
}
1.1 jboss/src/main/org/jboss/minerva/factories/package.html
Index: package.html
===================================================================
<HTML>
<HEAD>
<TITLE>Minerva Pools: Package org.jboss.minerva.factories</TITLE>
</HEAD>
<BODY BGCOLOR="WHITE">
<P>PoolObjectFactories that manage Connections and XAConnections in a
connection pool. These handle the mechanics of wrapping and unwrapping
connections, registering XAConnections with the TransactionManager,
etc.</P>
</BODY>
</HTML>