AbstractMultiJobHandler.java
package org.osate.ui.handlers;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.osate.core.AadlNature;
/**
* Abstract root class for handlers that generate multiple independent jobs and that shows a single
* result dialog at the end showing their status.
*
* NB. This is not fully formed right now but I am leaving it as a placeholder for future work to
* abstract the commonalities between {@link InstantiationHandler} and {@link ReinstantiationHandler}.
* Really the only thing in here right now is the class used for storing job results.
* @since 3.0
*/
@Deprecated
public abstract class AbstractMultiJobHandler extends AbstractHandler {
/**
* Records the state of one of the jobs, i.e, was it successful, was it cancelled, did it have
* an error of some sort?
*
* <p>The job is <i>cancelled</i> if the user cancelled it via the progress monitor. When {@link #cancelled}
* is non-{@code true}, {@link #successful} must be {@code false}.
*
* <p>An <i>error</i> is a message that was generated by internals of the job when
* the job found something wrong. When {@link #errorMessage} is non-{@code null}, {@link #successful}
* must be {@code false}.
*
* <P>An <i>exception<i> is an exception that was thrown during execution of the job. Here we expect
* this to be some low-level eclipse craziness that the job is not equipped to deal with. It is expected
* that a job either has an error, an exception, or neither, but never both. When {@link #exception} is
* non-{@code null}, {@link #successful} must be {@code false}.
*/
public static final class Result {
/**
* The result value for a job that has not been scheduled or executed yet. This is used to
* initialize the set of results for a set of jobs. It identifies a job as cancelled
* because a job that is cancelled by the user before it runs never updates its state
* in the shared list of jobs, so we must make its initial state as cancelled.
*/
public static final Result NOT_EXECUTED = new Result(false, true, null, null);
/* Make everything final here so that this class is thread-safe immutable */
public final boolean successful;
public final boolean cancelled;
public final String errorMessage;
public final Exception exception;
public Result(final boolean successful, final boolean cancelled, final String errorMessage,
final Exception exception) {
this.successful = successful;
this.cancelled = cancelled;
this.errorMessage = errorMessage;
this.exception = exception;
}
/**
* @since 4.0
*/
public static boolean allSuccessful(final Collection<Result> results) {
boolean allSuccessful = true;
for (final Result r : results) {
allSuccessful &= r.successful;
}
return allSuccessful;
}
}
/**
* Ask to save all the dirty editors that belong to open AADL projects.
* @return {@code true} If the action should continue; {@code false} if the user
* selected the cancel option in the save dialog.
*/
protected boolean saveDirtyEditors() {
/* Find all the open AADL projects */
final IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
final List<IProject> openAADLProjects = new ArrayList<>(allProjects.length);
for (final IProject project : allProjects) {
if (project.isOpen() && AadlNature.hasNature(project)) {
openAADLProjects.add(project);
}
}
final AtomicBoolean result = new AtomicBoolean();
PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
result.set(IDE.saveAllEditors(openAADLProjects.toArray(new IProject[openAADLProjects.size()]), true));
});
return result.get();
}
protected AbstractMultiJobHandler() {
super();
}
}