KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > ide > IDEExceptionHandler


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.ide;
12
13 import com.ibm.icu.text.MessageFormat;
14
15 import org.eclipse.jface.dialogs.IDialogConstants;
16 import org.eclipse.jface.dialogs.MessageDialog;
17 import org.eclipse.jface.window.Window;
18 import org.eclipse.osgi.util.NLS;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.SWTError;
21 import org.eclipse.swt.widgets.MessageBox;
22 import org.eclipse.swt.widgets.Shell;
23 import org.eclipse.ui.application.IWorkbenchConfigurer;
24 import org.eclipse.ui.internal.ide.dialogs.InternalErrorDialog;
25
26 /**
27  * Handles exception while running the event loop.
28  * <p>
29  * In case of a "simpler" exception such as NPE, log the exception,
30  * open a dialog to inform the user and try to keep running.
31  * In case of a exception like OutOfMemory and SWTError, log the exception,
32  * open a dialog to ask the user to decide if the workbench should
33  * be terminated.
34  * </p>
35  */

36 public final class IDEExceptionHandler {
37
38     private int exceptionCount = 0;
39
40     private InternalErrorDialog dialog;
41
42     private Shell defaultParent = new Shell();
43
44     private boolean closing = false;
45
46     private IWorkbenchConfigurer workbenchConfigurer;
47
48     //Pre-load all Strings trying to run as light as possible in case of fatal errors.
49
private static String JavaDoc MSG_OutOfMemoryError = IDEWorkbenchMessages.FatalError_OutOfMemoryError;
50
51     private static String JavaDoc MSG_StackOverflowError = IDEWorkbenchMessages.FatalError_StackOverflowError;
52
53     private static String JavaDoc MSG_VirtualMachineError = IDEWorkbenchMessages.FatalError_VirtualMachineError;
54
55     private static String JavaDoc MSG_SWTError = IDEWorkbenchMessages.FatalError_SWTError;
56
57     private static String JavaDoc MSG_FATAL_ERROR = IDEWorkbenchMessages.FatalError;
58
59     private static String JavaDoc MSG_FATAL_ERROR_Recursive = IDEWorkbenchMessages.FatalError_RecursiveError;
60
61     private static String JavaDoc MSG_FATAL_ERROR_RecursiveTitle = IDEWorkbenchMessages.Internal_error;
62
63     /**
64      * Creates the exception handle for the IDE application
65      *
66      * @param configurer an object for configuring the workbench
67      */

68     public IDEExceptionHandler(IWorkbenchConfigurer configurer) {
69         super();
70         workbenchConfigurer = configurer;
71     }
72
73     /**
74      * Handles an event loop exception
75      *
76      * @param t the exception to handle
77      */

78     public void handleException(Throwable JavaDoc t) {
79         try {
80             exceptionCount++;
81             if (exceptionCount > 1) {
82                 if (closing) {
83                     return;
84                 }
85                 Shell parent = defaultParent;
86                 if (dialog != null && dialog.getShell() != null
87                         && !dialog.getShell().isDisposed()) {
88                     parent = dialog.getShell();
89                 }
90                 MessageBox box = new MessageBox(parent, SWT.ICON_ERROR
91                         | SWT.YES | SWT.NO | SWT.SYSTEM_MODAL);
92                 box.setText(MSG_FATAL_ERROR_RecursiveTitle);
93                 box.setMessage(MessageFormat.format(MSG_FATAL_ERROR,
94                         new Object JavaDoc[] { MSG_FATAL_ERROR_Recursive }));
95                 int result = box.open();
96                 if (result == SWT.YES) {
97                     closeWorkbench();
98                 }
99             } else {
100                 if (openQuestionDialog(t)) {
101                     closeWorkbench();
102                 }
103             }
104         } finally {
105             exceptionCount--;
106         }
107     }
108
109     /**
110      * Close the workbench and make sure all exceptions are handled.
111      */

112     private void closeWorkbench() {
113         if (closing) {
114             return;
115         }
116
117         try {
118             closing = true;
119             if (dialog != null && dialog.getShell() != null
120                     && !dialog.getShell().isDisposed()) {
121                 dialog.close();
122             }
123             workbenchConfigurer.emergencyClose();
124         } catch (RuntimeException JavaDoc re) {
125             // Workbench may be in such bad shape (no OS handles left, out of memory, etc)
126
// that is cannot even close. Just bail out now.
127
System.err
128                     .println("Fatal runtime error happened during workbench emergency close."); //$NON-NLS-1$
129
re.printStackTrace();
130             throw re;
131         } catch (Error JavaDoc e) {
132             // Workbench may be in such bad shape (no OS handles left, out of memory, etc)
133
// that is cannot even close. Just bail out now.
134
System.err
135                     .println("Fatal error happened during workbench emergency close."); //$NON-NLS-1$
136
e.printStackTrace();
137             throw e;
138         }
139     }
140
141     /**
142      * Inform the user about a fatal error. Return true if the user decide to
143      * exit workbench or if another fatal error happens while reporting it.
144      */

145     private boolean openQuestionDialog(Throwable JavaDoc internalError) {
146         try {
147             String JavaDoc msg = null;
148             if (internalError instanceof OutOfMemoryError JavaDoc) {
149                 msg = MSG_OutOfMemoryError;
150             } else if (internalError instanceof StackOverflowError JavaDoc) {
151                 msg = MSG_StackOverflowError;
152             } else if (internalError instanceof VirtualMachineError JavaDoc) {
153                 msg = MSG_VirtualMachineError;
154             } else if (internalError instanceof SWTError) {
155                 msg = MSG_SWTError;
156             } else {
157                 if (internalError.getMessage() == null) {
158                     msg = IDEWorkbenchMessages.InternalErrorNoArg;
159                 } else {
160                     msg = NLS.bind(IDEWorkbenchMessages.InternalErrorOneArg, internalError.getMessage());
161                 }
162                 if (Policy.DEBUG_OPEN_ERROR_DIALOG) {
163                     return openQuestion(null, IDEWorkbenchMessages.Internal_error, msg, internalError, 1);
164                 }
165                 return false;
166             }
167             // Always open the dialog in case of major error but do not show the
168
// detail button if not in debug mode.
169
Throwable JavaDoc detail = internalError;
170             if (!Policy.DEBUG_OPEN_ERROR_DIALOG) {
171                 detail = null;
172             }
173             return InternalErrorDialog
174                     .openQuestion(null, IDEWorkbenchMessages.Internal_error,
175                             MessageFormat.format(MSG_FATAL_ERROR,
176                                     new Object JavaDoc[] { msg }), detail, 1);
177         } catch (Throwable JavaDoc th) {
178             // Workbench may be in such bad shape (no OS handles left, out of memory, etc)
179
// that is cannot show a message to the user. Just bail out now.
180
System.err
181                     .println("Error while informing user about event loop exception:"); //$NON-NLS-1$
182
internalError.printStackTrace();
183             System.err.println("Dialog open exception:"); //$NON-NLS-1$
184
th.printStackTrace();
185             return true;
186         }
187     }
188
189     private boolean openQuestion(Shell parent, String JavaDoc title, String JavaDoc message,
190             Throwable JavaDoc detail, int defaultIndex) {
191         String JavaDoc[] labels;
192         if (detail == null) {
193             labels = new String JavaDoc[] { IDialogConstants.YES_LABEL,
194                     IDialogConstants.NO_LABEL };
195         } else {
196             labels = new String JavaDoc[] { IDialogConstants.YES_LABEL,
197                     IDialogConstants.NO_LABEL,
198                     IDialogConstants.SHOW_DETAILS_LABEL };
199         }
200
201         dialog = new InternalErrorDialog(parent, title, null, message, detail,
202                 MessageDialog.QUESTION, labels, defaultIndex);
203
204         if (detail != null) {
205             dialog.setDetailButton(2);
206         }
207         boolean result = dialog.open() == Window.OK;
208         dialog = null;
209         return result;
210     }
211 }
212
Popular Tags