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