KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > jdbc > pool > ConnectionWrapper


1 package com.protomatter.jdbc.pool;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 import java.io.*;
54 import java.sql.*;
55 import java.util.*;
56 import java.text.MessageFormat JavaDoc;
57 import com.protomatter.util.*;
58 import com.protomatter.pool.*;
59 import com.protomatter.syslog.*;
60
61 /**
62  * A wrapper.
63  *
64  * @see java.sql.Connection
65  * @see JdbcConnectionPoolDriver
66  * @see JdbcConnectionPool
67  */

68 class ConnectionWrapper
69 implements Connection, SyslogChannelAware
70 {
71     private JdbcConnectionPool pool = null;
72     private JdbcConnectionPoolConnection connection = null;
73     private boolean isClosed = false;
74     
75     protected static Debug DEBUG = Debug.forPackage(ConnectionWrapper.class);
76     protected static Channel log = Channel.forPackage(ConnectionWrapper.class);
77
78     ConnectionWrapper(JdbcConnectionPoolConnection connection, JdbcConnectionPool pool)
79     {
80         super();
81         this.connection = connection;
82         this.pool = pool;
83     }
84
85     /**
86      * Get the connection that this object wraps. This method
87      * should only be called if you <i>really</i> know what
88      * you're doing. This method exposes the connection
89      * that is actually connected to the database, but you should
90      * not really have any need to get ahold of it. This method
91      * will return <tt>null</tt> if you have called the
92      * <tt>close()</tt> method already.
93      */

94     public Connection getConnection()
95     {
96         if (this.connection == null)
97             return null;
98         return this.connection.getConnection();
99     }
100
101     /**
102      * Get the pool that this connection is associated with.
103      */

104     public JdbcConnectionPool getConnectionPool()
105     {
106         return this.pool;
107     }
108
109     /**
110      * Returns the channel information from the pool
111      * this connection is associated with.
112      */

113     public Object JavaDoc getSyslogChannel()
114     {
115         return this.pool.getSyslogChannel();
116     }
117
118     /**
119      * Invalidates this connection manually. When this connection
120      * is closed, the pool will discard it.
121      */

122     public void invalidate()
123     {
124         if (DEBUG.debug())
125             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod());
126         if (this.connection != null)
127             this.connection.invalidate();
128     }
129
130
131     /**
132      * Will check that this connection is working and refresh it if not.
133      * This executes the validity check statement that was set when
134      * the connection pool was created. If that statement was not set,
135      * the connection is refreshed no matter what. If the statement was
136      * set, it is executed and if an exception is generated, the connection
137      * is refreshed. If there's a problem refreshing the connection, this
138      * connection wrapper is invalidated -- you will have to either keep
139      * calling <tt>refresh()</tt> until it doesn't throw a <tt>SQLException</tt>, or just call
140      * <tt>close()</tt> and open another connection using the <tt>JdbcConnectionPoolDriver</tt>.
141      * If <tt>verbose</tt> is true, messages are written to Syslog
142      * during the refresh operation. Note that after the <tt>close()</tt>
143      * method has been called, calling this method will throw a
144      * <tt>SQLException</tt> stating that the connection is closed.
145      *
146      * @exception SQLException If the connection needs refreshing and there is
147      * a problem re-opening the connection.
148      */

149
150     public synchronized void refresh(boolean verbose)
151     throws SQLException
152     {
153         if (DEBUG.debug())
154             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod());
155         checkClosed();
156         this.connection.refresh(verbose);
157     }
158
159     /**
160      * Performs a non-verbose refresh. This method
161      * will throw a <tt>SQLException</tt> and
162      * the connection will not be refreshed if
163      * the <tt>close()</tt> method has been called.
164      *
165      * @see #refresh(boolean)
166      */

167     public synchronized void refresh()
168     throws SQLException
169     {
170         refresh(false);
171     }
172
173     private final void checkClosed()
174     throws SQLException
175     {
176         if (this.isClosed)
177             throw new SQLException(PoolResources.getResourceString(MessageConstants.CONNECTION_IS_CLOSED));
178     }
179
180     /**
181      * @see java.sql.Connection
182      *
183      * @exception SQLException Because the underlying connection can throw one.
184      */

185     public Statement createStatement()
186     throws SQLException
187     {
188         checkClosed();
189         long time = System.currentTimeMillis();
190         Statement stmt = this.connection.createStatement();
191         time = System.currentTimeMillis() - time;
192         if (DEBUG.debug())
193         {
194             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " took " + time + "ms");
195             return new StatementWrapper(this, stmt);
196         }
197         return stmt;
198     }
199
200     /**
201      * @see java.sql.Connection
202      *
203      * @exception SQLException Because the underlying connection can throw one.
204      */

205     public PreparedStatement prepareStatement(String JavaDoc sql)
206     throws SQLException
207     {
208         checkClosed();
209         long time = System.currentTimeMillis();
210         PreparedStatement stmt = this.connection.prepareStatement(sql);
211         time = System.currentTimeMillis() - time;
212         if (DEBUG.debug())
213         {
214             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " SQL=\"" + sql + "\" took " + time + "ms");
215             return new PreparedStatementWrapper(this, stmt);
216         }
217         return stmt;
218     }
219
220     /**
221      * @see java.sql.Connection
222      *
223      * @exception SQLException Because the underlying connection can throw one.
224      */

225     public CallableStatement prepareCall(String JavaDoc sql)
226     throws SQLException
227     {
228         checkClosed();
229         long time = System.currentTimeMillis();
230         CallableStatement stmt = this.connection.prepareCall(sql);
231         time = System.currentTimeMillis() - time;
232         if (DEBUG.debug())
233         {
234             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " SQL=\"" + sql + "\" took " + time + "ms");
235             return new CallableStatementWrapper(this, stmt);
236         }
237         return stmt;
238     }
239
240     /**
241      * @see java.sql.Connection
242      *
243      * @exception SQLException Because the underlying connection can throw one.
244      */

245     public String JavaDoc nativeSQL(String JavaDoc sql)
246     throws SQLException
247     {
248         checkClosed();
249         long time = System.currentTimeMillis();
250         String JavaDoc nsql = this.connection.nativeSQL(sql);
251         time = System.currentTimeMillis() - time;
252         if (DEBUG.debug())
253             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " SQL=\"" + sql + "\" NativeSQL=\"" + nsql + "\" took " + time + "ms");
254         return nsql;
255     }
256
257     /**
258      * @see java.sql.Connection
259      *
260      * @exception SQLException Because the underlying connection can throw one.
261      */

262     public void setAutoCommit(boolean autoCommit)
263     throws SQLException
264     {
265         if (DEBUG.debug())
266             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " AutoCommit=\"" + autoCommit + "\"");
267         checkClosed();
268         this.connection.setAutoCommit(autoCommit);
269     }
270
271     /**
272      * @see java.sql.Connection
273      *
274      * @exception SQLException Because the underlying connection can throw one.
275      */

276     public boolean getAutoCommit()
277     throws SQLException
278     {
279         checkClosed();
280         return this.connection.getAutoCommit();
281     }
282
283     /**
284      * @see java.sql.Connection
285      *
286      * @exception SQLException Because the underlying connection can throw one.
287      */

288     public void commit()
289     throws SQLException
290     {
291         if (DEBUG.debug())
292             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod());
293         checkClosed();
294         this.connection.commit();
295     }
296
297     /**
298      * @see java.sql.Connection
299      *
300      * @exception SQLException Because the underlying connection can throw one.
301      */

302     public void rollback()
303     throws SQLException
304     {
305         if (DEBUG.debug())
306             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod());
307         checkClosed();
308         this.connection.rollback();
309     }
310
311     /**
312      * Close the connection. The underlying connection is checked
313      * back into the pool so it can be used by someone else. If this
314      * method completes without throwing a
315      * <tt>SQLException</tt>, then calling any method on this class
316      * (except this <tt>close()</tt> method) will throw a
317      * <tt>SQLException</tt> stating that the connection is closed.
318      * Repeatedly calling this method has no effect and will not
319      * throw exceptions (which some JDBC drivers do).
320      *
321      * @see java.sql.Connection
322      *
323      * @exception SQLException Because the underlying connection can throw one.
324      */

325     public void close()
326     throws SQLException
327     {
328         if (DEBUG.debug())
329             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod());
330         if (this.isClosed)
331             return;
332
333         this.connection.close();
334         this.isClosed = true;
335         this.connection = null;
336     }
337
338     /**
339      * @see java.sql.Connection
340      *
341      * @exception SQLException Because the underlying connection can throw one.
342      */

343     public boolean isClosed()
344     throws SQLException
345     {
346         // since we don't really close the this.connection, we need to
347
// tell the if they think the closed it ;-)
348
return this.isClosed;
349     }
350
351     /**
352      * @see java.sql.Connection
353      *
354      * @exception SQLException Because the underlying connection can throw one.
355      */

356     public DatabaseMetaData getMetaData()
357     throws SQLException
358     {
359         checkClosed();
360         return this.connection.getMetaData();
361     }
362
363     /**
364      * @see java.sql.Connection
365      *
366      * @exception SQLException Because the underlying connection can throw one.
367      */

368     public void setReadOnly(boolean readOnly)
369     throws SQLException
370     {
371         if (DEBUG.debug())
372             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " ReadOnly=\"" + readOnly + "\"");
373         checkClosed();
374         this.connection.setReadOnly(readOnly);
375     }
376
377     /**
378      * @see java.sql.Connection
379      *
380      * @exception SQLException Because the underlying connection can throw one.
381      */

382     public boolean isReadOnly()
383     throws SQLException
384     {
385         checkClosed();
386         return this.connection.isReadOnly();
387     }
388
389     /**
390      * @see java.sql.Connection
391      *
392      * @exception SQLException Because the underlying connection can throw one.
393      */

394     public void setCatalog(String JavaDoc catalog)
395     throws SQLException
396     {
397         if (DEBUG.debug())
398             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " Catalog=\"" + catalog + "\"");
399         checkClosed();
400         this.connection.setCatalog(catalog);
401     }
402
403     /**
404      * @see java.sql.Connection
405      *
406      * @exception SQLException Because the underlying connection can throw one.
407      */

408     public String JavaDoc getCatalog()
409     throws SQLException
410     {
411         checkClosed();
412         return this.connection.getCatalog();
413     }
414
415     /**
416      * @see java.sql.Connection
417      *
418      * @exception SQLException Because the underlying connection can throw one.
419      */

420     public void setTransactionIsolation(int level)
421     throws SQLException
422     {
423         if (DEBUG.debug())
424             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " IsolationLevel=\"" + level + "\"");
425         checkClosed();
426         this.connection.setTransactionIsolation(level);
427     }
428
429     /**
430      * @see java.sql.Connection
431      *
432      * @exception SQLException Because the underlying connection can throw one.
433      */

434     public int getTransactionIsolation()
435     throws SQLException
436     {
437         checkClosed();
438         return this.connection.getTransactionIsolation();
439     }
440
441     /**
442      * @see java.sql.Connection
443      *
444      * @exception SQLException Because the underlying connection can throw one.
445      */

446     public SQLWarning getWarnings()
447     throws SQLException
448     {
449         checkClosed();
450         return this.connection.getWarnings();
451     }
452
453     /**
454      * @see java.sql.Connection
455      *
456      * @exception SQLException Because the underlying connection can throw one.
457      */

458     public void clearWarnings()
459     throws SQLException
460     {
461         if (DEBUG.debug())
462             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod());
463         checkClosed();
464         this.connection.clearWarnings();
465     }
466
467     /**
468      * @see java.sql.Connection
469      *
470      * @exception SQLException Because the underlying connection can throw one.
471      */

472     public Statement createStatement(int resultSetType, int resultSetConcurrency)
473     throws SQLException
474     {
475         checkClosed();
476         long time = System.currentTimeMillis();
477         Statement stmt = this.connection.createStatement(resultSetType, resultSetConcurrency);
478         time = System.currentTimeMillis() - time;
479         if (DEBUG.debug())
480         {
481             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " Type=\"" + resultSetType + "\" Concurrency=\"" + resultSetConcurrency + "\" took " + time + "ms");
482             return new StatementWrapper(this, stmt);
483         }
484         return stmt;
485     }
486
487     /**
488      * @see java.sql.Connection
489      *
490      * @exception SQLException Because the underlying connection can throw one.
491      */

492     public Map getTypeMap()
493     throws SQLException
494     {
495         checkClosed();
496         return this.connection.getTypeMap();
497     }
498
499     /**
500      * @see java.sql.Connection
501      *
502      * @exception SQLException Because the underlying connection can throw one.
503      */

504     public CallableStatement prepareCall(String JavaDoc sql, int resultSetType, int resultSetConcurrency)
505     throws SQLException
506     {
507         checkClosed();
508
509         long time = System.currentTimeMillis();
510         CallableStatement stmt = this.connection.prepareCall(sql, resultSetType, resultSetConcurrency);
511         time = System.currentTimeMillis() - time;
512         if (DEBUG.debug())
513         {
514             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " SQL=\"" + sql + "\" Type=\"" + resultSetType + "\" Concurrency=\"" + resultSetConcurrency + "\" took " + time + "ms");
515             return new CallableStatementWrapper(this, stmt);
516         }
517         return stmt;
518     }
519
520     /**
521      * @see java.sql.Connection
522      *
523      * @exception SQLException Because the underlying connection can throw one.
524      */

525     public PreparedStatement prepareStatement(String JavaDoc sql, int resultSetType, int resultSetConcurrency)
526     throws SQLException
527     {
528         checkClosed();
529
530         long time = System.currentTimeMillis();
531         PreparedStatement stmt = this.connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
532         time = System.currentTimeMillis() - time;
533         if (DEBUG.debug())
534         {
535             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " SQL=\"" + sql + "\" Type=\"" + resultSetType + "\" Concurrency=\"" + resultSetConcurrency + "\" took " + time + "ms");
536             return new PreparedStatementWrapper(this, stmt);
537         }
538         return stmt;
539     }
540
541     /**
542      * @see java.sql.Connection
543      *
544      * @exception SQLException Because the underlying connection can throw one.
545      */

546     public void setTypeMap(Map typeMap)
547     throws SQLException
548     {
549         if (DEBUG.debug())
550             log.debug(this, StackTraceUtil.whereAmI().getShortClassAndMethod() + " TypeMap=\"" + typeMap + "\"");
551         checkClosed();
552         this.connection.setTypeMap(typeMap);
553     }
554 }
555
Popular Tags