KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.lang.reflect.Constructor JavaDoc;
12 import java.lang.reflect.InvocationTargetException JavaDoc;
13 import java.lang.reflect.Method JavaDoc;
14 import java.sql.SQLException JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 /**
18  * Will wrap up exceptions in another exception which can be defined at runtime.
19  * @version $Revision: 1.5 $, $Date: 2006/01/18 14:40:01 $
20  * @author billhorsman
21  * @author $Author: billhorsman $ (current maintainer)
22  */

23 class FatalSqlExceptionHelper {
24
25     private static final Log LOG = LogFactory.getLog(FatalSqlExceptionHelper.class);
26
27     /**
28      * Throws a wrapped SQLException if a wrapper is defined
29      * @param className the classname of the wrapping exception (must be either a RuntimeException or
30      * an SQLException). If null, then the original exception is rethrown.
31      * @param originalException the orginal exception
32      * @throws ProxoolException if there is an unexpected error with wrapping the exception
33      * @throws SQLException either the original exception, or a wrapped version of it
34      * @throws RuntimeException a wrapped up version of the orginal
35      */

36     protected static void throwFatalSQLException(String JavaDoc className, Throwable JavaDoc originalException) throws ProxoolException, SQLException JavaDoc, RuntimeException JavaDoc {
37         if (className != null && className.trim().length() > 0) {
38             Class JavaDoc clazz = null;
39             try {
40                 clazz = Class.forName(className);
41             } catch (ClassNotFoundException JavaDoc e) {
42                 throw new ProxoolException("Couldn't find class " + className);
43             }
44             if (SQLException JavaDoc.class.isAssignableFrom(clazz)) {
45                 // That's OK
46
} else if (RuntimeException JavaDoc.class.isAssignableFrom(clazz)) {
47                 // That's OK
48
} else {
49                 throw new ProxoolException("Couldn't wrap up using " + clazz.getName() + " because it isn't either a RuntimeException or an SQLException");
50             }
51             Constructor JavaDoc toUse = null;
52             Object JavaDoc[] args = null;
53             String JavaDoc argDescription = "";
54             Constructor JavaDoc[] constructors = clazz.getConstructors();
55             for (int i = 0; i < constructors.length; i++) {
56                 Constructor JavaDoc constructor = constructors[i];
57                 Class JavaDoc[] parameterTypes = constructor.getParameterTypes();
58                 if (toUse == null && parameterTypes.length == 0) {
59                     toUse = constructor;
60                 }
61                 if (parameterTypes.length == 1 && Exception JavaDoc.class.isAssignableFrom(parameterTypes[0])) {
62                     toUse = constructor;
63                     args = new Object JavaDoc[]{originalException};
64                     argDescription = "Exception";
65                     break;
66                 }
67             }
68             try {
69                 Object JavaDoc exceptionToThrow = toUse.newInstance(args);
70                 if (exceptionToThrow instanceof RuntimeException JavaDoc) {
71                     LOG.debug("Wrapping up a fatal exception: " + originalException.getMessage(), originalException);
72                     throw (RuntimeException JavaDoc) exceptionToThrow;
73                 } else if (exceptionToThrow instanceof SQLException JavaDoc) {
74                     throw (SQLException JavaDoc) exceptionToThrow;
75                 } else {
76                     throw new ProxoolException("Couldn't throw " + clazz.getName() + " because it isn't either a RuntimeException or an SQLException");
77                 }
78             } catch (InstantiationException JavaDoc e) {
79                 throw new ProxoolException("Couldn't create " + clazz.getName() + "(" + argDescription + ")", e);
80             } catch (IllegalAccessException JavaDoc e) {
81                 throw new ProxoolException("Couldn't create " + clazz.getName() + "(" + argDescription + ")", e);
82             } catch (InvocationTargetException JavaDoc e) {
83                 throw new ProxoolException("Couldn't create " + clazz.getName() + "(" + argDescription + ")", e);
84             }
85         } else {
86             if (originalException instanceof SQLException JavaDoc) {
87                 throw (SQLException JavaDoc) originalException;
88             } else if (originalException instanceof RuntimeException JavaDoc) {
89                 throw (RuntimeException JavaDoc) originalException;
90             } else {
91                 throw new RuntimeException JavaDoc("Unexpected exception:" + originalException.getMessage());
92             }
93         }
94     }
95
96     /**
97      * Test to see if an exception is a fatal one
98      * @param cpd the definition so we can find out what a fatal exception looks like
99      * @param t the exception to test
100      * @return true if it is fatal
101      */

102     protected static boolean testException(ConnectionPoolDefinitionIF cpd, Throwable JavaDoc t) {
103         return testException(cpd, t, 0);
104     }
105
106     /**
107      * Test to see if an exception is a fatal one
108      * @param cpd the definition so we can find out what a fatal exception looks like
109      * @param t the exception to test
110      * @param level the recursion level (max 20)
111      * @return true if it is fatal
112      */

113     protected static boolean testException(ConnectionPoolDefinitionIF cpd, Throwable JavaDoc t, int level) {
114         boolean fatalSqlExceptionDetected = false;
115         Iterator JavaDoc i = cpd.getFatalSqlExceptions().iterator();
116         while (i.hasNext()) {
117             if (t.getMessage() != null && t.getMessage().indexOf((String JavaDoc) i.next()) > -1) {
118                 // This SQL exception indicates a fatal problem with this connection.
119
fatalSqlExceptionDetected = true;
120             }
121         }
122
123         // If it isn't fatal, then try testing the contained exception
124
if (!fatalSqlExceptionDetected && level < 20) {
125             Throwable JavaDoc cause = getCause(t);
126             if (cause != null) {
127                 fatalSqlExceptionDetected = testException(cpd, cause, level + 1);
128             }
129         }
130
131         return fatalSqlExceptionDetected;
132     }
133
134     /**
135      * Tries to drill down into an exception to find its cause. Only goes one level deep.
136      * Uses reflection to look at getCause(), getTargetException(), getRootCause() and
137      * finally getOriginalException() methods to see if it can find one. Doesn't throw
138      * an error - it will just log a warning and return a null if nothing was found.
139      * @param t the exception to look inside
140      * @return the original exception or null if none was found.
141      */

142     protected static Throwable JavaDoc getCause(Throwable JavaDoc t) {
143         Throwable JavaDoc cause = null;
144         Method JavaDoc causeMethod = null;
145
146         try {
147             // Try a series of likely accessor methods
148
if (causeMethod == null) {
149                 causeMethod = getMethod(t, "getCause");
150             }
151             if (causeMethod == null) {
152                 causeMethod = getMethod(t, "getTargetException");
153             }
154             if (causeMethod == null) {
155                 causeMethod = getMethod(t, "getRootCause");
156             }
157             if (causeMethod == null) {
158                 causeMethod = getMethod(t, "getOriginalException");
159             }
160
161             // If one was found, invoke it.
162
if (causeMethod != null) {
163                 try {
164                     cause = (Throwable JavaDoc) causeMethod.invoke(t, null);
165                 } catch (IllegalAccessException JavaDoc e) {
166                     LOG.warn("Problem invoking " + t.getClass().getName() + "." + causeMethod.getName() + ". Ignoring.", e);
167                 } catch (IllegalArgumentException JavaDoc e) {
168                     LOG.warn("Problem invoking " + t.getClass().getName() + "." + causeMethod.getName() + ". Ignoring.", e);
169                 } catch (InvocationTargetException JavaDoc e) {
170                     LOG.warn("Problem invoking " + t.getClass().getName() + "." + causeMethod.getName() + ". Ignoring.", e);
171                 }
172             }
173         } catch (Exception JavaDoc e) {
174             LOG.warn("Unexpected exception drilling into exception. Ignoring.", e);
175         }
176         return cause;
177     }
178
179     private static Method JavaDoc getMethod(Object JavaDoc o, String JavaDoc methodName) {
180         Method JavaDoc m = null;
181         try {
182             m = o.getClass().getMethod(methodName, null);
183             // Reject any method that doesn't return a throwable.
184
if (!Throwable JavaDoc.class.isAssignableFrom(m.getReturnType())) {
185                 m = null;
186             }
187         } catch (NoSuchMethodException JavaDoc e) {
188             // That's OK
189
} catch (SecurityException JavaDoc e) {
190             LOG.warn("Problem finding method " + methodName, e);
191         }
192         return m;
193     }
194
195 }
196
197 /*
198  Revision history:
199  $Log: FatalSqlExceptionHelper.java,v $
200  Revision 1.5 2006/01/18 14:40:01 billhorsman
201  Unbundled Jakarta's Commons Logging.
202
203  Revision 1.4 2005/07/01 08:02:50 billhorsman
204  Check for exception message being null
205
206  Revision 1.3 2003/09/30 18:39:08 billhorsman
207  New test-before-use, test-after-use and fatal-sql-exception-wrapper-class properties.
208
209  Revision 1.2 2003/09/29 18:12:33 billhorsman
210  Doc
211
212 */
Popular Tags