KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > connection > AbstractPoolConnectionManager


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Mathieu Peltier.
23  */

24
25 package org.objectweb.cjdbc.controller.connection;
26
27 import java.sql.Connection JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.LinkedList JavaDoc;
31
32 import org.objectweb.cjdbc.common.i18n.Translate;
33
34 /**
35  * This connection manager uses a pool of persistent connections with the
36  * database. The allocation/release policy is implemented by the subclasses
37  * (abstract
38  * {@link org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#getConnection()}/
39  * {@link org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#releaseConnection(Connection)}
40  * from
41  * {@link org.objectweb.cjdbc.controller.connection.AbstractConnectionManager}).
42  *
43  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
44  * @author <a HREF="mailto:Mathieu.Peltier@inrialpes.fr">Mathieu Peltier </a>
45  * @version 1.0
46  */

47 public abstract class AbstractPoolConnectionManager
48     extends AbstractConnectionManager
49 {
50   //
51
// How the code is organized ?
52
//
53
// 1. Member variables
54
// 2. Constructor(s)
55
// 3. Connection handling
56
// 4. Getter/Setter (possibly in alphabetical order)
57
//
58

59   /** Stack of available connections (pool). */
60   protected transient LinkedList JavaDoc freeConnections;
61
62   /**
63    * Pool of currently used connections (<code>Vector</code> type because
64    * synchronisation is needed).
65    */

66   protected transient ArrayList JavaDoc activeConnections;
67
68   /** Size of the connection pool with the real database. */
69   protected int poolSize;
70
71   /*
72    * Constructor(s)
73    */

74
75   /**
76    * Creates a new <code>AbstractPoolConnectionManager</code> instance.
77    *
78    * @param backendUrl URL of the <code>DatabaseBackend</code> owning this
79    * connection manager.
80    * @param backendName name of the <code>DatabaseBackend</code> owning this
81    * connection manager.
82    * @param login backend connection login to be used by this connection
83    * manager.
84    * @param password backend connection password to be used by this connection
85    * manager.
86    * @param driverPath path for driver
87    * @param driverClassName class name for driver
88    * @param poolSize size of the connection pool.
89    */

90   public AbstractPoolConnectionManager(String JavaDoc backendUrl, String JavaDoc backendName,
91       String JavaDoc login, String JavaDoc password, String JavaDoc driverPath, String JavaDoc driverClassName,
92       int poolSize)
93   {
94     super(backendUrl, backendName, login, password, driverPath, driverClassName);
95
96     if (poolSize < 1)
97       throw new IllegalArgumentException JavaDoc(
98           "Illegal value for size of the pool connection manager: " + poolSize);
99
100     this.poolSize = poolSize;
101     this.freeConnections = new LinkedList JavaDoc();
102     this.activeConnections = new ArrayList JavaDoc(poolSize);
103     this.initialized = false;
104
105     if (logger.isDebugEnabled())
106       logger.debug(Translate.get("connection.backend.pool.created",
107           new String JavaDoc[]{backendName, String.valueOf(poolSize)}));
108   }
109
110   /*
111    * Connection handling
112    */

113
114   /**
115    * @see org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#initializeConnections()
116    */

117   public synchronized void initializeConnections() throws SQLException JavaDoc
118   {
119     initializeConnections(poolSize);
120   }
121
122   /**
123    * Initialize initPoolSize connections in the pool.
124    *
125    * @param initPoolSize number of connections to initialize
126    * @throws SQLException if an error occurs
127    */

128   public synchronized void initializeConnections(int initPoolSize)
129       throws SQLException JavaDoc
130   {
131     if (initialized)
132       throw new SQLException JavaDoc("Connection pool for backend '" + backendUrl
133           + "' already initialized");
134
135     if (initPoolSize > poolSize)
136     {
137       logger.warn(Translate.get("connection.max.poolsize.reached",
138           new String JavaDoc[]{String.valueOf(initPoolSize), String.valueOf(poolSize),
139               String.valueOf(poolSize)}));
140       initPoolSize = poolSize;
141     }
142
143     Connection JavaDoc c = null;
144
145     boolean connectionsAvailable = true;
146     int i = 0;
147     while ((i < initPoolSize) && connectionsAvailable)
148     {
149       c = getConnectionFromDriver();
150
151       if (c == null)
152         connectionsAvailable = false;
153
154       if (!connectionsAvailable)
155       {
156         if (i > 0)
157         {
158           logger.warn(Translate.get("connection.limit.poolsize", i));
159         }
160         else
161         {
162           logger.warn(Translate.get("connection.initialize.pool.failed"));
163           poolSize = 0;
164         }
165       }
166       else
167       {
168         freeConnections.addLast(c);
169         i++;
170       }
171     }
172
173     poolSize = i;
174     initialized = true;
175
176     if (poolSize == 0) // Should never happen
177
logger.error(Translate.get("connection.empty.pool"));
178     if (logger.isDebugEnabled())
179       logger.debug(Translate.get("connection.pool.initialized", new String JavaDoc[]{
180           String.valueOf(initPoolSize), backendUrl}));
181
182   }
183
184   /**
185    * @see org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#finalizeConnections()
186    */

187   public synchronized void finalizeConnections() throws SQLException JavaDoc
188   {
189     if (!initialized)
190     {
191       String JavaDoc msg = Translate.get("connection.pool.not.initialized");
192       logger.error(msg);
193       throw new SQLException JavaDoc(msg);
194     }
195
196     Connection JavaDoc c;
197     boolean error = false;
198
199     // Close free connections
200
initialized = false;
201     int freed = 0;
202     while (!freeConnections.isEmpty())
203     {
204       c = (Connection JavaDoc) freeConnections.removeLast();
205       try
206       {
207         c.close();
208       }
209       catch (SQLException JavaDoc e)
210       {
211         error = true;
212       }
213       freed++;
214     }
215     if (logger.isInfoEnabled())
216       logger.info(Translate.get("connection.freed.connection", new String JavaDoc[]{
217           String.valueOf(freed), backendUrl}));
218
219     // Close active connections
220
int size = activeConnections.size();
221     if (size > 0)
222     {
223       logger.warn(Translate.get("connection.connections.still.active", size));
224       for (int i = 0; i < size; i++)
225       {
226         c = (Connection JavaDoc) activeConnections.get(i);
227         try
228         {
229           c.close();
230         }
231         catch (SQLException JavaDoc e)
232         {
233           error = true;
234         }
235       }
236     }
237
238     // Clear connections to ensure that the eventually not closed connections
239
// will be closed when the objects will be garbage collected
240
freeConnections.clear();
241     activeConnections.clear();
242
243     if (error)
244     {
245       String JavaDoc msg = Translate.get("connection.free.connections.failed");
246       logger.error(msg);
247       throw new SQLException JavaDoc(msg);
248     }
249   }
250
251   /**
252    * @see org.objectweb.cjdbc.controller.connection.AbstractConnectionManager#getCurrentNumberOfConnections()
253    */

254   public int getCurrentNumberOfConnections()
255   {
256     return poolSize;
257   }
258
259 }
Popular Tags