
/*==============================================================================*
 *																				*
 *  说明：此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最大连接数*
 *        为止.在返回连接给客户程序之前,它能够验证连接的有效性.                 *
 *  功能：																		*
 *        1、从连接池获取（如果需要则先创建）JDBC连接;							*
 *		  2、把连接返回给连接池													*
 *		  3、释放所有资源，关闭所有JDBC连接										*
 *																				*
 *==============================================================================*/ 
 
package  com.Quincy.common.pools;

import java.util.Vector;
import java.util.Date;
import java.util.Enumeration;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;
import com.Quincy.common.pools.dbPoolConstants;

public class dbConnPool implements dbPoolConstants
{ 
  		private int checkedOut; 
  		private Vector freeConnections = new Vector(); 
  		private dbLogging DBLogFile=new dbLogging();
  		private int maxConn; 
  		private String name; 
  		private String password; 
  		private String URL; 
  		private String user; 

		/* =============================================================================
		 * 作用：创建新的连接池  
 	 	 * 参数：name     连接池名字，
 	 	 		 URL      数据库的JDBC URL，
 	 	 		 user     数据库帐号(或null)，
 	 	 		 password 密码(或null)，
 	 	 		 maxConn  此连接池允许建立的最大连接数 
 	 	 * 返回：无
 		 =============================================================================*/ 
		public dbConnPool(String name, String URL, String user, String password, int maxConn) 
		{ 
  			this.name = name; 
  			this.URL = URL; 
  			this.user = user; 
  			this.password = password; 
  			this.maxConn = maxConn; 
  			DBLogFile.setLogFilePath(DB_POOL_LOG_FILE);
		} 	

		/* =============================================================================
		   作用：将不再使用的连接返回给连接池 
		   参数：con 客户程序释放的连接  
		   返回：无
		=============================================================================*/ 
		public synchronized void freeConnection(Connection con) 
		{ 
  			freeConnections.addElement(con); //将指定连接加入到向量末尾 
  			checkedOut--; 
  			notifyAll(); 
		}
		 
		/*=============================================================================
		  作用：从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接数限制,
		        则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,然后递归调用
		        自己以尝试新的可用连接.
		  参数：无
		  返回：无      
		 =============================================================================*/ 
		public synchronized Connection getConnection() 
		{ 
  			Connection con = null; 
  			if (freeConnections.size() > 0) 
  			{ 
    			// 获取向量中第一个可用连接 
    			con = (Connection) freeConnections.firstElement(); 
    			freeConnections.removeElementAt(0); 
    			try 
    			{ 
      				if (con.isClosed()) 
      				{ 
        				DBLogFile.Logging("从连接池"+name+"删除一个无效连接"); 
        				con = getConnection();// 递归调用自己,尝试再次获取可用连接  
      				} 
    			} 
    			catch (SQLException e) 
    			{ 
      				DBLogFile.Logging("从连接池" + name+"删除一个无效连接"); 
      				con = getConnection(); // 递归调用自己,尝试再次获取可用连接 
    			} 
  			} 
  			else 
  				if (maxConn == 0 || checkedOut < maxConn) { con = newConnection(); 	} 
  			if (con != null) 
  			{ 
    			checkedOut++; 
  			} 
  			return con; 
		} 

		/* =============================================================================
		  作用：从连接池获取可用连接.可以指定客户程序能够等待的最长时间参见前一个getConnection()方法. 
		  参数：timeout 以毫秒计的等待时间限制 
		  返回：无
		=============================================================================*/ 
		public synchronized Connection getConnection(long timeout) 
		{ 
  			long startTime = new Date().getTime(); 
  			Connection con; 
  			while ((con = getConnection()) == null) 
  			{ 
    			try 
    			{ 
      				wait(timeout); 
    			} 
    			catch (InterruptedException e) {} 
    			if ((new Date().getTime() - startTime) >= timeout) 
    			{ 
	      			// wait()返回的原因是超时 
    	  			return null; 
    			} 
  			} 
  			return con; 
		} 

		/*=============================================================================
		 作用：关闭所有连接 
		 参数：无
		 返回：无
		=============================================================================*/ 
		public synchronized void release() 
		{ 
  			Enumeration allConnections = freeConnections.elements(); 
  			while (allConnections.hasMoreElements()) 
  			{ 
    			Connection con = (Connection) allConnections.nextElement(); 
    			try 
    			{ 
	   	   			con.close(); 
    	  			DBLogFile.Logging("关闭连接池" + name+"中的一个连接"); 
    			} 
    			catch (SQLException e) 
    			{ 
		      		DBLogFile.Logging(e, "无法关闭连接池" + name+"中的连接"); 
    			} 
  			} 
  			freeConnections.removeAllElements(); 
		} 

		/*=============================================================================
		 作用：创建新的连接 
		 参数：无
		 返回：无
		=============================================================================*/ 
		private Connection newConnection() 
		{ 
  			Connection con = null; 
  			try 
  			{ 
    			if (user == null) { 
      				con = DriverManager.getConnection(URL); 
    			} 
    			else 
    			{ 
      				con = DriverManager.getConnection(URL, user, password); 
    			} 
    			DBLogFile.Logging("连接池" + name+"创建一个新的连接"); 
  			} 
  			catch (SQLException e) 
  			{ 
    			DBLogFile.Logging(e, "无法创建下列URL的连接: " + URL); 
    			return null; 
  			} 
  			return con; 
		} 
} 