ConnectionPool.java
001 /*
002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Atanas Kiryakov, 01/02/2002
011  *
012  *  $Id: ConnectionPool.java 12006 2009-12-01 17:24:28Z thomas_heitz $
013  */
014 package gate.persist;
015 
016 
017 import java.sql.Connection;
018 import java.sql.SQLException;
019 import java.util.Vector;
020 
021 /**
022    A generic implementation of pool of references to objects of any kind.
023    It is thread-safe, so, allows multiple users to get and release objects
024    "simultaneously". In fact, the standard Java synchronization is used.
025    <BR><BR>
026    The base idea is that, a calling routine will try to get
027    an object from the pool with method Get. On success, it will use the
028    object and return it in the pool with the method Put.
029    <BR><BR>
030    If there ares no available objects in the pool, Get will return <B>null</B>.
031    Then the calling routine should create a new object. Further, scenario goes
032    in the same way - when finished using the object, calling routine shoud Put
033    it in the pool for future use, instead of leaving it to be garbage-collected.
034    <BR><BR>
035    The pool initially is empty. The only way to increase the number of objects
036    managed by the pool, is some external process to Put an object, that was
037    created, instead of previously Get from the pool.
038    <BR><BR>
039    Pool stores only references to currently "free" or available objects. When
040    some external routine Gets an object from the pool, its reference is not
041    locked, it is simply removed from the pool.
042  */
043 public class ConnectionPool {
044    private Vector   connections;
045    private int      size;
046    private String   url;
047    private int      connCount;
048 
049 /**
050    Constructs and object pool with specified size.
051    @param size determines the maximum size of the pool. This is the number
052          free objects that it can manage at the same time
053  */
054    public ConnectionPool(int size, String url) {
055       this.size = size;
056       connections = new Vector(this.size);
057       this.url = url;
058       this.connCount = 0;
059    // ConnectionPool
060 
061 /**
062    Pulls out an object from the pool. The reference to the object is removed
063    from the pool and their is no longer any kind of relation between this
064    object and the pool. It can be returned back (released) by Put method.
065    @return  an object from the pool, if available.<BR>
066             Otherwise, returns <B>null</B>
067  */
068   public synchronized Connection get()
069       throws SQLException,ClassNotFoundException{
070       int currAvailable = connections.size();
071       if (currAvailable > 0){
072         Connection conn = (Connectionconnections.elementAt(currAvailable-1);
073         connections.removeElementAt(currAvailable-1);
074         return conn;
075       }
076       else {
077         if (connCount < size) {
078           Connection newCon = DBHelper.connect(url);
079           connCount++;
080           return newCon;
081         }
082         else {
083           try {
084             wait();
085           }
086           catch (java.lang.InterruptedException ie) {
087             throw new SQLException(" Thread interrupted while waiting "
088                                     +"to get Connection from ConnectionPool !");
089           }
090           return get();
091         }
092       }
093    // Get
094 
095 /**
096    Puts an object in the pool, those stating that it's "free" or available
097    for use by another processes and routines. An object can be put in the pool,
098    without need to be get from there before.
099    @return  <B>true</B> on success<BR>
100             <B>false</B> when the object was not put in the pool,
101             because the maximal number of references in the pool was riched
102  */
103    public synchronized boolean put(Connection conn){
104       connections.addElement(conn);
105       notify();
106       return true;
107    // Put
108 
109    public void finalize() {
110      for (int i = 0; i<connections.size(); i++){
111         try {
112           DBHelper.disconnect((Connectionconnections.elementAt(i));
113         }
114         catch (Exception e){
115             e.printStackTrace();
116         }
117      }
118    }
119 }