KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > config > ExceptionHelper


1 /*
2  * $Id: ExceptionHelper.java 4259 2006-12-14 03:12:07Z aperepel $
3  * --------------------------------------------------------------------------------------
4  * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
5  *
6  * The software in this package is published under the terms of the MuleSource MPL
7  * license, a copy of which has been included with this distribution in the
8  * LICENSE.txt file.
9  */

10
11 package org.mule.config;
12
13 import org.apache.commons.collections.MapUtils;
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.mule.MuleRuntimeException;
17 import org.mule.config.i18n.Message;
18 import org.mule.umo.UMOException;
19 import org.mule.util.ClassUtils;
20 import org.mule.util.SpiUtils;
21 import org.mule.util.StringUtils;
22
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Properties JavaDoc;
31
32 /**
33  * <code>ExceptionHelper</code> provides a number of helper functions that can be
34  * useful for detailing with Mule exceptions. This class has 3 core functions - <p/>
35  * 1. ErrorCode lookup. A corresponding Mule error code can be found using for a
36  * given Mule exception 2. Addtional Error information such as Java doc url for a
37  * given exception can be resolved using this class 3. Error code mappings can be
38  * looked up by providing the the protocol to map to and the Mule exception
39  *
40  * @author <a HREF="mailto:ross.mason@symphonysoft.com">Ross Mason</a>
41  * @version $Revision: 4259 $
42  */

43
44 public class ExceptionHelper
45 {
46     /**
47      * This is the property to set the error code to no the message it is the
48      * property name the Transport provider uses set the set the error code on the
49      * underlying message
50      */

51     public static final String JavaDoc ERROR_CODE_PROPERTY = "error.code.property";
52
53     /**
54      * a comma-separated list of other protocols the mappings in a file can be
55      * applied to
56      */

57     public static final String JavaDoc APPLY_TO_PROPERTY = "apply.to";
58
59     /**
60      * logger used by this class
61      */

62     protected static final Log logger = LogFactory.getLog(ExceptionHelper.class);
63
64     private static Properties JavaDoc errorDocs = new Properties JavaDoc();
65     private static Properties JavaDoc errorCodes = new Properties JavaDoc();
66     private static Map JavaDoc reverseErrorCodes = null;
67     private static Map JavaDoc errorMappings = new HashMap JavaDoc();
68
69     private static int exceptionThreshold = 0;
70     private static boolean verbose = true;
71
72     private static boolean initialised = false;
73
74     private static String JavaDoc J2SE_VERSION = "";
75
76     /** todo How do you get the j2ee version?? */
77     private static String JavaDoc J2EE_VERSION = "1.3ee";
78
79     /**
80      * A list of the exception readers to use for different types of exceptions
81      */

82     private static List JavaDoc exceptionReaders = new ArrayList JavaDoc();
83
84     /**
85      * The default ExceptionReader which will be used for most types of exceptions
86      */

87     private static ExceptionReader defaultExceptionReader = new DefaultExceptionReader();
88
89     static
90     {
91         initialise();
92     }
93
94     public static void initialise()
95     {
96         try
97         {
98             if (initialised)
99             {
100                 return;
101             }
102
103             registerExceptionReader(new UMOExceptionReader());
104             registerExceptionReader(new NamingExceptionReader());
105             J2SE_VERSION = System.getProperty("java.specification.version");
106
107             InputStream JavaDoc is = SpiUtils.findServiceDescriptor("org/mule/config",
108                 "mule-exception-codes.properties", ExceptionHelper.class);
109             if (is == null)
110             {
111                 throw new NullPointerException JavaDoc(
112                     "Failed to load resource: META_INF/services/org/mule/config/mule-exception-codes.properties");
113             }
114             errorCodes.load(is);
115             reverseErrorCodes = MapUtils.invertMap(errorCodes);
116             is = SpiUtils.findServiceDescriptor("org/mule/config", "mule-exception-config.properties",
117                 ExceptionHelper.class);
118             if (is == null)
119             {
120                 throw new NullPointerException JavaDoc(
121                     "Failed to load resource: META_INF/services/org/mule/config/mule-exception-config.properties");
122             }
123             errorDocs.load(is);
124
125             initialised = true;
126         }
127         catch (IOException JavaDoc e)
128         {
129             throw new MuleRuntimeException(Message.createStaticMessage("Failed to load Exception resources"),
130                 e);
131         }
132     }
133
134     public static int getErrorCode(Class JavaDoc exception)
135     {
136         String JavaDoc code = errorCodes.getProperty(exception.getName(), "-1");
137         return Integer.parseInt(code);
138     }
139
140     public static Class JavaDoc getErrorClass(int code)
141     {
142         String JavaDoc key = String.valueOf(code);
143         Object JavaDoc clazz = reverseErrorCodes.get(key);
144         if (clazz == null)
145         {
146             return null;
147         }
148         else if (clazz instanceof Class JavaDoc)
149         {
150             return (Class JavaDoc)clazz;
151         }
152         else
153         {
154             try
155             {
156                 clazz = ClassUtils.loadClass(clazz.toString(), ExceptionHelper.class);
157             }
158             catch (ClassNotFoundException JavaDoc e)
159             {
160                 logger.error(e.getMessage(), e);
161                 return null;
162             }
163             reverseErrorCodes.put(key, clazz);
164             return (Class JavaDoc)clazz;
165         }
166     }
167
168     public static String JavaDoc getErrorMapping(String JavaDoc protocol, int code)
169     {
170         Class JavaDoc c = getErrorClass(code);
171         if (c != null)
172         {
173             return getErrorMapping(protocol, c);
174         }
175         else
176         {
177             logger.error("Class not known for code: " + code);
178             return "-1";
179         }
180     }
181
182     private static Properties JavaDoc getErrorMappings(String JavaDoc protocol)
183     {
184         Object JavaDoc m = errorMappings.get(protocol);
185         if (m != null)
186         {
187             if (m instanceof Properties JavaDoc)
188             {
189                 return (Properties JavaDoc)m;
190             }
191             else
192             {
193                 return null;
194             }
195         }
196         else
197         {
198             InputStream JavaDoc is = SpiUtils.findServiceDescriptor("org/mule/config",
199                 protocol + "-exception-mappings.properties", ExceptionHelper.class);
200             if (is == null)
201             {
202                 errorMappings.put(protocol, "not found");
203                 logger.warn("Failed to load error mappings from: META-INF/services/org/mule/config/"
204                             + protocol
205                             + "-exception-mappings.properties. This may be because there are no error code mappings for protocol: "
206                             + protocol);
207                 return null;
208             }
209             Properties JavaDoc p = new Properties JavaDoc();
210             try
211             {
212                 p.load(is);
213             }
214             catch (IOException JavaDoc e)
215             {
216                 throw new MuleRuntimeException(
217                     Message.createStaticMessage("Failed to load Exception resources"), e);
218             }
219             errorMappings.put(protocol, p);
220             String JavaDoc applyTo = p.getProperty(APPLY_TO_PROPERTY, null);
221             if (applyTo != null)
222             {
223                 String JavaDoc[] protocols = StringUtils.splitAndTrim(applyTo, ",");
224                 for (int i = 0; i < protocols.length; i++)
225                 {
226                     errorMappings.put(protocols[i], p);
227                 }
228             }
229             return p;
230         }
231     }
232
233     public static String JavaDoc getErrorCodePropertyName(String JavaDoc protocol)
234     {
235         protocol = protocol.toLowerCase();
236         Properties JavaDoc mappings = getErrorMappings(protocol);
237         if (mappings == null)
238         {
239             return null;
240         }
241         return mappings.getProperty(ERROR_CODE_PROPERTY);
242     }
243
244     public static String JavaDoc getErrorMapping(String JavaDoc protocol, Class JavaDoc exception)
245     {
246         protocol = protocol.toLowerCase();
247         Properties JavaDoc mappings = getErrorMappings(protocol);
248         if (mappings == null)
249         {
250             logger.info("No mappings found for protocol: " + protocol);
251             return String.valueOf(getErrorCode(exception));
252         }
253
254         Class JavaDoc clazz = exception;
255         String JavaDoc code = null;
256         while (!clazz.equals(Object JavaDoc.class))
257         {
258             code = mappings.getProperty(clazz.getName());
259             if (code == null)
260             {
261                 clazz = clazz.getSuperclass();
262             }
263             else
264             {
265                 return code;
266             }
267         }
268         code = String.valueOf(getErrorCode(exception));
269         // Finally lookup mapping based on error code and return the Mule error
270
// code if a match is not found
271
return mappings.getProperty(code, code);
272     }
273
274     public static String JavaDoc getJavaDocUrl(Class JavaDoc exception)
275     {
276         return getDocUrl("javadoc.", exception.getName());
277     }
278
279     public static String JavaDoc getDocUrl(Class JavaDoc exception)
280     {
281         return getDocUrl("doc.", exception.getName());
282     }
283
284     private static String JavaDoc getDocUrl(String JavaDoc prefix, String JavaDoc packageName)
285     {
286         String JavaDoc key = prefix;
287         if (packageName.startsWith("java.") || packageName.startsWith("javax."))
288         {
289             key += J2SE_VERSION;
290         }
291         String JavaDoc url = getUrl(key, packageName);
292         if (url == null && (packageName.startsWith("java.") || packageName.startsWith("javax.")))
293         {
294             key = prefix + J2EE_VERSION;
295             url = getUrl(key, packageName);
296         }
297         if (url != null)
298         {
299             if (!url.endsWith("/"))
300             {
301                 url += "/";
302             }
303             String JavaDoc s = packageName.replaceAll("[.]", "/");
304             s += ".html";
305             url += s;
306         }
307
308         /*
309          * If the exception is actually expected to occur by the calling code, the
310          * following output becomes misleading when reading the logs. if
311          * (logger.isDebugEnabled()) { if ("javadoc".equalsIgnoreCase(prefix)) {
312          * logger.debug("Javadoc Url for package '" + packageName + "' is: " + url); }
313          * else if ("doc".equalsIgnoreCase(prefix)) { logger.debug("Online Doc Url
314          * for package '" + packageName + "' is: " + url); } else {
315          * logger.debug(prefix + " Url for package '" + packageName + "' is: " +
316          * url); } }
317          */

318         return url;
319     }
320
321     private static String JavaDoc getUrl(String JavaDoc key, String JavaDoc packageName)
322     {
323         String JavaDoc url = null;
324         if (!key.endsWith("."))
325         {
326             key += ".";
327         }
328         while (packageName.length() > 0)
329         {
330             url = errorDocs.getProperty(key + packageName, null);
331             if (url == null)
332             {
333                 int i = packageName.lastIndexOf(".");
334                 if (i == -1)
335                 {
336                     packageName = "";
337                 }
338                 else
339                 {
340                     packageName = packageName.substring(0, i);
341                 }
342             }
343             else
344             {
345                 break;
346             }
347         }
348         return url;
349     }
350
351     public static Throwable JavaDoc getRootException(Throwable JavaDoc t)
352     {
353         Throwable JavaDoc cause = t;
354         Throwable JavaDoc root = null;
355         while (cause != null)
356         {
357             root = cause;
358             cause = getExceptionReader(cause).getCause(cause);
359             // address some misbehaving exceptions, avoid endless loop
360
if (t == cause)
361             {
362                 break;
363             }
364         }
365         return root;
366     }
367
368     public static Throwable JavaDoc getRootParentException(Throwable JavaDoc t)
369     {
370         Throwable JavaDoc cause = t;
371         Throwable JavaDoc parent = t;
372         while (cause != null)
373         {
374             if (cause.getCause() == null)
375             {
376                 return parent;
377             }
378             parent = cause;
379             cause = getExceptionReader(cause).getCause(cause);
380             // address some misbehaving exceptions, avoid endless loop
381
if (t == cause)
382             {
383                 break;
384             }
385         }
386         return t;
387     }
388
389     public static UMOException getRootMuleException(Throwable JavaDoc t)
390     {
391         Throwable JavaDoc cause = t;
392         UMOException umoException = null;
393         while (cause != null)
394         {
395             if (cause instanceof UMOException)
396             {
397                 umoException = (UMOException)cause;
398             }
399             cause = getExceptionReader(cause).getCause(cause);
400             // address some misbehaving exceptions, avoid endless loop
401
if (t == cause)
402             {
403                 break;
404             }
405         }
406         return umoException;
407     }
408
409     public static List JavaDoc getExceptionsAsList(Throwable JavaDoc t)
410     {
411         List JavaDoc exceptions = new ArrayList JavaDoc();
412         Throwable JavaDoc cause = t;
413         while (cause != null)
414         {
415             exceptions.add(0, cause);
416             cause = getExceptionReader(cause).getCause(cause);
417             // address some misbehaving exceptions, avoid endless loop
418
if (t == cause)
419             {
420                 break;
421             }
422         }
423         return exceptions;
424     }
425
426     public static Map JavaDoc getExceptionInfo(Throwable JavaDoc t)
427     {
428         Map JavaDoc info = new HashMap JavaDoc();
429         Throwable JavaDoc cause = t;
430         while (cause != null)
431         {
432             info.putAll(getExceptionReader(cause).getInfo(cause));
433             cause = getExceptionReader(cause).getCause(cause);
434             // address some misbehaving exceptions, avoid endless loop
435
if (t == cause)
436             {
437                 break;
438             }
439         }
440         return info;
441     }
442
443     public static String JavaDoc getExceptionStack(Throwable JavaDoc t)
444     {
445         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
446         // get exception stack
447
List JavaDoc exceptions = getExceptionsAsList(t);
448
449         int i = 1;
450         for (Iterator JavaDoc iterator = exceptions.iterator(); iterator.hasNext(); i++)
451         {
452             if (i > exceptionThreshold && exceptionThreshold > 0)
453             {
454                 buf.append("(").append(exceptions.size() - i + 1).append(" more...)");
455                 break;
456             }
457             Throwable JavaDoc throwable = (Throwable JavaDoc)iterator.next();
458             ExceptionReader er = getExceptionReader(throwable);
459             buf.append(i).append(". ").append(er.getMessage(throwable)).append(" (");
460             buf.append(throwable.getClass().getName()).append(")\n");
461             if (verbose && throwable.getStackTrace().length > 0)
462             {
463                 StackTraceElement JavaDoc e = throwable.getStackTrace()[0];
464                 buf.append(" ")
465                     .append(e.getClassName())
466                     .append(":")
467                     .append(e.getLineNumber())
468                     .append(" (")
469                     .append(getJavaDocUrl(throwable.getClass()))
470                     .append(")\n");
471             }
472         }
473         return buf.toString();
474     }
475
476     /**
477      * Registers an exception reader with Mule
478      *
479      * @param reader the reader to register.
480      */

481     public static void registerExceptionReader(ExceptionReader reader)
482     {
483         exceptionReaders.add(reader);
484     }
485
486     /**
487      * Gets an exception reader for the exception
488      *
489      * @param t the exception to get a reader for
490      * @return either a specific reader or an instance of DefaultExceptionReader.
491      * This method never returns null;
492      */

493     public static ExceptionReader getExceptionReader(Throwable JavaDoc t)
494     {
495         for (Iterator JavaDoc iterator = exceptionReaders.iterator(); iterator.hasNext();)
496         {
497             ExceptionReader exceptionReader = (ExceptionReader)iterator.next();
498             if (exceptionReader.getExceptionType().isInstance(t))
499             {
500                 return exceptionReader;
501             }
502         }
503         return defaultExceptionReader;
504     }
505
506     public static String JavaDoc writeException(Throwable JavaDoc t)
507     {
508         ExceptionReader er = getExceptionReader(t);
509         StringBuffer JavaDoc msg = new StringBuffer JavaDoc();
510         msg.append(er.getMessage(t)).append(". Type: ").append(t.getClass());
511         return msg.toString();
512     }
513 }
514
Popular Tags