/**
*
*/
package org.jboss.web.tomcat.service.session.persistent;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
*
* @author Brian Stansberry
*
* @version $Revision: $
*/
public class DriverManagerPersistentStore extends RDBMSStoreBase
{
private static final String storeName = DriverManagerPersistentStore.class.getSimpleName();
/**
* The descriptive information about this implementation.
*/
private static final String info = storeName + "/1.0";
// ------------------------------------------------------ Instance Fields
/**
* Connection string to use when connecting to the DB.
*/
private String connectionURL = null;
private Lock lock = new ReentrantLock();
/**
* The database connection.
*/
private volatile Connection dbConnection = null;
/**
* Instance of the JDBC Driver class we use as a connection factory.
*/
private Driver driver = null;
/**
* Driver to use.
*/
private String driverName = null;
// ------------------------------------------------------------ Properties
public String getStoreName()
{
return storeName;
}
public String getConnectionURL()
{
return connectionURL;
}
public void setConnectionURL(String connectionURL)
{
this.connectionURL = connectionURL;
}
public String getDriverName()
{
return driverName;
}
public void setDriverName(String driverName)
{
this.driverName = driverName;
}
@Override
protected Connection getConnection() throws SQLException
{
try
{
lock.lockInterruptibly();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted while acquiring connection lock");
}
// Do nothing if there is a database connection already open
if (dbConnection == null)
{
open();
}
return dbConnection;
}
@Override
protected void cleanup(Connection conn, ResultSet resultSet, boolean rollback)
{
this.dbConnection = null;
super.cleanup(conn, resultSet, rollback);
}
@Override
protected void releaseConnection(Connection dbConnection)
{
lock.unlock();
}
@Override
public String getInfo()
{
return info;
}
@Override
protected void startStore()
{
try
{
Class<?> clazz = Class.forName(driverName);
driver = (Driver) clazz.newInstance();
}
catch (RuntimeException ex)
{
throw ex;
}
catch (Exception ex)
{
throw new RuntimeException("Caught exception creating driver of class " + driverName, ex);
}
try
{
lock.lockInterruptibly();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted while acquiring connection lock");
}
try
{
open();
}
catch (SQLException e)
{
throw new RuntimeException("Caught SQLException while opening database connection -- " + e.toString());
}
finally
{
lock.unlock();
}
}
private Connection open() throws SQLException {
synchronized (this)
{
// Double-checked locking is ok since dbConnection is volatile
if (dbConnection != null)
return (dbConnection);
// Open a new connection
Properties props = new Properties();
if (getConnectionName() != null)
props.put("user", getConnectionName());
if (getConnectionPassword() != null)
props.put("password", getConnectionPassword());
dbConnection = driver.connect(connectionURL, props);
dbConnection.setAutoCommit(true);
return (dbConnection);
}
}
}