User: mulder
Date: 00/06/02 06:48:42
Added: src/main/org/jboss/minerva/datasource
JDBCPoolDataSource.java PoolDriver.java
XAPoolDataSource.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/datasource/JDBCPoolDataSource.java
Index: JDBCPoolDataSource.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.minerva.datasource;
import java.sql.Connection;
import java.io.PrintWriter;
import java.util.*;
import javax.sql.DataSource;
import javax.naming.*;
import javax.naming.spi.*;
import org.jboss.minerva.factories.JDBCConnectionFactory;
import org.jboss.minerva.pools.ObjectPool;
/**
* DataSource for non-transactional JDBC pools. This handles configuration
* parameters for both the pool and the JDBC driver. It is important that you
* set all the configuration parameters before you initialize the DataSource,
* and you must initialize it before you use it. All the configuration
* parameters are not documented here; you are instead referred to ObjectPool
* and JDBCConnectionFactory.
* @see org.jboss.minerva.pools.ObjectPool
* @see org.jboss.minerva.factories.JDBCConnectionFactory
* @version $Revision: 1.1 $
* @author Aaron Mulder ([EMAIL PROTECTED])
*/
public class JDBCPoolDataSource implements DataSource, Referenceable, ObjectFactory {
private static HashMap sources = new HashMap();
/**
* Gets all the current JDBC pool data sources.
*/
public static Collection getDataSources() {
return new HashSet(sources.values());
}
/**
* Gets a specific JDBC pool data source by pool name.
*/
public static JDBCPoolDataSource getDataSource(String poolName) {
return (JDBCPoolDataSource)sources.get(poolName);
}
private ObjectPool pool;
private JDBCConnectionFactory factory;
private PrintWriter logWriter;
private int timeout;
private boolean initialized = false;
private String jndiName;
/**
* Creates a new JDBC pool data source. Be sure to configure it and then
* call initialize before you try to use it.
*/
public JDBCPoolDataSource() {
pool = new ObjectPool();
factory = new JDBCConnectionFactory();
PoolDriver.instance();
}
// Unique properties
/**
* If you use this to set a JNDI name, this pool will be bound to that name
* using the default InitialContext. You can also do this manually if you
* have additional requirements.
*/
public void setJNDIName(String name) throws NamingException {
InitialContext ctx = new InitialContext();
if(jndiName != null && !jndiName.equals(name))
ctx.unbind(jndiName);
if(name != null)
ctx.bind(name, this);
jndiName = name;
}
/**
* Gets the JNDI name this pool is bound to. Only valid if you used
* setJNDIName to bind it.
* @see #setJNDIName
*/
public String getJNDIName() {return jndiName;}
// JDBC properties
public void setJDBCURL(String url) {factory.setConnectURL(url);}
public String getJDBCURL() {return factory.getConnectURL();}
public void setJDBCProperties(Properties props)
{factory.setConnectProperties(props);}
public Properties getJDBCProperties() {return factory.getConnectProperties();}
public void setJDBCUser(String user) {factory.setUser(user);}
public String getJDBCUser() {return factory.getUser();}
public void setJDBCPassword(String password) {factory.setPassword(password);}
public String getJDBCPassword() {return factory.getPassword();}
// Pool properties
public void setPoolName(String name) {
pool.setName(name);
sources.put(pool.getName(), this);
}
public String getPoolName() {return pool.getName();}
public void setMinSize(int size) {pool.setMinSize(size);}
public int getMinSize() {return pool.getMinSize();}
public void setMaxSize(int size) {pool.setMaxSize(size);}
public int getMaxSize() {return pool.getMaxSize();}
public void setBlocking(boolean blocking) {pool.setBlocking(blocking);}
public boolean isBlocking() {return pool.isBlocking();}
public void setShrinkingEnabled(boolean allowShrinking)
{pool.setShrinkingEnabled(allowShrinking);}
public boolean isShrinkingEnabled() {return pool.isShrinkingEnabled();}
public void setGCEnabled(boolean allowGC) {pool.setGCEnabled(allowGC);}
public boolean isGCEnabled() {return pool.isGCEnabled();}
public void setShrinkPercent(float percent) {pool.setShrinkPercent(percent);}
public float getShrinkPercent() {return pool.getShrinkPercent();}
public void setShrinkMinIdleTime(long millis)
{pool.setShrinkMinIdleTime(millis);}
public long getShrinkMinIdleTime() {return pool.getShrinkMinIdleTime();}
public void setGCMinIdleTime(long millis) {pool.setGCMinIdleTime(millis);}
public long getGCMinIdleTime() {return pool.getGCMinIdleTime();}
public void setGCInterval(long millis) {pool.setGCInterval(millis);}
public long getGCInterval() {return pool.getGCInterval();}
public void setTimestampUsed(boolean timestamp)
{pool.setTimestampUsed(timestamp);}
public boolean isTimestampUsed() {return pool.isTimestampUsed();}
// Other methods
/**
* Initializes the pool. You need to have configured all the pool and
* JDBC properties first.
*/
public void initialize() {
initialized = true;
pool.setObjectFactory(factory);
pool.initialize();
}
/**
* Returns a string describing the pool status (number of connections
* created, used, and maximum).
*/
public String getPoolStatus() {
return pool.toString();
}
/**
* Shuts down this data source and the underlying pool. If you used
* setJNDI name to bind it in JNDI, it is unbound.
*/
public void close() {
try {
setJNDIName(null);
} catch(NamingException e) {
e.printStackTrace();
}
sources.remove(pool.getName());
pool.shutDown();
pool = null;
factory = null;
}
/**
* Gets a connection from the pool.
*/
public Connection getConnection() throws java.sql.SQLException {
if(!initialized) initialize();
return (Connection)pool.getObject();
}
/**
* Gets a connection from the pool. If a new connection must be
* created, it will use the specified user name and password. If there is
* a connection available in the pool, it will be used, regardless of the
* user name and password use to created it initially.
*/
public Connection getConnection(String user, String password) throws
java.sql.SQLException {
if(!initialized) initialize();
factory.setUser(user);
factory.setPassword(password);
return (Connection)pool.getObject();
}
/**
* Gets a log writer used to record pool events.
*/
public PrintWriter getLogWriter() throws java.sql.SQLException {
return logWriter;
}
/**
* Sets a log writer used to record pool events.
*/
public void setLogWriter(PrintWriter writer) throws java.sql.SQLException {
logWriter = writer;
pool.setLogWriter(writer);
}
/**
* This property is not used by this implementation.
*/
public int getLoginTimeout() throws java.sql.SQLException {
return timeout;
}
/**
* This property is not used by this implementation.
*/
public void setLoginTimeout(int timeout) throws java.sql.SQLException {
this.timeout = timeout;
}
// Referenceable implementation ----------------------------------
/**
* Gets a reference to this data source.
*/
public Reference getReference() {
return new Reference(getClass().getName(), new StringRefAddr("JDBCPool",
pool.getName()), getClass().getName(), null);
}
// ObjectFactory implementation ----------------------------------
/**
* Decodes a reference to a specific pool data source.
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment) {
if(obj instanceof Reference) {
Reference ref = (Reference)obj;
if(ref.getClassName().equals(getClass().getName())) {
RefAddr addr = ref.get("JDBCPool");
return sources.get((String)addr.getContent());
}
}
return null;
}
}
1.1 jboss/src/main/org/jboss/minerva/datasource/PoolDriver.java
Index: PoolDriver.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.minerva.datasource;
import java.sql.*;
import java.util.Properties;
import javax.sql.*;
/**
* JDBC Driver to access pooled JDBC connections. Supports both JDBC 1.0
* connections and JDBC 2.0 transactional XAConnections. You will get a
* java.sql.Connection back in any case (in the case of XAConnections, the
* transactional-ness is handled under the covers). You must create the pools
* ahead of time by creating and initializing the appropriate DataSource.
* <TABLE BORDER="1">
* <TR><TH>Connection Type</TH><TH>URL Form</TH></TR>
* <TR><TD>Connection</TD><TD>jdbc:minerva:<I>PoolName</I></TD></TR>
* <TR><TD>XAConnection</TD><TD>jdbc:minervaxa:<I>PoolName</I></TD></TR>
* </TABLE>
* <P>Note that you must load this driver like normal in order to use it:<BR>
* <CODE>Class.forName("org.minerva.datasource.PoolDriver");</CODE></P>
* @see org.jboss.minerva.datasource.JDBCPoolDataSource
* @see org.jboss.minerva.datasource.XAPoolDataSource
* @version $Revision: 1.1 $
* @author Aaron Mulder ([EMAIL PROTECTED])
*/
public class PoolDriver implements Driver {
private final static String URL_START = "jdbc:minerva:";
private final static String XA_URL_START = "jdbc:minervaxa:";
private final static PoolDriver instance;
static {
instance = new PoolDriver();
try {
DriverManager.registerDriver(PoolDriver.instance());
} catch(SQLException e) {
System.out.println("Unable to register Minerva DB pool driver!");
e.printStackTrace();
}
}
/**
* Gets the singleton driver instance.
*/
public static PoolDriver instance() {
return instance;
}
private PoolDriver() {
}
/**
* Tells which URLs this driver can handle.
*/
public boolean acceptsURL(String url) throws java.sql.SQLException {
return url.startsWith(URL_START) || url.startsWith(XA_URL_START);
}
/**
* Retrieves a connection from a connection pool.
*/
public Connection connect(String url, Properties props) throws
java.sql.SQLException {
if(url.startsWith(URL_START))
return getJDBCConnection(url.substring(URL_START.length()));
else if(url.startsWith(XA_URL_START))
return getXAConnection(url.substring(XA_URL_START.length()));
else
throw new SQLException("Invalid URL!");
}
private Connection getJDBCConnection(String name) {
Connection con = null;
try {
DataSource source = JDBCPoolDataSource.getDataSource(name);
con = source.getConnection();
} catch(Exception e) {
e.printStackTrace();
}
return con;
}
private Connection getXAConnection(String name) {
Connection con = null;
try {
DataSource source = XAPoolDataSource.getDataSource(name);
con = source.getConnection();
} catch(Exception e) {
e.printStackTrace();
}
return con;
}
/**
* Returns the driver version.
*/
public int getMajorVersion() {
return 2;
}
/**
* Returns the driver version.
*/
public int getMinorVersion() {
return 0;
}
/**
* Returns no properties. You do not need properties to connect to the
* pool, and the properties for the underlying driver are not managed here.
*/
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws
SQLException {
return new DriverPropertyInfo[0];
}
/**
* Returns <B>false</B> since it is not known which underlying driver will
* be used and what its capabilities are.
*/
public boolean jdbcCompliant() {
return false;
}
}
1.1
jboss/src/main/org/jboss/minerva/datasource/XAPoolDataSource.java
Index: XAPoolDataSource.java
===================================================================
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.minerva.datasource;
import java.sql.Connection;
import java.io.PrintWriter;
import java.util.*;
import javax.sql.*;
import javax.naming.*;
import javax.naming.spi.*;
import org.jboss.minerva.factories.XAConnectionFactory;
import org.jboss.minerva.pools.ObjectPool;
/**
* DataSource for transactional JDBC pools. This handles configuration
* parameters for both the pool and the JDBC connection. It is important that
* you set all the configuration parameters before you initialize the DataSource,
* and you must initialize it before you use it. All the configuration
* parameters are not documented here; you are instead referred to ObjectPool
* and XAConnectionFactory.
* @see org.jboss.minerva.pools.ObjectPool
* @see org.jboss.minerva.factories.XAConnectionFactory
* @version $Revision: 1.1 $
* @author Aaron Mulder ([EMAIL PROTECTED])
*/
public class XAPoolDataSource implements DataSource, Referenceable, ObjectFactory {
private static HashMap sources = new HashMap();
/**
* Gets all the current JDBC pool data sources.
*/
public static Collection getDataSources() {
return new HashSet(sources.values());
}
/**
* Gets a specific JDBC pool data source by pool name.
*/
public static XAPoolDataSource getDataSource(String poolName) {
return (XAPoolDataSource)sources.get(poolName);
}
private ObjectPool pool;
private XAConnectionFactory factory;
private PrintWriter logWriter;
private int timeout;
private boolean initialized = false;
private String jndiName;
/**
* Creates a new XA pool data source. Be sure to configure it and then
* call initialize before you try to use it.
*/
public XAPoolDataSource() {
pool = new ObjectPool();
try {
factory = new XAConnectionFactory();
} catch(NamingException e) {
e.printStackTrace();
}
PoolDriver.instance();
}
// Unique properties
/**
* If you use this to set a JNDI name, this pool will be bound to that name
* using the default InitialContext. You can also do this manually if you
* have additional requirements.
*/
public void setJNDIName(String name) throws NamingException {
InitialContext ctx = new InitialContext();
if(jndiName != null && !jndiName.equals(name))
ctx.unbind(jndiName);
if(name != null)
ctx.bind(name, this);
jndiName = name;
}
/**
* Gets the JNDI name this pool is bound to. Only valid if you used
* setJNDIName to bind it.
* @see #setJNDIName
*/
public String getJNDIName() {return jndiName;}
// XA properties
public void setDataSource(XADataSource ds) {factory.setDataSource(ds);}
public XADataSource getDataSource() {return factory.getDataSource();}
public void setTransactionManagerJNDIName(String name)
{factory.setTransactionManagerJNDIName(name);}
public String getTransactionManagerJNDIName() {return
factory.getTransactionManagerJNDIName();}
public void setJDBCUser(String user) {factory.setUser(user);}
public String getJDBCUser() {return factory.getUser();}
public void setJDBCPassword(String password) {factory.setPassword(password);}
public String getJDBCPassword() {return factory.getPassword();}
// Pool properties
public void setPoolName(String name) {
pool.setName(name);
sources.put(pool.getName(), this);
}
public String getPoolName() {return pool.getName();}
public void setMinSize(int size) {pool.setMinSize(size);}
public int getMinSize() {return pool.getMinSize();}
public void setMaxSize(int size) {pool.setMaxSize(size);}
public int getMaxSize() {return pool.getMaxSize();}
public void setBlocking(boolean blocking) {pool.setBlocking(blocking);}
public boolean isBlocking() {return pool.isBlocking();}
public void setShrinkingEnabled(boolean allowShrinking)
{pool.setShrinkingEnabled(allowShrinking);}
public boolean isShrinkingEnabled() {return pool.isShrinkingEnabled();}
public void setGCEnabled(boolean allowGC) {pool.setGCEnabled(allowGC);}
public boolean isGCEnabled() {return pool.isGCEnabled();}
public void setShrinkPercent(float percent) {pool.setShrinkPercent(percent);}
public float getShrinkPercent() {return pool.getShrinkPercent();}
public void setShrinkMinIdleTime(long millis)
{pool.setShrinkMinIdleTime(millis);}
public long getShrinkMinIdleTime() {return pool.getShrinkMinIdleTime();}
public void setGCMinIdleTime(long millis) {pool.setGCMinIdleTime(millis);}
public long getGCMinIdleTime() {return pool.getGCMinIdleTime();}
public void setGCInterval(long millis) {pool.setGCInterval(millis);}
public long getGCInterval() {return pool.getGCInterval();}
public void setTimestampUsed(boolean timestamp)
{pool.setTimestampUsed(timestamp);}
public boolean isTimestampUsed() {return pool.isTimestampUsed();}
// Other methods
/**
* Initializes the pool. You need to have configured all the pool and
* XA properties first.
*/
public void initialize() {
initialized = true;
pool.setObjectFactory(factory);
pool.initialize();
}
/**
* Returns a string describing the pool status (number of connections
* created, used, and maximum).
*/
public String getPoolStatus() {
return pool.toString();
}
/**
* Shuts down this data source and the underlying pool. If you used
* setJNDI name to bind it in JNDI, it is unbound.
*/
public void close() {
try {
setJNDIName(null);
} catch(NamingException e) {
e.printStackTrace();
}
sources.remove(pool.getName());
pool.shutDown();
pool = null;
factory = null;
}
/**
* Gets a connection from the pool.
*/
public Connection getConnection() throws java.sql.SQLException {
if(!initialized) initialize();
return ((XAConnection)pool.getObject()).getConnection();
}
/**
* Gets a new connection from the pool. If a new connection must be
* created, it will use the specified user name and password. If there is
* a connection available in the pool, it will be used, regardless of the
* user name and password use to created it initially.
*/
public Connection getConnection(String user, String password) throws
java.sql.SQLException {
if(!initialized) initialize();
factory.setUser(user);
factory.setPassword(password);
return ((XAConnection)pool.getObject()).getConnection();
}
/**
* Gets a log writer used to record pool events.
*/
public PrintWriter getLogWriter() throws java.sql.SQLException {
return logWriter;
}
/**
* Sets a log writer used to record pool events.
*/
public void setLogWriter(PrintWriter writer) throws java.sql.SQLException {
logWriter = writer;
pool.setLogWriter(writer);
}
/**
* This property is not used by this implementation.
*/
public int getLoginTimeout() throws java.sql.SQLException {
return timeout;
}
/**
* This property is not used by this implementation.
*/
public void setLoginTimeout(int timeout) throws java.sql.SQLException {
this.timeout = timeout;
}
// Referenceable implementation ----------------------------------
/**
* Gets a reference to this data source.
*/
public Reference getReference() {
return new Reference(getClass().getName(), new StringRefAddr("XAPool",
pool.getName()), getClass().getName(), null);
}
// ObjectFactory implementation ----------------------------------
/**
* Decodes a reference to a specific pool data source.
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment) {
if(obj instanceof Reference) {
Reference ref = (Reference)obj;
if(ref.getClassName().equals(getClass().getName())) {
RefAddr addr = ref.get("XAPool");
return sources.get((String)addr.getContent());
}
}
return null;
}
}
1.1 jboss/src/main/org/jboss/minerva/datasource/package.html
Index: package.html
===================================================================
<HTML>
<HEAD>
<TITLE>Minerva Pools: Package org.jboss.minerva.datasource</TITLE>
</HEAD>
<BODY BGCOLOR="WHITE">
<P>Data Sources that are the main client interface for connection pools.
The quickest way to get up and running with a JDBC or XA connection pool
is to create and configure a DataSource. This package includes both
non-transactional JDBC pools, and transactional JDBC pools that will
automatically register with a JTA TransactionManager. You may choose
to use the wrappers for non-transactional drivers in a transactional
JDBC pool by using that as your XADataSource (see
org.minerva.xa.XADataSourceImpl).</P>
</BODY>
</HTML>