/**
* Title: Code Repository Project<p>
* Description: The code repository is a web application
* that keeps hints and tips in a hierarchical fashion.
* The user can search the repository in several different ways,
* and the repository can contain any data, along with a
* description of the data. Most of the time the data will be code.
* Eventually the web application should be able to do syntax
* highlighting on-the-fly when showing the code.
* <p>
* Copyright: Copyright (c) David Martinez<p>
* Company: <p>
* @author David Martinez
* @version 1.0
*/
package com.hackerdude.lib.dataaccess;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Vector;
/**
* The ConnectionPool is basically a class that manages simultaneous connections across multiple
* threads
*
* This is done by keeping a busy flag that is raised when you call {@link #getConnection()} and lowered
* when you call {@link #releaseConnection(Connection)}.
*
* {@link #getConnection()} <B>will return a null if all the connections are busy</B> and the maximum connections
* value has been exceeded. The calling program should know enough to check for this and return
* a "Server too busy" message or something similar.
*/
public class ConnectionPool {
private Vector pooledConnections = new Vector();
private int maxConnections = 10;
private ConnectionFactory connectionFactory;
public String poolName;
/**
* Return the maximum number of connections this class is configured
* to support.
*/
public int getMaxConnections() { return (maxConnections); }
/**
* Changes the maximum number of connections this class is configured
* to support.
*/
public synchronized void setMaxConnections( int max ) { maxConnections = max; }
/** When creating a connection pool you can give it a name. In the future
* I might create a final list of connection pools for an application. For now
* simply give a name to each connection pool you want to use.
*/
public ConnectionPool(String name, ConnectionFactory factory) {
poolName = name;
this.connectionFactory = factory;
}
/** Use this methods to add connections to the list manually.
* The pooler will also be able to generate connections
* automatically, both as needed and at the class creation time.
*/
public synchronized PooledConnection addConnection(Connection c) {
PooledConnection result = new PooledConnection(c);
pooledConnections.add(result);
return(result);
}
/** Every time you want a connection, call this function instead of creating one.
* This is the magic function that will find you an unused connection from the
* pool and give it to you. When you're done, make sure you release the
* connection.
*/
public synchronized Connection getConnection() throws SQLException {
Enumeration e = pooledConnections.elements();
PooledConnection p = null;
int elements = 0;
while ( e.hasMoreElements() ) {
elements++;
p = (PooledConnection)e.nextElement();
if ( ! p.isBusy ) {
p.isBusy = true;
break;
}
}
// Create more connections as needed, until maxConnections hit.
if ( p == null && elements < maxConnections ) {
Connection c = connectionFactory.createConnection();
p = addConnection( c );
}
if ( p == null ) return null;
return p.connection;
}
/**
* This finds out if a connection is in the pool and releases it.
* it returns null if the system was able to release it.
*/
public synchronized Connection releaseConnection(Connection c) {
if ( c == null ) return null;
Enumeration e = pooledConnections.elements();
PooledConnection p = null;
while ( e.hasMoreElements() ) {
p = (PooledConnection)e.nextElement();
if ( p.connection == c ) {
p.isBusy = false;
break;
}
}
return ( null );
}
public synchronized void disconectAll() {
Enumeration e = pooledConnections.elements();
PooledConnection p = null;
while ( e.hasMoreElements() ) {
p = (PooledConnection)e.nextElement();
if ( p.connection != null ) {
try {
p.connection.close();
} catch ( SQLException exc ) {}
}
}
pooledConnections.clear();
}
public Enumeration elements() {
return pooledConnections.elements();
}
/**
* This <I>private</I> class is what keeps the busy information for each
* connection. It could be extended.
*/
private class PooledConnection {
public boolean isBusy;
public Connection connection;
public PooledConnection(Connection c) {
isBusy = false;
connection = c;
}
}
}