blob: 35c75a0dd4c7d1929312c315ba08438f9c7dd8d5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 SSI Schaefer IT Solutions GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SSI Schaefer IT Solutions GmbH
*******************************************************************************/
package org.eclipse.tea.core.ui;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.di.InjectionException;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tea.core.TaskExecutionContext;
import org.eclipse.tea.core.TaskingEngine;
import org.eclipse.tea.core.TaskingInjectionHelper;
import org.eclipse.tea.core.internal.model.TaskingModel;
import org.eclipse.tea.core.services.TaskChain;
import org.eclipse.tea.core.ui.annotations.TaskChainUiInit;
import org.eclipse.ui.PlatformUI;
/**
* Job that wraps running a given task chain.
* <p>
* Note that this {@link Job}'s result is always {@link Status#OK_STATUS} to
* prevent further error handling by Eclipse itself. Errors are handled inside
* the {@link TaskingEngine} already. In case the actual status of the execution
* is required, use {@link #getActualResult()} instead.
*/
public final class TaskingEngineJob extends Job {
private final TaskingEngine engine;
private final Object chain;
private IStatus actualResult;
/**
* @param engine
* the engine to use to run the {@link TaskChain}
* @param chain
* either a {@link TaskChain} or a name identifying a registered
* {@link TaskChain} ({@link String}).
*/
public TaskingEngineJob(TaskingEngine engine, Object chain) {
super("Tasking");
this.chain = chain;
this.engine = engine;
// it is illegal to instantiate the job from outside the UI thread
Assert.isLegal(Display.getCurrent() != null, "Cannot instantiate TaskingEngine Job from non-UI thread");
// fetch the currently active window and set it's shell into the context
// to allow creation of windows with a correct parent shell argument.
if (!TaskingInjectionHelper.isHeadless(engine.getContext())) {
engine.getContext().set(Shell.class, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
try {
// this is run from the UI thread intentionally
ContextInjectionFactory.invoke(chain, TaskChainUiInit.class, engine.getContext(), null);
} catch (InjectionException e) {
if (e.getCause() instanceof OperationCanceledException) {
// UI init cancelled, should not run chain
this.actualResult = Status.CANCEL_STATUS;
} else {
throw e;
}
}
}
}
@Override
protected IStatus run(IProgressMonitor monitor) {
if (actualResult != null) {
// something happened during initialization.
return actualResult;
}
TaskExecutionContext context;
if (chain instanceof TaskChain) {
context = TaskingInjectionHelper.createNewChainContext(engine, (TaskChain) chain, monitor);
} else if (chain instanceof String) {
context = TaskingInjectionHelper.createNewChainContext(engine, (String) chain, monitor);
} else {
return new Status(IStatus.ERROR, Activator.PLUGIN_ID,
"Given object is not a TaskChain or String: " + chain);
}
setName(TaskingModel.getTaskChainName(context.getUnderlyingChain()));
actualResult = engine.runTaskChain(context);
// the engine handles logging of failures internally (using TaskingLog).
// We do not want to report failures multiple times, thus we swallow any
// error condition here to prevent message boxes popping up on the user.
// to still be able to consume the actual status of the job, the
// getActualResult() method must be used.
return Status.OK_STATUS;
}
public IStatus getActualResult() {
return actualResult;
}
@Override
public boolean belongsTo(Object family) {
return family == TaskChain.class;
}
}