1
2
3
4
5
6
7
8
9
10
11 package org.mule.config;
12
13 import org.mule.MuleRuntimeException;
14 import org.mule.config.i18n.MessageFactory;
15 import org.mule.umo.UMOException;
16 import org.mule.util.ClassUtils;
17 import org.mule.util.SpiUtils;
18 import org.mule.util.StringUtils;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Properties;
28
29 import org.apache.commons.collections.MapUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33
34
35
36
37
38
39
40
41
42 public final class ExceptionHelper
43 {
44
45
46
47
48
49 public static final String ERROR_CODE_PROPERTY = "error.code.property";
50
51
52
53
54
55 public static final String APPLY_TO_PROPERTY = "apply.to";
56
57
58
59
60 protected static final Log logger = LogFactory.getLog(ExceptionHelper.class);
61
62 private static String J2SE_VERSION = "";
63
64
65 private static final String J2EE_VERSION = "1.3ee";
66
67 private static Properties errorDocs = new Properties();
68 private static Properties errorCodes = new Properties();
69 private static Map reverseErrorCodes = null;
70 private static Map errorMappings = new HashMap();
71
72 private static int exceptionThreshold = 0;
73 private static boolean verbose = true;
74
75 private static boolean initialised = false;
76
77
78
79
80 private static List exceptionReaders = new ArrayList();
81
82
83
84
85 private static ExceptionReader defaultExceptionReader = new DefaultExceptionReader();
86
87 static
88 {
89 initialise();
90 }
91
92
93 private ExceptionHelper ()
94 {
95
96 }
97
98 public static void initialise()
99 {
100 try
101 {
102 if (initialised)
103 {
104 return;
105 }
106
107 registerExceptionReader(new UMOExceptionReader());
108 registerExceptionReader(new NamingExceptionReader());
109 J2SE_VERSION = System.getProperty("java.specification.version");
110
111 InputStream is = SpiUtils.findServiceDescriptor("org/mule/config",
112 "mule-exception-codes.properties", ExceptionHelper.class);
113 if (is == null)
114 {
115 throw new IllegalArgumentException(
116 "Failed to load resource: META_INF/services/org/mule/config/mule-exception-codes.properties");
117 }
118 errorCodes.load(is);
119 reverseErrorCodes = MapUtils.invertMap(errorCodes);
120 is = SpiUtils.findServiceDescriptor("org/mule/config", "mule-exception-config.properties",
121 ExceptionHelper.class);
122 if (is == null)
123 {
124 throw new IllegalArgumentException(
125 "Failed to load resource: META_INF/services/org/mule/config/mule-exception-config.properties");
126 }
127 errorDocs.load(is);
128
129 initialised = true;
130 }
131 catch (IOException e)
132 {
133 throw new MuleRuntimeException(
134 MessageFactory.createStaticMessage("Failed to load Exception resources"),
135 e);
136 }
137 }
138
139 public static int getErrorCode(Class exception)
140 {
141 String code = errorCodes.getProperty(exception.getName(), "-1");
142 return Integer.parseInt(code);
143 }
144
145 public static Class getErrorClass(int code)
146 {
147 String key = String.valueOf(code);
148 Object clazz = reverseErrorCodes.get(key);
149 if (clazz == null)
150 {
151 return null;
152 }
153 else if (clazz instanceof Class)
154 {
155 return (Class) clazz;
156 }
157 else
158 {
159 try
160 {
161 clazz = ClassUtils.loadClass(clazz.toString(), ExceptionHelper.class);
162 }
163 catch (ClassNotFoundException e)
164 {
165 logger.error(e.getMessage(), e);
166 return null;
167 }
168 reverseErrorCodes.put(key, clazz);
169 return (Class) clazz;
170 }
171 }
172
173 public static String getErrorMapping(String protocol, int code)
174 {
175 Class c = getErrorClass(code);
176 if (c != null)
177 {
178 return getErrorMapping(protocol, c);
179 }
180 else
181 {
182 logger.error("Class not known for code: " + code);
183 return "-1";
184 }
185 }
186
187 private static Properties getErrorMappings(String protocol)
188 {
189 Object m = errorMappings.get(protocol);
190 if (m != null)
191 {
192 if (m instanceof Properties)
193 {
194 return (Properties) m;
195 }
196 else
197 {
198 return null;
199 }
200 }
201 else
202 {
203 InputStream is = SpiUtils.findServiceDescriptor("org/mule/config",
204 protocol + "-exception-mappings.properties", ExceptionHelper.class);
205 if (is == null)
206 {
207 errorMappings.put(protocol, "not found");
208 logger.warn("Failed to load error mappings from: META-INF/services/org/mule/config/"
209 + protocol
210 + "-exception-mappings.properties. This may be because there are no error code mappings for protocol: "
211 + protocol);
212 return null;
213 }
214 Properties p = new Properties();
215 try
216 {
217 p.load(is);
218 }
219 catch (IOException e)
220 {
221 throw new MuleRuntimeException(
222 MessageFactory.createStaticMessage("Failed to load Exception resources"), e);
223 }
224 errorMappings.put(protocol, p);
225 String applyTo = p.getProperty(APPLY_TO_PROPERTY, null);
226 if (applyTo != null)
227 {
228 String[] protocols = StringUtils.splitAndTrim(applyTo, ",");
229 for (int i = 0; i < protocols.length; i++)
230 {
231 errorMappings.put(protocols[i], p);
232 }
233 }
234 return p;
235 }
236 }
237
238 public static String getErrorCodePropertyName(String protocol)
239 {
240 protocol = protocol.toLowerCase();
241 Properties mappings = getErrorMappings(protocol);
242 if (mappings == null)
243 {
244 return null;
245 }
246 return mappings.getProperty(ERROR_CODE_PROPERTY);
247 }
248
249 public static String getErrorMapping(String protocol, Class exception)
250 {
251 protocol = protocol.toLowerCase();
252 Properties mappings = getErrorMappings(protocol);
253 if (mappings == null)
254 {
255 logger.info("No mappings found for protocol: " + protocol);
256 return String.valueOf(getErrorCode(exception));
257 }
258
259 Class clazz = exception;
260 String code = null;
261 while (!clazz.equals(Object.class))
262 {
263 code = mappings.getProperty(clazz.getName());
264 if (code == null)
265 {
266 clazz = clazz.getSuperclass();
267 }
268 else
269 {
270 return code;
271 }
272 }
273 code = String.valueOf(getErrorCode(exception));
274
275
276 return mappings.getProperty(code, code);
277 }
278
279 public static String getJavaDocUrl(Class exception)
280 {
281 return getDocUrl("javadoc.", exception.getName());
282 }
283
284 public static String getDocUrl(Class exception)
285 {
286 return getDocUrl("doc.", exception.getName());
287 }
288
289 private static String getDocUrl(String prefix, String packageName)
290 {
291 String key = prefix;
292 if (packageName.startsWith("java.") || packageName.startsWith("javax."))
293 {
294 key += J2SE_VERSION;
295 }
296 String url = getUrl(key, packageName);
297 if (url == null && (packageName.startsWith("java.") || packageName.startsWith("javax.")))
298 {
299 key = prefix + J2EE_VERSION;
300 url = getUrl(key, packageName);
301 }
302 if (url != null)
303 {
304 if (!url.endsWith("/"))
305 {
306 url += "/";
307 }
308 String s = packageName.replaceAll("[.]", "/");
309 s += ".html";
310 url += s;
311 }
312
313
314
315
316
317
318
319
320
321
322
323 return url;
324 }
325
326 private static String getUrl(String key, String packageName)
327 {
328 String url = null;
329 if (!key.endsWith("."))
330 {
331 key += ".";
332 }
333 while (packageName.length() > 0)
334 {
335 url = errorDocs.getProperty(key + packageName, null);
336 if (url == null)
337 {
338 int i = packageName.lastIndexOf(".");
339 if (i == -1)
340 {
341 packageName = "";
342 }
343 else
344 {
345 packageName = packageName.substring(0, i);
346 }
347 }
348 else
349 {
350 break;
351 }
352 }
353 return url;
354 }
355
356 public static Throwable getRootException(Throwable t)
357 {
358 Throwable cause = t;
359 Throwable root = null;
360 while (cause != null)
361 {
362 root = cause;
363 cause = getExceptionReader(cause).getCause(cause);
364
365 if (t == cause)
366 {
367 break;
368 }
369 }
370 return root;
371 }
372
373 public static Throwable getRootParentException(Throwable t)
374 {
375 Throwable cause = t;
376 Throwable parent = t;
377 while (cause != null)
378 {
379 if (cause.getCause() == null)
380 {
381 return parent;
382 }
383 parent = cause;
384 cause = getExceptionReader(cause).getCause(cause);
385
386 if (t == cause)
387 {
388 break;
389 }
390 }
391 return t;
392 }
393
394 public static UMOException getRootMuleException(Throwable t)
395 {
396 Throwable cause = t;
397 UMOException umoException = null;
398 while (cause != null)
399 {
400 if (cause instanceof UMOException)
401 {
402 umoException = (UMOException) cause;
403 }
404 cause = getExceptionReader(cause).getCause(cause);
405
406 if (t == cause)
407 {
408 break;
409 }
410 }
411 return umoException;
412 }
413
414 public static List getExceptionsAsList(Throwable t)
415 {
416 List exceptions = new ArrayList();
417 Throwable cause = t;
418 while (cause != null)
419 {
420 exceptions.add(0, cause);
421 cause = getExceptionReader(cause).getCause(cause);
422
423 if (t == cause)
424 {
425 break;
426 }
427 }
428 return exceptions;
429 }
430
431 public static Map getExceptionInfo(Throwable t)
432 {
433 Map info = new HashMap();
434 Throwable cause = t;
435 while (cause != null)
436 {
437 info.putAll(getExceptionReader(cause).getInfo(cause));
438 cause = getExceptionReader(cause).getCause(cause);
439
440 if (t == cause)
441 {
442 break;
443 }
444 }
445 return info;
446 }
447
448 public static String getExceptionStack(Throwable t)
449 {
450 StringBuffer buf = new StringBuffer();
451
452 List exceptions = getExceptionsAsList(t);
453
454 int i = 1;
455 for (Iterator iterator = exceptions.iterator(); iterator.hasNext(); i++)
456 {
457 if (i > exceptionThreshold && exceptionThreshold > 0)
458 {
459 buf.append("(").append(exceptions.size() - i + 1).append(" more...)");
460 break;
461 }
462 Throwable throwable = (Throwable) iterator.next();
463 ExceptionReader er = getExceptionReader(throwable);
464 buf.append(i).append(". ").append(er.getMessage(throwable)).append(" (");
465 buf.append(throwable.getClass().getName()).append(")\n");
466 if (verbose && throwable.getStackTrace().length > 0)
467 {
468 StackTraceElement e = throwable.getStackTrace()[0];
469 buf.append(" ")
470 .append(e.getClassName())
471 .append(":")
472 .append(e.getLineNumber())
473 .append(" (")
474 .append(getJavaDocUrl(throwable.getClass()))
475 .append(")\n");
476 }
477 }
478 return buf.toString();
479 }
480
481
482
483
484
485
486 public static void registerExceptionReader(ExceptionReader reader)
487 {
488 exceptionReaders.add(reader);
489 }
490
491
492
493
494
495
496
497
498 public static ExceptionReader getExceptionReader(Throwable t)
499 {
500 for (Iterator iterator = exceptionReaders.iterator(); iterator.hasNext();)
501 {
502 ExceptionReader exceptionReader = (ExceptionReader) iterator.next();
503 if (exceptionReader.getExceptionType().isInstance(t))
504 {
505 return exceptionReader;
506 }
507 }
508 return defaultExceptionReader;
509 }
510
511 public static String writeException(Throwable t)
512 {
513 ExceptionReader er = getExceptionReader(t);
514 StringBuffer msg = new StringBuffer();
515 msg.append(er.getMessage(t)).append(". Type: ").append(t.getClass());
516 return msg.toString();
517 }
518 }