KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > proxool > ProxyStatement


1 /*
2  * This software is released under a licence similar to the Apache Software Licence.
3  * See org.logicalcobwebs.proxool.package.html for details.
4  * The latest version is available at http://proxool.sourceforge.net
5  */

6 package org.logicalcobwebs.proxool;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10
11 import org.logicalcobwebs.cglib.proxy.MethodInterceptor;
12 import org.logicalcobwebs.cglib.proxy.MethodProxy;
13 import org.logicalcobwebs.cglib.proxy.InvocationHandler;
14 import org.logicalcobwebs.proxool.proxy.InvokerFacade;
15
16 import java.lang.reflect.InvocationTargetException JavaDoc;
17 import java.lang.reflect.Method JavaDoc;
18 import java.sql.Statement JavaDoc;
19 import java.sql.Connection JavaDoc;
20
21 /**
22  * Delegates to Statement for all calls. But also, for all execute methods, it
23  * checks the SQLException and compares it to the fatalSqlException list in the
24  * ConnectionPoolDefinition. If it detects a fatal exception it will destroy the
25  * Connection so that it isn't used again.
26  * @version $Revision: 1.32 $, $Date: 2006/03/03 09:58:26 $
27  * @author billhorsman
28  * @author $Author: billhorsman $ (current maintainer)
29  */

30 class ProxyStatement extends AbstractProxyStatement implements MethodInterceptor {
31
32     private static final Log LOG = LogFactory.getLog(ProxyStatement.class);
33
34     private static final String JavaDoc EXECUTE_FRAGMENT = "execute";
35
36     private static final String JavaDoc EXECUTE_BATCH_METHOD = "executeBatch";
37
38     private static final String JavaDoc ADD_BATCH_METHOD = "addBatch";
39
40     private static final String JavaDoc EQUALS_METHOD = "equals";
41
42     private static final String JavaDoc CLOSE_METHOD = "close";
43
44     private static final String JavaDoc GET_CONNECTION_METHOD = "getConnection";
45
46     private static final String JavaDoc FINALIZE_METHOD = "finalize";
47
48     private static final String JavaDoc SET_NULL_METHOD = "setNull";
49
50     private static final String JavaDoc SET_PREFIX = "set";
51
52     public ProxyStatement(Statement JavaDoc statement, ConnectionPool connectionPool, ProxyConnectionIF proxyConnection, String JavaDoc sqlStatement) {
53         super(statement, connectionPool, proxyConnection, sqlStatement);
54     }
55
56     public Object JavaDoc intercept(Object JavaDoc obj, Method JavaDoc method, Object JavaDoc[] args, MethodProxy proxy) throws Throwable JavaDoc {
57         return invoke(proxy, method, args);
58     }
59
60     public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
61         Object JavaDoc result = null;
62         long startTime = System.currentTimeMillis();
63         final int argCount = args != null ? args.length : 0;
64
65         Method JavaDoc concreteMethod = InvokerFacade.getConcreteMethod(getStatement().getClass(), method);
66
67         // This gets called /before/ the method has run
68
if (concreteMethod.getName().equals(ADD_BATCH_METHOD)) {
69             // If we have just added a batch call then we need to update the sql log
70
if (argCount > 0 && args[0] instanceof String JavaDoc) {
71                 setSqlStatementIfNull((String JavaDoc) args[0]);
72             }
73             appendToSqlLog();
74         } else if (concreteMethod.getName().equals(EXECUTE_BATCH_METHOD)) {
75             // executing a batch should do a trace
76
startExecute();
77         } else if (concreteMethod.getName().startsWith(EXECUTE_FRAGMENT)) {
78             // executing should update the log and do a trace
79
if (argCount > 0 && args[0] instanceof String JavaDoc) {
80                 setSqlStatementIfNull((String JavaDoc) args[0]);
81             }
82             appendToSqlLog();
83             startExecute();
84         }
85
86         // We need to remember an exceptions that get thrown so that we can optionally
87
// pass them to the onExecute() call below
88
Exception JavaDoc exception = null;
89         try {
90             if (concreteMethod.getName().equals(EQUALS_METHOD) && argCount == 1) {
91                 result = (equals(args[0])) ? Boolean.TRUE : Boolean.FALSE;
92             } else if (concreteMethod.getName().equals(CLOSE_METHOD) && argCount == 0) {
93                 close();
94             } else if (concreteMethod.getName().equals(GET_CONNECTION_METHOD) && argCount == 0) {
95                 result = getConnection();
96             } else if (concreteMethod.getName().equals(FINALIZE_METHOD) && argCount == 0) {
97                 finalize();
98             } else {
99                 try {
100                     result = concreteMethod.invoke(getStatement(), args);
101                 } catch (IllegalAccessException JavaDoc e) {
102                     // This is probably because we are trying to access a non-public concrete class. But don't worry,
103
// we can always use the proxy supplied method. This will only fail if we try to use an injectable
104
// method on a method in a class that isn't public and for a method that isn't declared in an interface -
105
// but if that is the case then that method is inaccessible by any means (even by bypassing Proxool and
106
// using the vendor's driver directly).
107
LOG.debug("Ignoring IllegalAccessException whilst invoking the " + concreteMethod + " concrete method and trying the " + method + " method directly.");
108                     // By overriding the method cached in the InvokerFacade we ensure that we only log this message once, and
109
// we speed up subsequent usages by not calling the method that fails first.
110
InvokerFacade.overrideConcreteMethod(getStatement().getClass(), method, method);
111                     result = method.invoke(getStatement(), args);
112                 }
113             }
114
115             // We only dump sql calls if we are in verbose mode and debug is enabled
116
if (isTrace()) {
117                 try {
118
119                     // What sort of method is it
120
if (concreteMethod.getName().equals(SET_NULL_METHOD) && argCount > 0 && args[0] instanceof Integer JavaDoc) {
121                         int index = ((Integer JavaDoc) args[0]).intValue();
122                         putParameter(index, null);
123                     } else if (concreteMethod.getName().startsWith(SET_PREFIX) && argCount > 1 && args[0] instanceof Integer JavaDoc) {
124                         int index = ((Integer JavaDoc) args[0]).intValue();
125                         putParameter(index, args[1]);
126                     }
127
128                 } catch (Exception JavaDoc e) {
129                     // We don't want an error during dump screwing up the transaction
130
LOG.error("Ignoring error during dump", e);
131                 }
132             }
133         } catch (InvocationTargetException JavaDoc e) {
134             if (e.getTargetException() instanceof Exception JavaDoc) {
135                 exception = (Exception JavaDoc) e.getTargetException();
136             } else {
137                 exception = e;
138             }
139             if (testException(e.getTargetException())) {
140                 // This is really a fatal one
141
FatalSqlExceptionHelper.throwFatalSQLException(getConnectionPool().getDefinition().getFatalSqlExceptionWrapper(), e.getTargetException());
142             }
143             throw e.getTargetException();
144         } catch (Exception JavaDoc e) {
145             exception = e;
146             if (testException(e)) {
147                 // This is really a fatal one
148
FatalSqlExceptionHelper.throwFatalSQLException(getConnectionPool().getDefinition().getFatalSqlExceptionWrapper(), e);
149             }
150             throw e;
151         } finally {
152
153             // This gets called /after/ the method has run
154
if (concreteMethod.getName().equals(EXECUTE_BATCH_METHOD) || concreteMethod.getName().startsWith(EXECUTE_FRAGMENT)) {
155                 trace(startTime, exception);
156             }
157
158         }
159
160         return result;
161
162     }
163
164 }
165
166 /*
167  Revision history:
168  $Log: ProxyStatement.java,v $
169  Revision 1.32 2006/03/03 09:58:26 billhorsman
170  Fix for statement.getConnection(). See bug 1149834.
171
172  Revision 1.31 2006/01/18 14:40:02 billhorsman
173  Unbundled Jakarta's Commons Logging.
174
175  Revision 1.30 2006/01/16 23:09:28 billhorsman
176  Call concrete finalize() method
177
178  Revision 1.29 2005/10/07 08:15:00 billhorsman
179  Update sqlCalls /before/ we execute so that we can see what slow calls are doing before they finish.
180
181  Revision 1.28 2004/07/13 21:06:18 billhorsman
182  Fix problem using injectable interfaces on methods that are declared in non-public classes.
183
184  Revision 1.27 2004/06/17 21:56:53 billhorsman
185  Use MethodMapper for concrete methods.
186
187  Revision 1.26 2004/06/02 20:48:14 billhorsman
188  Dropped obsolete InvocationHandler reference.
189
190  Revision 1.25 2003/12/12 19:29:47 billhorsman
191  Now uses Cglib 2.0
192
193  Revision 1.24 2003/10/19 09:50:33 billhorsman
194  Drill down into InvocationTargetException during execution debug.
195
196  Revision 1.23 2003/10/18 20:44:48 billhorsman
197  Better SQL logging (embed parameter values within SQL call) and works properly with batched statements now.
198
199  Revision 1.22 2003/09/30 18:39:08 billhorsman
200  New test-before-use, test-after-use and fatal-sql-exception-wrapper-class properties.
201
202  Revision 1.21 2003/09/29 17:48:49 billhorsman
203  New fatal-sql-exception-wrapper-class allows you to define what exception is used as a wrapper. This means that you
204  can make it a RuntimeException if you need to.
205
206  Revision 1.20 2003/09/10 22:21:04 chr32
207  Removing > jdk 1.2 dependencies.
208
209  Revision 1.19 2003/09/05 17:01:00 billhorsman
210  Trap and throw FatalSQLExceptions.
211
212  Revision 1.18 2003/03/03 11:11:58 billhorsman
213  fixed licence
214
215  Revision 1.17 2003/02/13 17:06:42 billhorsman
216  allow for sqlStatement in execute() method
217
218  Revision 1.16 2003/02/06 17:41:04 billhorsman
219  now uses imported logging
220
221  Revision 1.15 2003/01/31 16:53:19 billhorsman
222  checkstyle
223
224  Revision 1.14 2003/01/28 11:47:08 billhorsman
225  new isTrace() and made close() public
226
227  Revision 1.13 2003/01/27 18:26:40 billhorsman
228  refactoring of ProxyConnection and ProxyStatement to
229  make it easier to write JDK 1.2 patch
230
231  Revision 1.12 2002/12/19 00:08:36 billhorsman
232  automatic closure of statements when a connection is closed
233
234  Revision 1.11 2002/12/16 10:57:48 billhorsman
235  add getDelegateStatement to allow access to the
236  delegate JDBC driver's Statement
237
238  Revision 1.10 2002/12/03 12:24:00 billhorsman
239  fixed fatal sql exception
240
241  Revision 1.9 2002/11/13 18:22:04 billhorsman
242  fix for trace output
243
244  Revision 1.8 2002/11/13 12:32:38 billhorsman
245  now correctly logs trace messages even with verbose off
246
247  Revision 1.7 2002/11/09 15:57:33 billhorsman
248  finished off execute logging and listening
249
250  Revision 1.6 2002/10/29 23:20:55 billhorsman
251  logs execute time when debug is enabled and verbose is true
252
253  Revision 1.5 2002/10/28 19:28:25 billhorsman
254  checkstyle
255
256  Revision 1.4 2002/10/28 08:20:23 billhorsman
257  draft sql dump stuff
258
259  Revision 1.3 2002/10/25 15:59:32 billhorsman
260  made non-public where possible
261
262  Revision 1.2 2002/10/17 15:29:18 billhorsman
263  fixes so that equals() works
264
265  Revision 1.1.1.1 2002/09/13 08:13:30 billhorsman
266  new
267
268  Revision 1.8 2002/08/24 19:57:15 billhorsman
269  checkstyle changes
270
271  Revision 1.7 2002/08/24 19:42:26 billhorsman
272  new proxy stuff to work with JDK 1.4
273
274  Revision 1.6 2002/07/10 16:14:47 billhorsman
275  widespread layout changes and move constants into ProxoolConstants
276
277  Revision 1.5 2002/07/02 11:19:08 billhorsman
278  layout code and imports
279
280  Revision 1.4 2002/06/28 11:19:47 billhorsman
281  improved doc
282
283 */

284
Popular Tags