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
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 import org.dbforms.util.Util;
31
32 import java.sql.Connection;
33 import java.sql.DriverManager;
34 import java.sql.SQLException;
35
36 import java.util.Enumeration;
37 import java.util.Hashtable;
38 import java.util.Properties;
39
40
41
42 /***
43 * Connection provider for Protomatter Connection pool. <br>
44 * See <code>http://protomatter.sourceforge.net/</code> for further
45 * informations.
46 *
47 * @author Luca Fossato
48 */
49 public class ProtomatterConnectionProvider extends AbstractConnectionProvider {
50 /*** the initial pool size (default is 0) */
51 protected static final String CP_PROPS_INITIALSIZE = "pool.initialSize";
52
53 /***
54 * the max pool size (default is -1). If the max pool size is -1, the pool
55 * grows infinitely.
56 */
57 protected static final String CP_PROPS_MAXSIZE = "pool.maxSize";
58
59 /***
60 * the grow size (default is 1). When a new object is needed, this many are
61 * created.
62 */
63 protected static final String CP_PROPS_GROWBLOCK = "pool.growBlock";
64
65 /***
66 * the time (in ms) to sleep between pool object creates (default is 0).
67 * This is useful for database connection pools where it's possible to
68 * overload the database by trying to make too many connections too
69 * quickly.
70 */
71 protected static final String CP_PROPS_CREATEWAITTIME = "pool.createWaitTime";
72
73 /***
74 * A SQL statement that is guaranteed to return at least 1 row. For Oracle,
75 * this is "select 1 from dual" and for Sybase it is "select 1". This
76 * statement is used as a means of checking that a connection is indeed
77 * working.
78 */
79 protected static final String CP_PROPS_VALIDITYCHECKSTATEMENT = "jdbc.validityCheckStatement";
80
81 /***
82 * If this property is present, and the
83 * <code>pool.maidThreadCheckInterval</code> property is also present, then
84 * a thread will be created that looks for connections that have been idle
85 * for more than <code>pool.maxConnectionIdleTime</code> seconds. When this
86 * thread finds them, it closed the connection and logs a warning with a
87 * stack trace of when the connection was checked out of the pool. This is
88 * primarily here as a debugging aid for finding places where connections
89 * are not getting close, and should not be used in a production
90 * environment
91 */
92 protected static final String CP_PROPS_MAXCONNECTIONIDLETIME = "pool.maxConnectionIdleTime";
93
94 /***
95 * this is the number of seconds between attempts by the maid thread (if
96 * present) to find idle connections.
97 */
98 protected static final String CP_PROPS_MAIDTHREADCHECKINTERVAL = "pool.maidThreadCheckInterval";
99
100 /*** connection pool driver class */
101 private static final String CP_DRIVER = "com.protomatter.jdbc.pool.JdbcConnectionPoolDriver";
102
103 /*** Protomatter connectionPool */
104 private static Log logCat = LogFactory.getLog(ProtomatterConnectionProvider.class);
105
106 /***
107 * Default constructor.
108 *
109 * @exception Exception Description of the Exception
110 * @throws Exception because of the <code>throws Exception</code> clause of
111 * the <code>init</code> method.
112 */
113 public ProtomatterConnectionProvider() throws Exception {
114 super();
115 }
116
117 /***
118 * Get a JDBC Connection
119 *
120 * @return a JDBC Connection
121 *
122 * @exception SQLException Description of the Exception
123 */
124 protected Connection getConnection() throws SQLException {
125 return DriverManager.getConnection(getPrefs().getConnectionPoolURL(),
126 getPrefs().getUser(),
127 getPrefs().getPassword());
128 }
129
130
131 /***
132 * Initialize the Protomatter connection pool.
133 *
134 * @throws Exception if any error occurs
135 */
136 protected void init() throws Exception {
137 Properties props = null;
138
139
140 Hashtable args = new Hashtable();
141
142
143 args.put("jdbc.driver", getPrefs().getJdbcDriver());
144
145
146 args.put("jdbc.URL", getPrefs().getJdbcURL());
147
148
149 Properties jdbcProperties = new Properties();
150 jdbcProperties.put("user", getPrefs().getUser());
151 jdbcProperties.put("password", getPrefs().getPassword());
152
153
154 if ((props = getPrefs()
155 .getProperties()) != null) {
156 for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
157 String key = (String) e.nextElement();
158 jdbcProperties.put(key, props.getProperty(key));
159 logCat.info("::init - JDBC property [" + key + "] = ["
160 + props.getProperty(key) + "]");
161 }
162 }
163
164 args.put("jdbc.properties", jdbcProperties);
165
166
167
168
169 if ((props = getPrefs()
170 .getPoolProperties()) == null) {
171 props = new Properties();
172 }
173
174
175 setIntegerArg(args, props, CP_PROPS_INITIALSIZE, "0");
176 setIntegerArg(args, props, CP_PROPS_MAXSIZE, "-1");
177 setIntegerArg(args, props, CP_PROPS_GROWBLOCK, "1");
178 setIntegerArg(args, props, CP_PROPS_CREATEWAITTIME, "0");
179 setArg(args, props, CP_PROPS_VALIDITYCHECKSTATEMENT, null);
180 setIntegerArg(args, props, CP_PROPS_MAXCONNECTIONIDLETIME, null);
181 setIntegerArg(args, props, CP_PROPS_MAIDTHREADCHECKINTERVAL, null);
182
183
184 Class.forName(CP_DRIVER).newInstance();
185 }
186
187
188 /***
189 * Set a new String value into the input hashTable.
190 *
191 * @param args the hashTable where to put the value
192 * @param props the properties object where to retrieve the value;
193 * @param key the key value used to retrieve the value from the props
194 * object. The same key is used to store the retrieved value into
195 * the args hashMap
196 * @param defValue the default value to use if the input key does not
197 * retrieve a valid value from the props object
198 */
199 private final void setArg(Hashtable args,
200 Properties props,
201 String key,
202 String defValue) {
203 String value = props.getProperty(key, defValue);
204
205 if (!Util.isNull(value)) {
206 args.put(key, value);
207 logCat.info("::setArg - [" + key + "] = [" + value + "]");
208 }
209 }
210
211
212 /***
213 * Set a new Integer value into the input hashTable.
214 *
215 * @param args the hashTable where to put the value
216 * @param props the properties object where to retrieve the value;
217 * @param key the key value used to retrieve the value from the props
218 * object. The same key is used to store the retrieved value into
219 * the args hashMap
220 * @param defValue the default value to use if the input key does not
221 * retrieve a valid value from the props object
222 */
223 private final void setIntegerArg(Hashtable args,
224 Properties props,
225 String key,
226 String defValue) {
227 String value = props.getProperty(key, defValue);
228
229 if (!Util.isNull(value)) {
230 args.put(key, new Integer(value));
231 logCat.info("::setIntegerArg - [" + key + "] = [" + value + "]");
232 }
233 }
234 }