public class oracleconnectionmanager {
private dbconnectionmanager connmgr;
private final string poolname="oracle";
private connection conn;
public oracleconnectionmanager() {
string userid = "system";
string password = "manager";
string jdbcdriver = "oracle.jdbc.driver.oracledriver";
string jdbcdrivertype = "jdbc:oracle:thin";
string dbhost = "127.0.0.1";
string port = "1521";
string sid="sid";
string url = jdbcdrivertype+":@"+dbhost + ":" + port + ":" +sid;
connmgr = dbconnectionmanager.getinstance();
if (dbconnectionmanager.clients == 1){
connmgr.init(poolname, jdbcdriver, url, userid, password);
connmgr.init("egongoracle", jdbcdriver, jdbcdrivertype+":@110.7.6.22:1521:egong", "abcusername", "abcpasswd");
}
}
public connection getconnection() {
return (conn=connmgr.getconnection(poolname));
}
public connection getconnection(string neworacle) {
return (conn=connmgr.getconnection(neworacle));
}
public void freeconnection() {
connmgr.freeconnection(poolname,conn);
}
public void freeconnection(string neworacle) {
connmgr.freeconnection(neworacle,conn);
}
}
public class dbconnectionmanager {
static private dbconnectionmanager instance=null; // the single instance
static public int clients=0;
private vector drivers = new vector();
private printwriter log;
private hashtable pools = new hashtable();
private final int max_conn = 1000;
/**
* returns the single instance, creating one if its the
* first time this method is called.
*
* @return dbconnectionmanager the single instance.
*/
static synchronized public dbconnectionmanager getinstance() {
if (instance == null) {
instance = new dbconnectionmanager();
}
clients++;
return instance;
}
/**
* a private constructor since this is a singleton
*/
private dbconnectionmanager() {
// init();
}
/**
* returns a connection to the named pool.
*
* @param name the pool name as defined in the properties file
* @param con the connection
*/
public void freeconnection(string name, connection con) {
dbconnectionpool pool = (dbconnectionpool) pools.get(name);
if (pool != null) {
pool.freeconnection(con);
}
}
/**
* returns an open connection. if no one is available, and the max
* number of connections has not been reached, a new connection is
* created.
*
* @param name the pool name as defined in the properties file
* @return connection the connection or null
*/
public connection getconnection(string name) {
dbconnectionpool pool = (dbconnectionpool) pools.get(name);
if (pool != null) {
return pool.getconnection();
}
return null;
}
/**
* returns an open connection. if no one is available, and the max
* number of connections has not been reached, a new connection is
* created. if the max number has been reached, waits until one
* is available or the specified time has elapsed.
*
* @param name the pool name as defined in the properties file
* @param time the number of milliseconds to wait
* @return connection the connection or null
*/
public connection getconnection(string name, long time) {
dbconnectionpool pool = (dbconnectionpool) pools.get(name);
if (pool != null) {
return pool.getconnection(time);
}
return null;
}
/**
* closes all open connections and deregisters all drivers.
*/
public synchronized void release() {
// wait until called by the last client
if (–clients != 0) {
return;
}
enumeration allpools = pools.elements();
while (allpools.hasmoreelements()) {
dbconnectionpool pool = (dbconnectionpool) allpools.nextelement();
pool.release();
}
enumeration alldrivers = drivers.elements();
while (alldrivers.hasmoreelements()) {
driver driver = (driver) alldrivers.nextelement();
try {
drivermanager.deregisterdriver(driver);
log("deregistered jdbc driver " + driver.getclass().getname());
}
catch (sqlexception e) {
log(e, "cant deregister jdbc driver: " + driver.getclass().getname());
}
}
log.close();
}
/**
* creates instances of dbconnectionpool based on the properties.
* a dbconnectionpool can be defined with the following properties:
* <pre>
* <poolname>.url the jdbc url for the database
* <poolname>.user a database user (optional)
* <poolname>.password a database user password (if user specified)
* <poolname>.maxconn the maximal number of connections (optional)
* </pre>
*
* @param props the connection pool properties
*/
private void createpools(string poolname, string url, string user, string password, int max) {
/*
enumeration propnames = props.propertynames();
while (propnames.hasmoreelements()) {
string name = (string) propnames.nextelement();
if (name.endswith(".url")) {
string poolname = name.substring(0, name.lastindexof("."));
string url = props.getproperty(poolname + ".url");
if (url == null) {
log("no url specified for " + poolname);
continue;
}
string user = props.getproperty(poolname + ".user");
string password = props.getproperty(poolname + ".password");
string maxconn = props.getproperty(poolname + ".maxconn", "0");
int max;
try {
max = integer.valueof(maxconn).intvalue();
}
catch (numberformatexception e) {
log("invalid maxconn value " + maxconn + " for " + poolname);
max = 0;
}
dbconnectionpool pool =
new dbconnectionpool(poolname, url, user, password, max);
pools.put(poolname, pool);
log("initialized pool " + poolname);
}
}
*/
dbconnectionpool pool =
new dbconnectionpool(poolname, url, user, password, max);
pools.put(poolname, pool);
log("initialized pool " + poolname);
}
public void init(string poolname, string driver, string url, string user, string passwd) {
init(poolname, driver, url, user, passwd, max_conn);
}
/**
* loads properties and initializes the instance with its values.
*/
public void init(string poolname, string driver, string url, string user, string passwd, int maxconn) {
/*
inputstream is = getclass().getresourceasstream("/db.properties");
properties dbprops = new properties();
try {
dbprops.load(is);
}
catch (exception e) {
system.err.println("cant read the properties file. " +
"make sure db.properties is in the classpath");
return;
}
string logfile = dbprops.getproperty("logfile", "dbconnectionmanager.log");
string logfile = "." + file.separator + "logs" + file.separator + "dbpool";
try {
log = new printwriter(new filewriter(logfile, true), true);
}
catch (ioexception e) {
system.err.println("cant open the log file: " + logfile);
log = new printwriter(system.err);
}
*/
log = new printwriter(system.err);
loaddrivers(driver);
createpools(poolname, url, user, passwd, maxconn);
}
/**
* loads and registers all jdbc drivers. this is done by the
* dbconnectionmanager, as opposed to the dbconnectionpool,
* since many pools may share the same driver.
*
* @param props the connection pool properties
*/
private void loaddrivers(string driverclassname) {
/*
string driverclasses = props.getproperty("drivers");
stringtokenizer st = new stringtokenizer(driverclasses);
while (st.hasmoreelements()) {
string driverclassname = st.nexttoken().trim();
try {
driver driver = (driver)
class.forname(driverclassname).newinstance();
drivermanager.registerdriver(driver);
drivers.addelement(driver);
log("registered jdbc driver " + driverclassname);
}
catch (exception e) {
log("cant register jdbc driver: " +
driverclassname + ", exception: " + e);
}
}
*/
try {
driver driver = (driver)
class.forname(driverclassname).newinstance();
drivermanager.registerdriver(driver);
drivers.addelement(driver);
log("registered jdbc driver " + driverclassname);
}
catch (exception e) {
log("cant register jdbc driver: " +
driverclassname + ", exception: " + e);
}
}
/**
* writes a message to the log file.
*/
private void log(string msg) {
log.println(new date() + ": " + msg);
}
/**
* writes a message with an exception to the log file.
*/
private void log(throwable e, string msg) {
log.println(new date() + ": " + msg);
e.printstacktrace(log);
}
/**
* this inner class represents a connection pool. it creates new
* connections on demand, up to a max number if specified.
* it also makes sure a connection is still open before it is
* returned to a client.
*/
class dbconnectionpool {
private int checkedout;
private vector freeconnections = new vector();
private int maxconn;
private string name;
private string password;
private string url;
private string user;
/**
* creates new connection pool.
*
* @param name the pool name
* @param url the jdbc url for the database
* @param user the database user, or null
* @param password the database user password, or null
* @param maxconn the maximal number of connections, or 0
* for no limit
*/
public dbconnectionpool(string name, string url, string user, string password,
int maxconn) {
this.name = name;
this.url = url;
this.user = user;
this.password = password;
this.maxconn = maxconn;
}
/**
* checks in a connection to the pool. notify other threads that
* may be waiting for a connection.
*
* @param con the connection to check in
*/
public synchronized void freeconnection(connection con) {
// put the connection at the end of the vector
freeconnections.addelement(con);
checkedout–;
notifyall();
}
/**
* checks out a connection from the pool. if no free connection
* is available, a new connection is created unless the max
* number of connections has been reached. if a free connection
* has been closed by the database, its removed from the pool
* and this method is called again recursively.
*/
public synchronized connection getconnection() {
connection con = null;
if (freeconnections.size() > 0) {
// pick the first connection in the vector
// to get round-robin usage
con = (connection) freeconnections.firstelement();
freeconnections.removeelementat(0);
try {
if (con.isclosed()) {
log("removed bad connection from " + name);
// try again recursively
con = getconnection();
}
}
catch (sqlexception e) {
log("removed bad connection from " + name);
// try again recursively
con = getconnection();
}
}
else if (maxconn == 0 || checkedout < maxconn) {
con = newconnection();
}
if (con != null) {
checkedout++;
}
return con;
}
/**
* checks out a connection from the pool. if no free connection
* is available, a new connection is created unless the max
* number of connections has been reached. if a free connection
* has been closed by the database, its removed from the pool
* and this method is called again recursively.
* <p>
* if no connection is available and the max number has been
* reached, this method waits the specified time for one to be
* checked in.
*
* @param timeout the timeout value in milliseconds
*/
public synchronized connection getconnection(long timeout) {
long starttime = new date().gettime();
connection con;
while ((con = getconnection()) == null) {
try {
wait(timeout);
}
catch (interruptedexception e) {}
if ((new date().gettime() – starttime) >= timeout) {
// timeout has expired
return null;
}
}
return con;
}
/**
* closes all available connections.
*/
public synchronized void release() {
enumeration allconnections = freeconnections.elements();
while (allconnections.hasmoreelements()) {
connection con = (connection) allconnections.nextelement();
try {
con.close();
log("closed connection for pool " + name);
}
catch (sqlexception e) {
log(e, "cant close connection for pool " + name);
}
}
freeconnections.removeallelements();
}
/**
* creates a new connection, using a userid and password
* if specified.
*/
private connection newconnection() {
connection con = null;
try {
if (user == null) {
con = drivermanager.getconnection(url);
}
else {
con = drivermanager.getconnection(url, user, password);
}
log("created a new connection in pool " + name);
}
catch (sqlexception e) {
log(e, "cant create a new connection for " + url);
return null;
}
return con;
}
}
}
