KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 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
12 package org.eclipse.ui.internal.ide;
13
14 import org.eclipse.core.runtime.IProgressMonitor;
15 import org.eclipse.core.runtime.IStatus;
16 import org.eclipse.core.runtime.Status;
17 import org.eclipse.jface.dialogs.IDialogConstants;
18 import org.eclipse.jface.dialogs.MessageDialog;
19 import org.eclipse.osgi.util.NLS;
20 import org.eclipse.swt.SWTError;
21 import org.eclipse.swt.graphics.Image;
22 import org.eclipse.swt.widgets.Shell;
23 import org.eclipse.ui.PlatformUI;
24 import org.eclipse.ui.application.IWorkbenchConfigurer;
25 import org.eclipse.ui.internal.ide.dialogs.InternalErrorDialog;
26 import org.eclipse.ui.progress.IProgressConstants;
27 import org.eclipse.ui.progress.UIJob;
28 import org.eclipse.ui.statushandlers.StatusAdapter;
29 import org.eclipse.ui.statushandlers.StatusManager;
30 import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
31
32 import com.ibm.icu.text.MessageFormat;
33
34 /**
35  * This is the IDE workbench error handler. The instance of this handler is
36  * returned from {@link IDEWorkbenchAdvisor#getWorkbenchErrorHandler()}. All
37  * handled statuses are checked against severity and logged using logging
38  * facility (by superclass).
39  *
40  * @since 3.3
41  */

42 public class IDEWorkbenchErrorHandler extends WorkbenchErrorHandler {
43
44     private int exceptionCount = 0;
45
46     static private FatalErrorDialog dialog;
47
48     private boolean closing = false;
49
50     private IWorkbenchConfigurer workbenchConfigurer;
51
52     // Pre-load all Strings trying to run as light as possible in case of fatal
53
// errors.
54
private static String JavaDoc MSG_OutOfMemoryError = IDEWorkbenchMessages.FatalError_OutOfMemoryError;
55
56     private static String JavaDoc MSG_StackOverflowError = IDEWorkbenchMessages.FatalError_StackOverflowError;
57
58     private static String JavaDoc MSG_VirtualMachineError = IDEWorkbenchMessages.FatalError_VirtualMachineError;
59
60     private static String JavaDoc MSG_SWTError = IDEWorkbenchMessages.FatalError_SWTError;
61
62     private static String JavaDoc MSG_FATAL_ERROR = IDEWorkbenchMessages.FatalError;
63
64     private static String JavaDoc MSG_FATAL_ERROR_Recursive = IDEWorkbenchMessages.FatalError_RecursiveError;
65
66     private static String JavaDoc MSG_FATAL_ERROR_Title = IDEWorkbenchMessages.InternalError;
67
68     /**
69      * @param configurer
70      */

71     public IDEWorkbenchErrorHandler(IWorkbenchConfigurer configurer) {
72         workbenchConfigurer = configurer;
73     }
74
75     /*
76      * (non-Javadoc)
77      *
78      * @see org.eclipse.ui.statushandlers.WorkbenchErrorHandler#handle(org.eclipse.ui.statushandlers.StatusAdapter,
79      * int)
80      */

81     public void handle(final StatusAdapter statusAdapter, int style) {
82
83         // if fatal error occurs, we will show the blocking error dialog anyway
84
if (isFatal(statusAdapter)) {
85             if (statusAdapter
86                     .getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) == Boolean.TRUE) {
87                 statusAdapter.setProperty(
88                         IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY,
89                         Boolean.FALSE);
90             }
91             super.handle(statusAdapter, style | StatusManager.BLOCK);
92         } else {
93             super.handle(statusAdapter, style);
94         }
95
96         // if fatal error occurs, we will ask to close the workbench
97
if (isFatal(statusAdapter) && style != StatusManager.NONE) {
98             UIJob handlingExceptionJob = new UIJob("IDE Exception Handler") //$NON-NLS-1$
99
{
100                 /*
101                  * (non-Javadoc)
102                  *
103                  * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
104                  */

105                 public IStatus runInUIThread(IProgressMonitor monitor) {
106                     handleException(statusAdapter.getStatus().getException());
107                     return new Status(
108                             IStatus.OK,
109                             IDEWorkbenchPlugin.IDE_WORKBENCH,
110                             IDEWorkbenchMessages.IDEExceptionHandler_ExceptionHandledMessage);
111                 }
112
113             };
114
115             handlingExceptionJob.setSystem(true);
116             handlingExceptionJob.schedule();
117         }
118     }
119
120     private boolean isFatal(final StatusAdapter statusAdapter) {
121         if (statusAdapter.getStatus().getException() != null
122                 && (statusAdapter.getStatus().getException() instanceof OutOfMemoryError JavaDoc
123                         || statusAdapter.getStatus().getException() instanceof StackOverflowError JavaDoc
124                         || statusAdapter.getStatus().getException() instanceof VirtualMachineError JavaDoc || statusAdapter
125                         .getStatus().getException() instanceof SWTError)) {
126             return true;
127         }
128         return false;
129     }
130
131     private void handleException(Throwable JavaDoc t) {
132         try {
133             exceptionCount++;
134             if (exceptionCount > 1) {
135                 dialog.updateMessage(MessageFormat.format(MSG_FATAL_ERROR,
136                         new Object JavaDoc[] { MSG_FATAL_ERROR_Recursive }));
137                 dialog.getShell().forceActive();
138             } else {
139                 if (openQuestionDialog(t)) {
140                     closeWorkbench();
141                 }
142             }
143         } finally {
144             exceptionCount--;
145         }
146     }
147
148     /**
149      * Informs the user about a fatal error. Returns true if the user decide to
150      * exit workbench or if another fatal error happens while reporting it.
151      */

152     private boolean openQuestionDialog(Throwable JavaDoc t) {
153         try {
154             String JavaDoc msg = null;
155             if (t instanceof OutOfMemoryError JavaDoc) {
156                 msg = MSG_OutOfMemoryError;
157             } else if (t instanceof StackOverflowError JavaDoc) {
158                 msg = MSG_StackOverflowError;
159             } else if (t instanceof VirtualMachineError JavaDoc) {
160                 msg = MSG_VirtualMachineError;
161             } else if (t instanceof SWTError) {
162                 msg = MSG_SWTError;
163             } else {
164                 if (t.getMessage() == null) {
165                     msg = IDEWorkbenchMessages.InternalErrorNoArg;
166                 } else {
167                     msg = NLS.bind(IDEWorkbenchMessages.InternalErrorOneArg, t
168                             .getMessage());
169                 }
170             }
171
172             // Always open the dialog in case of major error but do not show the
173
// detail button if not in debug mode.
174
Throwable JavaDoc detail = t;
175             if (!Policy.DEBUG_OPEN_ERROR_DIALOG) {
176                 detail = null;
177             }
178
179             dialog = openInternalQuestionDialog(PlatformUI.getWorkbench()
180                     .getActiveWorkbenchWindow().getShell(),
181                     MSG_FATAL_ERROR_Title, MessageFormat.format(
182                             MSG_FATAL_ERROR, new Object JavaDoc[] { msg }), detail, 1);
183
184             return dialog.open() == 0;
185         } catch (Throwable JavaDoc th) {
186             // Workbench may be in such bad shape (no OS handles left, out of
187
// memory, etc)
188
// that is cannot show a message to the user. Just bail out now.
189
System.err
190                     .println("Error while informing user about event loop exception:"); //$NON-NLS-1$
191
t.printStackTrace();
192             System.err.println("Dialog open exception:"); //$NON-NLS-1$
193
th.printStackTrace();
194             return true;
195         }
196     }
197
198     private FatalErrorDialog openInternalQuestionDialog(Shell parent,
199             String JavaDoc title, String JavaDoc message, Throwable JavaDoc detail, int defaultIndex) {
200         String JavaDoc[] labels;
201         if (detail == null) {
202             labels = new String JavaDoc[] { IDialogConstants.YES_LABEL,
203                     IDialogConstants.NO_LABEL };
204         } else {
205             labels = new String JavaDoc[] { IDialogConstants.YES_LABEL,
206                     IDialogConstants.NO_LABEL,
207                     IDialogConstants.SHOW_DETAILS_LABEL };
208         }
209
210         FatalErrorDialog dialog = new FatalErrorDialog(parent, title, null, // accept
211
// the
212
// default
213
// window
214
// icon
215
message, detail, MessageDialog.QUESTION, labels, defaultIndex);
216         if (detail != null) {
217             dialog.setDetailButton(2);
218         }
219         return dialog;
220     }
221
222     /**
223      * Closes the workbench and make sure all exceptions are handled.
224      */

225     private void closeWorkbench() {
226         if (closing) {
227             return;
228         }
229
230         try {
231             closing = true;
232             if (dialog != null && dialog.getShell() != null
233                     && !dialog.getShell().isDisposed()) {
234                 dialog.close();
235             }
236             workbenchConfigurer.emergencyClose();
237         } catch (RuntimeException JavaDoc re) {
238             // Workbench may be in such bad shape (no OS handles left, out of
239
// memory, etc)
240
// that is cannot even close. Just bail out now.
241
System.err
242                     .println("Fatal runtime error happened during workbench emergency close."); //$NON-NLS-1$
243
re.printStackTrace();
244             throw re;
245         } catch (Error JavaDoc e) {
246             // Workbench may be in such bad shape (no OS handles left, out of
247
// memory, etc)
248
// that is cannot even close. Just bail out now.
249
System.err
250                     .println("Fatal error happened during workbench emergency close."); //$NON-NLS-1$
251
e.printStackTrace();
252             throw e;
253         }
254     }
255
256     private class FatalErrorDialog extends InternalErrorDialog {
257
258         /**
259          * @param parentShell
260          * @param dialogTitle
261          * @param dialogTitleImage
262          * @param dialogMessage
263          * @param detail
264          * @param dialogImageType
265          * @param dialogButtonLabels
266          * @param defaultIndex
267          */

268         public FatalErrorDialog(Shell parentShell, String JavaDoc dialogTitle,
269                 Image dialogTitleImage, String JavaDoc dialogMessage, Throwable JavaDoc detail,
270                 int dialogImageType, String JavaDoc[] dialogButtonLabels,
271                 int defaultIndex) {
272             super(parentShell, dialogTitle, dialogTitleImage, dialogMessage,
273                     detail, dialogImageType, dialogButtonLabels, defaultIndex);
274         }
275
276         /**
277          * Updates the dialog message
278          *
279          * @param message
280          * new message
281          */

282         public void updateMessage(String JavaDoc message) {
283             this.message = message;
284             this.messageLabel.setText(message);
285             this.messageLabel.update();
286         }
287     }
288 }
289
Popular Tags