KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > minerva > pool > jdbc > ConnectionInPool


1 /*
2  * Licensed under the X license (see http://www.x.org/terms.htm)
3  */

4 package org.ofbiz.minerva.pool.jdbc;
5
6 import java.sql.CallableStatement JavaDoc;
7 import java.sql.Connection JavaDoc;
8 import java.sql.DatabaseMetaData JavaDoc;
9 import java.sql.PreparedStatement JavaDoc;
10 import java.sql.ResultSet JavaDoc;
11 import java.sql.SQLException JavaDoc;
12 import java.sql.SQLWarning JavaDoc;
13 import java.sql.Savepoint JavaDoc;
14 import java.sql.Statement JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Vector JavaDoc;
21
22 import org.ofbiz.minerva.pool.PoolEvent;
23 import org.ofbiz.minerva.pool.PoolEventListener;
24 import org.ofbiz.minerva.pool.PooledObject;
25 import org.ofbiz.minerva.pool.cache.LeastRecentlyUsedCache;
26 import org.ofbiz.minerva.pool.cache.ObjectCache;
27
28 /**
29  * Wrapper for database connections in a pool. Handles closing appropriately.
30  * The connection is returned to the pool rather than truly closing, any
31  * outstanding statements are closed, and the connection is rolled back. This
32  * class is also used by statements, etc. to update the last used time for the
33  * connection.
34  *
35  * @author Aaron Mulder (ammulder@alumni.princeton.edu)
36  */

37 public class ConnectionInPool implements PooledObject, ConnectionWrapper {
38
39     private final static String JavaDoc CLOSED = "Connection has been closed!";
40     public final static int PS_CACHE_UNLIMITED = 0;
41     public final static int PS_CACHE_DISABLED = -1;
42     public final static HashMap JavaDoc psCaches = new HashMap JavaDoc();
43
44     private Connection JavaDoc con;
45     private HashSet JavaDoc statements;
46     private Vector JavaDoc listeners;
47     private int preparedStatementCacheSize = 0;
48     private ObjectCache preparedStatementCache;
49
50     /**
51      * Creates a new connection wrapper.
52      * @param con The "real" database connection to wrap.
53      */

54     public ConnectionInPool(Connection JavaDoc con) {
55         this.con = con;
56         preparedStatementCache = (ObjectCache) psCaches.get(con);
57         if (preparedStatementCache == null) {
58             PreparedStatementFactory factory = new PreparedStatementFactory(con);
59             preparedStatementCache = new LeastRecentlyUsedCache(factory, preparedStatementCacheSize);
60             psCaches.put(con, preparedStatementCache);
61         }
62         statements = new HashSet JavaDoc();
63         listeners = new Vector JavaDoc();
64     }
65
66     /**
67      * Creates a new connection wrapper, using the specified maximum size for
68      * the prepared statement cache.
69      * @param con The "real" database connection to wrap.
70      * @param psCacheSize The size of the PreparedStatement cache.
71      * @see #PS_CACHE_UNLIMITED
72      * @see #PS_CACHE_DISABLED
73      */

74     public ConnectionInPool(Connection JavaDoc con, int psCacheSize) {
75         this.con = con;
76         if (psCacheSize >= 0) {
77             preparedStatementCache = (ObjectCache) psCaches.get(con);
78             if (preparedStatementCache == null) {
79                 PreparedStatementFactory factory = new PreparedStatementFactory(con);
80                 preparedStatementCache = new LeastRecentlyUsedCache(factory, preparedStatementCacheSize);
81                 psCaches.put(con, preparedStatementCache);
82             }
83         }
84         setPSCacheSize(psCacheSize);
85         statements = new HashSet JavaDoc();
86         listeners = new Vector JavaDoc();
87     }
88
89     /**
90      * Sets the number of PreparedStatements to be cached for each
91      * Connection. Your DB product may impose a limit on the number
92      * of open PreparedStatements.
93      * @see #PS_CACHE_UNLIMITED
94      * @see #PS_CACHE_DISABLED
95      */

96     public void setPSCacheSize(int maxSize) {
97         preparedStatementCacheSize = maxSize;
98         if (maxSize >= 0 && preparedStatementCache != null)
99             preparedStatementCache.setSize(maxSize);
100     }
101
102     /**
103      * Gets the number of PreparedStatements to be cached for each
104      * Connection.
105      */

106     public int getPSCacheSize() {
107         return preparedStatementCacheSize;
108     }
109
110     /**
111      * Adds a listener for pool events.
112      */

113     public void addPoolEventListener(PoolEventListener listener) {
114         listeners.addElement(listener);
115     }
116
117     /**
118      * Removes a listener for pool events.
119      */

120     public void removePoolEventListener(PoolEventListener listener) {
121         listeners.remove(listener);
122     }
123
124     /**
125      * Gets a reference to the "real" connection. This should only be used if
126      * you need to cast that to a specific type to call a proprietary method -
127      * you will defeat all the pooling if you use the underlying connection
128      * directly.
129      */

130     public Connection JavaDoc getUnderlyingConnection() {
131         return con;
132     }
133
134     /**
135      * Closes this connection wrapper permanently. All further calls with throw
136      * a SQLException.
137      */

138     public void shutdown() {
139         con = null;
140         statements = null;
141         listeners = null;
142     }
143
144     /**
145      * Updates the last used time for this connection to the current time.
146      */

147     public void setLastUsed() {
148         firePoolEvent(new PoolEvent(this, PoolEvent.OBJECT_USED));
149     }
150
151     /**
152      * Indicates that an error occured on this connection.
153      */

154     public void setError(SQLException JavaDoc e) {
155         firePoolEvent(new PoolEvent(this, PoolEvent.OBJECT_ERROR));
156     }
157
158     /**
159      * Indicates that an error occured on this connection.
160      */

161     public void setCatastrophicError(SQLException JavaDoc e) {
162         PoolEvent pe = new PoolEvent(this, PoolEvent.OBJECT_ERROR);
163         pe.setCatastrophic();
164         firePoolEvent(pe);
165     }
166
167     /**
168      * Indicates that a statement has been closed and no longer needs to be
169      * tracked. Outstanding statements are closed when the connection is
170      * returned to the pool.
171      */

172     public void statementClosed(Statement JavaDoc st) {
173         statements.remove(st);
174         if ((con != null) && (st instanceof PreparedStatementInPool)) {
175             // Now return the "real" statement to the pool
176
PreparedStatementInPool ps = (PreparedStatementInPool) st;
177             PreparedStatement JavaDoc ups = ps.getUnderlyingPreparedStatement();
178             if (preparedStatementCacheSize >= 0) {
179                 preparedStatementCache.returnObject(ps.getSql(), ups);
180             } else {
181                 try {
182                     ups.close();
183                 } catch (SQLException JavaDoc e) {
184                 }
185             }
186 /*
187             int rsType = ResultSet.TYPE_FORWARD_ONLY;
188             int rsConcur = ResultSet.CONCUR_READ_ONLY;
189
190             // We may have JDBC 1.0 driver
191             try {
192                 rsType = ups.getResultSetType();
193                 rsConcur = ups.getResultSetConcurrency();
194             } catch (Throwable th) {
195             }
196             PreparedStatementInPool.preparedStatementCache.put(
197                     new PSCacheKey(con, ps.getSql(), rsType, rsConcur), ups);
198 */

199         }
200     }
201
202     /**
203      * Prepares a connection to be returned to the pool. All outstanding
204      * statements are closed, and if AutoCommit is off, the connection is
205      * rolled back. No further SQL calls are possible once this is called.
206      */

207     public void reset() throws SQLException JavaDoc {
208         Collection JavaDoc copy = (Collection JavaDoc) statements.clone();
209         Iterator JavaDoc it = copy.iterator();
210         while (it.hasNext())
211             try {
212                 ((Statement JavaDoc) it.next()).close();
213             } catch (SQLException JavaDoc e) {
214             }
215         if (!con.getAutoCommit())
216             con.rollback();
217         con = null;
218     }
219
220     /**
221      * Dispatches an event to the listeners.
222      */

223     protected void firePoolEvent(PoolEvent evt) {
224         Vector JavaDoc local = (Vector JavaDoc) listeners.clone();
225         for (int i = local.size() - 1; i >= 0; i--)
226             if (evt.getType() == PoolEvent.OBJECT_CLOSED)
227                 ((PoolEventListener) local.elementAt(i)).objectClosed(evt);
228             else if (evt.getType() == PoolEvent.OBJECT_ERROR)
229                 ((PoolEventListener) local.elementAt(i)).objectError(evt);
230             else
231                 ((PoolEventListener) local.elementAt(i)).objectUsed(evt);
232     }
233
234     // ---- Implementation of java.sql.Connection ----
235
public Statement JavaDoc createStatement() throws SQLException JavaDoc {
236         if (con == null) throw new SQLException JavaDoc(CLOSED);
237         try {
238             StatementInPool st = new StatementInPool(con.createStatement(), this);
239             statements.add(st);
240             return st;
241         } catch (SQLException JavaDoc e) {
242             setError(e);
243             throw e;
244         }
245     }
246
247     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql) throws SQLException JavaDoc {
248         return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
249     }
250
251     public CallableStatement JavaDoc prepareCall(String JavaDoc sql) throws SQLException JavaDoc {
252         if (con == null) throw new SQLException JavaDoc(CLOSED);
253         try {
254             return con.prepareCall(sql);
255         } catch (SQLException JavaDoc e) {
256             setError(e);
257             throw e;
258         }
259     }
260
261     public String JavaDoc nativeSQL(String JavaDoc sql) throws SQLException JavaDoc {
262         if (con == null) throw new SQLException JavaDoc(CLOSED);
263         try {
264             return con.nativeSQL(sql);
265         } catch (SQLException JavaDoc e) {
266             setError(e);
267             throw e;
268         }
269     }
270
271     public void setAutoCommit(boolean autoCommit) throws SQLException JavaDoc {
272         if (con == null) throw new SQLException JavaDoc(CLOSED);
273         try {
274             con.setAutoCommit(autoCommit);
275         } catch (SQLException JavaDoc e) {
276             setError(e);
277             throw e;
278         }
279     }
280
281     public boolean getAutoCommit() throws SQLException JavaDoc {
282         if (con == null) throw new SQLException JavaDoc(CLOSED);
283         try {
284             return con.getAutoCommit();
285         } catch (SQLException JavaDoc e) {
286             setError(e);
287             throw e;
288         }
289     }
290
291     public void commit() throws SQLException JavaDoc {
292         if (con == null) throw new SQLException JavaDoc(CLOSED);
293         try {
294             con.commit();
295         } catch (SQLException JavaDoc e) {
296             setCatastrophicError(e);
297             throw e;
298         }
299     }
300
301     public void rollback() throws SQLException JavaDoc {
302         if (con == null) throw new SQLException JavaDoc(CLOSED);
303         try {
304             con.rollback();
305         } catch (SQLException JavaDoc e) {
306             setCatastrophicError(e);
307             throw e;
308         }
309     }
310
311     public void close() throws SQLException JavaDoc {
312         if (con == null) throw new SQLException JavaDoc(CLOSED);
313         firePoolEvent(new PoolEvent(this, PoolEvent.OBJECT_CLOSED));
314         shutdown();
315     }
316
317     public boolean isClosed() throws SQLException JavaDoc {
318         if (con == null) return true;
319         try {
320             return con.isClosed();
321         } catch (SQLException JavaDoc e) {
322             setError(e);
323             throw e;
324         }
325     }
326
327     public DatabaseMetaData JavaDoc getMetaData() throws SQLException JavaDoc {
328         if (con == null) throw new SQLException JavaDoc(CLOSED);
329         try {
330             return con.getMetaData();
331         } catch (SQLException JavaDoc e) {
332             setError(e);
333             throw e;
334         }
335     }
336
337     public void setReadOnly(boolean readOnly) throws SQLException JavaDoc {
338         if (con == null) throw new SQLException JavaDoc(CLOSED);
339         try {
340             con.setReadOnly(readOnly);
341         } catch (SQLException JavaDoc e) {
342             setError(e);
343             throw e;
344         }
345     }
346
347     public boolean isReadOnly() throws SQLException JavaDoc {
348         if (con == null) throw new SQLException JavaDoc(CLOSED);
349         try {
350             return con.isReadOnly();
351         } catch (SQLException JavaDoc e) {
352             setError(e);
353             throw e;
354         }
355     }
356
357     public void setCatalog(String JavaDoc catalog) throws SQLException JavaDoc {
358         if (con == null) throw new SQLException JavaDoc(CLOSED);
359         try {
360             con.setCatalog(catalog);
361         } catch (SQLException JavaDoc e) {
362             setError(e);
363             throw e;
364         }
365     }
366
367     public String JavaDoc getCatalog() throws SQLException JavaDoc {
368         if (con == null) throw new SQLException JavaDoc(CLOSED);
369         try {
370             return con.getCatalog();
371         } catch (SQLException JavaDoc e) {
372             setError(e);
373             throw e;
374         }
375     }
376
377     public void setTransactionIsolation(int level) throws SQLException JavaDoc {
378         if (con == null) throw new SQLException JavaDoc(CLOSED);
379         try {
380             con.setTransactionIsolation(level);
381         } catch (SQLException JavaDoc e) {
382             setError(e);
383             throw e;
384         }
385     }
386
387     public int getTransactionIsolation() throws SQLException JavaDoc {
388         if (con == null) throw new SQLException JavaDoc(CLOSED);
389         try {
390             return con.getTransactionIsolation();
391         } catch (SQLException JavaDoc e) {
392             setError(e);
393             throw e;
394         }
395     }
396
397     public SQLWarning JavaDoc getWarnings() throws SQLException JavaDoc {
398         if (con == null) throw new SQLException JavaDoc(CLOSED);
399         try {
400             return con.getWarnings();
401         } catch (SQLException JavaDoc e) {
402             setError(e);
403             throw e;
404         }
405     }
406
407     public void clearWarnings() throws SQLException JavaDoc {
408         if (con == null) throw new SQLException JavaDoc(CLOSED);
409         try {
410             con.clearWarnings();
411         } catch (SQLException JavaDoc e) {
412             setError(e);
413             throw e;
414         }
415     }
416
417     public Statement JavaDoc createStatement(int resultSetType, int resultSetConcurrency) throws SQLException JavaDoc {
418         if (con == null) throw new SQLException JavaDoc(CLOSED);
419         try {
420             StatementInPool st = new StatementInPool(con.createStatement(resultSetType, resultSetConcurrency), this);
421             statements.add(st);
422             return st;
423         } catch (SQLException JavaDoc e) {
424             setError(e);
425             throw e;
426         }
427     }
428
429
430     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, int resultSetType, int resultSetConcurrency) throws SQLException JavaDoc {
431         if (con == null) throw new SQLException JavaDoc(CLOSED);
432         try {
433             PreparedStatementInPool wrapper = null;
434             if (preparedStatementCacheSize >= 0) {
435                 PreparedStatement JavaDoc ps = (PreparedStatement JavaDoc) preparedStatementCache.useObject(sql);
436                 if (ps == null)
437                     throw new SQLException JavaDoc("Unable to create PreparedStatement!");
438                 wrapper = new PreparedStatementInPool(ps, this, sql);
439             } else {
440                 wrapper = new PreparedStatementInPool(con.prepareStatement(sql, resultSetType, resultSetConcurrency), this, sql);
441             }
442             statements.add(wrapper);
443             return wrapper;
444         } catch (SQLException JavaDoc e) {
445             setError(e);
446             throw e;
447         }
448     }
449
450     /*
451       public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
452       return prepareStatement(sql);
453       }
454     */

455
456     public CallableStatement JavaDoc prepareCall(String JavaDoc sql, int resultSetType, int resultSetConcurrency) throws SQLException JavaDoc {
457         if (con == null) throw new SQLException JavaDoc(CLOSED);
458         try {
459             return con.prepareCall(sql, resultSetType, resultSetConcurrency);
460         } catch (SQLException JavaDoc e) {
461             setError(e);
462             throw e;
463         }
464     }
465
466     public Map JavaDoc getTypeMap() throws SQLException JavaDoc {
467         if (con == null) throw new SQLException JavaDoc(CLOSED);
468         try {
469             return con.getTypeMap();
470         } catch (SQLException JavaDoc e) {
471             setError(e);
472             throw e;
473         }
474     }
475
476     public void setTypeMap(Map JavaDoc map) throws SQLException JavaDoc {
477         if (con == null) throw new SQLException JavaDoc(CLOSED);
478         try {
479             con.setTypeMap(map);
480         } catch (SQLException JavaDoc e) {
481             setError(e);
482             throw e;
483         }
484     }
485
486
487     // ------- J2SE 1.4 methods comment; needed to compile -------
488

489     /* (non-Javadoc)
490      * @see java.sql.Connection#setHoldability(int)
491      */

492     public void setHoldability(int arg0) throws SQLException JavaDoc {
493         // TODO Auto-generated method stub
494

495     }
496
497     /* (non-Javadoc)
498      * @see java.sql.Connection#getHoldability()
499      */

500     public int getHoldability() throws SQLException JavaDoc {
501         // TODO Auto-generated method stub
502
return 0;
503     }
504
505     /* (non-Javadoc)
506      * @see java.sql.Connection#setSavepoint()
507      */

508     public Savepoint JavaDoc setSavepoint() throws SQLException JavaDoc {
509         // TODO Auto-generated method stub
510
return null;
511     }
512
513     /* (non-Javadoc)
514      * @see java.sql.Connection#setSavepoint(java.lang.String)
515      */

516     public Savepoint JavaDoc setSavepoint(String JavaDoc arg0) throws SQLException JavaDoc {
517         // TODO Auto-generated method stub
518
return null;
519     }
520
521     /* (non-Javadoc)
522      * @see java.sql.Connection#rollback(java.sql.Savepoint)
523      */

524     public void rollback(Savepoint JavaDoc arg0) throws SQLException JavaDoc {
525         // TODO Auto-generated method stub
526

527     }
528
529     /* (non-Javadoc)
530      * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
531      */

532     public void releaseSavepoint(Savepoint JavaDoc arg0) throws SQLException JavaDoc {
533         // TODO Auto-generated method stub
534

535     }
536
537     /* (non-Javadoc)
538      * @see java.sql.Connection#createStatement(int, int, int)
539      */

540     public Statement JavaDoc createStatement(int arg0, int arg1, int arg2) throws SQLException JavaDoc {
541         // TODO Auto-generated method stub
542
return null;
543     }
544
545     /* (non-Javadoc)
546      * @see java.sql.Connection#prepareStatement(java.lang.String, int, int, int)
547      */

548     public PreparedStatement JavaDoc prepareStatement(String JavaDoc arg0, int arg1, int arg2, int arg3) throws SQLException JavaDoc {
549         // TODO Auto-generated method stub
550
return null;
551     }
552
553     /* (non-Javadoc)
554      * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
555      */

556     public CallableStatement JavaDoc prepareCall(String JavaDoc arg0, int arg1, int arg2, int arg3) throws SQLException JavaDoc {
557         // TODO Auto-generated method stub
558
return null;
559     }
560
561     /* (non-Javadoc)
562      * @see java.sql.Connection#prepareStatement(java.lang.String, int)
563      */

564     public PreparedStatement JavaDoc prepareStatement(String JavaDoc arg0, int arg1) throws SQLException JavaDoc {
565         // TODO Auto-generated method stub
566
return null;
567     }
568
569     /* (non-Javadoc)
570      * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
571      */

572     public PreparedStatement JavaDoc prepareStatement(String JavaDoc arg0, int[] arg1) throws SQLException JavaDoc {
573         // TODO Auto-generated method stub
574
return null;
575     }
576
577     /* (non-Javadoc)
578      * @see java.sql.Connection#prepareStatement(java.lang.String, java.lang.String[])
579      */

580     public PreparedStatement JavaDoc prepareStatement(String JavaDoc arg0, String JavaDoc[] arg1) throws SQLException JavaDoc {
581         // TODO Auto-generated method stub
582
return null;
583     }
584 }
585
Popular Tags