KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > conn > ConnectionWrapper


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. 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, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.conn;
57
58 import java.sql.CallableStatement JavaDoc;
59 import java.sql.Connection JavaDoc;
60 import java.sql.DatabaseMetaData JavaDoc;
61 import java.sql.PreparedStatement JavaDoc;
62 import java.sql.SQLException JavaDoc;
63 import java.sql.SQLWarning JavaDoc;
64 import java.sql.Savepoint JavaDoc;
65 import java.sql.Statement JavaDoc;
66 import java.util.Map JavaDoc;
67
68 /**
69  * ConnectionWrapper is a <code>java.sql.Connection</code> implementation that wraps another
70  * Connection, delegating method calls to this connection. It
71  * works in conjunction with PooledConnectionImpl, to generate pool events, provide
72  * limited automated reconnection functionality, etc.
73  *
74  * @author Andrei Adamchik
75  */

76 public class ConnectionWrapper implements Connection JavaDoc {
77     private Connection JavaDoc connectionObj;
78     private PooledConnectionImpl pooledConnection;
79     private long lastReconnected;
80     private int reconnectCount;
81
82     /**
83      * Fixes Sybase problems with autocommit. Used idea from
84      * Jonas org.objectweb.jonas.jdbc_xa.ConnectionImpl
85      * (http://www.objectweb.org/jonas/).
86      *
87      * <p>If problem is not the one that can be fixed by this patch,
88      * original exception is rethrown. If exception occurs when fixing
89      * the problem, new exception is thrown.</p>
90      */

91     static void sybaseAutoCommitPatch(
92         Connection JavaDoc c,
93         SQLException JavaDoc e,
94         boolean autoCommit)
95         throws SQLException JavaDoc {
96
97         String JavaDoc s = e.getMessage().toLowerCase();
98         if (s.indexOf("set chained command not allowed") >= 0) {
99             c.commit();
100             c.setAutoCommit(autoCommit); // Shouldn't fail now.
101
} else {
102             throw e;
103         }
104     }
105
106     /** Creates new ConnectionWrapper */
107     public ConnectionWrapper(
108         Connection JavaDoc connectionObj,
109         PooledConnectionImpl pooledConnection) {
110         this.connectionObj = connectionObj;
111         this.pooledConnection = pooledConnection;
112     }
113
114     protected void reconnect(SQLException JavaDoc exception) throws SQLException JavaDoc {
115
116         // if there was a relatively recent reconnect, just rethrow an error
117
// and retire itself. THIS WILL PREVENT RECONNECT LOOPS
118
if (reconnectCount > 0
119             && System.currentTimeMillis() - lastReconnected < 60000) {
120
121             retire(exception);
122             throw exception;
123         }
124
125         pooledConnection.reconnect();
126         
127         // Pooled connection will wrap returned connection into
128
// another ConnectionWrapper.... lets get the real connection
129
// underneath...
130
Connection JavaDoc connection = pooledConnection.getConnection();
131         if (connection instanceof ConnectionWrapper) {
132             this.connectionObj = ((ConnectionWrapper) connection).connectionObj;
133         }
134         else {
135             this.connectionObj = connection;
136         }
137         
138         lastReconnected = System.currentTimeMillis();
139         reconnectCount++;
140     }
141
142     protected void retire(SQLException JavaDoc exception) {
143         // notify all the listeners....
144
pooledConnection.connectionErrorNotification(exception);
145     }
146
147     public void clearWarnings() throws SQLException JavaDoc {
148         try {
149             connectionObj.clearWarnings();
150         } catch (SQLException JavaDoc sqlEx) {
151             retire(sqlEx);
152             throw sqlEx;
153         }
154     }
155
156     public void close() throws SQLException JavaDoc {
157         pooledConnection.returnConnectionToThePool();
158         connectionObj = null;
159         pooledConnection = null;
160     }
161
162     public void commit() throws SQLException JavaDoc {
163         try {
164             connectionObj.commit();
165         } catch (SQLException JavaDoc sqlEx) {
166             retire(sqlEx);
167             throw sqlEx;
168         }
169     }
170
171     public Statement JavaDoc createStatement() throws SQLException JavaDoc {
172         try {
173             return connectionObj.createStatement();
174         } catch (SQLException JavaDoc sqlEx) {
175
176             // reconnect has code to prevent loops
177
reconnect(sqlEx);
178             return createStatement();
179         }
180     }
181
182     public Statement JavaDoc createStatement(
183         int resultSetType,
184         int resultSetConcurrency)
185         throws SQLException JavaDoc {
186         try {
187             return connectionObj.createStatement(
188                 resultSetType,
189                 resultSetConcurrency);
190         } catch (SQLException JavaDoc sqlEx) {
191
192             // reconnect has code to prevent loops
193
reconnect(sqlEx);
194             return createStatement(resultSetType, resultSetConcurrency);
195         }
196     }
197
198     public boolean getAutoCommit() throws SQLException JavaDoc {
199         try {
200             return connectionObj.getAutoCommit();
201         } catch (SQLException JavaDoc sqlEx) {
202             retire(sqlEx);
203             throw sqlEx;
204         }
205     }
206
207     public String JavaDoc getCatalog() throws SQLException JavaDoc {
208         try {
209             return connectionObj.getCatalog();
210         } catch (SQLException JavaDoc sqlEx) {
211             retire(sqlEx);
212             throw sqlEx;
213         }
214     }
215
216     public DatabaseMetaData JavaDoc getMetaData() throws SQLException JavaDoc {
217         try {
218             return connectionObj.getMetaData();
219         } catch (SQLException JavaDoc sqlEx) {
220             retire(sqlEx);
221             throw sqlEx;
222         }
223     }
224
225     public int getTransactionIsolation() throws SQLException JavaDoc {
226         try {
227             return connectionObj.getTransactionIsolation();
228         } catch (SQLException JavaDoc sqlEx) {
229             retire(sqlEx);
230             throw sqlEx;
231         }
232     }
233
234     public SQLWarning JavaDoc getWarnings() throws SQLException JavaDoc {
235         try {
236             return connectionObj.getWarnings();
237         } catch (SQLException JavaDoc sqlEx) {
238             retire(sqlEx);
239             throw sqlEx;
240         }
241     }
242
243     public boolean isClosed() throws SQLException JavaDoc {
244         if (connectionObj != null) {
245             try {
246                 return connectionObj.isClosed();
247             } catch (SQLException JavaDoc sqlEx) {
248                 retire(sqlEx);
249                 throw sqlEx;
250             }
251         } else
252             return true;
253     }
254
255     public boolean isReadOnly() throws SQLException JavaDoc {
256         try {
257             return connectionObj.isReadOnly();
258         } catch (SQLException JavaDoc sqlEx) {
259             retire(sqlEx);
260             throw sqlEx;
261         }
262     }
263
264     public String JavaDoc nativeSQL(String JavaDoc sql) throws SQLException JavaDoc {
265         try {
266             return connectionObj.nativeSQL(sql);
267         } catch (SQLException JavaDoc sqlEx) {
268             retire(sqlEx);
269             throw sqlEx;
270         }
271     }
272
273     public CallableStatement JavaDoc prepareCall(String JavaDoc sql) throws SQLException JavaDoc {
274         try {
275             return connectionObj.prepareCall(sql);
276         } catch (SQLException JavaDoc sqlEx) {
277
278             // reconnect has code to prevent loops
279
reconnect(sqlEx);
280             return prepareCall(sql);
281         }
282     }
283
284     public CallableStatement JavaDoc prepareCall(
285         String JavaDoc sql,
286         int resultSetType,
287         int resultSetConcurrency)
288         throws SQLException JavaDoc {
289         try {
290             return connectionObj.prepareCall(
291                 sql,
292                 resultSetType,
293                 resultSetConcurrency);
294         } catch (SQLException JavaDoc sqlEx) {
295
296             // reconnect has code to prevent loops
297
reconnect(sqlEx);
298             return prepareCall(sql, resultSetType, resultSetConcurrency);
299         }
300     }
301
302     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql) throws SQLException JavaDoc {
303         try {
304             return connectionObj.prepareStatement(sql);
305         } catch (SQLException JavaDoc sqlEx) {
306
307             // reconnect has code to prevent loops
308
reconnect(sqlEx);
309             return prepareStatement(sql);
310         }
311     }
312
313     public PreparedStatement JavaDoc prepareStatement(
314         String JavaDoc sql,
315         int resultSetType,
316         int resultSetConcurrency)
317         throws SQLException JavaDoc {
318         try {
319             return connectionObj.prepareStatement(
320                 sql,
321                 resultSetType,
322                 resultSetConcurrency);
323         } catch (SQLException JavaDoc sqlEx) {
324
325             // reconnect has code to prevent loops
326
reconnect(sqlEx);
327             return prepareStatement(sql, resultSetType, resultSetConcurrency);
328         }
329     }
330
331     public void rollback() throws SQLException JavaDoc {
332         try {
333             connectionObj.rollback();
334         } catch (SQLException JavaDoc sqlEx) {
335             retire(sqlEx);
336             throw sqlEx;
337         }
338     }
339
340     public void setAutoCommit(boolean autoCommit) throws SQLException JavaDoc {
341         try {
342             connectionObj.setAutoCommit(autoCommit);
343         } catch (SQLException JavaDoc sqlEx) {
344
345             try {
346                 // apply Sybase patch
347
sybaseAutoCommitPatch(connectionObj, sqlEx, autoCommit);
348             } catch (SQLException JavaDoc patchEx) {
349                 retire(sqlEx);
350                 throw sqlEx;
351             }
352         }
353     }
354
355     public void setCatalog(String JavaDoc catalog) throws SQLException JavaDoc {
356         try {
357             connectionObj.setCatalog(catalog);
358         } catch (SQLException JavaDoc sqlEx) {
359             retire(sqlEx);
360             throw sqlEx;
361         }
362     }
363
364     public void setReadOnly(boolean readOnly) throws SQLException JavaDoc {
365         try {
366             connectionObj.setReadOnly(readOnly);
367         } catch (SQLException JavaDoc sqlEx) {
368             retire(sqlEx);
369             throw sqlEx;
370         }
371     }
372
373     public void setTransactionIsolation(int level) throws SQLException JavaDoc {
374         try {
375             connectionObj.setTransactionIsolation(level);
376         } catch (SQLException JavaDoc sqlEx) {
377             retire(sqlEx);
378             throw sqlEx;
379         }
380     }
381
382     public Map JavaDoc getTypeMap() throws SQLException JavaDoc {
383         try {
384             return connectionObj.getTypeMap();
385         } catch (SQLException JavaDoc sqlEx) {
386             retire(sqlEx);
387             throw sqlEx;
388         }
389     }
390
391     public void setTypeMap(Map JavaDoc map) throws SQLException JavaDoc {
392         try {
393             connectionObj.setTypeMap(map);
394         } catch (SQLException JavaDoc sqlEx) {
395             retire(sqlEx);
396             throw sqlEx;
397         }
398     }
399
400     public void setHoldability(int holdability) throws SQLException JavaDoc {
401         throw new java.lang.UnsupportedOperationException JavaDoc(
402             "Method setHoldability() not yet implemented.");
403     }
404
405     public int getHoldability() throws SQLException JavaDoc {
406         throw new java.lang.UnsupportedOperationException JavaDoc(
407             "Method getHoldability() not yet implemented.");
408     }
409
410     public Savepoint JavaDoc setSavepoint() throws SQLException JavaDoc {
411         throw new java.lang.UnsupportedOperationException JavaDoc(
412             "Method setSavepoint() not yet implemented.");
413     }
414
415     public Savepoint JavaDoc setSavepoint(String JavaDoc name) throws SQLException JavaDoc {
416         throw new java.lang.UnsupportedOperationException JavaDoc(
417             "Method setSavepoint() not yet implemented.");
418     }
419
420     public void rollback(Savepoint JavaDoc savepoint) throws SQLException JavaDoc {
421         throw new java.lang.UnsupportedOperationException JavaDoc(
422             "Method rollback() not yet implemented.");
423     }
424
425     public void releaseSavepoint(Savepoint JavaDoc savepoint) throws SQLException JavaDoc {
426         throw new java.lang.UnsupportedOperationException JavaDoc(
427             "Method releaseSavepoint() not yet implemented.");
428     }
429
430     public Statement JavaDoc createStatement(
431         int resultSetType,
432         int resultSetConcurrency,
433         int resultSetHoldability)
434         throws SQLException JavaDoc {
435         throw new java.lang.UnsupportedOperationException JavaDoc(
436             "Method createStatement() not yet implemented.");
437     }
438
439     public PreparedStatement JavaDoc prepareStatement(
440         String JavaDoc sql,
441         int resultSetType,
442         int resultSetConcurrency,
443         int resultSetHoldability)
444         throws SQLException JavaDoc {
445         throw new java.lang.UnsupportedOperationException JavaDoc(
446             "Method prepareStatement() not yet implemented.");
447     }
448
449     public CallableStatement JavaDoc prepareCall(
450             String JavaDoc sql,
451             int resultSetType,
452             int resultSetConcurrency,
453             int resultSetHoldability) throws SQLException JavaDoc {
454         try {
455             return connectionObj.prepareCall(
456                     sql,
457                     resultSetType,
458                     resultSetConcurrency,
459                     resultSetHoldability);
460         }
461         catch (SQLException JavaDoc sqlEx) {
462
463             // reconnect has code to prevent loops
464
reconnect(sqlEx);
465             return prepareCall(
466                     sql,
467                     resultSetType,
468                     resultSetConcurrency,
469                     resultSetHoldability);
470         }
471     }
472
473     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, int autoGeneratedKeys)
474             throws SQLException JavaDoc {
475         
476         try {
477             return connectionObj.prepareStatement(sql, autoGeneratedKeys);
478         }
479         catch (SQLException JavaDoc sqlEx) {
480
481             // reconnect has code to prevent loops
482
reconnect(sqlEx);
483             return prepareStatement(sql, autoGeneratedKeys);
484         }
485     }
486
487     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, int[] columnIndexes)
488             throws SQLException JavaDoc {
489         try {
490             return connectionObj.prepareStatement(sql, columnIndexes);
491         }
492         catch (SQLException JavaDoc sqlEx) {
493
494             // reconnect has code to prevent loops
495
reconnect(sqlEx);
496             return prepareStatement(sql, columnIndexes);
497         }
498     }
499
500     public PreparedStatement JavaDoc prepareStatement(String JavaDoc sql, String JavaDoc[] columnNames)
501             throws SQLException JavaDoc {
502         try {
503             return connectionObj.prepareStatement(sql, columnNames);
504         }
505         catch (SQLException JavaDoc sqlEx) {
506
507             // reconnect has code to prevent loops
508
reconnect(sqlEx);
509             return prepareStatement(sql, columnNames);
510         }
511     }
512
513 }
Popular Tags