KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > jdbc > pool > StandardPoolDataSource


1 /*
2  * XAPool: Open Source XA JDBC Pool
3  * Copyright (C) 2003 Objectweb.org
4  * Initial Developer: Lutris Technologies Inc.
5  * Contact: xapool-public@lists.debian-sf.objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA
21  */

22 package org.enhydra.jdbc.pool;
23
24 import java.io.PrintWriter JavaDoc;
25 import java.sql.Connection JavaDoc;
26 import java.sql.SQLException JavaDoc;
27 import java.sql.Statement JavaDoc;
28 import java.util.Hashtable JavaDoc;
29
30 import javax.naming.Context JavaDoc;
31 import javax.naming.InitialContext JavaDoc;
32 import javax.naming.Name JavaDoc;
33 import javax.naming.NamingException JavaDoc;
34 import javax.naming.Reference JavaDoc;
35 import javax.naming.StringRefAddr JavaDoc;
36 import javax.sql.ConnectionEvent JavaDoc;
37 import javax.sql.ConnectionEventListener JavaDoc;
38 import javax.sql.ConnectionPoolDataSource JavaDoc;
39 import javax.sql.DataSource JavaDoc;
40 import javax.sql.PooledConnection JavaDoc;
41 import org.enhydra.jdbc.core.CoreDataSource;
42 import org.enhydra.jdbc.core.JdbcThreadFactory;
43 import org.enhydra.jdbc.util.Logger;
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46
47 /**
48  * StandardPoolDataSource class allows to make some operations on
49  * PooledConnection. It implements PoolHelper for the 3 methods :<p>
50  * create : create a PooledConnection<p>
51  * create(user,password) : create a PooledConnection with an other user/password<p>
52  * testThisObject : check if the object is still valid<p>
53  * checkThisObject : check if the object is closed<p>
54  * expire : kill the object<p>
55  */

56 public class StandardPoolDataSource
57     extends CoreDataSource
58     implements DataSource JavaDoc, PoolHelper, ConnectionEventListener JavaDoc {
59
60     public ConnectionPoolDataSource JavaDoc cpds; // object to build PooledConnection
61
public GenericPool pool; // pool to store StandardDataSource object
62
public String JavaDoc dataSourceName; // jndi name for DataSource Factory
63
public String JavaDoc jdbcTestStmt;
64     // JDBC test statement for checkLevelObject=1 or 2
65
public boolean onOff; // If the pool is started or not
66
public Context JavaDoc ictx; // the initial context
67
public Log glog = LogFactory.getLog("org.enhydra.jdbc.xapool");
68
69     /**
70      * Constructor
71      */

72     public StandardPoolDataSource() {
73         log = new Logger(glog);
74         super.setLogWriter(log);
75
76         pool = new GenericPool(this);
77         // create the pool with StandardPoolDataSource object
78
pool.setLogger(log);
79         onOff = false;
80         dataSourceName = null;
81     }
82
83     /**
84      * Constructor
85      */

86     public StandardPoolDataSource(int initSize) { // with an init Max size
87
log = new Logger(glog);
88         super.setLogWriter(log);
89
90         pool = new GenericPool(this, initSize);
91         // create the pool with StandardPoolDataSource object
92
pool.setLogger(log);
93         onOff = false;
94         dataSourceName = null;
95     }
96
97     /**
98      * Constructor
99      */

100     public StandardPoolDataSource(ConnectionPoolDataSource JavaDoc cc) {
101         cpds = cc;
102         log = new Logger(glog);
103
104         super.setLogWriter(log);
105         pool = new GenericPool(this);
106         // create the pool with StandardPoolDataSource object
107
pool.setLogger(log);
108         try {
109             cpds.setLogWriter(log);
110         } catch (SQLException JavaDoc sqle) {
111
112         }
113
114         onOff = false;
115         dataSourceName = null;
116     }
117
118     /**
119      * Constructor
120      */

121     public StandardPoolDataSource(
122         ConnectionPoolDataSource JavaDoc cc,
123         int initSize) { // with an init Max size
124
cpds = cc;
125         log = new Logger(glog);
126         super.setLogWriter(log);
127
128         pool = new GenericPool(this, initSize);
129         // create the pool with StandardPoolDataSource object
130
pool.setLogger(log);
131
132         onOff = false;
133         dataSourceName = null;
134     }
135
136     /**
137      * Set up the data source name, get the initial context,
138      * and lookup in JNDI to obtain a reference of the DataSourceName
139      * this method must be called before a getConnection (in this case
140      * an exception is returned
141      */

142     public void setDataSourceName(String JavaDoc dataSourceName) {
143         log.debug("StandardPoolDataSource:setDataSourceName");
144         this.dataSourceName = dataSourceName; // set up the data source name
145
/*
146                 synchronized(this) {
147                     if (onOff) {
148                         pool.stop();
149                         onOff = false;
150                     }
151                 }
152                 */

153     }
154
155     public String JavaDoc getDataSourceName() {
156         return dataSourceName; // return the dataSourceName (jndi mechanism)
157
}
158
159     /**
160      * getConnection allows to get an object from the pool and returns it
161      * to the user. In this case, we return an PooledConnection
162      */

163     public Connection JavaDoc getConnection() throws SQLException JavaDoc {
164         return getConnection(getUser(), getPassword());
165     }
166
167     /**
168      * getConnection allows to get an object from the pool and returns it
169      * to the user. In this case, we return an PooledConnection
170      */

171     public Connection JavaDoc getConnection(String JavaDoc _user, String JavaDoc _password)
172         throws SQLException JavaDoc {
173         log.debug("StandardPoolDataSource:getConnection");
174         Connection JavaDoc ret = null;
175         PooledConnection JavaDoc con = null;
176
177         synchronized (this) {
178             if (!onOff) {
179                 log.debug(
180                     "StandardPoolDataSource:getConnection must configure the pool...");
181                 pool.start(); // the pool starts now
182
onOff = true; // and is initialized
183
log.debug(
184                     "StandardPoolDataSource:getConnection pool config : \n"
185                         + pool.toString());
186             }
187         }
188
189         try {
190             try {
191                 log.debug(
192                     "StandardPoolDataSource:getConnection Try to give a "
193                         + "connection (checkOut)");
194                 con = (PooledConnection JavaDoc) pool.checkOut(_user, _password);
195                 // get a connection from the pool
196
log.debug(
197                     "StandardPoolDataSource:getConnection checkOut return"
198                         + "a new connection");
199             } catch (Exception JavaDoc e) {
200                                 e.printStackTrace();
201                 log.debug(
202                     "StandardPoolDataSource:getConnection SQLException in StandardPoolDataSource:getConnection"
203                         + e);
204                 throw new SQLException JavaDoc(
205                     "SQLException in StandardPoolDataSource:getConnection no connection available "
206                         + e);
207             }
208
209             ret = con.getConnection();
210         } catch (Exception JavaDoc e) {
211             log.debug("StandardPoolDataSource:getConnection exception" + e);
212                         e.printStackTrace();
213             SQLException JavaDoc sqle =
214                 new SQLException JavaDoc(
215                     "SQLException in StandardPoolDataSource:getConnection exception: "
216                         + e);
217             if (e instanceof SQLException JavaDoc)
218                 sqle.setNextException((SQLException JavaDoc) e);
219             if (con != null) {
220                 pool.checkIn(con);
221             }
222             throw sqle;
223         }
224         log.debug("StandardPoolDataSource:getConnection return a connection");
225         return ret;
226     }
227
228     /**
229      * connectionErrorOccurred and connectionClosed are methods
230      * from ConnectionEventListener interface
231      *
232      * Invoked when a fatal connection error occurs,
233      * just before an SQLException is thrown to the application
234      */

235     public void connectionErrorOccurred(ConnectionEvent JavaDoc event) {
236         Object JavaDoc obj = event.getSource();
237         PooledConnection JavaDoc pc = (PooledConnection JavaDoc) obj;
238         pool.nextGeneration(pc);
239         pool.removeLockedObject(pc); // remove the object from the locked pool
240
expire(pc); // kill the connection (from super)
241
log.debug(
242             "StandardXAPoolDataSource:connectionErrorOccurred remove the object from the pool");
243     }
244
245     /**
246      * Invoked when the application calls close()
247      * on its representation of the connection
248      */

249     public void connectionClosed(ConnectionEvent JavaDoc event) {
250         log.debug(
251             "StandardPoolDataSource:connectionClosed close the connection");
252         Object JavaDoc obj = event.getSource();
253         pool.checkIn(obj);
254     }
255
256     /**
257      * object specific work to kill the object
258      */

259     public void expire(Object JavaDoc o) {
260         log.debug(
261             "StandardPoolDataSource:expire expire a connection, remove from the pool");
262         if (o == null)
263             return;
264         try {
265             PooledConnection JavaDoc pooledCon = (PooledConnection JavaDoc) o;
266             pooledCon.close(); // call close() of PooledConnection
267
pooledCon.removeConnectionEventListener(this);
268             log.debug("StandardPoolDataSource:expire close the connection");
269         } catch (java.sql.SQLException JavaDoc e) {
270             log.error(
271                 "StandardPoolDataSource:expire Error java.sql.SQLException in StandardPoolDataSource:expire");
272         }
273     }
274
275     /**
276      * This method tests if a connection is closed or not
277      */

278     public boolean checkThisObject(Object JavaDoc o) {
279
280         PooledConnection JavaDoc con;
281         Connection JavaDoc ret;
282         log.debug(
283             "StandardPoolDataSource:checkThisObject verify the current object");
284         try {
285             con = (PooledConnection JavaDoc) o;
286             ret = con.getConnection(); // get the connection from the pool
287
if (ret.isClosed()) {
288                 return false;
289             }
290             try {
291                 ret.close();
292             } catch (Exception JavaDoc e) {
293                 log.error(
294                     "StandardPoolDataSource:checkThisObject can't closed the connection: "
295                         + e);
296             }
297
298             return true;
299         } catch (java.sql.SQLException JavaDoc e) {
300             log.error(
301                 "StandardPoolDataSource:checkThisObject Error java.sql.SQLException in StandardPoolDataSource:checkThisObject");
302             return false;
303         }
304     }
305
306     /**
307      * This method tests if a connection is valid or not
308      */

309     public boolean testThisObject(Object JavaDoc o) {
310         Connection JavaDoc ret = null;
311         log.debug(
312             "StandardPoolDataSource:testThisObject verify the current object");
313         try {
314             PooledConnection JavaDoc con = (PooledConnection JavaDoc) o;
315             ret = con.getConnection();
316             Statement JavaDoc s = ret.createStatement();
317             s.execute(jdbcTestStmt);
318             s.close();
319             try {
320                 ret.close();
321             } catch (Exception JavaDoc e) {
322                 log.error(
323                     "StandardPoolDataSource:checkThisObject can't closed the connection: "
324                         + e);
325             }
326             return true;
327         } catch (java.sql.SQLException JavaDoc e) {
328             log.error(
329                 "StandardPoolDataSource:checkThisObject Error java.sql.SQLException in StandardPoolDataSource:testThisObject");
330             return false;
331         }
332     }
333
334     public GenerationObject create() throws SQLException JavaDoc {
335         return create(getUser(), getPassword());
336     }
337
338     public GenerationObject create(String JavaDoc _user, String JavaDoc _password)
339         throws SQLException JavaDoc {
340         log.debug(
341             "StandardPoolDataSource:create create a connection for the pool");
342         GenerationObject genObject;
343         PooledConnection JavaDoc pooledCon = cpds.getPooledConnection(_user, _password);
344         // get the pooled connection
345

346         pooledCon.addConnectionEventListener(this);
347         // add it to the event listener
348
log.debug("StandardPoolDataSource:create create a object for the pool");
349         genObject =
350             new GenerationObject(
351                 pooledCon,
352                 pool.getGeneration(),
353                 _user,
354                 _password);
355         return genObject; // return a connection
356
}
357
358     /**
359      * stop method to switch off the pool
360      */

361     public void stopPool() {
362         pool.stop();
363         onOff = false;
364         log.debug("StandardPoolDataSource:stopPool stop now the pool");
365     }
366
367     public void shutdown(boolean force) {
368         stopPool();
369     }
370
371     /**
372      * set the logwriter for the current object, the logwriter will be use by
373      * the current object and by the generic pool
374      * @param logWriter a PrintWriter object
375      */

376     public void setLogWriter(PrintWriter JavaDoc logWriter) {
377         pool.setLogger(log);
378         super.setLogger(log);
379     }
380
381     /**
382      * set the debug flag
383      * @param debug a boolean flag
384      */

385     public void setDebug(boolean debug) {
386         super.setDebug(debug);
387         pool.setDebug(debug);
388     }
389
390     /**
391      * set the minimum size of the pool
392      * @param minSize minimum size of the pool
393      * @throws Exception
394      */

395     public void setMinSize(int minSize) throws Exception JavaDoc {
396         pool.setMinSize(minSize);
397     }
398
399     /**
400      * set the maximum size of the pool
401      * @param maxSize maximum size of the pool
402      * @throws Exception
403      */

404     public void setMaxSize(int maxSize) throws Exception JavaDoc {
405         pool.setMaxSize(maxSize);
406     }
407
408     /**
409      * set the life time of the pooled objects
410      * @param lifeTime life time of the pooled objects (in milliseconds)
411      */

412     public void setLifeTime(long lifeTime) {
413         pool.setLifeTime(lifeTime);
414     }
415
416     /**
417      * set the sleep time of pooled objects
418      * @param sleepTime sleep time of the pooled objects (in milliseconds)
419      */

420     public void setSleepTime(long sleepTime) {
421         pool.setSleepTime(sleepTime);
422     }
423
424     /**
425      * set the garbage collection option
426      * @param gc true: the garbage collector will be launched when clean up of the
427      * pool, else false
428      */

429     public void setGC(boolean gc) {
430         pool.setGC(gc);
431     }
432
433     /**
434      * set the check level of the pooled object before using them
435      * @param checkLevelObject (<br>
436      * 0 = no special checking
437      * 1 = just a check on an object
438      * 2 = test the object
439      * 3 = just a check on an object (for all the objects)
440      * 4 = test the object (for all the objects)
441      */

442     public void setCheckLevelObject(int checkLevelObject) {
443         pool.setCheckLevelObject(checkLevelObject);
444     }
445
446     /**
447      * set the String to test the jdbc connection before using it
448      * @param jdbcTestStmt an sql statement
449      */

450     public void setJdbcTestStmt(String JavaDoc jdbcTestStmt) {
451         this.jdbcTestStmt = jdbcTestStmt;
452     }
453
454     /**
455      * set the generation number for future connection, the generation number
456      * is used to identify a group a created objects
457      * @param generation an integer value which represents a generation
458      */

459     public void setGeneration(int generation) {
460         pool.setGeneration(generation);
461     }
462
463     /**
464      * set the global time the pool can wait for a free object
465      * @param deadLock in milliseconds
466      */

467     public void setDeadLockMaxWait(long deadLock) {
468         pool.setDeadLockMaxWait(deadLock);
469     }
470
471     /**
472      * set the time before 2 tries when trying to obtain an object from the pool
473      * @param loopWait in milliseconds
474      */

475     public void setDeadLockRetryWait(long loopWait) {
476         pool.setDeadLockRetryWait(loopWait);
477     }
478
479     public PrintWriter JavaDoc getLogWriter() {
480         return log;
481     }
482
483     public int getMinSize() {
484         return pool.getMinSize();
485     }
486
487     public int getMaxSize() {
488         return pool.getMaxSize();
489     }
490
491     public long getLifeTime() {
492         return pool.getLifeTime();
493     }
494
495     public long getSleepTime() {
496         return pool.getSleepTime();
497     }
498
499     public int getGeneration() {
500         return pool.generation;
501     }
502
503     public boolean isGC() {
504         return pool.isGC();
505     }
506
507     public int getLockedObjectCount() {
508         return pool.getLockedObjectCount();
509     }
510
511     public int getUnlockedObjectCount() {
512         return pool.getUnlockedObjectCount();
513     }
514
515     public int getCheckLevelObject() {
516         return pool.getCheckLevelObject();
517     }
518
519     public String JavaDoc getJdbcTestStmt() {
520         return jdbcTestStmt;
521     }
522
523     public long getDeadLockMaxWait() {
524         return pool.getDeadLockMaxWait();
525     }
526
527     public long getDeadLockRetryWait() {
528         return pool.getDeadLockRetryWait();
529     }
530
531     public String JavaDoc toString() {
532         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
533         sb.append("StandardPoolDataSource:\n");
534         sb.append(" data source name=<"+this.dataSourceName+">\n");
535         sb.append(" jdbc test stmt=<"+this.jdbcTestStmt+">\n");
536         sb.append(" user=<"+this.user+">\n");
537         if (this.cpds != null)
538             sb.append(this.cpds.toString());
539         sb.append(pool.toString());
540                 
541         return sb.toString();
542     }
543
544     /**
545      * Retrieves the Reference of this object. Used at binding time by JNDI
546      * to build a reference on this object.
547      *
548      * @return The non-null Reference of this object.
549      * @exception NamingException If a naming exception was encountered while
550      * retrieving the reference.
551      */

552     public Reference JavaDoc getReference() throws NamingException JavaDoc {
553         log.debug(
554             "StandardPoolDataSource:getReference return a reference of the object");
555         Reference JavaDoc ref = super.getReference();
556         ref.add(
557             new StringRefAddr JavaDoc(
558                 "checkLevelObject",
559                 Integer.toString(getCheckLevelObject())));
560         ref.add(new StringRefAddr JavaDoc("lifeTime", Long.toString(getLifeTime())));
561         ref.add(new StringRefAddr JavaDoc("jdbcTestStmt", getJdbcTestStmt()));
562         ref.add(new StringRefAddr JavaDoc("maxSize", Integer.toString(getMaxSize())));
563         ref.add(new StringRefAddr JavaDoc("minSize", Integer.toString(getMinSize())));
564         ref.add(new StringRefAddr JavaDoc("dataSourceName", getDataSourceName()));
565         return ref;
566     }
567
568     /* (non-Javadoc)
569      * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object, javax.naming.Name, javax.naming.Context, java.util.Hashtable)
570      */

571     public Object JavaDoc getObjectInstance(
572         Object JavaDoc refObj,
573         Name JavaDoc name,
574         Context JavaDoc nameCtx,
575         Hashtable JavaDoc env)
576         throws Exception JavaDoc {
577
578         super.getObjectInstance(refObj, name, nameCtx, env);
579         Reference JavaDoc ref = (Reference JavaDoc) refObj;
580         this.setLifeTime(
581             Long.parseLong((String JavaDoc) ref.get("lifeTime").getContent()));
582         this.setJdbcTestStmt((String JavaDoc) ref.get("jdbcTestStmt").getContent());
583         this.setMaxSize(
584             Integer.parseInt((String JavaDoc) ref.get("maxSize").getContent()));
585         this.setMinSize(
586             Integer.parseInt((String JavaDoc) ref.get("minSize").getContent()));
587         this.setDataSourceName((String JavaDoc) ref.get("dataSourceName").getContent());
588         InitialContext JavaDoc ictx = new InitialContext JavaDoc(env);
589         cpds = (ConnectionPoolDataSource JavaDoc) ictx.lookup(this.dataSourceName);
590         return this;
591     }
592
593     /**
594      * Override this so that the pool's tf gets set as well
595      */

596     public void setThreadFactory(JdbcThreadFactory tf) {
597         super.setThreadFactory(tf);
598         pool.setThreadFactory(tf);
599     }
600 }
Popular Tags