1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 import java.util.Date;
32 import java.util.Properties;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37 import org.dbforms.util.Util;
38
39 /***
40 * Single Connection per thread provider. <br>
41 * provides one connection for all
42 *
43 * @author Henner Kollmann
44 */
45 public class SinglePerThreadConnectionProvider extends
46 AbstractConnectionProvider {
47 private static final ThreadLocal singlePerThread = new ThreadLocal();
48 private static final ThreadLocal singlePerThreadDateNext = new ThreadLocal();
49 private static Log logCat = LogFactory.getLog(SinglePerThreadConnectionProvider.class);
50
51
52
53 /***
54 * Default constructor.
55 *
56 * @exception Exception
57 * Description of the Exception
58 * @throws Exception
59 * because of the <code>throws Exception</code> clause of the
60 * <code>init</code> method.
61 */
62 public SinglePerThreadConnectionProvider() throws Exception {
63 super();
64 }
65
66 /***
67 * Get a JDBC Connection
68 *
69 * @return a JDBC Connection
70 *
71 * @exception SQLException
72 * Description of the Exception
73 */
74 protected synchronized Connection getConnection() throws SQLException {
75 Connection con = (Connection) singlePerThread.get();
76
77 long validationInterval;
78
79
80 try {
81 validationInterval = Long.parseLong(getPrefs().getPoolProperties()
82 .getProperty("validationInterval", "21600"));
83
84 validationInterval = validationInterval * 1000;
85 } catch (NumberFormatException ex) {
86 validationInterval = 21600000;
87 }
88
89 Date rightNow = new Date();
90 Date conNextValidationDate = (Date) singlePerThreadDateNext.get();
91
92
93 if (conNextValidationDate == null) {
94 conNextValidationDate = new Date(validationInterval
95 + rightNow.getTime());
96 ;
97 singlePerThreadDateNext.set(conNextValidationDate);
98 }
99
100 if (con != null && conNextValidationDate.before(rightNow)) {
101 conNextValidationDate.setTime(validationInterval
102 + rightNow.getTime());
103 String validationQuery = getPrefs().getPoolProperties()
104 .getProperty("validationQuery", "");
105 if (!Util.isNull(validationQuery)) {
106 logCat.debug("Testing connection: checking validation timestamp='"
107 + rightNow.toString() + "'.");
108 logCat.debug("Testing connection: next validation check='"
109 + conNextValidationDate.toString() + "'.");
110 logCat.debug("Testing connection: validationQuery='"
111 + validationQuery + "'.");
112
113 try {
114 Statement st = con.createStatement();
115 ResultSet rs = st.executeQuery(validationQuery);
116 try {
117 rs.next();
118 logCat.debug("Testing connection: Connection is valid.");
119 } finally {
120 rs.close();
121 st.close();
122 }
123 } catch (SQLException sqlex) {
124
125
126
127 logCat.debug("Testing connection: Connection is invalid. Forcing recreate.");
128 con.close();
129 con = null;
130 }
131 }
132 }
133
134 if (con == null) {
135 Properties props = getPrefs().getProperties();
136
137 if ((props != null) && !props.isEmpty()) {
138 props.put("user", getPrefs().getUser());
139 props.put("password", getPrefs().getPassword());
140 con = DriverManager.getConnection(getPrefs().getJdbcURL(),
141 props);
142 }
143
144 else {
145 con = DriverManager.getConnection(getPrefs().getJdbcURL(),
146 getPrefs().getUser(), getPrefs().getPassword());
147 }
148
149 singlePerThread.set(con);
150 }
151
152 return new SingleConnectionWrapper(con);
153 }
154
155 /***
156 * Initialize the ConnectionProvider.
157 *
158 * @throws Exception
159 * if any error occurs
160 */
161 protected void init() throws Exception {
162 Class.forName(getPrefs().getJdbcDriver()).newInstance();
163 }
164 }