View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.dbcp;
19  
20  import java.sql.Connection;
21  import java.sql.Statement;
22  import java.sql.ResultSet;
23  import java.sql.SQLException;
24  import java.util.Collection;
25  import java.util.Iterator;
26  import org.apache.commons.pool.KeyedObjectPool;
27  import org.apache.commons.pool.KeyedObjectPoolFactory;
28  import org.apache.commons.pool.PoolableObjectFactory;
29  import org.apache.commons.pool.ObjectPool;
30  
31  /**
32   * A {@link PoolableObjectFactory} that creates
33   * {@link PoolableConnection}s.
34   *
35   * @author Rodney Waldhoff
36   * @author Glenn L. Nielsen
37   * @author James House
38   * @author Dirk Verbeeck
39   * @version $Revision: 1023401 $ $Date: 2010-10-16 21:54:24 -0400 (Sat, 16 Oct 2010) $
40   */
41  public class PoolableConnectionFactory implements PoolableObjectFactory {
42      /**
43       * Create a new <tt>PoolableConnectionFactory</tt>.
44       * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
45       * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
46       * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
47       * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
48       * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
49       * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
50       */
51      public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, boolean defaultReadOnly, boolean defaultAutoCommit) {
52          _connFactory = connFactory;
53          _pool = pool;
54          _pool.setFactory(this);
55          _stmtPoolFactory = stmtPoolFactory;
56          _validationQuery = validationQuery;
57          _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
58          _defaultAutoCommit = defaultAutoCommit;
59      }
60  
61      /**
62       * Create a new <tt>PoolableConnectionFactory</tt>.
63       * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
64       * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
65       * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
66       * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
67       * @param connectionInitSqls a Collection of SQL statements to initialize {@link Connection}s. Using <tt>null</tt> turns off initialization.
68       * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
69       * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
70       * @since 1.3
71       */
72      public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, Collection connectionInitSqls, boolean defaultReadOnly, boolean defaultAutoCommit) {
73          _connFactory = connFactory;
74          _pool = pool;
75          _pool.setFactory(this);
76          _stmtPoolFactory = stmtPoolFactory;
77          _validationQuery = validationQuery;
78          _connectionInitSqls = connectionInitSqls;
79          _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
80          _defaultAutoCommit = defaultAutoCommit;
81      }
82      
83      /**
84       * Create a new <tt>PoolableConnectionFactory</tt>.
85       * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
86       * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
87       * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
88       * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
89       * @param validationQueryTimeout the number of seconds that validation queries will wait for database response before failing.  Use a value less than or equal to 0 for no timeout.
90       * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
91       * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
92       * @since 1.3
93       */
94      public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, int validationQueryTimeout, boolean defaultReadOnly, boolean defaultAutoCommit) {
95          _connFactory = connFactory;
96          _pool = pool;
97          _pool.setFactory(this);
98          _stmtPoolFactory = stmtPoolFactory;
99          _validationQuery = validationQuery;
100         _validationQueryTimeout = validationQueryTimeout;
101         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
102         _defaultAutoCommit = defaultAutoCommit;
103     }
104     
105     /**
106      * Create a new <tt>PoolableConnectionFactory</tt>.
107      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
108      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
109      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
110      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
111      * @param validationQueryTimeout the number of seconds that validation queries will wait for database response before failing.  Use a value less than or equal to 0 for no timeout.
112      * @param connectionInitSqls a Collection of SQL statements to initialize {@link Connection}s. Using <tt>null</tt> turns off initialization.
113      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
114      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
115      * @since 1.3
116      */
117     public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, int validationQueryTimeout, Collection connectionInitSqls, boolean defaultReadOnly, boolean defaultAutoCommit) {
118         _connFactory = connFactory;
119         _pool = pool;
120         _pool.setFactory(this);
121         _stmtPoolFactory = stmtPoolFactory;
122         _validationQuery = validationQuery;
123         _validationQueryTimeout = validationQueryTimeout;
124         _connectionInitSqls = connectionInitSqls;
125         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
126         _defaultAutoCommit = defaultAutoCommit;
127     }
128 
129     /**
130      * Create a new <tt>PoolableConnectionFactory</tt>.
131      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
132      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
133      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
134      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
135      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
136      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
137      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
138      */
139     public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, boolean defaultReadOnly, boolean defaultAutoCommit, int defaultTransactionIsolation) {
140         _connFactory = connFactory;
141         _pool = pool;
142         _pool.setFactory(this);
143         _stmtPoolFactory = stmtPoolFactory;
144         _validationQuery = validationQuery;
145         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
146         _defaultAutoCommit = defaultAutoCommit;
147         _defaultTransactionIsolation = defaultTransactionIsolation;
148     }
149 
150     /**
151      * Create a new <tt>PoolableConnectionFactory</tt>.
152      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
153      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
154      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
155      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
156      * @param connectionInitSqls a Collection of SQL statement to initialize {@link Connection}s. Using <tt>null</tt> turns off initialization.
157      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
158      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
159      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
160      * @since 1.3
161      */
162     public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, Collection connectionInitSqls, boolean defaultReadOnly, boolean defaultAutoCommit, int defaultTransactionIsolation) {
163         _connFactory = connFactory;
164         _pool = pool;
165         _pool.setFactory(this);
166         _stmtPoolFactory = stmtPoolFactory;
167         _validationQuery = validationQuery;
168         _connectionInitSqls = connectionInitSqls;
169         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
170         _defaultAutoCommit = defaultAutoCommit;
171         _defaultTransactionIsolation = defaultTransactionIsolation;
172     }
173     
174     /**
175      * Create a new <tt>PoolableConnectionFactory</tt>.
176      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
177      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
178      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
179      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
180      * @param validationQueryTimeout the number of seconds that validation queries will wait for database response before failing.  Use a value less than or equal to 0 for no timeout.
181      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
182      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
183      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
184      * @since 1.3
185      */
186     public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, int validationQueryTimeout, boolean defaultReadOnly, boolean defaultAutoCommit, int defaultTransactionIsolation) {
187         _connFactory = connFactory;
188         _pool = pool;
189         _pool.setFactory(this);
190         _stmtPoolFactory = stmtPoolFactory;
191         _validationQuery = validationQuery;
192         _validationQueryTimeout = validationQueryTimeout;
193         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
194         _defaultAutoCommit = defaultAutoCommit;
195         _defaultTransactionIsolation = defaultTransactionIsolation;
196     }
197     
198     /**
199      * Create a new <tt>PoolableConnectionFactory</tt>.
200      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
201      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
202      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
203      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
204      * @param validationQueryTimeout the number of seconds that validation queries will wait for database response before failing.  Use a value less than or equal to 0 for no timeout.
205      * @param connectionInitSqls a Collection of SQL statement to initialize {@link Connection}s. Using <tt>null</tt> turns off initialization.
206      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
207      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
208      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
209      * @since 1.3
210      */
211     public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, int validationQueryTimeout, Collection connectionInitSqls, boolean defaultReadOnly, boolean defaultAutoCommit, int defaultTransactionIsolation) {
212         _connFactory = connFactory;
213         _pool = pool;
214         _pool.setFactory(this);
215         _stmtPoolFactory = stmtPoolFactory;
216         _validationQuery = validationQuery;
217         _validationQueryTimeout = validationQueryTimeout;
218         _connectionInitSqls = connectionInitSqls;
219         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
220         _defaultAutoCommit = defaultAutoCommit;
221         _defaultTransactionIsolation = defaultTransactionIsolation;
222     }
223 
224     /**
225      * Create a new <tt>PoolableConnectionFactory</tt>.
226      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
227      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
228      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
229      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
230      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
231      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
232      * @param config the AbandonedConfig if tracing SQL objects
233      */
234     public PoolableConnectionFactory(
235         ConnectionFactory connFactory,
236         ObjectPool pool,
237         KeyedObjectPoolFactory stmtPoolFactory,
238         String validationQuery,
239         boolean defaultReadOnly,
240         boolean defaultAutoCommit,
241         AbandonedConfig config) {
242 
243         _connFactory = connFactory;
244         _pool = pool;
245         _config = config;
246         _pool.setFactory(this);
247         _stmtPoolFactory = stmtPoolFactory;
248         _validationQuery = validationQuery;
249         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
250         _defaultAutoCommit = defaultAutoCommit;
251     }
252 
253     /**
254      * Create a new <tt>PoolableConnectionFactory</tt>.
255      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
256      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
257      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
258      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
259      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
260      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
261      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
262      * @param config the AbandonedConfig if tracing SQL objects
263      */
264     public PoolableConnectionFactory(
265         ConnectionFactory connFactory,
266         ObjectPool pool,
267         KeyedObjectPoolFactory stmtPoolFactory,
268         String validationQuery,
269         boolean defaultReadOnly,
270         boolean defaultAutoCommit,
271         int defaultTransactionIsolation,
272         AbandonedConfig config) {
273 
274         _connFactory = connFactory;
275         _pool = pool;
276         _config = config;
277         _pool.setFactory(this);
278         _stmtPoolFactory = stmtPoolFactory;
279         _validationQuery = validationQuery;
280         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
281         _defaultAutoCommit = defaultAutoCommit;
282         _defaultTransactionIsolation = defaultTransactionIsolation;
283     }
284 
285     /**
286      * Create a new <tt>PoolableConnectionFactory</tt>.
287      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
288      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
289      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
290      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
291      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
292      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
293      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
294      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
295      * @param config the AbandonedConfig if tracing SQL objects
296      */
297     public PoolableConnectionFactory(
298         ConnectionFactory connFactory,
299         ObjectPool pool,
300         KeyedObjectPoolFactory stmtPoolFactory,
301         String validationQuery,
302         boolean defaultReadOnly,
303         boolean defaultAutoCommit,
304         int defaultTransactionIsolation,
305         String defaultCatalog,
306         AbandonedConfig config) {
307 
308         _connFactory = connFactory;
309         _pool = pool;
310         _config = config;
311         _pool.setFactory(this);
312         _stmtPoolFactory = stmtPoolFactory;
313         _validationQuery = validationQuery;
314         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
315         _defaultAutoCommit = defaultAutoCommit;
316         _defaultTransactionIsolation = defaultTransactionIsolation;
317         _defaultCatalog = defaultCatalog;
318     }
319 
320     /**
321      * Create a new <tt>PoolableConnectionFactory</tt>.
322      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
323      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
324      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
325      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
326      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
327      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
328      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
329      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
330      * @param config the AbandonedConfig if tracing SQL objects
331      */
332     public PoolableConnectionFactory(
333         ConnectionFactory connFactory,
334         ObjectPool pool,
335         KeyedObjectPoolFactory stmtPoolFactory,
336         String validationQuery,
337         Boolean defaultReadOnly,
338         boolean defaultAutoCommit,
339         int defaultTransactionIsolation,
340         String defaultCatalog,
341         AbandonedConfig config) {
342 
343         _connFactory = connFactory;
344         _pool = pool;
345         _config = config;
346         _pool.setFactory(this);
347         _stmtPoolFactory = stmtPoolFactory;
348         _validationQuery = validationQuery;
349         _defaultReadOnly = defaultReadOnly;
350         _defaultAutoCommit = defaultAutoCommit;
351         _defaultTransactionIsolation = defaultTransactionIsolation;
352         _defaultCatalog = defaultCatalog;
353     }
354 
355     /**
356      * Create a new <tt>PoolableConnectionFactory</tt>.
357      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
358      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
359      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
360      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
361      * @param connectionInitSqls a Collection of SQL statements to initialize {@link Connection}s. Using <tt>null</tt> turns off initialization.
362      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
363      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
364      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
365      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
366      * @param config the AbandonedConfig if tracing SQL objects
367      * @since 1.3
368      */
369     public PoolableConnectionFactory(
370         ConnectionFactory connFactory,
371         ObjectPool pool,
372         KeyedObjectPoolFactory stmtPoolFactory,
373         String validationQuery,
374         Collection connectionInitSqls,
375         Boolean defaultReadOnly,
376         boolean defaultAutoCommit,
377         int defaultTransactionIsolation,
378         String defaultCatalog,
379         AbandonedConfig config) {
380 
381         _connFactory = connFactory;
382         _pool = pool;
383         _config = config;
384         _pool.setFactory(this);
385         _stmtPoolFactory = stmtPoolFactory;
386         _validationQuery = validationQuery;
387         _connectionInitSqls = connectionInitSqls;
388         _defaultReadOnly = defaultReadOnly;
389         _defaultAutoCommit = defaultAutoCommit;
390         _defaultTransactionIsolation = defaultTransactionIsolation;
391         _defaultCatalog = defaultCatalog;
392     }
393     
394     /**
395      * Create a new <tt>PoolableConnectionFactory</tt>.
396      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
397      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
398      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
399      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
400      * @param validationQueryTimeout the number of seconds that validation queries will wait for database response before failing.  Use a value less than or equal to 0 for no timeout.
401      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
402      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
403      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
404      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
405      * @param config the AbandonedConfig if tracing SQL objects
406      * @since 1.3
407      */
408     public PoolableConnectionFactory(
409         ConnectionFactory connFactory,
410         ObjectPool pool,
411         KeyedObjectPoolFactory stmtPoolFactory,
412         String validationQuery,
413         int validationQueryTimeout,
414         Boolean defaultReadOnly,
415         boolean defaultAutoCommit,
416         int defaultTransactionIsolation,
417         String defaultCatalog,
418         AbandonedConfig config) {
419 
420         _connFactory = connFactory;
421         _pool = pool;
422         _config = config;
423         _pool.setFactory(this);
424         _stmtPoolFactory = stmtPoolFactory;
425         _validationQuery = validationQuery;
426         _validationQueryTimeout = validationQueryTimeout;
427         _defaultReadOnly = defaultReadOnly;
428         _defaultAutoCommit = defaultAutoCommit;
429         _defaultTransactionIsolation = defaultTransactionIsolation;
430         _defaultCatalog = defaultCatalog;
431     }
432     
433     /**
434      * Create a new <tt>PoolableConnectionFactory</tt>.
435      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
436      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
437      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
438      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
439      * @param validationQueryTimeout the number of seconds that validation queries will wait for database response before failing.  Use a value less than or equal to 0 for no timeout.
440      * @param connectionInitSqls a Collection of SQL statements to initialize {@link Connection}s. Using <tt>null</tt> turns off initialization.
441      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
442      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
443      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
444      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
445      * @param config the AbandonedConfig if tracing SQL objects
446      * @since 1.3
447      */
448     public PoolableConnectionFactory(
449         ConnectionFactory connFactory,
450         ObjectPool pool,
451         KeyedObjectPoolFactory stmtPoolFactory,
452         String validationQuery,
453         int validationQueryTimeout,
454         Collection connectionInitSqls,
455         Boolean defaultReadOnly,
456         boolean defaultAutoCommit,
457         int defaultTransactionIsolation,
458         String defaultCatalog,
459         AbandonedConfig config) {
460 
461         _connFactory = connFactory;
462         _pool = pool;
463         _config = config;
464         _pool.setFactory(this);
465         _stmtPoolFactory = stmtPoolFactory;
466         _validationQuery = validationQuery;
467         _validationQueryTimeout = validationQueryTimeout;
468         _connectionInitSqls = connectionInitSqls;
469         _defaultReadOnly = defaultReadOnly;
470         _defaultAutoCommit = defaultAutoCommit;
471         _defaultTransactionIsolation = defaultTransactionIsolation;
472         _defaultCatalog = defaultCatalog;
473     }
474 
475     /**
476      * Sets the {@link ConnectionFactory} from which to obtain base {@link Connection}s.
477      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
478      */
479     public void setConnectionFactory(ConnectionFactory connFactory) {
480         _connFactory = connFactory;
481     }
482 
483     /**
484      * Sets the query I use to {@link #validateObject validate} {@link Connection}s.
485      * Should return at least one row.
486      * Using <tt>null</tt> turns off validation.
487      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.
488      */
489     public void setValidationQuery(String validationQuery) {
490         _validationQuery = validationQuery;
491     }
492     
493     /**
494      * Sets the validation query timeout, the amount of time, in seconds, that
495      * connection validation will wait for a response from the database when
496      * executing a validation query.  Use a value less than or equal to 0 for
497      * no timeout.
498      *
499      * @param timeout new validation query timeout value in seconds
500      * @since 1.3
501      */
502     public void setValidationQueryTimeout(int timeout) {
503         _validationQueryTimeout = timeout;
504     }
505 
506     /**
507      * Sets the SQL statements I use to initialize newly created {@link Connection}s.
508      * Using <tt>null</tt> turns off connection initialization.
509      * @param connectionInitSqls SQL statement to initialize {@link Connection}s.
510      * @since 1.3
511      */
512     synchronized public void setConnectionInitSql(Collection connectionInitSqls) {
513         _connectionInitSqls = connectionInitSqls;
514     }
515 
516     /**
517      * Sets the {@link ObjectPool} in which to pool {@link Connection}s.
518      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
519      */
520     synchronized public void setPool(ObjectPool pool) {
521         if(null != _pool && pool != _pool) {
522             try {
523                 _pool.close();
524             } catch(Exception e) {
525                 // ignored !?!
526             }
527         }
528         _pool = pool;
529     }
530 
531     /**
532      * Returns the {@link ObjectPool} in which {@link Connection}s are pooled.
533      * @return the connection pool
534      */
535     public synchronized ObjectPool getPool() {
536         return _pool;
537     }
538 
539     /**
540      * Sets the {@link KeyedObjectPoolFactory} I use to create {@link KeyedObjectPool}s
541      * for pooling {@link java.sql.PreparedStatement}s.
542      * Set to <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling.
543      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s
544      */
545     public void setStatementPoolFactory(KeyedObjectPoolFactory stmtPoolFactory) {
546         _stmtPoolFactory = stmtPoolFactory;
547     }
548 
549     /**
550      * Sets the default "read only" setting for borrowed {@link Connection}s
551      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
552      */
553     public void setDefaultReadOnly(boolean defaultReadOnly) {
554         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
555     }
556 
557     /**
558      * Sets the default "auto commit" setting for borrowed {@link Connection}s
559      * @param defaultAutoCommit the default "auto commit" setting for borrowed {@link Connection}s
560      */
561     public void setDefaultAutoCommit(boolean defaultAutoCommit) {
562         _defaultAutoCommit = defaultAutoCommit;
563     }
564 
565     /**
566      * Sets the default "Transaction Isolation" setting for borrowed {@link Connection}s
567      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
568      */
569     public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {
570         _defaultTransactionIsolation = defaultTransactionIsolation;
571     }
572 
573     /**
574      * Sets the default "catalog" setting for borrowed {@link Connection}s
575      * @param defaultCatalog the default "catalog" setting for borrowed {@link Connection}s
576      */
577     public void setDefaultCatalog(String defaultCatalog) {
578         _defaultCatalog = defaultCatalog;
579     }
580 
581     public Object makeObject() throws Exception {
582         Connection conn = _connFactory.createConnection();
583         if (conn == null) {
584             throw new IllegalStateException("Connection factory returned null from createConnection");
585         }
586         initializeConnection(conn);
587         if(null != _stmtPoolFactory) {
588             KeyedObjectPool stmtpool = _stmtPoolFactory.createPool();
589             conn = new PoolingConnection(conn,stmtpool);
590             stmtpool.setFactory((PoolingConnection)conn);
591         }
592         return new PoolableConnection(conn,_pool,_config);
593     }
594 
595     protected void initializeConnection(Connection conn) throws SQLException {
596         Collection sqls = _connectionInitSqls;
597         if(conn.isClosed()) {
598             throw new SQLException("initializeConnection: connection closed");
599         }
600         if(null != sqls) {
601             Statement stmt = null;
602             try {
603                 stmt = conn.createStatement();
604                 for (Iterator iterator = sqls.iterator(); iterator.hasNext();)
605                 {
606                     Object o = iterator.next();
607                     if (o == null) {
608                         throw new NullPointerException("null connectionInitSqls element");
609                     }
610                     // o might not be a String instance
611                     String sql = o.toString();
612                     stmt.execute(sql);
613                 }
614             } finally {
615                 if (stmt != null) {
616                     try {
617                         stmt.close();
618                     } catch(Exception t) {
619                         // ignored
620                     }
621                 }
622             }
623         }
624     }
625 
626     public void destroyObject(Object obj) throws Exception {
627         if(obj instanceof PoolableConnection) {
628             ((PoolableConnection)obj).reallyClose();
629         }
630     }
631 
632     public boolean validateObject(Object obj) {
633         if(obj instanceof Connection) {
634             try {
635                 validateConnection((Connection) obj);
636                 return true;
637             } catch(Exception e) {
638                 return false;
639             }
640         } else {
641             return false;
642         }
643     }
644 
645     public void validateConnection(Connection conn) throws SQLException {
646         String query = _validationQuery;
647         if(conn.isClosed()) {
648             throw new SQLException("validateConnection: connection closed");
649         }
650         if(null != query) {
651             Statement stmt = null;
652             ResultSet rset = null;
653             try {
654                 stmt = conn.createStatement();
655                 if (_validationQueryTimeout > 0) {
656                     stmt.setQueryTimeout(_validationQueryTimeout);
657                 }
658                 rset = stmt.executeQuery(query);
659                 if(!rset.next()) {
660                     throw new SQLException("validationQuery didn't return a row");
661                 }
662             } finally {
663                 if (rset != null) {
664                     try {
665                         rset.close();
666                     } catch(Exception t) {
667                         // ignored
668                     }
669                 }
670                 if (stmt != null) {
671                     try {
672                         stmt.close();
673                     } catch(Exception t) {
674                         // ignored
675                     }
676                 }
677             }
678         }
679     }
680 
681     public void passivateObject(Object obj) throws Exception {
682         if(obj instanceof Connection) {
683             Connection conn = (Connection)obj;
684             if(!conn.getAutoCommit() && !conn.isReadOnly()) {
685                 conn.rollback();
686             }
687             conn.clearWarnings();
688             if(!conn.getAutoCommit()) {
689                 conn.setAutoCommit(true);
690             }
691         }
692         if(obj instanceof DelegatingConnection) {
693             ((DelegatingConnection)obj).passivate();
694         }
695     }
696 
697     public void activateObject(Object obj) throws Exception {
698         if(obj instanceof DelegatingConnection) {
699             ((DelegatingConnection)obj).activate();
700         }
701         if(obj instanceof Connection) {
702             Connection conn = (Connection)obj;
703             if (conn.getAutoCommit() != _defaultAutoCommit) {
704                 conn.setAutoCommit(_defaultAutoCommit);
705             }
706             if ((_defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) 
707                     && (conn.getTransactionIsolation() != 
708                     _defaultTransactionIsolation)) {
709                 conn.setTransactionIsolation(_defaultTransactionIsolation);
710             }
711             if ((_defaultReadOnly != null) && 
712                     (conn.isReadOnly() != _defaultReadOnly.booleanValue())) {
713                 conn.setReadOnly(_defaultReadOnly.booleanValue());
714             }
715             if ((_defaultCatalog != null) &&
716                     (!_defaultCatalog.equals(conn.getCatalog()))) {
717                 conn.setCatalog(_defaultCatalog);
718             }
719         }
720     }
721 
722     protected volatile ConnectionFactory _connFactory = null;
723     protected volatile String _validationQuery = null;
724     protected volatile int _validationQueryTimeout = -1;
725     protected Collection _connectionInitSqls = null;
726     protected volatile ObjectPool _pool = null;
727     protected volatile KeyedObjectPoolFactory _stmtPoolFactory = null;
728     protected Boolean _defaultReadOnly = null;
729     protected boolean _defaultAutoCommit = true;
730     protected int _defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
731     protected String _defaultCatalog;
732 
733     /**
734      * Configuration for removing abandoned connections.
735      */
736     protected AbandonedConfig _config = null;
737 
738     /**
739      * Internal constant to indicate the level is not set.
740      */
741     static final int UNKNOWN_TRANSACTIONISOLATION = -1;
742 }