KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > support > sqlstore > connection > ConnectionManager


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * ConnectionManager.java
26  *
27  * Create on March 3, 2000
28  */

29
30 package com.sun.jdo.spi.persistence.support.sqlstore.connection;
31
32 import com.sun.jdo.api.persistence.support.Transaction;
33 import com.sun.jdo.spi.persistence.utility.I18NHelper;
34 import com.sun.jdo.spi.persistence.utility.DoubleLinkedList;
35 import com.sun.jdo.spi.persistence.utility.Linkable;
36 import com.sun.jdo.spi.persistence.support.sqlstore.utility.StringScanner;
37 import com.sun.jdo.spi.persistence.utility.logging.Logger;
38 import com.sun.jdo.spi.persistence.support.sqlstore.LogHelperSQLStore;
39
40
41 import java.sql.Connection JavaDoc;
42 import java.sql.DriverManager JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.util.Hashtable JavaDoc;
45 import java.util.ResourceBundle JavaDoc;
46
47 /**
48  * <P>This class represents a connection manager, which creates a
49  * JDBC driver manager and manages
50  * established database connections. This class lets you specify the following
51  * settings for JDBC connections:
52  * <UL>
53  * <LI>JDBC driver type
54  * <LI>data source name (JDBC URL)
55  * <LI>user name
56  * <LI>password
57  * <LI>number of pooled connections (settable when running)
58  * <LI>how often to try to get a connection after failing the first time and how long
59  * to retry (settable when running)
60  * </UL>
61  * If you define a connection manager as a component, you can define
62  * these settings when you partition the application instead of when you write the application.
63  * <P>You can change only the following settings when the connection manager is
64  * running:
65  * <UL>
66  * <LI> minimum and maximum number of pooled connections, although not whether pooling is
67  * on or off (<code>setMinPool</code> and <code>setMaxPool</code>)
68  * <LI> how often to try to get a connection after failing the first time and how
69  * long to retry for a connection (<code>setMsWait</code> and <code>setMsInterval</code>)
70  * </UL>
71  * <P>You cannot set any other setting while the connection manager is running.
72  * To change other settings, shut down the connection manager using the
73  * <code>shutDown</code> method, then change
74  * the settings. Then, start the connection manager
75  * using the <code>startUp</code> method.
76  * <P>If you use a connection manager to manage your database connections,
77  * the connection manager can also extend a SynerJ transaction to include
78  * JDBC database transactions. In other words, if the JDBC database
79  * transactions occur within a SynerJ transaction, the JDBC database
80  * transactions are committed or rolled back when the SynerJ transaction
81  * committed or rolled back.
82  * <P>You can set up your connection manager to manage database connections in
83  * the following ways:
84  * <UL>
85  * <LI>Start a new connection every time you request a connection. This approach is
86  * often referred to as <i>client-based security</i>, because the security
87  * for the connection is based on a particular database client and can be
88  * different for each client.
89  * <LI>Maintain a pool of connections for a given user name and password,
90  * and return one of these connections when you request a connection using the
91  * getConnection method with no parameters.
92  * This approach is often referred to as <i>application-based security</i>, because
93  * the security information for the pool of connections is the same and is the
94  * same for all clients of the application.
95  * <LI>Maintain a pool of connections for a given user name and password
96  * and start a new connection if you specify another user name and password
97  * with the getConnection method.
98  * This approach is a blend of client-based and application-based security.
99  * </UL>
100  * <P>You also have the choice of either defining the connection manager
101  * as a service object typed as a ConnectionManager object, or
102  * defining the connection manager by dynamically creating a
103  * ConnectionManager object in your code. If you define the
104  * connection manager as a service object, the SynerJ partitioning system
105  * can help you determine how to define partitions that contain the
106  * service object by being aware of where JDBC drivers are installed,
107  * for example. If you define the ConnectionManager object
108  * dynamically, then you need to keep such issues in mind when you
109  * define the partitions whose code defines the ConnectionManager
110  * objects; the partitioning system will not help you.
111  *
112  * <H4>Starting a New Database Connection for Each Request (Client-based Security)</H4>
113  * <P>In this situation, the connection
114  * manager establishes a new connection each time you request a connection.
115  * By default, the connection manager does not establish and maintain a
116  * pool of connections. In this case, you can leave the maximum and minimum
117  * number of pooled connections set to 0.
118  * Each time you need a connection to the database,
119  * use the getConnection method.
120  * You can use the default user name, password, and database URL for the current
121  * connection manager by invoking the getConnection method with no parameters.
122  * The default settings are specified in one of the ConnectionManager
123  * constructors when you create the connection manager.
124  * You can also specify a user name, password, and database URL on the
125  * getConnection method.
126  *
127  * <H5>Example of Using ConnectionManager without Pooling</H4>
128  * <PRE>
129  * import java.sql.*;
130  * import com.sun.jdo.api.persistence.support.*;
131  * Connection con = myTransaction.getConnection();
132  * Statement stmt = con.createStatement();
133  * ResultSet rs = stmt.executeQuery("SELECT * FROM T1");
134  * </PRE>
135  *
136  * <H4>Using a Pool of Database Connections (Application-based Security)</H4>
137  * <P>When you create a connection manager using the
138  * ConnectionManager class, you can have the connection manager
139  * establish a pool of connections for a given user name and password
140  * to allow a thread to using an existing connection instead of waiting
141  * for a new database connection to be created.
142  * <P>To create a connection manager with a pool of connections using
143  * a service object:
144  * <OL>
145  * <LI>Define a service object of the class ConnectionManager.
146  * <LI>In the Partition Workshop, set the component properties for
147  * the component instance represented by the service
148  * object to define the driver name and the default database URL,
149  * user name, and password. You can also define the values for the
150  * minimum connections and the maximum connections for the connection pool, as well
151  * as for how often and how long to try to get a connection after an initial
152  * failure to do so.
153  * <P>If you set the values for the minimum and maximum connections to
154  * 0, then no pool of connections is established. Any value greater
155  * than 0 means that a pool of connections is established. The maximum
156  * value must be equal to or greater than the value of the minimum
157  * value. If you set the maximum and minimum as equal values, the
158  * number of connections established for the pool will be constant.
159  * <P>The connection manager establishes the minimum number of connections
160  * when it starts up using the default database URL, user name, and password.
161  * </OL>
162  * <P>To get one of the pooled connections, you can use the
163  * <CODE>getConnection</CODE>
164  * method with no parameters. If all the existing connections are in
165  * use, the connection manager establishes another connection with
166  * the same database URL, user name, and password and adds it to the pool,
167  * up to the specified maximum number of connections.
168  * <P>When you have finished using a connection, you can use the
169  * <CODE>close()</CODE> method to return the connection to the pool
170  * of available connections.
171  * The connection manager periodically checks its pool of connections,
172  * and can reduce the number of established connections to the minimum
173  * number, if enough connections are not in use.
174  * At runtime, you can change the maximum and minimum number of connections,
175  * because the ConnectionManager
176  * is a component.
177  *
178  * <H4>Using a Pool of Connections and Starting New Connections</H4>
179  * <P>You can have the connection manager establish and maintain a
180  * pool of connections and have the connection manager establish new
181  * connections on a request-by-request basis.
182  *
183  * <H5>Example of Using ConnectionManager with Pooling</H5>
184  * <PRE>
185  * import com.sun.jdo.api.persistence.support.*;
186  * void getT1Data() {
187  * // The following connection is from the connection pool.
188  * Connection myConn = myTransaction.getConnection();
189  * Statement myStatement = myConn.createStatement();
190  * ResultSet myResults = myStatement.executeQuery(
191  * "SELECT * FROM T1);
192  * // Free the connection; it is returned to the connection pool.
193  * myConn.close();
194  *
195  * // The connection manager creates a new connection for the
196  * // following request.
197  * Connection yourConn = myConnMgr.getConnection(
198  * "data:oracle:thin:@CUSTOMERDB:1521:ORCL", "paul", "omni8");
199  * Statement yourStatement = yourConn.createStatement();
200  * ResultSet yourResults = yourStatement.executeQuery(
201  * "SELECT Customer, Date, Amount FROM Orders");
202  * .
203  * .
204  * .
205  * }
206  * </PRE>
207  */

208 public class ConnectionManager {
209     /**
210      * Name of the driver; e.g. "oracle.jdbc.driver.OracleDriver"
211      * @serial
212      */

213     private String JavaDoc driverName;
214
215     /**
216      * Expanded name of the driver
217      * @serial
218      */

219     private transient String JavaDoc expandedDriverName;
220
221     /**
222      * Datasource url; e.g. "jdbc:oracle:oci7:@ABYSS_ORACLE"
223      * @serial
224      */

225     private String JavaDoc url;
226
227     /**
228      * Expanded datasource url
229      * @serial
230      */

231     private transient String JavaDoc expandedUrl;
232
233     /**
234      * DBMS Username.
235      * @serial
236      */

237     private String JavaDoc userName;
238
239     /**
240      * Expanded user name
241      * @serial
242      */

243     private transient String JavaDoc expandedUserName;
244
245     /**
246      * DBMS password.
247      * @serial
248      */

249     private String JavaDoc password;
250
251     /**
252      * Expanded DBMS password.
253      * @serial
254      */

255     private transient String JavaDoc expandedPassword;
256
257     /**
258      * The minimum size of the connection pool.
259      * @serial
260      */

261     private int minPool;
262
263     /**
264      * The maximum size of the connection pool.
265      * @serial
266      */

267     private int maxPool;
268
269     /**
270      * The current size of the connection pool.
271      * @serial
272      */

273     private transient int poolSize;
274
275     /**
276      * True if connection pooling is enabled.
277      * @serial
278      */

279     private transient boolean pooling;
280
281     /**
282      * The linked list of idle DB connections.
283      * @serial
284      */

285     transient DoubleLinkedList freeList;
286
287     /**
288      * The linked list of in-use DB connections.
289      * @serial
290      */

291     transient DoubleLinkedList busyList;
292
293     /**
294      * List of Connections associated with transactions, indexed by
295      * transaction object (javax.transaction.Transaction).
296      * @serial
297      */

298     private transient Hashtable JavaDoc xactConnections;
299
300     /**
301      * Flag that a shutdown to this ConnectionManager object is pending.
302      * @serial
303      */

304     transient boolean shutDownPending;
305
306     /**
307      * Flag that specifies we are using default connection blocking.
308      * @serial
309      */

310     private transient boolean connectionBlocking;
311
312     /**
313      * Millisecond time to wait between attempts to connect
314      * to the database.
315      * @serial
316      */

317     private int msInterval;
318
319     /**
320      * Millisecond time to block while attempting to connect
321      * to the database.
322      * @serial
323      */

324     private int msWait;
325
326     //
327
// Default number of milliseconds to block while retrying to get
328
// a pooled connection to the database.
329
//
330
private static final int DEFAULT_RETRY_INTERVAL = 1000;
331
332     /**
333      * Indicates whether this ConnectionManager is properly initialized.
334      * @serial
335      */

336     private transient boolean initialized;
337
338     /**
339      * Maximumn number of seconds this DataSource will wait while attempting to
340      * connection to a database.
341      */

342     private int loginTimeout;
343
344     /**
345      * Free non-pooled connection to reduce time for getting a new connection.
346      */

347     private transient ConnectionImpl freeConn = null;
348
349     
350     /**
351      * The logger
352      */

353     private static Logger logger = LogHelperSQLStore.getLogger();
354     
355     /**
356      * I18N message handler
357      */

358     private final static ResourceBundle JavaDoc messages = I18NHelper.loadBundle(
359             "com.sun.jdo.spi.persistence.support.sqlstore.Bundle", // NOI18N
360
ConnectionManager.class.getClassLoader());
361
362
363     //
364
// SQL92 State Codes.
365
//
366

367     //
368
// SQL92 "00000" Successful completion.
369
//
370
static final String JavaDoc SQL_SUCCESS = "00000"; // NOI18N
371

372     //
373
// SQL92 "01000" Warning.
374
//
375
static final String JavaDoc SQL_WARNING = "01000"; // NOI18N
376

377     //
378
// SQL92 "01001" Warning; cursor operation conflict.
379
//
380
static final String JavaDoc SQL_CURSOR_OP = "01001"; // NOI18N
381

382     //
383
// SQL92 "01002" Warning; disconnect error.
384
//
385
static final String JavaDoc SQL_DISCONNECT = "01002"; // NOI18N
386

387     //
388
// SQL92 "01003" Warning; null value eliminated in set function.
389
//
390
static final String JavaDoc SQL_NULL_ELIM = "01003"; // NOI18N
391

392     //
393
// SQL92 "01004" Warning; string date, right truncation.
394
//
395
static final String JavaDoc SQL_R_TRUNC = "01004"; // NOI18N
396

397     //
398
// SQL92 "01005" Warning; insufficient item descriptor areas.
399
//
400
static final String JavaDoc SQL_INSUFF_ITEM = "01005"; // NOI18N
401

402     //
403
// SQL92 "01006" Warning; privilege not revoked.
404
//
405
static final String JavaDoc SQL_NOT_REVOKED = "01006"; // NOI18N
406

407     //
408
// SQL92 "01007" Warning; privilege not granted.
409
//
410
static final String JavaDoc SQL_NOT_GRANTED = "01007"; // NOI18N
411

412     //
413
// SQL92 "01008" Warning; implicit zero-bit padding.
414
//
415
static final String JavaDoc SQL_ZERO_BIT_PAD = "01008"; // NOI18N
416

417     //
418
// SQL92 "01009" Warning; search condition too long for
419
// information schema.
420
//
421
static final String JavaDoc SQL_COND_TOO_LONG = "01009"; // NOI18N
422

423     //
424
// SQL92 "0100A" Warning; query condition too long for
425
// information schema.
426
//
427
static final String JavaDoc SQL_QUERY_TOO_LONG = "0100A"; // NOI18N
428

429     //
430
// SQL92 "02000" No data.
431
//
432
static final String JavaDoc SQL_NO_DATA = "02000"; // NOI18N
433

434     //
435
// SQL92 "07000" Dynamic SQL error.
436
//
437
static final String JavaDoc SQL_DYN_ERROR = "07000"; // NOI18N
438

439     //
440
// SQL92 "07001" Dynamic SQL error; using clause does not
441
// match dynamic parameter specifications.
442
//
443
static final String JavaDoc SQL_USING_NO_PARAM = "07001"; // NOI18N
444

445     //
446
// SQL92 "07002" Dynamic SQL error; using clause does not
447
// match target specifications.
448
//
449
static final String JavaDoc SQL_USING_NO_TARGET = "07002"; // NOI18N
450

451     //
452
// SQL92 "07003" Dynamic SQL error; cursor specification
453
// cannot be executed.
454
//
455
static final String JavaDoc SQL_CURSOR_NOEXE = "07003"; // NOI18N
456

457     //
458
// SQL92 "07004" Dynamic SQL error; using clause
459
// required for dynamic parameters.
460
//
461
static final String JavaDoc SQL_USING_REQ = "07004"; // NOI18N
462

463     //
464
// SQL92 "07005" Dynamic SQL error; prepared statement
465
// not a cursor specification.
466
//
467
static final String JavaDoc SQL_PREP_NO_CURSOR = "07005"; // NOI18N
468

469     //
470
// SQL92 "07006" Dynamic SQL error; restricted datatype
471
// attribute violation.
472
//
473
static final String JavaDoc SQL_RESTRIC_ATTR = "07006"; // NOI18N
474

475     //
476
// SQL92 "07007" Dynamic SQL error; using caluse required
477
// for result fields.
478
//
479
static final String JavaDoc SQL_USING_RESULTS = "07007"; // NOI18N
480

481     //
482
// SQL92 "07008" Dynamic SQL error; invalid descriptor count.
483
//
484
static final String JavaDoc SQL_INVAL_DESC_CNT = "07008"; // NOI18N
485

486     //
487
// SQL92 "07009" Dynamic SQL error; invalid descriptor index.
488
//
489
static final String JavaDoc SQL_INVAL_DESC_IDX = "07009"; // NOI18N
490

491     //
492
// SQL92 "08000" Connection exception.
493
//
494
static final String JavaDoc SQL_CONN = "08000"; // NOI18N
495

496     //
497
// SQL92 "08001" Connection exception; SQL-client unable
498
// to establish SQL-connection.
499
//
500
static final String JavaDoc SQL_CLIENT_NO_CONN = "08001"; // NOI18N
501

502     //
503
// SQL92 "08002" Connection exception; connection name
504
// in use.
505
//
506
static final String JavaDoc SQL_CONN_IN_USE = "08002"; // NOI18N
507

508     //
509
// SQL92 "08003" Connection exception; connection does not exist.
510
//
511
static final String JavaDoc SQL_NO_CONN = "08003"; // NOI18N
512

513     //
514
// SQL92 "08004" Connection exception; SQL-server rejected
515
// establishment of SQL-connection.
516
//
517
static final String JavaDoc SQL_REJECT_CONN = "08004"; // NOI18N
518

519     //
520
// SQL92 "08006" Connection exception; connection failure.
521
//
522
static final String JavaDoc SQL_CONN_FAIL = "08006"; // NOI18N
523

524     //
525
// SQL92 "08007" Connection exception; transaction resolution unknown.
526
//
527
static final String JavaDoc SQL_TRANS_UNK = "08007"; // NOI18N
528

529     //
530
// SQL92 "0A000" Feature not supported.
531
//
532
static final String JavaDoc SQL_NO_SUPPORT = "0A000"; // NOI18N
533

534     //
535
// SQL92 "0A001" Feature not supported; multiple
536
// server transactions
537
//
538
static final String JavaDoc SQL_NO_SUPPORT_MULTI = "0A001"; // NOI18N
539

540     //
541
// SQL92 "21000" Cardinality violation.
542
//
543
static final String JavaDoc SQL_INVALID_VALUE = "21000"; // NOI18N
544

545     //
546
// SQL92 "22000" Data exception.
547
//
548
static final String JavaDoc SQL_DATA = "22000"; // NOI18N
549

550     //
551
// SQL92 "22001" Data exception; string data,
552
// right trunctation.
553
//
554
static final String JavaDoc SQL_DATA_RTRUNC = "22001"; // NOI18N
555

556     //
557
// SQL92 "22002" Data exception; null value, no
558
// indicator parameter.
559
//
560
static final String JavaDoc SQL_DATA_NULL = "22002"; // NOI18N
561

562     //
563
// SQL92 "22003" Data exception; numeric value out
564
// of range.
565
//
566
static final String JavaDoc SQL_OUT_OF_RANGE = "22003"; // NOI18N
567

568     //
569
// SQL92 "22005" Data exception; error in assignment.
570
//
571
static final String JavaDoc SQL_DATA_EXCEPT = "22005"; // NOI18N
572

573     //
574
// SQL92 "22007" Data exception; invalid datetime format.
575
//
576
static final String JavaDoc SQL_DATETIME_FMT = "22007"; // NOI18N
577

578     //
579
// SQL92 "22008" Data exception; datetime field overflow.
580
//
581
static final String JavaDoc SQL_DATETIME_OVFLO = "22008"; // NOI18N
582

583     //
584
// SQL92 "22009" Data exception; invalid time zone
585
// displacement value.
586
//
587
static final String JavaDoc SQL_TIMEZONE = "22009"; // NOI18N
588

589     //
590
// SQL92 "22011" Data exception; substring error.
591
//
592
static final String JavaDoc SQL_SUBSTR_ERROR = "22011"; // NOI18N
593

594     //
595
// SQL92 "22012" Data exception; division by zero.
596
//
597
static final String JavaDoc SQL_DIV_BY_ZERO = "22012"; // NOI18N
598

599     //
600
// SQL92 "22015" Data exception; interval field overflow.
601
//
602
static final String JavaDoc SQL_INTERVAL_OVFLO = "22015"; // NOI18N
603

604     //
605
// SQL92 "22018" Data exception; invalid character value
606
// for cast.
607
//
608
static final String JavaDoc SQL_INVAL_CHAR_CAST = "22018"; // NOI18N
609

610     //
611
// SQL92 "22019" Data exception; invalid escape character.
612
//
613
static final String JavaDoc SQL_INVAL_ESCAPE_CHAR = "22019"; // NOI18N
614

615     //
616
// SQL92 "22021" Data exception; character not in repertoire.
617
//
618
static final String JavaDoc SQL_CHAR_NOT_REP = "22021"; // NOI18N
619

620     //
621
// SQL92 "22022" Data exception; indicator overflow.
622
//
623
static final String JavaDoc SQL_IND_OVERFLOW = "22022"; // NOI18N
624

625     //
626
// SQL92 "22023" Data exception; invalid parameter value.
627
//
628
static final String JavaDoc SQL_INVAL_PARAM_VALUE = "22023"; // NOI18N
629

630     //
631
// SQL92 "22024" Data exception; unterminated C string.
632
//
633
static final String JavaDoc SQL_UNTERM_C_STR = "22024"; // NOI18N
634

635     //
636
// SQL92 "22025" Data exception; invalid escape sequence.
637
//
638
static final String JavaDoc SQL_INVAL_ESCAPE_SEQ = "22025"; // NOI18N
639

640     //
641
// SQL92 "22026" Data exception; string data, length mismatch.
642
//
643
static final String JavaDoc SQL_STR_LEN_MISMATCH = "22026"; // NOI18N
644

645     //
646
// SQL92 "22027" Data exception; trim error.
647
//
648
static final String JavaDoc SQL_TRIM_ERROR = "22027"; // NOI18N
649

650     //
651
// SQL92 "23000" Integrity constraint violation.
652
//
653
static final String JavaDoc SQL_INTEG_CONSTRAINT = "23000"; // NOI18N
654

655     //
656
// SQL92 "24000" Invalid cursor state.
657
//
658
static final String JavaDoc SQL_INVAL_CURSOR_STATE = "24000"; // NOI18N
659

660     //
661
// SQL92 "25000" Invalid transaction state
662
//
663
static final String JavaDoc SQL_INVAL_TRANS_STATE = "25000"; // NOI18N
664

665     //
666
// SQL92 "26000" Invalid SQL statement name.
667
//
668
static final String JavaDoc SQL_INVAL_SQL_NAME = "26000"; // NOI18N
669

670     //
671
// SQL92 "28000" Invalid authorization specification.
672
//
673
static final String JavaDoc SQL_INVAL_AUTH = "28000"; // NOI18N
674

675     //
676
// SQL92 "2A000" Syntax error or access rule violation
677
// in direct SQL statement.
678
//
679
static final String JavaDoc SQL_SYNTAX_DIRECT = "2A000"; // NOI18N
680

681     //
682
// SQL92 "2B000" Dependent privilege descriptors
683
// still exist.
684
//
685
static final String JavaDoc SQL_DESC_EXIST = "2B000"; // NOI18N
686

687     //
688
// SQL92 "2C000" Invalid character set name.
689
//
690
static final String JavaDoc SQL_INVAL_CHAR_SET = "2C000"; // NOI18N
691

692     //
693
// SQL92 "2D000" Invalid transaction termination.
694
//
695
static final String JavaDoc SQL_INVAL_TRANS_TERM = "2D000"; // NOI18N
696

697     //
698
// SQL92 "2E000" Invalid connection name.
699
//
700
static final String JavaDoc SQL_INVAL_CONN_NAME = "2E000"; // NOI18N
701

702     //
703
// SQL92 "33000" Invalid SQL descriptor name
704
//
705
static final String JavaDoc SQL_INVAL_SQL_DESC_NAME = "33000"; // NOI18N
706

707     //
708
// SQL92 "34000" Invalid cursor name.
709
//
710
static final String JavaDoc SQL_INVAL_CURSOR_NAME = "34000"; // NOI18N
711

712     //
713
// SQL92 "35000" Invalid condition number
714
//
715
static final String JavaDoc SQL_INVAL_COND_NUM = "35000"; // NOI18N
716

717     //
718
// SQL92 "37000" Syntax error or access rule violation
719
// in dynamic SQL statement.
720
//
721
static final String JavaDoc SQL_SYNTAX_DYNAMIC = "37000"; // NOI18N
722

723     //
724
// SQL92 "3C000" Ambiguous cursor name.
725
//
726
static final String JavaDoc SQL_AMBIG_CURSOR = "3C000"; // NOI18N
727

728     //
729
// SQL92 "3D000" Invalid catalog name.
730
//
731
static final String JavaDoc SQL_INVAL_CATALOG = "3D000"; // NOI18N
732

733     //
734
// SQL92 "3F000" Invalid schema name.
735
//
736
static final String JavaDoc SQL_INVAL_SCHEMA_NAME = "3F000"; // NOI18N
737

738     //
739
// SQL92 "40000" Transaction rollback.
740
//
741
static final String JavaDoc SQL_TRANS_ROLLBACK = "40000"; // NOI18N
742

743     //
744
// SQL92 "40001" Transaction rollback; serialization
745
// failure.
746
//
747
static final String JavaDoc SQL_TRANS_SERIAL_FAIL = "40001"; // NOI18N
748

749     //
750
// SQL92 "40002" Transaction rollback; integrity
751
// constraint violation.
752
//
753
static final String JavaDoc SQL_TRANS_INTEG = "40002"; // NOI18N
754

755     //
756
// SQL92 "40003" Transaction rollback; statement
757
// completion unknown.
758
//
759
static final String JavaDoc SQL_TRANS_COMP_UNK = "40003"; // NOI18N
760

761     //
762
// SQL92 "42000" Syntax error or access rule violation.
763
//
764
static final String JavaDoc SQL_SYNTAX = "42000"; // NOI18N
765

766     //
767
// SQL92 "44000" With check option violation.
768
//
769
static final String JavaDoc SQL_CHECK_OPT = "44000"; // NOI18N
770

771     //
772
// SQL92 "HZ " Remote Database Access.
773
//
774
static final String JavaDoc SQL_RMT_DB_ACCESS = "HZ "; // NOI18N
775

776
777     /**
778      * Default constructor.
779      * Creates a new connection manager and loads the generic JDBC driver.
780      * You should typically use one of the other constructors, because
781      * you cannot change JDBC drivers after the connection manager has
782      * been created.
783      */

784     public ConnectionManager() {
785         super();
786         this.driverName = null;
787         this.expandedDriverName = null;
788         this.url = null;
789         this.expandedUrl = null;
790         this.userName = null;
791         this.expandedUserName = null;
792         this.password = null;
793         this.expandedPassword = null;
794         this.minPool = 0;
795         this.maxPool = 0;
796         this.busyList = null;
797         this.freeList = null;
798         this.poolSize = 0;
799         this.pooling = false;
800         this.xactConnections = null;
801         this.shutDownPending = false;
802         this.connectionBlocking = false;
803         this.msWait = 0;
804         this.msInterval = 0;
805         this.busyList = null;
806         this.xactConnections = null;
807         this.initialized = false;
808     }
809
810     // --------------- Overloaded Constructors -----------------
811

812     /**
813      * Creates a new connection manager and loads the named
814      * JDBC driver.
815      * <p>
816      * @param driverName name of JDBC driver.
817      * @exception ClassNotFoundException if the driver cannot be found.
818      * @exception SQLException if a SQL error is encountered.
819      */

820     public ConnectionManager(String JavaDoc driverName)
821             throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
822         this();
823         try {
824             this.setDriverName(driverName);
825             startUp();
826         } catch (SQLException JavaDoc se) {
827             throw se;
828         } catch (ClassNotFoundException JavaDoc e) {
829             throw e;
830         }
831     }
832
833     /**
834      * Creates a new connection manager, loads the named JDBC driver, and
835      * sets the default database URL for the new connection manager.
836      * <p>
837      * @param driverName the name of JDBC driver.
838      * @param url the database URL for the data source.
839      * @exception ClassNotFoundException if the driver cannot be found.
840      * @exception SQLException if a SQL error is encountered.
841      */

842     public ConnectionManager(String JavaDoc driverName, String JavaDoc url)
843             throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
844         this();
845         try {
846             this.setDriverName(driverName);
847             this.setURL(url);
848             startUp();
849         } catch (SQLException JavaDoc se) {
850             throw se;
851         }
852     }
853
854     /**
855      * Creates a new connection manager, loads the named JDBC driver, and
856      * sets the default database URL and user name for the new
857      * connection manager.
858      * @param driverName the name of JDBC driver.
859      * @param url the default database URL for the data source.
860      * @param userName the default user name for database connections.
861      * @exception ClassNotFoundException if the driver cannot be found.
862      * @exception SQLException if a SQL error is encountered.
863      */

864     public ConnectionManager(String JavaDoc driverName, String JavaDoc url,
865                              String JavaDoc userName) throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
866         this();
867         try {
868             this.setDriverName(driverName);
869             this.setURL(url);
870             this.setUserName(userName);
871             startUp();
872         } catch (SQLException JavaDoc se) {
873             throw se;
874         }
875     }
876
877     /**
878      * Creates a new connection manager, loads the named JDBC driver, and
879      * sets the default database URL, user name, and password for the new
880      * connection manager.
881      * @param driverName the name of JDBC driver.
882      * @param url the default database URL for the data source.
883      * @param userName the default user name for database connections.
884      * @param password the default password for database connections.
885      * @exception ClassNotFoundException if the driver cannot be found.
886      * @exception SQLException if a SQL error is encountered.
887      */

888     public ConnectionManager
889             (
890             String JavaDoc driverName,
891             String JavaDoc url,
892             String JavaDoc userName,
893             String JavaDoc password
894             ) throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
895         this();
896         try {
897             this.setDriverName(driverName);
898             this.setURL(url);
899             this.setUserName(userName);
900             this.setPassword(password);
901             startUp();
902         } catch (SQLException JavaDoc se) {
903             throw se;
904         }
905     }
906
907     /**
908      * Creates a new connection manager, loads the named JDBC driver, and sets
909      * the default database URL, user name, password and minimum and maximum
910      * connection pool sizes for the new
911      * connection manager.
912      * <P>If minPool and maxPool are 0, connection pooling is disabled.
913      * If minPool is greater than 0 and maxPool is greater than or equal
914      * to minPool, this constructor creates a connection pool containing
915      * minPool connections.
916      * @param driverName the name of JDBC driver.
917      * @param url the default database URL for the data source.
918      * @param userName the default user name for database connections.
919      * @param password the default password for database connections.
920      * @param minPool the default minimum size of the connection pool.
921      * @param maxPool the default maximum size of the connection pool.
922      * @exception ClassNotFoundException if the driver cannot be found.
923      * @exception SQLException if a SQL error is encountered or if the
924      * specified value of minPool is not less than or equal to the specified
925      * value of maxPool.
926      */

927     public ConnectionManager
928             (
929             String JavaDoc driverName,
930             String JavaDoc url,
931             String JavaDoc userName,
932             String JavaDoc password,
933             int minPool,
934             int maxPool
935             ) throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
936         this();
937         try {
938             this.setDriverName(driverName);
939             this.setURL(url);
940             this.setUserName(userName);
941             this.setPassword(password);
942             this.setMinPool(minPool);
943             this.setMaxPool(maxPool);
944             startUp();
945         } catch (SQLException JavaDoc se) {
946             throw se;
947         }
948     }
949
950     /**
951      * Creates a new connection manager, loads the named JDBC driver, and defines
952      * the default values for the database URL, user name, password, minimum and maximum
953      * connection pool sizes, and the length of time to wait for a
954      * database connection.
955      * <P>If minPool and maxPool are 0, connection pooling is disabled.
956      * If minPool is greater than 0 and maxPool is greater than or equal
957      * to minPool, this constructor creates a connection pool containing
958      * minPool connections.
959      * <P>If msWait is set to 0, the connection manager does not try again to
960      * create or return a database connection if the first try fails.
961      * For any other value, the connection manager waits 1000 milliseconds (ms)
962      * (1 second) before trying again.
963      * If the msWait value is less than 1000 ms, the connection manager
964      * waits 1000 ms before trying.
965      * The connection manager continues trying until the value specified
966      * by msWait is met or exceeded.
967      * <P>If you want to set the interval length yourself, you can use
968      * the <code>ConnectionManager</code> constructor that
969      * specifies the msInterval parameter or the <code>setInterval</code>
970      * method.
971      * @param driverName the name of JDBC driver.
972      * @param url the default database URL for the data source.
973      * @param userName the default user name for database connections.
974      * @param password the default password for database connections.
975      * @param minPool the default minimum size of the connection pool.
976      * @param maxPool the default maximum size of the connection pool.
977      * @param msWait the total number of milliseconds to wait for a successful connection.
978      * @exception ClassNotFoundException if the driver cannot be found.
979      * @exception SQLException if a SQL error is encountered or if the
980      * specified value of minPool is not less than or equal to the specified
981      * value of maxPool.
982      */

983     public ConnectionManager
984             (
985             String JavaDoc driverName,
986             String JavaDoc url,
987             String JavaDoc userName,
988             String JavaDoc password,
989             int minPool,
990             int maxPool,
991             int msWait
992             ) throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
993         this();
994         try {
995             this.setDriverName(driverName);
996             this.setURL(url);
997             this.setUserName(userName);
998             this.setPassword(password);
999             this.setMinPool(minPool);
1000            this.setMaxPool(maxPool);
1001            this.setMsWait(msWait);
1002            this.setMsInterval(DEFAULT_RETRY_INTERVAL);
1003            startUp();
1004        } catch (SQLException JavaDoc se) {
1005            throw se;
1006        }
1007    }
1008
1009    /**
1010     * Creates a new connection manager, loads the named JDBC driver, and
1011     * defines the default values for the database URL, user name, password, minimum and maximum
1012     * connection pool sizes, the length of time to wait for a database connection,
1013     * and how frequently to try again to get a database connection.
1014     * <P>If minPool and maxPool are 0, connection pooling is disabled.
1015     * If minPool is greater than 0 and maxPool is greater than or equal
1016     * to minPool, this constructor creates a connection pool containing
1017     * minPool connections.
1018     * <P>If msWait or msInterval is set to 0, the connection
1019     * manager does not try again to create or return a database connection
1020     * if the first try fails.
1021     * <P>For any other values greater than 0, the The connection manager
1022     * continues trying after every specified value for msInterval
1023     * until the value specified by msWait is met or exceeded.
1024     * If the value for msInterval is greater than the value for msWait,
1025     * the connection manager tries again to return a connection once, then
1026     * fails if it could get a connection.
1027     * @param driverName the name of JDBC driver.
1028     * @param url the default database URL for the data source.
1029     * @param userName the default user name for database connections.
1030     * @param password the default password for database connections.
1031     * @param minPool the default minimum size of the connection pool.
1032     * @param maxPool the default maximum size of the connection pool.
1033     * @param msWait the total number of milliseconds to wait to get a connection.
1034     * @param msInterval the number of milliseconds to wait before trying again to get a connection.
1035     * @exception ClassNotFoundException if the driver cannot be found.
1036     * @exception SQLException if a SQL error is encountered or if the
1037     * specified value of minPool is not less than or equal to the specified
1038     * value of maxPool.
1039     */

1040
1041    public ConnectionManager
1042            (
1043            String JavaDoc driverName,
1044            String JavaDoc url,
1045            String JavaDoc userName,
1046            String JavaDoc password,
1047            int minPool,
1048            int maxPool,
1049            int msWait,
1050            int msInterval
1051            ) throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
1052        this();
1053        try {
1054            this.setDriverName(driverName);
1055            this.setURL(url);
1056            this.setUserName(userName);
1057            this.setPassword(password);
1058            this.setMinPool(minPool);
1059            this.setMaxPool(maxPool);
1060            this.setMsWait(msWait);
1061            this.setMsInterval(msInterval);
1062            startUp();
1063        } catch (SQLException JavaDoc se) {
1064            throw se;
1065        }
1066    }
1067
1068    // --------------------- Public Methods -----------------------
1069

1070
1071    /**
1072     * Establishes a connection to the default database URL
1073     * using the default user name and password.
1074     * <P>If the current connection manager maintains a
1075     * connection pool, this method returns a pooled connection
1076     * instead of establishing a new connection.
1077     * If all pooled connections are in use, and the total wait time (msWait)
1078     * for the connection manager and the retry interval (msInterval) are
1079     * not 0, then the connection manager tries to get a database connection
1080     * after the retry interval. The connection manager continues to
1081     * try until a pooled connection becomes available or
1082     * until the total time equals or exceeds the wait time.
1083     * If the wait time expires before the connection manager returns
1084     * a database connection, this method throws a <code>SQLException</code>
1085     * exception with SQLState = "08006".
1086     *
1087     * <P>If the current connection manager is not set to try again for connections
1088     * (the wait time is 0) and no pooled connections are available, this
1089     * method throws a <code>SQLException</code> exception
1090     * with SQLState = "08006".
1091     *
1092     * <P>If the current connection manager is being shut down,
1093     * this method throws a <code>SQLException</code> exception with
1094     * SQLState = "08003".
1095     *
1096     * @return A new or pooled database connection.
1097     * @exception SQLException if no database connection is available.
1098     *
1099     */

1100    public synchronized Connection JavaDoc getConnection() throws SQLException JavaDoc {
1101        if (this.shutDownPending == true) {
1102            SQLException JavaDoc se = new SQLException JavaDoc
1103                    (
1104                            StringScanner.createParamString
1105                    (
1106                            I18NHelper.getMessage(messages,
1107                                    "connection.connectionmanager.isdown") // NOI18N
1108
),
1109                            SQL_NO_CONN
1110                    );
1111            throw se;
1112        }
1113
1114        ConnectionImpl conn = this.checkXact();
1115
1116        if (conn != null) {
1117            // We already know about this transaction.
1118
} else if (!this.pooling) // Get a non-pooled connection.
1119
{
1120            conn = (ConnectionImpl) this.getConnection(this.userName,
1121                    this.password);
1122            conn.setPooled(false);
1123            conn.checkXact();
1124        } else // This is a pooled connection.
1125
{
1126            if (this.freeList.size <= 0) // Is pool empty?
1127
{
1128                if (this.poolSize < this.maxPool) // Can we expand the pool?
1129
{
1130                    try {
1131                        this.expandPool(1); // Add new connection to the pool.
1132
} catch (SQLException JavaDoc se) {
1133                        throw se;
1134                    }
1135                } else if (this.connectionBlocking != true) // Can't expand the pool.
1136
{
1137                    // If not blocking, give up.
1138
SQLException JavaDoc se = new SQLException JavaDoc
1139                            (
1140                                    StringScanner.createParamString
1141                            (
1142                                    I18NHelper.getMessage(messages,
1143                                            "connection.connectionmanager.maxpool") // NOI18N
1144
),
1145                                    SQL_INVAL_PARAM_VALUE // 22023
1146
);
1147                    throw se;
1148                } else // We are blocking, so...
1149
{
1150                    try {
1151                        this.waitForConnection(); // wait for a connection.
1152
} catch (SQLException JavaDoc se) {
1153                        throw se;
1154                    }
1155                }
1156            }
1157            conn = (ConnectionImpl) (this.freeList.removeFromHead());
1158            if (conn == null) {
1159                // Shouldn't happen.
1160
SQLException JavaDoc se = new SQLException JavaDoc
1161                        (
1162                                StringScanner.createParamString
1163                        (
1164                                I18NHelper.getMessage(messages,
1165                                        "connection.connectionmanager.badvalue") // NOI18N
1166
),
1167                                SQL_INVAL_PARAM_VALUE // 22023
1168
);
1169                throw se;
1170            }
1171            conn.setPooled(true);
1172            conn.checkXact();
1173            this.busyList.insertAtTail((Linkable) conn);
1174        }
1175        conn.setFreePending(false);
1176        return ((Connection JavaDoc) conn);
1177    }
1178
1179    /**
1180     * Establishes a connection to the database at the default database URL using
1181     * the specified user name and password.
1182     *
1183     * @param userName the database user name.
1184     * @param password the database password.
1185     * @return A new database connection.
1186     * @exception SQLException if the connection fails.
1187     */

1188    public synchronized Connection JavaDoc getConnection
1189            (
1190            String JavaDoc userName,
1191            String JavaDoc password
1192            ) throws SQLException JavaDoc {
1193        boolean debug = logger.isLoggable(Logger.FINEST);
1194
1195
1196        if (this.shutDownPending == true) {
1197            SQLException JavaDoc se = new SQLException JavaDoc
1198                    (
1199                            StringScanner.createParamString
1200                    (
1201                            I18NHelper.getMessage(messages,
1202                                    "connection.connectionmanager.isdown") // NOI18N
1203
),
1204                            SQL_CONN_FAIL
1205                    );
1206            throw se;
1207        }
1208
1209        ConnectionImpl conn = this.checkXact();
1210
1211        if (conn == null) {
1212            if (freeConn != null) {
1213                // We have one available - use it
1214
if (debug) {
1215                    logger.finest("sqlstore.connection.conncectiomgr.found",freeConn); // NOI18N
1216
}
1217                conn = freeConn;
1218                freeConn = null;
1219            } else {
1220                // No connection is available - get new
1221
try {
1222                    // By default, a new ConnectionImpl is non-pooled.
1223
conn = new ConnectionImpl
1224                            (
1225                                    DriverManager.getConnection
1226                            (
1227                                    this.expandedUrl,
1228                                    this.expandAttribute(userName),
1229                                    this.expandAttribute(password)
1230                            ),
1231                                    this.expandedUrl,
1232                                    this.expandAttribute(userName),
1233                                    this
1234                            );
1235                    if (debug) {
1236                        logger.finest("sqlstore.connection.conncectiomgr.getnewconn",conn); // NOI18N
1237
}
1238                } catch (SQLException JavaDoc se) {
1239                    throw se;
1240                }
1241            }
1242            conn.checkXact();
1243        } else {
1244            if (!conn.getUserName().equals(this.expandAttribute(userName))) {
1245                SQLException JavaDoc se = new SQLException JavaDoc
1246                        (
1247                                StringScanner.createParamString
1248                        (
1249                                I18NHelper.getMessage(messages,
1250                                        "connection.connectionmanager.getconnection.mismatch") // NOI18N
1251
),
1252                                SQL_NO_CONN // 08003
1253
);
1254                throw se;
1255            }
1256        }
1257        conn.setFreePending(false);
1258        conn.setPooled(false);
1259        this.busyList.insertAtTail((Linkable) conn);
1260        return ((Connection JavaDoc) conn);
1261    }
1262
1263    /**
1264     * Establishes a connection to the specified
1265     * database URL using the specified user name and password.
1266     *
1267     * @param url the database URL for the database.
1268     * @param userName the database user name.
1269     * @param password the database password.
1270     * @return A new database connection.
1271     * @exception SQLException if the connection fails.
1272     */

1273    public synchronized Connection JavaDoc getConnection
1274            (
1275            String JavaDoc url,
1276            String JavaDoc userName,
1277            String JavaDoc password
1278            ) throws SQLException JavaDoc {
1279        boolean debug = logger.isLoggable(Logger.FINEST);
1280
1281        if (this.shutDownPending == true) {
1282            SQLException JavaDoc se = new SQLException JavaDoc
1283                    (
1284                            StringScanner.createParamString
1285                    (
1286                            I18NHelper.getMessage(messages,
1287                                    "connection.connectionmanager.isdown") // NOI18N
1288
),
1289                            SQL_CONN_FAIL
1290                    );
1291            throw se;
1292        }
1293
1294        ConnectionImpl conn = this.checkXact();
1295
1296        if (conn == null) {
1297            if (freeConn != null) {
1298                // We have one available - use it
1299
if (debug) {
1300                    logger.finest("sqlstore.connection.conncectiomgr.found",freeConn); // NOI18N
1301
}
1302                conn = freeConn;
1303                freeConn = null;
1304            } else {
1305                // No connection is available - get new
1306
try {
1307                    // By default, a new ConnectionImpl is non-pooled.
1308
conn = new ConnectionImpl
1309                            (
1310                                    DriverManager.getConnection
1311                            (
1312                                    this.expandAttribute(url),
1313                                    this.expandAttribute(userName),
1314                                    this.expandAttribute(password)
1315                            ),
1316                                    this.expandAttribute(url),
1317                                    this.expandAttribute(userName),
1318                                    this
1319                            );
1320                    if (debug) {
1321                        logger.finest("sqlstore.connection.conncectiomgr.getnewconn",conn); // NOI18N
1322
}
1323                } catch (SQLException JavaDoc se) {
1324                    throw se;
1325                }
1326            }
1327            conn.checkXact();
1328        } else {
1329            if ((!conn.getURL().equals(this.expandAttribute(url))) ||
1330                    (!conn.getUserName().equals(this.expandAttribute(userName)))) {
1331                SQLException JavaDoc se = new SQLException JavaDoc
1332                        (
1333                                StringScanner.createParamString
1334                        (
1335                                I18NHelper.getMessage(messages,
1336                                        "connection.connectionmanager.getconnection.mismatch") // NOI18N
1337
),
1338                                SQL_NO_CONN // 08003
1339
);
1340                throw se;
1341            }
1342        }
1343        conn.setFreePending(false);
1344        conn.setPooled(false);
1345        this.busyList.insertAtTail((Linkable) conn);
1346        return ((Connection JavaDoc) conn);
1347    }
1348
1349    /**
1350     * Check whether a ConnectionImpl is already associated with
1351     * the transaction on the current thread.
1352     * <p>
1353     * @return ConnectionImpl associated with the transaction on
1354     * the current thread; null otherwise.
1355     */

1356    private synchronized ConnectionImpl checkXact() {
1357        Transaction tran = null;
1358
1359        /* RESOLVE: Need to reimplement this???
1360        try
1361        {
1362            // Is this ForteJDBCConnet participating in a transaction?
1363            tran = ThreadContext.transactionContext().getTransaction();
1364        }
1365        catch (SystemException ex)
1366        {
1367            // There is no transaction.
1368            return null;
1369        }
1370        */

1371
1372        // Return Connection associated with this transaction - maybe null?
1373
if (tran == null)
1374            return null;
1375        return (ConnectionImpl) this.xactConnections.get(tran);
1376    }
1377
1378    /**
1379     * Starts up this ConnectionManager by loading the proper
1380     * JDBC driver class and initializing the pool if necessary.
1381     * <p>
1382     * You need to call this method if you are using the ConnectionManager
1383     * as a component, or if you use the default constructor and set the
1384     * attributes via the <code>set</code><I>XXX</I> methods.
1385     * @exception ClassNotFoundException if the driver cannot be found.
1386     * @exception SQLException if a SQL error is encountered.
1387     */

1388    public void startUp() throws ClassNotFoundException JavaDoc, SQLException JavaDoc {
1389        if (this.initialized == true) return;
1390
1391        this.busyList = new DoubleLinkedList();
1392        this.xactConnections = new Hashtable JavaDoc();
1393        this.expandedDriverName = this.expandAttribute(this.driverName);
1394        if (this.expandedDriverName == null) {
1395            SQLException JavaDoc se = new SQLException JavaDoc
1396                    (
1397                            StringScanner.createParamString
1398                    (
1399                            I18NHelper.getMessage(messages,
1400                                    "connection.connectionmanager.nulldriver") // NOI18N
1401
),
1402                            SQL_INVALID_VALUE // 21000
1403
);
1404            throw se;
1405        }
1406        this.expandedUrl = this.expandAttribute(this.url);
1407        if (this.expandedUrl == null) {
1408            SQLException JavaDoc se = new SQLException JavaDoc
1409                    (
1410                            StringScanner.createParamString
1411                    (
1412                            I18NHelper.getMessage(messages,
1413                                    "connection.connectionmanager.nullurl") // NOI18N
1414
),
1415                            SQL_INVALID_VALUE // 21000
1416
);
1417            throw se;
1418        }
1419        this.expandedUserName = this.expandAttribute(this.userName);
1420        if (this.expandedUserName == null) {
1421            this.expandedUserName = ""; // Allow null username. // NOI18N
1422
}
1423        this.expandedPassword = this.expandAttribute(this.password);
1424        if (this.expandedPassword == null) {
1425            this.expandedPassword = ""; // Allow null password. // NOI18N
1426
}
1427        try {
1428            Class.forName(this.expandedDriverName);
1429
1430            // Check if connection pooling is requested.
1431
if ((this.minPool > 0) && (this.maxPool >= this.minPool)) {
1432                // Yes, create a connection of minPool size.
1433
this.pooling = true;
1434                this.freeList = new DoubleLinkedList();
1435                expandPool(this.minPool);
1436            } else if ((this.minPool == 0) && (this.maxPool == 0)) {
1437                // No, pooling is to be disabled.
1438
this.pooling = false;
1439            }
1440
1441        } catch (SQLException JavaDoc se) {
1442            throw se;
1443        } catch (ClassNotFoundException JavaDoc e) {
1444            throw e;
1445        }
1446        this.initialized = true;
1447    }
1448
1449    /**
1450     * Disconnects all free database connections managed by
1451     * the current connection manager and sets the shutDownPending
1452     * flag to true.
1453     * All busy connections that are not participating
1454     * in a transaction will be closed when a yieldConnection() is
1455     * performed. If a connection is participating in a transaction,
1456     * the connection will be closed after the transaction is commited
1457     * or rolledback.
1458     *
1459     * @see #yieldConnection
1460     */

1461    public synchronized void shutDown() throws SQLException JavaDoc {
1462        this.shutDownPending = true;
1463
1464        if (this.pooling == true) {
1465            ConnectionImpl conn;
1466            this.connectionBlocking = false;
1467            this.pooling = false;
1468            this.initialized = false;
1469            for
1470                    (
1471                    conn = (ConnectionImpl) this.freeList.getHead();
1472                    conn != null;
1473                    conn = (ConnectionImpl) conn.getNext()
1474                    ) {
1475                try {
1476                    conn.close();
1477                } catch (SQLException JavaDoc e) {
1478                    throw e;
1479                }
1480            }
1481            this.freeList = null;
1482        }
1483    }
1484
1485
1486    /**
1487     * Disconnects all free database connections managed by
1488     * the current connection manager and sets the shutDownPending
1489     * flag to true.
1490     * All busy connections that are not participating
1491     * in a transaction will be closed when a yieldConnection() is
1492     * performed. If a connection is participating in a transaction,
1493     * the connection will be closed after the transaction is commited
1494     * or rolledback.
1495     *
1496     * @see #yieldConnection
1497     */

1498    protected void finalize() {
1499        try {
1500            shutDown();
1501        } catch (SQLException JavaDoc se) {
1502            ; // Ignore it.
1503
}
1504    }
1505
1506    // ----------- Public Methods to get and set properties --------------
1507

1508    /**
1509     * Gets the name of the JDBC driver.
1510     * @return Name of the JDBC driver.
1511     * @see #setDriverName
1512     */

1513    public synchronized String JavaDoc getDriverName() {
1514        return (this.driverName);
1515    }
1516
1517
1518    /**
1519     * Sets the name of the JDBC driver.
1520     * @param driverName the name of the JDBC driver.
1521     * @exception SQLException if the driverName is NULL.
1522     * @see #getDriverName
1523     */

1524    public synchronized void setDriverName(String JavaDoc driverName) throws SQLException JavaDoc {
1525        if (driverName == null) {
1526            SQLException JavaDoc se = new SQLException JavaDoc
1527                    (
1528                            StringScanner.createParamString
1529                    (
1530                            I18NHelper.getMessage(messages,
1531                                    "connection.connectionmanager.nulldriver") // NOI18N
1532
),
1533                            SQL_INVALID_VALUE // 21000
1534
);
1535            throw se;
1536        }
1537        this.driverName = driverName;
1538    }
1539
1540    /**
1541     * Gets the default database URL for the data source. This default is only for
1542     * the current connection manager and was set by the
1543     * <code>ConnectionManager</code> constructor.
1544     * This default is used if you don't specify another database URL
1545     * with a <code>getConnection</code> method.
1546     * To change this default value, use the <code>setURL</code> method.
1547     * @return The name of the default database URL.
1548     * @see #getConnection
1549     * @see #setURL
1550     */

1551    public synchronized String JavaDoc getURL() {
1552        return (this.url);
1553    }
1554
1555    /**
1556     * Sets the default database URL for the data source. This default is only
1557     * for the current connection manager.
1558     * To get a connection using a different data source than the default, use the
1559     * <code>getConnection</code> method that specifies a database URL as a parameter.
1560     * @param url URL for this connection manager.
1561     * @exception SQLException if the URL is NULL.
1562     * @see #getConnection
1563     * @see #getURL
1564     */

1565    public synchronized void setURL(String JavaDoc url) throws SQLException JavaDoc {
1566        if (url == null) {
1567            SQLException JavaDoc se = new SQLException JavaDoc
1568                    (
1569                            StringScanner.createParamString
1570                    (
1571                            I18NHelper.getMessage(messages,
1572                                    "connection.connectionmanager.nullurl") // NOI18N
1573
),
1574                            SQL_INVALID_VALUE // 21000
1575
);
1576            throw se;
1577        }
1578        this.url = url;
1579    }
1580
1581    /**
1582     * Gets the default database user name for the current
1583     * connection manager.
1584     * This default was set by the <code>ConnectionManager</code>
1585     * constructor, and is used if you don't specify another user name
1586     * with a <code>getConnection</code> method.
1587     * To change this default value, use the <code>setUserName</code> method.
1588     * @return The default database user name.
1589     * @see #getConnection
1590     * @see #setUserName
1591     */

1592    public synchronized String JavaDoc getUserName() {
1593        return (this.userName);
1594    }
1595
1596    /**
1597     * Sets the default database user name for the current
1598     * connection manager.
1599     *
1600     * @param userName the default user name for the current connection manager.
1601     * @see #getUserName
1602     */

1603    public synchronized void setUserName(String JavaDoc userName) throws SQLException JavaDoc {
1604        this.userName = userName;
1605    }
1606
1607    /**
1608     * Gets the default database password for the current
1609     * connection manager.
1610     * This default was set by the <code>ConnectionManager</code>
1611     * constructor, and is used if you don't specify another password
1612     * with a <code>getConnection</code> method.
1613     * To change this default value, use the <code>setPassword</code> method.
1614     * @return The default database password.
1615     * @see #getConnection
1616     * @see #setPassword
1617     */

1618    public synchronized String JavaDoc getPassword() {
1619        return (this.password);
1620    }
1621
1622    /**
1623     * Sets the default database password for the current connection manager.
1624     * @param password the default password for the current connection manager.
1625     * @see #getPassword
1626     */

1627    public synchronized void setPassword(String JavaDoc password) throws SQLException JavaDoc {
1628        this.password = password;
1629    }
1630
1631    /**
1632     * Gets the minimum number of pooled connections for the current
1633     * connection manager.
1634     * If this value is 0, the connection manager does not maintain
1635     * a connection pool until a connection is requested using the
1636     * getConnection method with no parameters.
1637     * <P>To change the minimum number of pooled connections, use the
1638     * <CODE>setMinPool</CODE> method.
1639     * @return The minimum number of pooled connections.
1640     * @see #getConnection
1641     * @see #setMinPool
1642     *
1643     */

1644    public synchronized int getMinPool() {
1645        return (this.minPool);
1646    }
1647
1648    /**
1649     * Sets the minimum number of pooled connections for the current
1650     * connection manager.
1651     * The default minimum number of pooled connections is 0, which means that
1652     * no connections are pooled until a pooled connection is requested.
1653     * <P>The specified value of the minPool parameter must be:
1654     * <UL>
1655     * <LI>greater than or equal to 0.
1656     * <LI>greater than or equal to the current minimum number of pooled
1657     * connections
1658     * <LI>less than or equal to the maximum number of pooled connections
1659     * </UL>
1660     * Otherwise, this method throws a SQLException.
1661     * @param minPool the minimum number of pooled connections.
1662     * @exception SQLException if the connection manager is being shut down or
1663     * if the minPool value is not valid.
1664     * @see #getMaxPool
1665     * @see #getMinPool
1666     * @see #setMaxPool
1667     */

1668    public synchronized void setMinPool(int minPool) throws SQLException JavaDoc {
1669        if (shutDownPending == true) {
1670            SQLException JavaDoc se = new SQLException JavaDoc
1671                    (
1672                            StringScanner.createParamString
1673                    (
1674                            I18NHelper.getMessage(messages,
1675                                    "connection.connectionmanager.isdown") // NOI18N
1676
),
1677                            SQL_CONN_FAIL // 08006
1678
);
1679
1680            throw se;
1681        }
1682        if (minPool < 0) {
1683            SQLException JavaDoc se = new SQLException JavaDoc
1684                    (
1685                            StringScanner.createParamString
1686                    (
1687                            I18NHelper.getMessage(messages,
1688                                    "connection.connectionmanager.zero") // NOI18N
1689
),
1690                            SQL_INVAL_PARAM_VALUE // 22023
1691
);
1692            throw se;
1693        }
1694        if (minPool < this.minPool) {
1695            SQLException JavaDoc se = new SQLException JavaDoc
1696                    (
1697                            StringScanner.createParamString
1698                    (
1699                            I18NHelper.getMessage(messages,
1700                                    "connection.connectionmanager.badnew"), // NOI18N
1701
Integer.toString(minPool),
1702                            Integer.toString(minPool)
1703                    ),
1704                            SQL_INVAL_PARAM_VALUE // 22023
1705
);
1706            throw se;
1707        }
1708        if (pooling == true) {
1709            if (minPool > maxPool) {
1710                SQLException JavaDoc se = new SQLException JavaDoc
1711                        (
1712                                StringScanner.createParamString
1713                        (
1714                                I18NHelper.getMessage(messages,
1715                                        "connection.connectionmanager.poolsize") // NOI18N
1716
),
1717                                SQL_INVAL_PARAM_VALUE // 22023
1718
);
1719                throw se;
1720            }
1721        }
1722        this.minPool = minPool;
1723    }
1724
1725    /**
1726     * Gets the maximum number of pooled connections for the current
1727     * connection manager.
1728     * If this value is 0, the connection manager does not maintain
1729     * a connection pool.
1730     * When you request a connection with the <CODE>getConnection</CODE>
1731     * method, the <CODE>getConnection</CODE>
1732     * method always returns a new connection.
1733     * <P>To change the maximum number of pooled connections, use the
1734     * <CODE>setMaxPool</CODE> method.
1735     * @return The maximum number of pooled connections the current connection
1736     * manager maintains.
1737     * @see #setMaxPool
1738     *
1739     */

1740    public synchronized int getMaxPool() {
1741        return (this.maxPool);
1742    }
1743
1744    /**
1745     * Sets the maximum number of pooled connections for the current
1746     * connection manager.
1747     * The default maximum number of pooled connections is 0, which means
1748     * that no connections are pooled.
1749     * <P>The specified value of the maxPool parameter must be:
1750     * <UL>
1751     * <LI>greater than or equal to 0.
1752     * <LI>greater than or equal to the current maximum number of pooled
1753     * connections
1754     * <LI>greater than or equal to the minimum number of pooled connections
1755     * </UL>
1756     * Otherwise, this method throws a SQLException.
1757     *
1758     * @param maxPool the maximum number of pooled connections.
1759     * @exception SQLException if the connection manager is being shut down or
1760     * if the maxPool value is not valid.
1761     * @see #getMaxPool
1762     * @see #getMinPool
1763     * @see #setMinPool
1764     */

1765    public synchronized void setMaxPool(int maxPool) throws SQLException JavaDoc {
1766        if (shutDownPending == true) {
1767            SQLException JavaDoc se = new SQLException JavaDoc
1768                    (
1769                            StringScanner.createParamString
1770                    (
1771                            I18NHelper.getMessage(messages,
1772                                    "connection.connectionmanager.isdown") // NOI18N
1773
),
1774                            SQL_CONN_FAIL // 08006
1775
);
1776            throw se;
1777        }
1778        if (maxPool < 0) {
1779            SQLException JavaDoc se = new SQLException JavaDoc
1780                    (
1781                            StringScanner.createParamString
1782                    (
1783                            I18NHelper.getMessage(messages,
1784                                    "connection.connectionmanager.zero"), // NOI18N
1785
Integer.toString(maxPool)
1786                    ),
1787                            SQL_INVAL_PARAM_VALUE // 22023
1788
);
1789            throw se;
1790        }
1791        if (pooling == true) {
1792            if (maxPool < this.maxPool) {
1793                SQLException JavaDoc se = new SQLException JavaDoc
1794                        (
1795                                StringScanner.createParamString
1796                        (
1797                                I18NHelper.getMessage(messages,
1798                                        "connection.connectionmanager.badnew"), // NOI18N
1799
Integer.toString(maxPool),
1800                                Integer.toString(maxPool)
1801                        ),
1802                                SQL_INVAL_PARAM_VALUE // 22023
1803
);
1804                throw se;
1805            }
1806        }
1807
1808        if (maxPool < this.minPool) {
1809            SQLException JavaDoc se = new SQLException JavaDoc
1810                    (
1811                            StringScanner.createParamString
1812                    (
1813                            I18NHelper.getMessage(messages,
1814                                    "connection.connectionmanager.poolsize") // NOI18N
1815
),
1816                            SQL_INVAL_PARAM_VALUE // 22023
1817
);
1818            throw se;
1819        }
1820        this.maxPool = maxPool;
1821    }
1822
1823    /**
1824     * Gets the amount of time, in milliseconds, the connection manager should spend trying
1825     * to get a pooled connection, which is the amount of time a requester might wait.
1826     * <p> This value is only meaningful when you use the <code>getConnection</code>
1827     * to get a pooled connection, which means that no database URL, user name, or
1828     * password is specified.
1829     * @return The wait time in milliseconds.
1830     * @see #getConnection
1831     * @see #setMsInterval
1832     *
1833     */

1834    public synchronized int getMsWait() {
1835        return (this.msWait);
1836    }
1837
1838    /**
1839     * Sets the amount of time, in milliseconds, the connection manager should spend trying
1840     * to get a pooled connection, which is the amount of time a requester might wait.
1841     * Setting this value to 0 means that the connection manager does not try again to
1842     * get a database connection if it fails on the first try.
1843     * <p> This value is only meaningful when you use the <code>getConnection</code>
1844     * to get a pooled connection, which means that no database URL, user name, or
1845     * password is specified.
1846     * <p> The connection manager retries after the set interval until the total wait
1847     * time is equal to or greater than the specified wait time.
1848     * You can determine the total number of tries for a connection based on wait time
1849     * and interval settings using the following formula,
1850     * where msWait is the wait time, msInterval is
1851     * the time between attempts to get a connection:
1852     * <pre>
1853     * tries = msWait/msInterval + 2
1854     * </pre>
1855     * For example, if msWait is set to 2000 ms and msInterval is set to 1500 ms, then the
1856     * connection manager will try to get a database connection 3 times before throwing
1857     * an exception if it has failed.
1858     * <p> If the wait time value is less than the set value for the interval between retries,
1859     * but not zero, the connection manager waits the amount of time specified by the
1860     * interval, tries once, then returns an exception if it still could not get a connection.
1861     * @param msWait the wait time in milliseconds.
1862     * @see #getConnection
1863     * @see #getMsInterval
1864     * @see #getMsWait
1865     * @see #setMsInterval
1866     *
1867     */

1868    public synchronized void setMsWait(int msWait) throws SQLException JavaDoc {
1869        if (msWait < 0) {
1870            SQLException JavaDoc se = new SQLException JavaDoc
1871                    (
1872                            StringScanner.createParamString
1873                    (
1874                            I18NHelper.getMessage(messages,
1875                                    "connection.connectionmanager.badvalue"), // NOI18N
1876
Integer.toString(msWait)
1877                    ),
1878                            SQL_INVAL_PARAM_VALUE // 22023
1879
);
1880            throw se;
1881        } else if (msWait > 0) {
1882            this.msWait = msWait;
1883            this.connectionBlocking = true;
1884        } else {
1885            this.msWait = msWait;
1886            this.connectionBlocking = false;
1887        }
1888    }
1889
1890    /**
1891     * Gets the amount of time, in milliseconds,
1892     * between the connection manager's attempts to get a pooled connection.
1893     * <p> This value is only meaningful when you use the <code>getConnection</code>
1894     * to get a pooled connection, which means that no database URL, user name, or
1895     * password is specified.
1896     * @return The length of the interval between tries in milliseconds.
1897     * @see #getConnection
1898     * @see #setMsInterval
1899     */

1900    public synchronized int getMsInterval() {
1901        return (this.msInterval);
1902    }
1903
1904    /**
1905     * Sets the amount of time, in milliseconds, between the connection
1906     * manager's attempts to get a pooled connection.
1907     * <p> This value is only meaningful when you use the <code>getConnection</code>
1908     * to get a pooled connection, which means that no database URL, user name, or
1909     * password is specified.
1910     * <p> The connection manager retries after the specified interval until the total wait
1911     * time is equal to or greater than the set wait time.
1912     * You can determine the total number of tries for a connection based on wait time
1913     * and interval settings using the following formula,
1914     * where msWait is the wait time, msInterval is
1915     * the time between attempts to get a connection:
1916     * <pre>
1917     * tries = msWait/msInterval + 2
1918     * </pre>
1919     * For example, if msWait is set to 2000 ms and msInterval is set to 1500 ms, then the
1920     * connection manager will try to get a database connection 3 times before throwing
1921     * an exception if it has failed.
1922     * <p> If the wait time value is greater than 0 but less than the
1923     * set value for the interval between retries,
1924     * the connection manager waits the amount of time specified by the
1925     * interval, tries once, then returns an exception if it still could not get a connection.
1926     * @param msInterval the interval between attempts to get a database connection, in milliseconds.
1927     * @see #getConnection
1928     * @see #getMsInterval
1929     * @see #getMsWait
1930     * @see #setMsWait
1931     *
1932     */

1933    public synchronized void setMsInterval(int msInterval) throws SQLException JavaDoc {
1934        if ((msInterval < 0) || (this.msWait < msInterval)) {
1935            SQLException JavaDoc se = new SQLException JavaDoc
1936                    (
1937                            StringScanner.createParamString
1938                    (
1939                            I18NHelper.getMessage(messages,
1940                                    "connection.connectionmanager.badnew"), // NOI18N
1941
"MsInterval", // NOI18N
1942
"MsWait" // NOI18N
1943
),
1944                            SQL_INVAL_PARAM_VALUE // 22023
1945
);
1946            throw se;
1947        } else {
1948            this.msInterval = msInterval;
1949        }
1950    }
1951
1952    /**
1953     * Returns a string representation of the current ConnectionManager object.
1954     * <p>
1955     * @return A <code>String</code> decribing the contents of the current
1956     * ConnectionManager object.
1957     */

1958    public synchronized String JavaDoc toString() {
1959        /*
1960        TraceLogger lgr = ThreadContext.lgr();
1961        // Check for trace flag sp:1:1
1962        boolean dif = ThreadContext.lgr().test
1963        (
1964            TraceLogger.CONFIGURATION,
1965            TraceLogger.SVC_SP,
1966            SPLogFlags.CFG_DIFFABLE_EXCEPTS,
1967            1
1968        );
1969        String buf = "ConnectManager@\n"; // NOI18N
1970        if (dif == false)
1971        {
1972            buf = buf + " busyList = " + this.busyList + "\n"; // NOI18N
1973        }
1974        if (this.busyList != null)
1975        {
1976            buf = buf + " busyList Object = " + this.busyList.toString(); // NOI18N
1977        }
1978        buf = buf + " connectionBlocking = " + this.connectionBlocking + "\n"; // NOI18N
1979        buf = buf + " driverName = " + this.driverName + "\n"; // NOI18N
1980        if (dif == false)
1981        {
1982            buf = buf + " expandedDriverName = " + this.expandedDriverName + "\n"; // NOI18N
1983            buf = buf + " expandedPassword = " + this.expandedPassword + "\n"; // NOI18N
1984            buf = buf + " expandedUrl = " + this.expandedUrl + "\n"; // NOI18N
1985            buf = buf + " expandedUserName = " + this.expandedUserName + "\n"; // NOI18N
1986            buf = buf + " freeList = " + this.freeList + "\n"; // NOI18N
1987        }
1988        if (this.freeList != null)
1989        {
1990            buf = buf + " freeList Object = " + this.freeList.toString(); // NOI18N
1991        }
1992        if (dif == false)
1993        {
1994            buf = buf + " hashCode = " + this.hashCode() + "\n"; // NOI18N
1995        }
1996        buf = buf + " maxPool = " + this.maxPool + "\n"; // NOI18N
1997        buf = buf + " minPool = " + this.minPool + "\n"; // NOI18N
1998        buf = buf + " msInterval = " + this.msInterval + "\n"; // NOI18N
1999        buf = buf + " msWait = " + this.msWait + "\n"; // NOI18N
2000        buf = buf + " password = " + this.password + "\n"; // NOI18N
2001        buf = buf + " pooling = " + this.pooling + "\n"; // NOI18N
2002        buf = buf + " poolSize = " + this.poolSize + "\n"; // NOI18N
2003        buf = buf + " shutDownPending = " + this.shutDownPending + "\n"; // NOI18N
2004        buf = buf + " url = " + this.url + "\n"; // NOI18N
2005        buf = buf + " userName = " + this.userName + "\n"; // NOI18N
2006
2007        return buf;
2008        */

2009
2010        return null;
2011    }
2012
2013    // ---------- Private and default (friendly) methods -----------
2014

2015    /**
2016     * Associate a Connection with a transaction.
2017     * <p>
2018     * @param tran The Transaction's object.
2019     * @param conn The Connection.
2020     */

2021    synchronized void associateXact(Transaction tran, ConnectionImpl conn) {
2022        if (tran != null)
2023            this.xactConnections.put((Object JavaDoc) tran, (Object JavaDoc) conn);
2024    }
2025
2026    /**
2027     * Disassociate a Connection with a transaction.
2028     * <p>
2029     * @param tran The Transaction's object.
2030     * @param conn The ForteJDBCConnect hosting the transaction.
2031     * @param free The ConnectionImpl should be returned to freePool.
2032     * @ForteInternal
2033     */

2034    synchronized void disassociateXact
2035            (
2036            Transaction tran,
2037            ConnectionImpl conn,
2038            boolean free
2039            ) throws SQLException JavaDoc {
2040        ConnectionImpl xactConn = null;
2041
2042        if (tran != null)
2043            xactConn = (ConnectionImpl) this.xactConnections.remove((Object JavaDoc) tran);
2044
2045        if (tran == null || xactConn.equals((Object JavaDoc) conn)) {
2046            if (free == true) {
2047                if (conn.connectionManager.shutDownPending == false) {
2048                    this.freeList.insertAtTail((Linkable) conn);
2049                } else {
2050                    conn.close();
2051                }
2052            }
2053        } else {
2054            SQLException JavaDoc se = new SQLException JavaDoc
2055                    (
2056                            StringScanner.createParamString
2057                    (
2058                            //MsgCat.getStr(DbmsMsgCat.DB_ERR_XACT_MISMATCH)
2059
"Internal Error: transaction mismatch" // NOI18N
2060
),
2061                            SQL_TRANS_UNK // 08007
2062
);
2063            throw se;
2064        }
2065    }
2066
2067    /**
2068     * Expand connection pool by connections size.
2069     * <p>
2070     * @param connections Number of connections to add to pool.
2071     * @exception SQLException if connection fails.
2072     * @ForteInternal
2073     */

2074    private synchronized void expandPool(int connections) throws SQLException JavaDoc {
2075        ConnectionImpl conn = null;
2076
2077        if (this.shutDownPending == true) {
2078            SQLException JavaDoc se = new SQLException JavaDoc
2079                    (
2080                            StringScanner.createParamString
2081                    (
2082                            I18NHelper.getMessage(messages,
2083                                    "connection.connectionmanager.isdown") // NOI18N
2084
),
2085                            SQL_CONN_FAIL
2086                    );
2087            throw se;
2088        }
2089
2090        for (int i = 0; i < connections; i++) {
2091            if (this.poolSize >= this.maxPool) {
2092                // There is no room for a new connection.
2093
SQLException JavaDoc se = new SQLException JavaDoc
2094                        (
2095                                StringScanner.createParamString
2096                        (
2097                                I18NHelper.getMessage(messages,
2098                                        "connection.connectionmanager.maxpool") // NOI18N
2099
),
2100                                SQL_CONN_FAIL
2101                        );
2102                throw se;
2103            } else // There is room in the pool, so get a new connection.
2104
{
2105                try {
2106                    conn = new ConnectionImpl
2107                            (
2108                                    DriverManager.getConnection
2109                            (
2110                                    this.expandedUrl,
2111                                    this.expandedUserName,
2112                                    this.expandedPassword
2113                            ),
2114                                    this.expandedUrl,
2115                                    this.expandedUserName,
2116                                    this
2117                            );
2118                    conn.setPooled(true);
2119                    this.freeList.insertAtTail((Linkable) conn);
2120                    this.poolSize++;
2121                } catch (SQLException JavaDoc e) {
2122                    throw e;
2123                }
2124            }
2125        }
2126    }
2127
2128    /**
2129     * Expand an environment variable specified in attributes into their
2130     * corresponding values; e.g, if url = ${MYURL}, expand ${MYURL} into
2131     * its corresponding value.
2132     * <P>
2133     * @param envname environment variable name.
2134     * @exceptions SQLException We should come up with a better one.
2135     */

2136    private String JavaDoc expandAttribute(String JavaDoc envname) throws SQLException JavaDoc {
2137        String JavaDoc attribute = null;
2138        /*RESOLVE:
2139        try
2140        {
2141            attribute = ForteProperties.expandVars(envname);
2142        }
2143        catch (EnvVariableException e)
2144        {
2145            SQLException se = new SQLException
2146            (
2147                StringScanner.createParamString
2148                (
2149                  I18NHelper.getMessage(messages,
2150                                             "connection.connectionmanager.badvalue"), // NOI18N
2151                    envname
2152                ),
2153                SQL_INVAL_PARAM_VALUE
2154            );
2155            throw se;
2156        }
2157        */

2158        if (attribute != null) {
2159            return attribute;
2160        } else {
2161            return envname;
2162        }
2163    }
2164
2165    /**
2166     * Wait for a pool connection. The thread will wait msInterval
2167     * milliseconds between tries to get a connection from the pool.
2168     * If no connection is available after msWait milliseconds, an
2169     * exception is thrown.
2170     * <p>
2171     * @exception SQLException if connection fails.
2172     * @ForteInternal
2173     */

2174    private synchronized void waitForConnection() throws SQLException JavaDoc {
2175        int interval = this.msInterval;
2176        int wait = this.msWait;
2177        int totalTime = 0;
2178        boolean done = false;
2179        Thread JavaDoc t = Thread.currentThread();
2180        do {
2181            // If there are idle connections in the pool
2182
if (this.freeList.size > 0) {
2183                done = true;
2184            } else // There are no idle connection in the pool
2185
{
2186                // Can the pool be expanded?
2187
if (this.poolSize < this.maxPool) {
2188                    // Yes, try to expand the pool.
2189
try {
2190                        expandPool(1);
2191                        done = true;
2192                    } catch (SQLException JavaDoc se) {
2193                        throw se;
2194                    }
2195                } else // the pool is at maximum size...
2196
{
2197                    // If we have waited long enough, throw an exception.
2198
if (totalTime >= wait) {
2199                        SQLException JavaDoc se = new SQLException JavaDoc
2200                                (
2201                                        StringScanner.createParamString
2202                                (
2203                                        I18NHelper.getMessage(messages,
2204                                                "connection.connectionmanager.conntimeout") // NOI18N
2205
),
2206                                        SQL_CONN_FAIL
2207                                );
2208                        throw se;
2209                    } else // Timeout has not expired, sleep for awhile.
2210
{
2211                        try {
2212                            this.wait(interval);
2213                        } catch (InterruptedException JavaDoc ie) {
2214                            SQLException JavaDoc se = new SQLException JavaDoc
2215                                    (
2216                                            StringScanner.createParamString
2217                                    (
2218                                            I18NHelper.getMessage(messages,
2219                                                    "connection.connectionmanager.threaditerupted") // NOI18N
2220
),
2221                                            SQL_CONN_FAIL
2222                                    );
2223                            throw se;
2224                        }
2225                    }
2226                    totalTime += interval;
2227                }
2228            }
2229        } while (!done);
2230    }
2231
2232
2233    public void setLoginTimeout(int seconds)
2234            throws SQLException JavaDoc {
2235        loginTimeout = seconds;
2236    }
2237
2238    public int getLoginTimeout()
2239            throws SQLException JavaDoc {
2240        return loginTimeout;
2241    }
2242
2243    /**
2244     * Called by ConnectionImpl to save a connection when it is no longer used.
2245     * Previous free connection can be released (closed) when a new one becomes available.
2246     */

2247    protected synchronized void replaceFreeConnection(ConnectionImpl c) {
2248        boolean debug = logger.isLoggable(Logger.FINEST);
2249
2250        if (debug) {
2251            logger.finest("sqlstore.connection.conncectiomgr.replacefreeconn",freeConn); // NOI18N
2252
}
2253        if (freeConn != null) {
2254            // Release (close) the old connection.
2255
freeConn.release();
2256        }
2257        freeConn = c;
2258    }
2259}
2260
Popular Tags