View Javadoc

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 }