View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/conprovider/SingleConnectionProvider.java,v 1.11 2006/01/25 20:09:50 hkollmann Exp $
3    * $Revision: 1.11 $
4    * $Date: 2006/01/25 20:09:50 $
5    *
6    * DbForms - a Rapid Application Development Framework
7    * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8    *
9    * This library is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU Lesser General Public
11   * License as published by the Free Software Foundation; either
12   * version 2.1 of the License, or (at your option) any later version.
13   *
14   * This library is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this library; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22   */
23  
24  package org.dbforms.conprovider;
25  
26  import java.sql.Connection;
27  import java.sql.DriverManager;
28  import java.sql.ResultSet;
29  import java.sql.SQLException;
30  import java.sql.Statement;
31  
32  import java.util.Date;
33  import java.util.Properties;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.dbforms.util.Util;
38  
39  
40  
41  
42  /***
43   * Single Connection provider. <br> provides one connection for all
44   *
45   * @author Henner Kollmann
46   */
47  public class SingleConnectionProvider extends AbstractConnectionProvider {
48     private static Connection con;
49     private static Date conNextValidationDate;
50     private static Log logCat = LogFactory.getLog(SinglePerThreadConnectionProvider.class);
51  
52     
53     /***
54      * Default constructor.
55      *
56      * @exception Exception Description of the Exception
57      * @throws Exception because of the <code>throws Exception</code> clause of
58      *         the  <code>init</code> method.
59      */
60     public SingleConnectionProvider() throws Exception {
61        super();
62     }
63  
64     /***
65      * Get a JDBC Connection
66      *
67      * @return a JDBC Connection
68      *
69      * @exception SQLException Description of the Exception
70      */
71     protected synchronized Connection getConnection() throws SQLException {
72  		long validationInterval;
73  		// Get Validation Interval from the config and convert to seconds.
74  		// Default interval is six hours (21,600,000 milliseconds).
75  		try {
76  			validationInterval = Long.parseLong(getPrefs().getPoolProperties()
77  					.getProperty("validationInterval", "21600"));
78  			// Convert from seconds as expressed in property to milliseconds.
79  			validationInterval = validationInterval * 1000;
80  		} catch (NumberFormatException ex) {
81  			validationInterval = 21600000;
82  		}
83  
84  		Date rightNow = new Date();
85  		// Initialise the validation check time, validationInterval into the
86  		// future from now.
87  		if (conNextValidationDate == null) {
88  			conNextValidationDate = new Date(validationInterval + rightNow.getTime());
89  		}
90  
91  		if (con != null && conNextValidationDate.before(rightNow)) {
92  			conNextValidationDate.setTime(validationInterval
93  					+ rightNow.getTime());
94  			String validationQuery = getPrefs().getPoolProperties().getProperty("validationQuery", "");
95  			if (!Util.isNull(validationQuery)) {
96  				logCat.debug("Testing connection: checking validation timestamp='"
97  								+ rightNow.toString() + "'.");
98  				logCat.debug("Testing connection: next validation check='"
99  						+ conNextValidationDate.toString() + "'.");
100 				logCat.debug("Testing connection: validationQuery='"
101 						+ validationQuery + "'.");
102 				// Test the connection.
103 				try {
104 					Statement st = con.createStatement();
105 					ResultSet rs = st.executeQuery(validationQuery);
106 					try {
107 						rs.next();
108 						logCat.debug("Testing connection: Connection is valid.");
109 					} finally {
110 						rs.close();
111 						st.close();
112 					}
113 				} catch (SQLException sqlex) {
114 					// Exception, so close the connection and set to null
115 					// so it is recreated in the body of the "if (con == null)"
116 					// below.
117 					logCat.debug("Testing connection: Connection is invalid. Forcing recreate.");
118 					con.close();
119 					con = null;
120 				}
121 			}
122 		}
123 	   
124 	   if (con == null) {
125          Properties props = getPrefs()
126                                .getProperties();
127 
128          // uses custom jdbc properties;
129          if ((props != null) && !props.isEmpty()) {
130             props.put("user", getPrefs().getUser());
131             props.put("password", getPrefs().getPassword());
132             con = DriverManager.getConnection(getPrefs().getJdbcURL(), props);
133          }
134          // "plain" flavour;
135          else {
136             con = DriverManager.getConnection(getPrefs().getJdbcURL(),
137                                               getPrefs().getUser(),
138                                               getPrefs().getPassword());
139          }
140       }
141 
142       return new SingleConnectionWrapper(con);
143    }
144 
145 
146    /***
147     * Initialize the ConnectionProvider.
148     *
149     * @throws Exception if any error occurs
150     */
151    protected void init() throws Exception {
152       Class.forName(getPrefs().getJdbcDriver())
153            .newInstance();
154    }
155 }