001: /*******************************************************************************
002: * Copyright (c) 2003, 2006 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 - Initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.progress;
011:
012: import org.eclipse.core.runtime.Assert;
013: import org.eclipse.core.runtime.IProgressMonitor;
014: import org.eclipse.core.runtime.IStatus;
015: import org.eclipse.core.runtime.Status;
016: import org.eclipse.core.runtime.jobs.Job;
017: import org.eclipse.swt.widgets.Display;
018: import org.eclipse.ui.PlatformUI;
019: import org.eclipse.ui.internal.WorkbenchPlugin;
020: import org.eclipse.ui.internal.misc.UIStats;
021: import org.eclipse.ui.internal.progress.ProgressMessages;
022:
023: /**
024: * The UIJob is a Job that runs within the UI Thread via an asyncExec.
025: *
026: * @since 3.0
027: */
028: public abstract class UIJob extends Job {
029: private Display cachedDisplay;
030:
031: /**
032: * Create a new instance of the receiver with the supplied name. The display
033: * used will be the one from the workbench if this is available. UIJobs with
034: * this constructor will determine thier display at runtime.
035: *
036: * @param name
037: * the job name
038: *
039: */
040: public UIJob(String name) {
041: super (name);
042: }
043:
044: /**
045: * Create a new instance of the receiver with the supplied Display.
046: *
047: * @param jobDisplay
048: * the display
049: * @param name
050: * the job name
051: * @see Job
052: */
053: public UIJob(Display jobDisplay, String name) {
054: this (name);
055: setDisplay(jobDisplay);
056: }
057:
058: /**
059: * Convenience method to return a status for an exception.
060: *
061: * @param exception
062: * @return IStatus an error status built from the exception
063: * @see Job
064: */
065: public static IStatus errorStatus(Throwable exception) {
066: return WorkbenchPlugin.getStatus(exception);
067: }
068:
069: /**
070: * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
071: * Note: this message is marked final. Implementors should use
072: * runInUIThread() instead.
073: */
074: public final IStatus run(final IProgressMonitor monitor) {
075: if (monitor.isCanceled()) {
076: return Status.CANCEL_STATUS;
077: }
078: Display asyncDisplay = getDisplay();
079: if (asyncDisplay == null || asyncDisplay.isDisposed()) {
080: return Status.CANCEL_STATUS;
081: }
082: asyncDisplay.asyncExec(new Runnable() {
083: public void run() {
084: IStatus result = null;
085: try {
086: //As we are in the UI Thread we can
087: //always know what to tell the job.
088: setThread(Thread.currentThread());
089: if (monitor.isCanceled()) {
090: result = Status.CANCEL_STATUS;
091: } else {
092: UIStats.start(UIStats.UI_JOB, getName());
093: result = runInUIThread(monitor);
094: }
095:
096: } finally {
097: UIStats.end(UIStats.UI_JOB, UIJob.this , getName());
098: if (result == null) {
099: result = new Status(IStatus.ERROR,
100: PlatformUI.PLUGIN_ID, IStatus.ERROR,
101: ProgressMessages.Error, null);
102: }
103: done(result);
104: }
105: }
106: });
107: return Job.ASYNC_FINISH;
108: }
109:
110: /**
111: * Run the job in the UI Thread.
112: *
113: * @param monitor
114: * @return IStatus
115: */
116: public abstract IStatus runInUIThread(IProgressMonitor monitor);
117:
118: /**
119: * Sets the display to execute the asyncExec in. Generally this is not'
120: * used if there is a valid display avaialble via PlatformUI.isWorkbenchRunning().
121: *
122: * @param runDisplay
123: * Display
124: * @see UIJob#getDisplay()
125: * @see PlatformUI#isWorkbenchRunning()
126: */
127: public void setDisplay(Display runDisplay) {
128: Assert.isNotNull(runDisplay);
129: cachedDisplay = runDisplay;
130: }
131:
132: /**
133: * Returns the display for use by the receiver when running in an
134: * asyncExec. If it is not set then the display set in the workbench
135: * is used.
136: * If the display is null the job will not be run.
137: *
138: * @return Display or <code>null</code>.
139: */
140: public Display getDisplay() {
141: //If it was not set get it from the workbench
142: if (cachedDisplay == null && PlatformUI.isWorkbenchRunning()) {
143: return PlatformUI.getWorkbench().getDisplay();
144: }
145: return cachedDisplay;
146: }
147: }
|