package ddth.dasp.framework.dbc;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mchange.v2.c3p0.DataSources;
import com.mchange.v2.c3p0.PooledDataSource;
/**
* This implementation of {@link IJdbcFactory} utilizes C3P0 as the connection
* pooling back-end.
*
* C3P0 homepage: http://www.mchange.com/projects/c3p0/
*
* @author NBThanh <btnguyen2k@gmail.com>
* @since class available since v0.2.0
*/
public class C3p0JdbcFactory extends AbstractJdbcFactory {
private final static Logger LOGGER = LoggerFactory.getLogger(C3p0JdbcFactory.class);
/**
* {@inheritDoc}
*/
@Override
protected void closeDataSource(DataSource ds) throws SQLException {
DataSources.destroy(ds);
}
/**
* {@inheritDoc}
*/
@Override
protected DataSourceInfo internalGetDataSourceInfo(String name, DataSource ds) {
DataSourceInfo dsInfo = internalGetDataSourceInfo(name);
if (ds instanceof PooledDataSource) {
PooledDataSource pooledDs = (PooledDataSource) ds;
try {
dsInfo.setNumActives(pooledDs.getNumBusyConnectionsAllUsers()).setNumIdles(
pooledDs.getNumIdleConnectionsAllUsers());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
return dsInfo;
}
/**
* {@inheritDoc}
*/
@Override
protected DataSource buildDataSource(String driver, String connUrl, String username,
String password) throws SQLException {
return buildDataSource(driver, connUrl, username, password, null);
}
/**
* {@inheritDoc}
*/
@Override
protected DataSource buildDataSource(String driver, String connUrl, String username,
String password, DbcpInfo dbcpInfo) throws SQLException {
int maxActive = dbcpInfo != null ? dbcpInfo.getMaxActive() : DbcpInfo.DEFAULT_MAX_ACTIVE;
long maxWaitTime = dbcpInfo != null ? dbcpInfo.getMaxWaitTime()
: DbcpInfo.DEFAULT_MAX_WAIT_TIME;
int maxIdle = dbcpInfo != null ? dbcpInfo.getMaxIdle() : DbcpInfo.DEFAULT_MAX_IDLE;
int minIdle = dbcpInfo != null ? dbcpInfo.getMinIdle() : DbcpInfo.DEFAULT_MIN_IDLE;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Building a datasource {driver:" + driver + ";connUrl:" + connUrl
+ ";username:" + username + ";maxActive:" + maxActive + ";maxWait:"
+ maxWaitTime + ";minIdle:" + minIdle + ";maxIdle:" + maxIdle + "}...");
}
try {
/*
* Note: we load the driver class here!
*/
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new SQLException(e);
}
Map<String, Object> overrideProps = new HashMap<String, Object>();
overrideProps.put("maxIdleTimeExcessConnections", 300); // seconds
overrideProps.put("acquireRetryAttempts", 2);
overrideProps.put("checkoutTimeout", maxWaitTime);// millisecs
// overrideProps.put("idleConnectionTestPeriod", 10); // seconds
// overrideProps.put("maxStatements", 0);
overrideProps.put("maxPoolSize", maxActive);
overrideProps.put("minPoolSize", minIdle);
overrideProps.put("testConnectionOnCheckout", true);
overrideProps.put("preferredTestQuery", getValidationQuery(driver));
// ClassLoader oldCladdLoader =
// Thread.currentThread().getContextClassLoader();
// CombinedClassLoader newClassLoader = new CombinedClassLoader();
// newClassLoader.addLoader(oldCladdLoader);
// newClassLoader.addLoader(C3p0JdbcFactory.class);
// newClassLoader.addLoader(DataSources.class);
// Thread.currentThread().setContextClassLoader(newClassLoader);
// try {
DataSource unpooledDs = DataSources.unpooledDataSource(connUrl, username, password);
PooledDataSource pooledDs = (PooledDataSource) DataSources.pooledDataSource(unpooledDs,
overrideProps);
if (pooledDs != null) {
String dsName = calcHash(driver, connUrl, username, password, dbcpInfo);
DataSourceInfo dsInfo = internalGetDataSourceInfo(dsName);
dsInfo.setMaxActives(maxActive).setMaxIdles(maxIdle).setMaxWait(maxWaitTime)
.setMinIdles(minIdle);
}
return pooledDs;
// } finally {
// Thread.currentThread().setContextClassLoader(oldCladdLoader);
// }
}
}