Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class represent a DBConnection pool. Another user can use the
4
 *    object to initial a connection pool, get db connection or return it. 
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jing Tao
8
 *    Release: @release@
9
 *
10
 *   '$Author: tao $'
11
 *     '$Date: 2002-06-14 09:36:04 -0700 (Fri, 14 Jun 2002) $'
12
 * '$Revision: 1220 $'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28

    
29
package edu.ucsb.nceas.metacat;
30

    
31
import java.io.*;
32
import java.util.Vector;
33
import java.lang.*;
34
import java.sql.*;
35
import java.util.Stack;
36
import java.util.Hashtable;
37
import java.util.Enumeration;
38

    
39
/** 
40
 * A class represent a DBConnection pool. Another user can use the
41
 * object to initial a connection pool, get db connection or return it.
42
 * This a singleton class, this means only one instance of this class could
43
 * be in the program at one time. 
44
 */
45
public class DBConnectionPool implements Runnable
46
{
47

    
48
  //static attributes
49
  private static DBConnectionPool instance;
50
  private static Vector connectionPool;
51
  private static Thread runner;
52
  
53
  //maximum connection number in the connection pool
54
  final static int MAXIMUMCONNECTIONNUMBER=
55
                  Integer.parseInt(MetaCatUtil.getOption("maximumConnections"));
56
  
57
  //inintila connection number int the connection pool
58
  final static int INITIALCONNECTIONNUMBER=
59
                  Integer.parseInt(MetaCatUtil.getOption("initialConnections"));
60
 
61
  //the number to increase connection pool size
62
  final static int INCREASECONNECTIONNUMBER=
63
                Integer.parseInt(MetaCatUtil.getOption("incrementConnections"));
64
                
65
  //maximum age for a connection (in milli seconds)
66
  final static long MAXIMUMAGE =
67
                  Long.parseLong(MetaCatUtil.getOption("maximumConnectionAge"));
68
  //maximum connection time for a connection ( in milli second)
69
  final static long MAXIMUMCONNECTIONTIME =
70
                 Long.parseLong(MetaCatUtil.getOption("maximumConnectionTime"));
71
  //maximum number for using a connection.
72
  final static int MAXIMUMUSAGENUMBER =
73
                  Integer.parseInt(MetaCatUtil.getOption("maximumUsageNumber"));
74
  //the parameter if run dbconncestionrecyclethread or not
75
  final static String DBCONNECTIONRECYCLETHREAD =
76
                          MetaCatUtil.getOption("runDBConnectionRecycleThread");
77
  //the cycle time of connection recycle action
78
  final static long CYCLETIMEOFDBCONNECTION = 
79
               Long.parseLong(MetaCatUtil.getOption("cycleTimeOfDBConnection"));
80
               
81
  //the number for trying to check out a connection in the pool in 
82
  //getDBConnection method
83
  final static int LIMIT = 2;
84
  
85
  final static int FREE = 0; //status of a connection
86
  final static int BUSY = 1; //statis of a connection
87
  /**
88
   * Returns the single instance, creating one if it's the
89
   * first time this method is called.
90
   */
91
  public static synchronized DBConnectionPool getInstance()
92
                                 throws SQLException 
93
  {
94
    MetaCatUtil.debugMessage
95
                      ("MaximumConnectionNumber: "+MAXIMUMCONNECTIONNUMBER, 49);
96
    MetaCatUtil.debugMessage
97
                     ("Intial connection number: "+INITIALCONNECTIONNUMBER, 49);
98
    MetaCatUtil.debugMessage
99
                 ("Increated connection Number: "+INCREASECONNECTIONNUMBER, 49);
100
    MetaCatUtil.debugMessage
101
                  ("Maximum connection age: "+MAXIMUMAGE, 49);
102
    MetaCatUtil.debugMessage
103
                  ("Maximum connection time: "+MAXIMUMCONNECTIONTIME, 49);
104
    MetaCatUtil.debugMessage
105
                  ("Maximum usage count: "+MAXIMUMUSAGENUMBER, 49);
106
    MetaCatUtil.debugMessage
107
             ("Running recycle thread or not: "+DBCONNECTIONRECYCLETHREAD, 49);
108
    MetaCatUtil.debugMessage
109
             ("Cycle time of recycle: "+CYCLETIMEOFDBCONNECTION, 49); 
110
    if (instance == null) 
111
    {
112
      instance = new DBConnectionPool();
113
    }
114
    return instance;
115
  }//getInstance
116

    
117

    
118
  /**
119
   * This is a private constructor since it is singleton
120
   */
121
   
122
  private DBConnectionPool()  throws SQLException 
123
  {
124
    connectionPool = new Vector();
125
    initialDBConnectionPool();
126
    //running the thread to recycle DBConnection
127
    if (DBCONNECTIONRECYCLETHREAD.equals("on"))
128
    {
129
      runner = new Thread(this);
130
      runner.start();
131
    }
132
  }//DBConnection
133

    
134
  /**
135
   * Method to get the size of DBConnectionPool
136
   */
137
  public int getSizeOfDBConnectionPool()
138
  {
139
    return connectionPool.size();
140
  }
141
  
142
  
143
  /**
144
   * Method to initial a pool of DBConnection objects 
145
   */
146
  private void initialDBConnectionPool() throws SQLException 
147
  {
148

    
149
    DBConnection dbConn = null;
150
    
151
    for ( int i = 0; i < INITIALCONNECTIONNUMBER; i++ ) 
152
    {
153
      //create a new object of DBConnection
154
      //this DBConnection object has a new connection in it
155
      //it automatically generate the createtime and tag
156
      dbConn = new DBConnection();
157
      //put DBConnection into vetor
158
      connectionPool.add(dbConn);
159
    }    
160
    
161
  
162
  }//initialDBConnectionPool
163
  
164
  /**
165
   * Method to get Connection object (Not DBConnection)
166
   */
167
  /*public static Connection getConnection() throws SQLException
168
  {
169
    DBConnection dbConn = null;
170
    //get a DBConnection
171
    dbConn = getDBConnection();
172
    //get connection object in DBConnection object
173
    //The following getConnections method is in DBConnection class
174
    return dbConn.getConnections();
175
  }*/
176
  
177
 
178
  /**
179
   * Method to get a DBConnection in connection pool
180
   * 1) try to get a DBConnection from DBConnection pool
181
   * 2) if 1) failed, then check the size of pool. If the size reach the
182
   *    maximum number of connection, throw a exception: couldn't get one
183
   * 3) If the size is less than the maximum number of connectio, create some
184
   *    new connections and recursive get one
185
   * @param methodName, the name of method which will check connection out
186
   */
187
  public static synchronized DBConnection getDBConnection(String methodName) 
188
                                                throws SQLException
189
  {
190
    DBConnection db = null;
191
    int random = 0; //random number
192
    int index = 0; //index
193
    int size = 0; //size of connection pool
194
    MetaCatUtil.debugMessage("Try to checking out connection...", 45);
195
    size = connectionPool.size();
196
    MetaCatUtil.debugMessage("size of connection pool: "+size, 45);
197
    
198
     //try every DBConnection in the pool
199
    //every DBConnection will be try LIMITE times
200
    for (int j=0 ; j<LIMIT; j++)
201
    {
202
       //create a random number as the started index for connection pool
203
      //So that the connection ofindex of 0 wouldn't be a the heaviest user
204
      random = (new Double (Math.random()*100)).intValue();
205
      for (int i=0; i<size; i++)
206
      {
207
        index =(i+random)%size;
208
        db = (DBConnection) connectionPool.elementAt(index);
209
        MetaCatUtil.debugMessage("Index: "+index, 45);
210
        MetaCatUtil.debugMessage("Tag: "+db.getTag(), 45);
211
        MetaCatUtil.debugMessage("Status: "+db.getStatus(), 45);
212
        //check if the connection is free
213
        if (db.getStatus()==FREE)
214
        {
215
          //If this connection is good, return this DBConnection
216
          if (validateDBConnection(db))
217
          {
218
            
219
            //set this DBConnection status
220
            db.setStatus(BUSY);
221
            //increase checkout serial number
222
            db.increaseCheckOutSerialNumber(1);
223
            //increase one usageCount
224
            db.increaseUsageCount(1);
225
            //set method name to DBConnection
226
            db.setCheckOutMethodName(methodName);
227
            //debug message
228
            MetaCatUtil.debugMessage("The connection is checked out: "
229
                                       +db.getTag(), 35);
230
            MetaCatUtil.debugMessage("The method for checking is: " 
231
                                              +db.getCheckOutMethodName(), 35);
232
            MetaCatUtil.debugMessage("The age is "+db.getAge(), 40);
233
            MetaCatUtil.debugMessage("The usage is "+db.getUsageCount(), 40);
234
            MetaCatUtil.debugMessage("The conection time it has: "
235
                                                +db.getConnectionTime(), 40);
236
            //set check out time
237
            db.setCheckOutTime(System.currentTimeMillis());
238
            //check it out
239
            return db;
240
          }//if
241
          else//The DBConnection has some problem
242
          {
243
            //close this DBConnection
244
            db.close();
245
            //remove it form connection pool
246
            connectionPool.remove(index);
247
            //insert a new DBConnection to same palace
248
            db = new DBConnection();
249
            connectionPool.insertElementAt(db, index);
250
          }//else
251
        }//if
252
      }//for
253
    }//for
254
    
255
    //if couldn't get a connection, we should increase DBConnection pool
256
    //if the connection pool size is less than maximum connection number
257
   
258
    if ( size < MAXIMUMCONNECTIONNUMBER )
259
    {
260
       if ((size+INCREASECONNECTIONNUMBER) < MAXIMUMCONNECTIONNUMBER)
261
       { 
262
         //if we can create INCREASECONNECTIONNUMBER of new DBConnection
263
         //add to connection pool
264
         for ( int i=0; i<INCREASECONNECTIONNUMBER; i++)
265
         {
266
           DBConnection dbConn = new DBConnection();
267
           connectionPool.add(dbConn);
268
         }//for
269
       }//if
270
       else
271
       {
272
         //There is no enough room to increase INCREASECONNECTIONNUMBER 
273
         //we create new DBCoonection to Maximum connection number
274
         for (int i= size+1; i<= MAXIMUMCONNECTIONNUMBER; i++)
275
         {
276
           DBConnection dbConn = new DBConnection();
277
           connectionPool.add(dbConn);
278
         }//for
279
       }//else
280
   
281
    }//if
282
    else
283
    {
284
      /*throw new SQLException("The maximum of " +MAXIMUMCONNECTIONNUMBER + 
285
                            " open db connections is reached." +
286
                            " New db connection to MetaCat" +
287
                            " cannot be established.");*/
288
       MetaCatUtil.debugMessage("The maximum of " +MAXIMUMCONNECTIONNUMBER + 
289
                            " open db connections is reached." +
290
                            " New db connection to MetaCat" +
291
                            " cannot be established.", 1);
292
       return null;
293
       //if couldn't get a connection, sleep 20 seconds and try again.
294
       /*try
295
       {
296
         System.out.println("sleep");
297
         Thread.sleep(2000);
298
       }
299
       catch (Exception e)
300
       {
301
       }*/
302
         
303
      
304
    }//else
305
    
306
    //recursive to get new connection    
307
    return getDBConnection(methodName); 
308
  }//getDBConnection
309

    
310
 
311
  
312
  
313
  /** 
314
   * Method to check if a db connection works fine or not
315
   * Check points include:
316
   * 1. check the usageCount if it is too many
317
   * 2. check the dbconne age if it is too old
318
   * 3. check the connection time if it is too long
319
   * 4. run simple sql query
320
   *
321
   * @param dbConn, the DBConnection object need to check
322
   */
323
  private static boolean validateDBConnection (DBConnection dbConn)
324
  {
325
    
326
    
327
    //Check if the DBConnection usageCount if it is too many
328
    if (dbConn.getUsageCount() >= MAXIMUMUSAGENUMBER )
329
    {
330
      MetaCatUtil.debugMessage("Connection usageCount is too many: "+
331
      dbConn.getUsageCount(), 40);
332
      return false;
333
    }
334
    
335
    //Check if the DBConnection has too much connection time
336
    if (dbConn.getConnectionTime() >= MAXIMUMCONNECTIONTIME)
337
    {
338
      MetaCatUtil.debugMessage("Connection has too much connection time: "+
339
      dbConn.getConnectionTime(), 40);
340
      return false;
341
    }
342
    
343
    //Check if the DBConnection is too old
344
    if (dbConn.getAge() >=MAXIMUMAGE)
345
    {
346
      MetaCatUtil.debugMessage("Connection is too old: "+dbConn.getAge(), 40);
347
      return false;
348
    }
349
    
350
    //Try to run a simple query
351
    try
352
    {
353
      long startTime=System.currentTimeMillis();
354
      DatabaseMetaData metaData = dbConn.getMetaData();
355
      long stopTime=System.currentTimeMillis();
356
      //increase one usagecount
357
      dbConn.increaseUsageCount(1);
358
      //increase connection time
359
      dbConn.setConnectionTime(stopTime-startTime);
360
  
361
    }
362
    catch (Exception e)
363
    {
364
      MetaCatUtil.debugMessage("Error in validateDBConnection: "
365
                                +e.getMessage(), 30);
366
      return false;
367
    }
368
    
369
    return true;
370
    
371
  }//validateDBConnection()
372
  
373
  /**
374
   * Method to return a connection to DBConnection pool.
375
   * @param conn, the Connection object need to check in
376
   */
377
  public static synchronized void returnDBConnection(DBConnection conn, 
378
                                                              int serialNumber)
379
  {
380
    int index = -1;
381
    DBConnection dbConn = null;
382
  
383
    index = getIndexOfPoolForConnection(conn);
384
    if ( index ==-1 )
385
    {
386
      MetaCatUtil.debugMessage("Couldn't find a DBConnection in the pool"
387
                                  +" which have same tag to the returned"
388
                                  +" DBConnetion object", 30);
389
      return;
390
                                  
391
    }//if
392
    else
393
    {
394
      //check the paramter - serialNumber which will be keep in calling method
395
      //if it is as same as the object's checkoutserial number.
396
      //if it is same return it. If it is not same, maybe the connection already
397
      // was returned ealier.
398
      MetaCatUtil.debugMessage("serial number in Connection: "
399
                                      +conn.getCheckOutSerialNumber(), 40);
400
      MetaCatUtil.debugMessage("serial number in local: "+serialNumber, 40);
401
      if (conn.getCheckOutSerialNumber() == serialNumber)
402
      {
403
        dbConn = (DBConnection) connectionPool.elementAt(index);
404
        //set status to free
405
        dbConn.setStatus(FREE);
406
        //count connection time
407
        dbConn.setConnectionTime
408
                          (System.currentTimeMillis()-dbConn.getCheckOutTime());
409
                          
410
        //set check out time to 0
411
        dbConn.setCheckOutTime(0);
412
        
413
        MetaCatUtil.debugMessage("Connection: "+dbConn.getTag()+" checked in.",
414
                                                                        35);
415
         MetaCatUtil.debugMessage("Connection: "+dbConn.getTag()+"'s status: "
416
                                                    +dbConn.getStatus(), 35);
417
                                                                       
418
      }//if
419
      else
420
      {
421
        MetaCatUtil.debugMessage("This DBConnection couldn't return", 30);
422
      }//else
423
    }//else
424
   
425
 
426
  }//returnConnection
427
  
428
  /**
429
   * Given a returned DBConnection, try to find the index of DBConnection object
430
   * in dbConnection pool by comparing DBConnection' tag and conn.toString.
431
   * If couldn't find , -1 will be returned.
432
   * @param conn, the connection need to be found
433
   */
434
  private static synchronized int getIndexOfPoolForConnection(DBConnection conn)
435
  {
436
    int index = -1;
437
    String info = null;
438
    //if conn is null return -1 too
439
    if (conn==null)
440
    {
441
      return -1;
442
    }
443
    //get tag of this returned DBConnection
444
    info = conn.getTag();
445
    //if the tag is null or empty, -1 will be returned
446
    if (info==null || info.equals(""))
447
    {
448
      return index;
449
    }
450
    //compare this info to the tag of every DBConnection in the pool
451
    for ( int i=0; i< connectionPool.size(); i++)
452
    {
453
      DBConnection dbConn = (DBConnection) connectionPool.elementAt(i);
454
      if (info.equals(dbConn.getTag()))
455
      {
456
        index = i;
457
        break;
458
      }//if
459
    }//for
460
    
461
    return index;
462
  }//getIndexOfPoolForConnection  
463
  
464
  /**
465
   * Method to shut down all connections
466
   */
467
  public static void release()
468
  {
469
    
470
    //shut down the backgroud recycle thread
471
    if (DBCONNECTIONRECYCLETHREAD.equals("on"))
472
    {
473
      runner.interrupt();
474
    }
475
    //cose every dbconnection in the pool
476
    synchronized(connectionPool)
477
    {
478
      for (int i=0;i<connectionPool.size();i++)
479
      {
480
        try
481
        {
482
          DBConnection dbConn= (DBConnection) connectionPool.elementAt(i);
483
          dbConn.close();
484
        }//try
485
        catch (SQLException e)
486
        {
487
          MetaCatUtil.debugMessage("Error in release connection: "
488
                                            +e.getMessage(), 10);
489
        }//catch
490
      }//for
491
    }//synchronized
492
  }//release()
493
  
494
  /**
495
   * periodically to recycle the connection
496
   */
497
  public void run()
498
  {
499
    DBConnection dbConn = null;
500
    //keep the thread running
501
    while (true)
502
    {
503
      //check every dbconnection in the pool
504
      synchronized(connectionPool)
505
      {
506
        for (int i=0; i<connectionPool.size(); i++)
507
        {
508
          dbConn = (DBConnection) connectionPool.elementAt(i);
509
          
510
          //if a DBConnection conncectioning time for one check out is greater 
511
          //than 30000 milliseconds print it out
512
          if (dbConn.getStatus()==BUSY && 
513
            (System.currentTimeMillis()-dbConn.getCheckOutTime())>=30000)
514
          {
515
            MetaCatUtil.debugMessage("This DBConnection is checked out for: "
516
            +(System.currentTimeMillis()-dbConn.getCheckOutTime())/1000
517
            +" secs" , 1);
518
            MetaCatUtil.debugMessage(dbConn.getTag(), 1);
519
            MetaCatUtil.debugMessage("method: "
520
                                          +dbConn.getCheckOutMethodName(), 10);
521
            
522
          }
523
          
524
          //check the validation of free connection in the pool
525
          if (dbConn.getStatus() == FREE)
526
          {
527
            try
528
            {
529
              //try to print out the warning message for every connection
530
              if (dbConn.getWarningMessage()!=null)
531
              {
532
                MetaCatUtil.debugMessage("Warning for connection "
533
                  +dbConn.getTag()+" : "+ dbConn.getWarningMessage(), 10);
534
              }
535
              //check if it is valiate, if not create new one and replace old one
536
              if (!validateDBConnection(dbConn))
537
              {
538
                MetaCatUtil.debugMessage("Recyle it: "+ dbConn.getTag(), 40);
539
                //close this DBConnection
540
                dbConn.close();
541
                //remove it form connection pool
542
                connectionPool.remove(i);
543
                //insert a new DBConnection to same palace
544
                dbConn = new DBConnection();
545
                connectionPool.insertElementAt(dbConn, i);
546
               }//if
547
            }//try
548
            catch (SQLException e)
549
            {
550
              MetaCatUtil.debugMessage("Error in DBConnectionPool.run: "
551
                                              +e.getMessage(), 20);
552
            }//catch
553
          }//if
554
        }//for
555
      }//synchronize   
556
      //Thread sleep 
557
      try
558
      {
559
        Thread.sleep(CYCLETIMEOFDBCONNECTION);
560
      }
561
      catch (Exception e)
562
      {
563
        MetaCatUtil.debugMessage("Error in DBConnectionPool.run: "
564
                                              +e.getMessage(), 20);
565
      }
566
    }//while
567
  }//run
568
  
569
  /**
570
   * Method to get the number of free DBConnection in DBConnection pool
571
   */
572
  public static synchronized int getFreeDBConnectionNumber()
573
  {
574
    int numberOfFreeDBConnetion = 0; //return number
575
    DBConnection db = null; //single DBconnection
576
    int poolSize = 0; //size of connection pool
577
    //get the size of DBConnection pool
578
    poolSize = connectionPool.size();
579
    //Check every DBConnection in the pool
580
    for ( int i=0; i<poolSize; i++)
581
    {
582
      
583
      db = (DBConnection) connectionPool.elementAt(i);
584
      //check the status of db. If it is free, count it
585
      if (db.getStatus() == FREE)
586
      {
587
        numberOfFreeDBConnetion++;
588
      }//if
589
    }//for
590
    //return the count result
591
    return numberOfFreeDBConnetion;
592
  }//getFreeDBConnectionNumber
593
      
594
   /**
595
   * Method to print out the method name which have busy DBconnection
596
   */
597
  public void printMethodNameHavingBusyDBConnection()
598
  {
599
    
600
    DBConnection db = null; //single DBconnection
601
    int poolSize = 0; //size of connection pool
602
    //get the size of DBConnection pool
603
    poolSize = connectionPool.size();
604
    //Check every DBConnection in the pool
605
    for ( int i=0; i<poolSize; i++)
606
    {
607
      
608
      db = (DBConnection) connectionPool.elementAt(i);
609
      //check the status of db. If it is free, count it
610
      if (db.getStatus() == BUSY)
611
      {
612
        MetaCatUtil.debugMessage("This method having a busy DBConnection: "
613
                                    +db.getCheckOutMethodName(), 30);
614
        MetaCatUtil.debugMessage("The busy DBConnection tag is: "
615
                                    +db.getTag(), 30);
616
      }//if
617
    }//for
618
  
619
  }//printMethodNameHavingBusyDBConnection
620
  
621
  /**
622
   * Method to decrease dbconnection pool size when all dbconnections are idle
623
   * If all connections are free and connection pool size greater than 
624
   * initial value, shrink connection pool size to intital value
625
   */
626
  public static synchronized boolean shrinkConnectionPoolSize() 
627
  {
628
     int connectionPoolSize = 0; //store the number of dbconnection pool size
629
     int freeConnectionSize = 0; //store the number of free dbconnection in pool
630
     int difference = 0; // store the difference number between connection size
631
                         // and free connection
632
     boolean hasException = false; //to check if has a exception happend
633
     boolean result = false; //result
634
     DBConnection conn = null; // the dbconnection
635
     connectionPoolSize = connectionPool.size();
636
     freeConnectionSize = getFreeDBConnectionNumber();
637
     MetaCatUtil.debugMessage("Connection pool size: " +connectionPoolSize, 3);
638
     MetaCatUtil.debugMessage("Free Connection number: "+freeConnectionSize, 3);
639
     difference = connectionPoolSize - freeConnectionSize;
640
     
641
     //If all connections are free and connection pool size greater than 
642
     //initial value, shrink connection pool size to intital value
643
     if (difference == 0 && connectionPoolSize > INITIALCONNECTIONNUMBER)
644
     {
645
       //db connection having index from  to connectionpoolsize -1
646
       //intialConnectionnumber should be close and remove from pool
647
       for ( int i=connectionPoolSize-1; i >= INITIALCONNECTIONNUMBER ; i--)
648
       {
649
        
650
         //get the dbconnection from pool
651
         conn = (DBConnection) connectionPool.elementAt(i);
652
         
653
         try
654
         {
655
           //close conn
656
           conn.close();
657
         }//try
658
         catch (SQLException e)
659
         { 
660
           // set hadException ture
661
           hasException = true;
662
           MetaCatUtil.debugMessage("Couldn't close a DBConnection in " +
663
                            "DBConnectionPool.shrinkDBConnectionPoolSize: " +
664
                            e.getMessage(), 30);
665
         }//catch
666
                                        
667
        //remove it from pool
668
        connectionPool.remove(i);
669
        // becuase enter the loop, set result true
670
        result = true;
671
       }//for
672
     }//if
673
     
674
     //if hasException is true ( there at least once exception happend)
675
     // the result should be false
676
     if (hasException)
677
     {
678
       result =false;
679
     }//if
680
     // return result
681
     return result;
682
  }//shrinkDBConnectionPoolSize
683
   
684
    /**
685
   * Method to decrease dbconnection pool size when all dbconnections are idle
686
   * If all connections are free and connection pool size greater than 
687
   * initial value, shrink connection pool size to intital value
688
   */
689
  public static synchronized void shrinkDBConnectionPoolSize() 
690
  {
691
     int connectionPoolSize = 0; //store the number of dbconnection pool size
692
     int freeConnectionSize = 0; //store the number of free dbconnection in pool
693
     int difference = 0; // store the difference number between connection size
694
                         // and free connection
695
    
696
     DBConnection conn = null; // the dbconnection
697
     connectionPoolSize = connectionPool.size();
698
     freeConnectionSize = getFreeDBConnectionNumber();
699
     MetaCatUtil.debugMessage("Connection pool size: " +connectionPoolSize, 3);
700
     MetaCatUtil.debugMessage("Free Connection number: "+freeConnectionSize, 3);
701
     difference = connectionPoolSize - freeConnectionSize;
702
     
703
     //If all connections are free and connection pool size greater than 
704
     //initial value, shrink connection pool size to intital value
705
     if (difference == 0 && connectionPoolSize > INITIALCONNECTIONNUMBER)
706
     {
707
       //db connection having index from  to connectionpoolsize -1
708
       //intialConnectionnumber should be close and remove from pool
709
       for ( int i=connectionPoolSize-1; i >= INITIALCONNECTIONNUMBER ; i--)
710
       {
711
        
712
         //get the dbconnection from pool
713
         conn = (DBConnection) connectionPool.elementAt(i);
714
         //make sure again the DBConnection status is free
715
         if (conn.getStatus()==FREE)
716
         {
717
           try
718
           {
719
             //close conn
720
             conn.close();
721
           }//try
722
           catch (SQLException e)
723
           { 
724
          
725
             MetaCatUtil.debugMessage("Couldn't close a DBConnection in " +
726
                            "DBConnectionPool.shrinkDBConnectionPoolSize: " +
727
                            e.getMessage(), 30);
728
           }//catch
729
        
730
           //remove it from pool
731
           connectionPool.remove(i);
732
         }//if
733
       
734
       }//for
735
     }//if
736
     
737
    
738
  }//shrinkDBConnectionPoolSize
739
   
740
  
741
}//DBConnectionPool
(14-14/43)