001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Chris Gross (schtoo@schtoo.com) - support for ISafeRunnableRunner added
011: * (bug 49497 [RCP] JFace dependency on org.eclipse.core.runtime enlarges standalone JFace applications)
012: *******************************************************************************/package org.eclipse.jface.util;
013:
014: import org.eclipse.core.runtime.ISafeRunnable;
015: import org.eclipse.core.runtime.IStatus;
016: import org.eclipse.core.runtime.OperationCanceledException;
017: import org.eclipse.core.runtime.Status;
018: import org.eclipse.jface.resource.JFaceResources;
019: import org.eclipse.swt.events.DisposeEvent;
020: import org.eclipse.swt.events.DisposeListener;
021: import org.eclipse.swt.widgets.Display;
022:
023: /**
024: * Implements a default implementation of ISafeRunnable. The default
025: * implementation of <code>handleException</code> opens a message dialog.
026: * <p>
027: * <b>Note:<b> This class can open an error dialog and should not be used
028: * outside of the UI Thread.
029: * </p>
030: */
031: public abstract class SafeRunnable implements ISafeRunnable {
032:
033: private static boolean ignoreErrors = false;
034:
035: private static ISafeRunnableRunner runner;
036:
037: private String message;
038:
039: private static SafeRunnableDialog dialog;
040:
041: /**
042: * Creates a new instance of SafeRunnable with a default error message.
043: */
044: public SafeRunnable() {
045: // do nothing
046: }
047:
048: /**
049: * Creates a new instance of SafeRunnable with the given error message.
050: *
051: * @param message
052: * the error message to use
053: */
054: public SafeRunnable(String message) {
055: this .message = message;
056: }
057:
058: /* (non-Javadoc)
059: * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
060: */
061: public void handleException(Throwable e) {
062: // Workaround to avoid interactive error dialogs during automated
063: // testing
064: if (!ignoreErrors) {
065: if (message == null)
066: message = JFaceResources
067: .getString("SafeRunnable.errorMessage"); //$NON-NLS-1$
068:
069: final IStatus status = new Status(IStatus.ERROR,
070: Policy.JFACE, message, e);
071:
072: Runnable runnable = new Runnable() {
073: public void run() {
074: if (dialog == null
075: || dialog.getShell().isDisposed()) {
076: dialog = new SafeRunnableDialog(status);
077: dialog.create();
078: dialog.getShell().addDisposeListener(
079: new DisposeListener() {
080: public void widgetDisposed(
081: DisposeEvent e) {
082: dialog = null;
083: }
084: });
085: dialog.open();
086: } else {
087: dialog.addStatus(status);
088: dialog.refresh();
089: }
090: }
091: };
092: if (Display.getCurrent() != null) {
093: runnable.run();
094: } else {
095: Display.getDefault().asyncExec(runnable);
096: }
097: }
098: }
099:
100: /**
101: * Flag to avoid interactive error dialogs during automated testing.
102: *
103: * @param flag
104: * @return true if errors should be ignored
105: * @deprecated use getIgnoreErrors()
106: */
107: public static boolean getIgnoreErrors(boolean flag) {
108: return ignoreErrors;
109: }
110:
111: /**
112: * Flag to avoid interactive error dialogs during automated testing.
113: *
114: * @return true if errors should be ignored
115: *
116: * @since 3.0
117: */
118: public static boolean getIgnoreErrors() {
119: return ignoreErrors;
120: }
121:
122: /**
123: * Flag to avoid interactive error dialogs during automated testing.
124: *
125: * @param flag
126: * set to true if errors should be ignored
127: */
128: public static void setIgnoreErrors(boolean flag) {
129: ignoreErrors = flag;
130: }
131:
132: /**
133: * Returns the safe runnable runner.
134: *
135: * @return the safe runnable runner
136: *
137: * @since 3.1
138: */
139: public static ISafeRunnableRunner getRunner() {
140: if (runner == null) {
141: runner = createDefaultRunner();
142: }
143: return runner;
144: }
145:
146: /**
147: * Creates the default safe runnable runner.
148: *
149: * @return the default safe runnable runner
150: * @since 3.1
151: */
152: private static ISafeRunnableRunner createDefaultRunner() {
153: return new ISafeRunnableRunner() {
154: public void run(ISafeRunnable code) {
155: try {
156: code.run();
157: } catch (Exception e) {
158: handleException(code, e);
159: } catch (LinkageError e) {
160: handleException(code, e);
161: }
162: }
163:
164: private void handleException(ISafeRunnable code, Throwable e) {
165: if (!(e instanceof OperationCanceledException)) {
166: try {
167: Policy.getLog().log(
168: new Status(IStatus.ERROR, Policy.JFACE,
169: IStatus.ERROR,
170: "Exception occurred", e)); //$NON-NLS-1$
171: } catch (Exception ex) {
172: e.printStackTrace();
173: }
174: }
175: code.handleException(e);
176: }
177: };
178: }
179:
180: /**
181: * Sets the safe runnable runner.
182: *
183: * @param runner
184: * the runner to set, or <code>null</code> to reset to the
185: * default runner
186: * @since 3.1
187: */
188: public static void setRunner(ISafeRunnableRunner runner) {
189: SafeRunnable.runner = runner;
190: }
191:
192: /**
193: * Runs the given safe runnable using the safe runnable runner. This is a
194: * convenience method, equivalent to:
195: * <code>SafeRunnable.getRunner().run(runnable)</code>.
196: *
197: * @param runnable
198: * the runnable to run
199: * @since 3.1
200: */
201: public static void run(ISafeRunnable runnable) {
202: getRunner().run(runnable);
203: }
204:
205: }
|