1   /*
2    *  Copyright (c) 1998-2005, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Atanas Kiryakov, 01/02/2002
10   *
11   *  $Id: ConnectionPool.java,v 1.4 2005/01/11 13:51:36 ian Exp $
12   */
13  package gate.persist;
14  
15  
16  import java.sql.Connection;
17  import java.sql.SQLException;
18  import java.util.Vector;
19  
20  /**
21     A generic implementation of pool of references to objects of any kind.
22     It is thread-safe, so, allows multiple users to get and release objects
23     "simultaneously". In fact, the standard Java synchronization is used.
24     <BR><BR>
25     The base idea is that, a calling routine will try to get
26     an object from the pool with method Get. On success, it will use the
27     object and return it in the pool with the method Put.
28     <BR><BR>
29     If there ares no available objects in the pool, Get will return <B>null</B>.
30     Then the calling routine should create a new object. Further, scenario goes
31     in the same way - when finished using the object, calling routine shoud Put
32     it in the pool for future use, instead of leaving it to be garbage-collected.
33     <BR><BR>
34     The pool initially is empty. The only way to increase the number of objects
35     managed by the pool, is some external process to Put an object, that was
36     created, instead of previously Get from the pool.
37     <BR><BR>
38     Pool stores only references to currently "free" or available objects. When
39     some external routine Gets an object from the pool, its reference is not
40     locked, it is simply removed from the pool.
41   */
42  public class ConnectionPool {
43     private Vector   connections;
44     private int      size;
45     private String   url;
46     private int      connCount;
47  
48  /**
49     Constructs and object pool with specified size.
50     @param size determines the maximum size of the pool. This is the number
51           free objects that it can manage at the same time
52   */
53     public ConnectionPool(int size, String url) {
54        this.size = size;
55        connections = new Vector(this.size);
56        this.url = url;
57        this.connCount = 0;
58     } // ConnectionPool
59  
60  /**
61     Pulls out an object from the pool. The reference to the object is removed
62     from the pool and their is no longer any kind of relation between this
63     object and the pool. It can be returned back (released) by Put method.
64     @return  an object from the pool, if available.<BR>
65              Otherwise, returns <B>null</B>
66   */
67    public synchronized Connection get()
68        throws SQLException,ClassNotFoundException{
69        int currAvailable = connections.size();
70        if (currAvailable > 0){
71          Connection conn = (Connection) connections.elementAt(currAvailable-1);
72          connections.removeElementAt(currAvailable-1);
73          return conn;
74        }
75        else {
76          if (connCount < size) {
77            Connection newCon = DBHelper.connect(url);
78            connCount++;
79            return newCon;
80          }
81          else {
82            try {
83              wait();
84            }
85            catch (java.lang.InterruptedException ie) {
86              throw new SQLException(" Thread interrupted while waiting "
87                                      +"to get Connection from ConnectionPool !");
88            }
89            return get();
90          }
91        }
92     } // Get
93  
94  /**
95     Puts an object in the pool, those stating that it's "free" or available
96     for use by another processes and routines. An object can be put in the pool,
97     without need to be get from there before.
98     @return  <B>true</B> on success<BR>
99              <B>false</B> when the object was not put in the pool,
100             because the maximal number of references in the pool was riched
101  */
102    public synchronized boolean put(Connection conn){
103       connections.addElement(conn);
104       notify();
105       return true;
106    } // Put
107 
108    public void finalize() {
109      for (int i = 0; i<connections.size(); i++){
110         try {
111           DBHelper.disconnect((Connection) connections.elementAt(i));
112         }
113         catch (Exception e){
114             e.printStackTrace();
115         }
116      }
117    }
118 }