KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > sql > DBPoolImpl


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.sql;
31
32 import com.caucho.config.ConfigException;
33 import com.caucho.config.types.InitParam;
34 import com.caucho.config.types.Period;
35 import com.caucho.loader.Environment;
36 import com.caucho.loader.EnvironmentClassLoader;
37 import com.caucho.loader.EnvironmentListener;
38 import com.caucho.log.Log;
39 import com.caucho.util.Alarm;
40 import com.caucho.util.AlarmListener;
41 import com.caucho.util.L10N;
42
43 import javax.naming.InitialContext JavaDoc;
44 import javax.naming.NamingException JavaDoc;
45 import javax.resource.spi.ManagedConnectionFactory JavaDoc;
46 import javax.sql.ConnectionPoolDataSource JavaDoc;
47 import javax.sql.XADataSource JavaDoc;
48 import javax.transaction.TransactionManager JavaDoc;
49 import java.io.PrintWriter JavaDoc;
50 import java.sql.Driver JavaDoc;
51 import java.sql.SQLException JavaDoc;
52 import java.util.ArrayList JavaDoc;
53 import java.util.HashMap JavaDoc;
54 import java.util.Iterator JavaDoc;
55 import java.util.logging.Level JavaDoc;
56 import java.util.logging.Logger JavaDoc;
57
58 /**
59  * Manages a pool of database connections. In addition, DBPool configures
60  * the database connection from a configuration file.
61  *
62  * <p>Like JDBC 2.0 pooling, DBPool returns a wrapped Connection.
63  * Applications can use that connection just like an unpooled connection.
64  * It is more important than ever to <code>close()</code> the connection,
65  * because the close returns the connection to the connection pool.
66  *
67  * <h4>Example using DataSource JNDI style (recommended)</h4>
68  *
69  * <pre><code>
70  * Context env = (Context) new InitialContext().lookup("java:comp/env");
71  * DataSource pool = (DataSource) env.lookup("jdbc/test");
72  * Connection conn = pool.getConnection();
73  * try {
74  * ... // normal connection stuff
75  * } finally {
76  * conn.close();
77  * }
78  * </code></pre>
79  *
80  * <h4>Configuration</h4>
81  *
82  * <pre><code>
83  * &lt;database name='jdbc/test'>
84  * &lt;init>
85  * &lt;driver>postgresql.Driver&lt;/driver>
86  * &lt;url>jdbc:postgresql://localhost/test&lt;/url>
87  * &lt;user>ferg&lt;/user>
88  * &lt;password>foobar&lt;/password>
89  * &lt;/init>
90  * &lt;/database>
91  * </code></pre>
92  *
93  * <h4>Pool limits and timeouts</h4>
94  *
95  * The pool will only allow getMaxConnections() connections alive at a time.
96  * If <code>getMaxConnection</code> connections are already active,
97  * <code>getPooledConnection</code> will block waiting for an available
98  * connection. The wait is timed. If connection-wait-time passes
99  * and there is still no connection, <code>getPooledConnection</code>
100  * create a new connection anyway.
101  *
102  * <p>Connections will only stay in the pool for about 5 seconds. After
103  * that they will be removed and closed. This reduces the load on the DB
104  * and also protects against the database dropping old connections.
105  */

106 public class DBPoolImpl implements AlarmListener, EnvironmentListener {
107   protected static final Logger JavaDoc log = Log.open(DBPoolImpl.class);
108   private static final L10N L = new L10N(DBPoolImpl.class);
109
110   /**
111    * The beginning of the URL used to connect to a database with
112    * this pooled connection driver.
113    */

114   private static final String JavaDoc URL_PREFIX = "jdbc:caucho:" ;
115
116   /**
117    * The key used to look into the properties passed to the
118    * connect method to find the username.
119    */

120   public static final String JavaDoc PROPERTY_USER = "user" ;
121   /**
122    * The key used to look into the properties passed to the
123    * connect method to find the password.
124    */

125   public static final String JavaDoc PROPERTY_PASSWORD = "password" ;
126
127   // How long an unused connection can remain in the pool
128
private static final long MAX_IDLE_TIME = 30000;
129
130   private String JavaDoc _name;
131
132   private ArrayList JavaDoc<DriverConfig> _driverList
133     = new ArrayList JavaDoc<DriverConfig>();
134
135   private ArrayList JavaDoc<DriverConfig> _backupDriverList
136     = new ArrayList JavaDoc<DriverConfig>();
137
138   private ConnectionConfig _connectionConfig
139     = new ConnectionConfig();
140
141   // private ManagedFactoryImpl _mcf;
142
private ManagedConnectionFactory JavaDoc _mcf;
143
144   private String JavaDoc _user;
145   private String JavaDoc _password;
146
147   // total connections allowed in this pool
148
private int _maxConnections = 128;
149   // time before an idle connection is closed
150
private long _maxIdleTime = MAX_IDLE_TIME;
151   // max time a connection is allowed to be active (6 hr)
152
private long _maxActiveTime = 6L * 3600L * 1000L;
153   // max time a connection is allowed in the pool
154
private long _maxPoolTime = 24L * 3600L * 1000L;
155
156   // how long to wait for a connection, say 10 minutes
157
private long _connectionWaitTime = 600 * 1000;
158   private int _connectionWaitCount = (int) (_connectionWaitTime / 1000);
159
160   // connections to create even when the max-connections overflows.
161
private int _maxOverflowConnections = 0;
162
163   // true if the pool has started
164
private boolean _isStarted;
165   // true if the pool has closed
166
private boolean _isClosed;
167   // if true, the pool can't be closed.
168
private boolean _forbidClose;
169
170   // The JDBC table to be used to ping for connection liveness.
171
private String JavaDoc _pingTable;
172   // The Query used for connection liveness.
173
private String JavaDoc _pingQuery;
174   // Ping when the connection is reused.
175
private boolean _isPing;
176   // How long between pings
177
private long _pingInterval = 1000;
178
179   // True if the pool is transactional
180
private boolean _isTransactional = true;
181   // True if the pool should never allow isSameRM
182
private boolean _isXAForbidSameRM = false;
183   // The transaction manager if the pool participates in transactions.
184
private TransactionManager JavaDoc _tm;
185   // how long before the transaction times out
186
private long _transactionTimeout = 0;
187
188   private boolean _isSpy;
189   private int _spyId;
190
191   private int _maxCloseStatements = 256;
192   // The prepared statement cache size.
193
private int _preparedStatementCacheSize = 0;
194
195   private boolean _isWrapStatements = true;
196   
197   // The connections currently in the pool.
198
// transient ArrayList<PoolItem> _connections = new ArrayList<PoolItem>();
199

200   // Count for debugging ids.
201
private int _idCount;
202
203   // The alarm
204
private Alarm _alarm;
205
206   /**
207    * Null constructor for the Driver interface; called by the JNDI
208    * configuration. Applications should not call this directly.
209    */

210   public DBPoolImpl()
211   {
212   }
213
214   /**
215    * Returns the Pool's name
216    */

217   public String JavaDoc getName()
218   {
219     return _name;
220   }
221
222   /**
223    * Sets the Pool's name. Also puts the pool in the classloader's
224    * list of pools.
225    */

226   public void setName(String JavaDoc name)
227   {
228     _name = name;
229   }
230
231   public String JavaDoc getURL()
232   {
233     return _driverList.get(0).getURL();
234   }
235
236   /**
237    * Returns the driver config.
238    */

239   public DriverConfig createDriver()
240   {
241     DriverConfig driver = new DriverConfig(this);
242
243     _driverList.add(driver);
244
245     return driver;
246   }
247
248   /**
249    * Returns the driver config.
250    */

251   public DriverConfig createBackupDriver()
252   {
253     DriverConfig driver = new DriverConfig(this);
254
255     _backupDriverList.add(driver);
256
257     return driver;
258   }
259
260   /**
261    * Sets a driver parameter.
262    */

263   public void setInitParam(InitParam init)
264   {
265     DriverConfig driver = _driverList.get(0);
266
267     HashMap JavaDoc<String JavaDoc,String JavaDoc> params = init.getParameters();
268
269     Iterator JavaDoc<String JavaDoc> iter = params.keySet().iterator();
270     while (iter.hasNext()) {
271       String JavaDoc key = iter.next();
272       driver.setInitParam(key, params.get(key));
273     }
274   }
275
276   /**
277    * Sets the jdbc-driver config.
278    */

279   public void setJDBCDriver(Driver JavaDoc jdbcDriver)
280     throws SQLException JavaDoc
281   {
282     DriverConfig driver;
283
284     if (_driverList.size() > 0)
285       driver = _driverList.get(0);
286     else
287       driver = createDriver();
288
289     driver.setDriver(jdbcDriver);
290   }
291
292   /**
293    * Creates the connection config.
294    */

295   public ConnectionConfig createConnection()
296   {
297     return _connectionConfig;
298   }
299
300   /**
301    * Returns the connection config.
302    */

303   public ConnectionConfig getConnectionConfig()
304   {
305     return _connectionConfig;
306   }
307
308   /**
309    * Sets the jdbc-driver config.
310    */

311   public void setPoolDataSource(ConnectionPoolDataSource JavaDoc poolDataSource)
312     throws SQLException JavaDoc
313   {
314     DriverConfig driver;
315
316     if (_driverList.size() > 0)
317       driver = _driverList.get(0);
318     else
319       driver = createDriver();
320
321     driver.setPoolDataSource(poolDataSource);
322   }
323
324   /**
325    * Sets the jdbc-driver config.
326    */

327   public void setXADataSource(XADataSource JavaDoc xaDataSource)
328     throws SQLException JavaDoc
329   {
330     DriverConfig driver;
331
332     if (_driverList.size() > 0)
333       driver = _driverList.get(0);
334     else
335       driver = createDriver();
336
337     driver.setXADataSource(xaDataSource);
338   }
339
340   /**
341    * Sets the jdbc-driver config.
342    */

343   public void setURL(String JavaDoc url)
344     throws ConfigException
345   {
346     DriverConfig driver;
347
348     if (_driverList.size() > 0)
349       driver = _driverList.get(0);
350     else
351       throw new ConfigException(L.l("The driver must be assigned before the URL."));
352
353     driver.setURL(url);
354   }
355
356   /**
357    * Returns the connection's user.
358    */

359   public String JavaDoc getUser()
360   {
361     return _user;
362   }
363
364   /**
365    * Sets the connection's user.
366    */

367   public void setUser(String JavaDoc user)
368   {
369     _user = user;
370   }
371
372   /**
373    * Returns the connection's password
374    */

375   public String JavaDoc getPassword()
376   {
377     return _password;
378   }
379
380   /**
381    * Sets the connection's password
382    */

383   public void setPassword(String JavaDoc password)
384   {
385     _password = password;
386   }
387
388   /**
389    * Get the maximum number of pooled connections.
390    */

391   public int getMaxConnections()
392   {
393     return _maxConnections;
394   }
395
396   /**
397    * Sets the maximum number of pooled connections.
398    */

399   public void setMaxConnections(int maxConnections)
400   {
401     _maxConnections = maxConnections;
402   }
403
404   /**
405    * Get the total number of connections
406    */

407   public int getTotalConnections()
408   {
409     // return _connections.size();
410
return 0;
411   }
412
413   /**
414    * Sets the time to wait for a connection when all are used.
415    */

416   public void setConnectionWaitTime(Period waitTime)
417   {
418     long period = waitTime.getPeriod();
419
420     _connectionWaitTime = period;
421
422     if (period < 0)
423       _connectionWaitCount = 3600; // wait for an hour == infinity
424
else {
425       _connectionWaitCount = (int) ((period + 999) / 1000);
426
427       if (_connectionWaitCount <= 0)
428         _connectionWaitCount = 1;
429     }
430   }
431
432   /**
433    * Gets the time to wait for a connection when all are used.
434    */

435   public long getConnectionWaitTime()
436   {
437     return _connectionWaitTime;
438   }
439
440   /**
441    * The number of connections to overflow if the connection pool fills
442    * and there's a timeout.
443    */

444   public void setMaxOverflowConnections(int maxOverflowConnections)
445   {
446     _maxOverflowConnections = maxOverflowConnections;
447   }
448
449   /**
450    * The number of connections to overflow if the connection pool fills
451    * and there's a timeout.
452    */

453   public int getMaxOverflowConnections()
454   {
455     return _maxOverflowConnections;
456   }
457
458   /**
459    * Sets the transaction timeout.
460    */

461   public void setTransactionTimeout(Period period)
462   {
463     _transactionTimeout = period.getPeriod();
464   }
465
466   /**
467    * Gets the transaction timeout.
468    */

469   public long getTransactionTimeout()
470   {
471     return _transactionTimeout;
472   }
473
474   /**
475    * Sets the max statement.
476    */

477   public void setMaxCloseStatements(int max)
478   {
479     _maxCloseStatements = max;
480   }
481
482   /**
483    * Gets the max statement.
484    */

485   public int getMaxCloseStatements()
486   {
487     return _maxCloseStatements;
488   }
489
490   /**
491    * Sets true if statements should be wrapped.
492    */

493   public void setWrapStatements(boolean isWrap)
494   {
495     _isWrapStatements = isWrap;
496   }
497
498   /**
499    * Sets true if statements should be wrapped.
500    */

501   public boolean isWrapStatements()
502   {
503     return _isWrapStatements;
504   }
505
506   /**
507    * Returns the prepared statement cache size.
508    */

509   public int getPreparedStatementCacheSize()
510   {
511     return _preparedStatementCacheSize;
512   }
513
514   /**
515    * Sets the prepared statement cache size.
516    */

517   public void setPreparedStatementCacheSize(int size)
518   {
519     _preparedStatementCacheSize = size;
520   }
521
522   /**
523    * Get the time in milliseconds a connection will remain in the pool before
524    * being closed.
525    */

526   public long getMaxIdleTime()
527   {
528     if (_maxIdleTime > Long.MAX_VALUE / 2)
529       return -1;
530     else
531       return _maxIdleTime;
532   }
533
534   /**
535    * Set the time in milliseconds a connection will remain in the pool before
536    * being closed.
537    */

538   public void setMaxIdleTime(Period idleTime)
539   {
540     long period = idleTime.getPeriod();
541
542     if (period < 0)
543       _maxIdleTime = Long.MAX_VALUE / 2;
544     else if (period < 1000L)
545       _maxIdleTime = 1000L;
546     else
547       _maxIdleTime = period;
548   }
549
550   /**
551    * Get the time in milliseconds a connection will remain in the pool before
552    * being closed.
553    */

554   public long getMaxPoolTime()
555   {
556     if (_maxPoolTime > Long.MAX_VALUE / 2)
557       return -1;
558     else
559       return _maxPoolTime;
560   }
561
562   /**
563    * Set the time in milliseconds a connection will remain in the pool before
564    * being closed.
565    */

566   public void setMaxPoolTime(Period maxPoolTime)
567   {
568     long period = maxPoolTime.getPeriod();
569
570     if (period < 0)
571       _maxPoolTime = Long.MAX_VALUE / 2;
572     else if (period == 0)
573       _maxPoolTime = 1000L;
574     else
575       _maxPoolTime = period;
576   }
577
578   /**
579    * Get the time in milliseconds a connection can remain active.
580    */

581   public long getMaxActiveTime()
582   {
583     if (_maxActiveTime > Long.MAX_VALUE / 2)
584       return -1;
585     else
586       return _maxActiveTime;
587   }
588
589   /**
590    * Set the time in milliseconds a connection can remain active.
591    */

592   public void setMaxActiveTime(Period maxActiveTime)
593   {
594     long period = maxActiveTime.getPeriod();
595
596     if (period < 0)
597       _maxActiveTime = Long.MAX_VALUE / 2;
598     else if (period == 0)
599       _maxActiveTime = 1000L;
600     else
601       _maxActiveTime = period;
602   }
603
604   /**
605    * Get the table to 'ping' to see if the connection is still live.
606    */

607   public String JavaDoc getPingTable()
608   {
609     return _pingTable;
610   }
611
612   /**
613    * Set the table to 'ping' to see if the connection is still live.
614    *
615    * @param pingTable name of the SQL table to ping.
616    */

617   public void setPingTable(String JavaDoc pingTable)
618   {
619     _pingTable = pingTable;
620
621     if (pingTable != null)
622       _pingQuery = "select 1 from " + pingTable + " where 1=0";
623     else
624       _pingQuery = null;
625   }
626
627   /**
628    * Returns the ping query.
629    */

630   public String JavaDoc getPingQuery()
631   {
632     return _pingQuery;
633   }
634
635   /**
636    * If true, the pool will ping when attempting to reuse a connection.
637    */

638   public boolean getPingOnReuse()
639   {
640     return _isPing;
641   }
642
643   /**
644    * Set the table to 'ping' to see if the connection is still live.
645    */

646   public void setPingOnReuse(boolean pingOnReuse)
647   {
648     _isPing = pingOnReuse;
649   }
650
651   /**
652    * If true, the pool will ping in the idle pool.
653    */

654   public boolean getPingOnIdle()
655   {
656     return _isPing;
657   }
658
659   /**
660    * Set the table to 'ping' to see if the connection is still live.
661    */

662   public void setPingOnIdle(boolean pingOnIdle)
663   {
664     _isPing = pingOnIdle;
665   }
666
667   /**
668    * Set true if pinging is enabled.
669    */

670   public void setPing(boolean ping)
671   {
672     _isPing = ping;
673   }
674
675   /**
676    * Returns true if pinging is enabled.
677    */

678   public boolean isPing()
679   {
680     return _isPing;
681   }
682
683   /**
684    * Sets the time to ping for ping-on-idle
685    */

686   public void setPingInterval(Period interval)
687   {
688     _pingInterval = interval.getPeriod();
689
690     if (_pingInterval < 0)
691       _pingInterval = Long.MAX_VALUE / 2;
692     else if (_pingInterval < 1000)
693       _pingInterval = 1000;
694   }
695
696   /**
697    * Gets how often the ping for ping-on-idle
698    */

699   public long getPingInterval()
700  {
701     return _pingInterval;
702   }
703
704   /**
705    * Set the transaction manager for this pool.
706    */

707   public void setTransactionManager(TransactionManager JavaDoc tm)
708   {
709     _tm = tm;
710   }
711
712   /**
713    * Returns the transaction manager.
714    */

715   /*
716   public TransactionManager getTransactionManager()
717   {
718     return _tm;
719   }
720   */

721
722   /**
723    * Returns true if this is transactional.
724    */

725   public boolean isXA()
726   {
727     return _isTransactional;
728   }
729
730   /**
731    * Returns true if this is transactional.
732    */

733   public void setXA(boolean isTransactional)
734   {
735     _isTransactional = isTransactional;
736   }
737
738   /**
739    * Returns true if transactions should force isSameRM to be false.
740    */

741   public boolean isXAForbidSameRM()
742   {
743     return _isXAForbidSameRM;
744   }
745
746   /**
747    * Returns true if transactions should force isSameRM to be false.
748    */

749   public void setXAForbidSameRM(boolean isXAForbidSameRM)
750   {
751     _isXAForbidSameRM = isXAForbidSameRM;
752   }
753
754   /**
755    * Set the output for spying.
756    */

757   public void setSpy(boolean isSpy)
758   {
759     _isSpy = isSpy;
760   }
761
762   /**
763    * Return true for a spy.
764    */

765   public boolean isSpy()
766   {
767     return _isSpy;
768   }
769
770   /**
771    * Returns the next spy id.
772    */

773   public int newSpyId()
774   {
775     return _spyId++;
776   }
777
778   /**
779    * Returns true if the pool supports transactions.
780    */

781   public boolean isTransactional()
782   {
783     return _isTransactional;
784   }
785
786   /**
787    * Returns true if there is a valid XAResource associated
788    * with the database.
789    */

790   public boolean isXATransaction()
791   {
792     if (_connectionConfig.isReadOnly())
793       return false;
794     else if (_driverList.size() > 0) {
795       DriverConfig driver = _driverList.get(0);
796
797       return driver.isXATransaction();
798     }
799     else
800       return false;
801   }
802
803   /**
804    * Returns true if there is a valid local transactino associated
805    * with the database.
806    */

807   public boolean isLocalTransaction()
808   {
809     if (_connectionConfig.isReadOnly())
810       return false;
811     else if (_driverList.size() > 0) {
812       DriverConfig driver = _driverList.get(0);
813
814       return driver.isLocalTransaction();
815     }
816     else
817       return false;
818   }
819
820   int createPoolId()
821   {
822     return _idCount++;
823   }
824
825   /**
826    * Sets the timeout for a database login.
827    */

828   public void setLoginTimeout(int seconds) throws SQLException JavaDoc
829   {
830   }
831
832   /**
833    * Gets the timeout for a database login.
834    */

835   public int getLoginTimeout() throws SQLException JavaDoc
836   {
837     return 0;
838   }
839   /**
840    * Sets the debugging log for the connection.
841    */

842   public void setLogWriter(PrintWriter JavaDoc out) throws SQLException JavaDoc
843   {
844   }
845
846   /**
847    * Sets the debugging log for the connection.
848    */

849   public PrintWriter JavaDoc getLogWriter() throws SQLException JavaDoc
850   {
851     return null;
852   }
853
854   /**
855    * Initialize the pool.
856    */

857   public void init()
858     throws Exception JavaDoc
859   {
860     Environment.addEnvironmentListener(this);
861
862     // _alarm = new Alarm("db-pool", this, 60000);
863

864     /*
865     if (_pingInterval > 0 &&
866         _pingInterval < _maxIdleTime &&
867         _pingInterval < 60000L)
868       _alarm.queue(_pingInterval);
869     else if (_maxIdleTime > 60000)
870       _alarm.queue(60000);
871     else
872       _alarm.queue(_maxIdleTime);
873     */

874
875     try {
876       if (_tm == null) {
877         Object JavaDoc obj = new InitialContext JavaDoc().lookup("java:comp/TransactionManager");
878
879         if (obj instanceof TransactionManager JavaDoc)
880           _tm = (TransactionManager JavaDoc) obj;
881       }
882     } catch (Exception JavaDoc e) {
883       log.log(Level.FINE, e.toString(), e);
884     }
885
886     /*
887     if (isXA() && _tm == null)
888       throw new ConfigException(L.l("Can't find TransactionManager in java:comp/TransactionManager for transaction-enabled DBPool."));
889     */

890
891     for (int i = 0; i < _driverList.size(); i++) {
892       DriverConfig driver = _driverList.get(i);
893
894       if (driver.getUser() == null)
895     driver.setUser(_user);
896       if (driver.getPassword() == null)
897     driver.setPassword(_password);
898
899       driver.initDriver();
900       driver.initDataSource(_isTransactional, _isSpy);
901
902       if (_mcf == null)
903     _mcf = driver.getManagedConnectionFactory();
904
905       /*
906       if (driver.getXADataSource() == null)
907     _isTransactional = false;
908       */

909     }
910
911     DriverConfig []drivers = new DriverConfig[_driverList.size()];
912     _driverList.toArray(drivers);
913
914     for (int i = 0; i < _backupDriverList.size(); i++) {
915       DriverConfig driver = _backupDriverList.get(i);
916
917       if (driver.getUser() == null)
918     driver.setUser(_user);
919       if (driver.getPassword() == null)
920     driver.setPassword(_password);
921
922       driver.initDriver();
923       driver.initDataSource(_isTransactional, _isSpy);
924       /*
925       if (driver.getXADataSource() == null)
926     _isTransactional = false;
927       */

928     }
929
930     DriverConfig []backupDrivers = new DriverConfig[_backupDriverList.size()];
931     _backupDriverList.toArray(backupDrivers);
932
933     if (_mcf == null)
934       _mcf = new ManagedFactoryImpl(this, drivers, backupDrivers);
935
936     if (_name != null) {
937       String JavaDoc name = _name;
938       if (! name.startsWith("java:"))
939         name = "java:comp/env/" + name;
940
941       if (drivers[0].getURL() != null)
942         log.config("database " + name + " starting (URL:" + drivers[0].getURL() + ")");
943       else
944         log.config("database " + name + " starting");
945
946       // XXX: actually should be proxy
947
// Jndi.bindDeep(name, this);
948
}
949   }
950
951   /**
952    * Returns the managed connection factory.
953    */

954   ManagedConnectionFactory JavaDoc getManagedConnectionFactory()
955   {
956     return _mcf;
957   }
958
959   /**
960    * Initialize the pool's data source
961    *
962    * <ul>
963    * <li>If data-source is set, look it up in JNDI.
964    * <li>Else if the driver is a pooled or xa data source, use it.
965    * <li>Else create wrappers.
966    * </ul>
967    */

968   synchronized void initDataSource()
969     throws SQLException JavaDoc
970   {
971     if (_isStarted)
972       return;
973
974     _isStarted = true;
975
976     for (int i = 0; i < _driverList.size(); i++) {
977       DriverConfig driver = _driverList.get(i);
978
979       driver.initDataSource(_isTransactional, _isSpy);
980     }
981
982     try {
983       if (_isTransactional && _tm == null) {
984         Object JavaDoc obj = new InitialContext JavaDoc().lookup("java:comp/TransactionManager");
985
986         if (obj instanceof TransactionManager JavaDoc)
987           _tm = (TransactionManager JavaDoc) obj;
988       }
989     } catch (NamingException JavaDoc e) {
990       throw new SQLExceptionWrapper(e);
991     }
992   }
993
994   /**
995    * Closes the idle connections in the pool.
996    */

997   public void closeIdleConnections()
998   {
999     
1000  }
1001
1002  /**
1003   * At the alarm, close all connections which have been sitting in
1004   * the pool for too long.
1005   *
1006   * @param alarm the alarm event.
1007   */

1008  public void handleAlarm(Alarm alarm)
1009  {
1010    if (_isClosed)
1011      return;
1012  }
1013
1014  /**
1015   * Callback when the environment starts.
1016   */

1017  public void environmentStart(EnvironmentClassLoader loader)
1018  {
1019  }
1020
1021  /**
1022   * Callback when the class loader dies.
1023   */

1024  public void environmentStop(EnvironmentClassLoader loader)
1025  {
1026    forceClose();
1027  }
1028
1029  /**
1030   * Returns true if the pool is closed.
1031   */

1032  public boolean isClosed()
1033  {
1034    return _isClosed;
1035  }
1036
1037  /**
1038   * Close the pool, closing the connections.
1039   */

1040  public void close()
1041  {
1042    if (_forbidClose)
1043      throw new IllegalStateException JavaDoc("illegal to call close() for this DBPool");
1044    forceClose();
1045  }
1046
1047  /**
1048   * Close all the connections in the pool.
1049   */

1050  public void forceClose()
1051  {
1052    if (_isClosed)
1053      return;
1054
1055    _isClosed = true;
1056
1057    if (log.isLoggable(Level.FINE))
1058      log.fine("closing pool " + getName());
1059  }
1060
1061  /**
1062   * Returns a string description of the pool.
1063   */

1064  public String JavaDoc toString()
1065  {
1066    return "DBPoolImpl[" + _name + "]";
1067  }
1068}
1069
1070
Popular Tags