1 /*
2 * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3 * the spring framework, http://el4j.sf.net
4 * Copyright (C) 2008 by ELCA Informatique SA, Av. de la Harpe 22-24,
5 * 1000 Lausanne, Switzerland, http://www.elca.ch
6 *
7 * EL4J is published under the GNU Lesser General Public License (LGPL)
8 * Version 2.1. See http://www.gnu.org/licenses/
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * For alternative licensing, please contact info@elca.ch
16 */
17 package ch.elca.el4j.services.gui.swing.exceptions;
18
19 import java.io.PrintWriter;
20 import java.io.StringWriter;
21 import java.util.Comparator;
22 import java.util.PriorityQueue;
23
24 import org.apache.commons.lang.exception.ExceptionUtils;
25
26 /**
27 * This Exception Handler Manager allows to register Exception Handlers. If an uncaught exception occurs,
28 * the handlers get executed in the order of their priority until a handler signals that no further handler
29 * should be called (handle() return <code>true</code>). In case that no handlers get executed, a stack
30 * trace will be printed to std err.
31 *
32 * @svnLink $Revision: 3979 $;$Date: 2009-10-22 16:29:06 +0200 (Do, 22. Okt 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/swing/src/main/java/ch/elca/el4j/services/gui/swing/exceptions/Exceptions.java $
33 *
34 * @author Stefan Wismer (SWI)
35 */
36 public final class Exceptions implements Thread.UncaughtExceptionHandler {
37 /**
38 * The Handler comparator that uses the priority to sort.
39 */
40 private static final Comparator<Handler> ORDER_BY_PRIORITY = new Comparator<Handler>() {
41 public int compare(Handler handler1, Handler handler2) {
42 return -Integer.valueOf(handler1.getPriority()).compareTo(handler2.getPriority());
43 }
44 };
45
46 /**
47 * The singleton instance.
48 */
49 private static final Exceptions INSTANCE = new Exceptions();
50
51 /**
52 * The list of exception handlers order by priority.
53 */
54 private PriorityQueue<Handler> m_handlers = new PriorityQueue<Handler>(5, ORDER_BY_PRIORITY);
55
56 /**
57 * @return the singleton instance
58 */
59 public static Exceptions getInstance() {
60 return INSTANCE;
61 }
62
63 /**
64 * Add an exception handler.
65 * @param handler the handler to add
66 */
67 public void addHandler(Handler handler) {
68 m_handlers.add(handler);
69 }
70
71 /**
72 * Remove an exception handler.
73 * @param handler the handler to add
74 */
75 public void removeHandler(Handler handler) {
76 m_handlers.remove(handler);
77 }
78
79 /**
80 * Execute all Handlers that recognize the given Exception (in the order of their priority)
81 * until a handler signals to stop. In case that no handlers get executed, a stack
82 * trace will be printed to std err.
83 * @param e the exception to handle
84 */
85 public void handle(Exception e) {
86 boolean handled = false;
87
88 for (Handler handler : m_handlers) {
89 if (handler.recognize(e)) {
90 boolean stop = handler.handle(e);
91 handled = true;
92 if (stop) {
93 break;
94 }
95 }
96 }
97
98 if (!handled) {
99 // print stacktrace to syserr
100 System.err.println("Exception was not recognized by any Exception Handler: " + e);
101 e.printStackTrace(System.err);
102
103 // open exception dialog
104 new ExceptionDialog(ExceptionUtils.getFullStackTrace(e)).setVisible(true);
105 }
106 }
107
108 /**
109 * Handler for AWT exceptions.
110 * @param t a Throwable
111 */
112 public void handle(Throwable t) {
113 if (t instanceof Exception) {
114 Exceptions.getInstance().handle((Exception) t);
115 } else if (t instanceof Error) {
116 // unwrap Error
117 handle(((Error) t).getCause());
118 }
119 }
120
121 /** {@inheritDoc} */
122 public void uncaughtException(Thread t, Throwable e) {
123 handle(new Exception(e));
124 }
125 }