/******************************************************************************* * Copyright (c) 2012 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat Incorporated - initial API and implementation ******************************************************************************/ package org.jboss.tools.openshift.internal.common.core.job; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; /** * @author Andre Dietisheim */ public class JobChainBuilder { public static class NullCondition implements ISchedulingCondition { @Override public boolean isFullfilled(Job preceedingJob) { return true; } } public static class SuccessfullyDoneCondition implements ISchedulingCondition { @Override public boolean isFullfilled(Job preceedingJob) { return preceedingJob != null && preceedingJob.getResult() != null && preceedingJob.getResult().isOK(); } } private Job job; private IProgressMonitor progressMonitor; public JobChainBuilder(Job job) { this(job, new NullProgressMonitor()); } public JobChainBuilder(Job job, IProgressMonitor progressMonitor) { this.job = job; setProgressMonitor(progressMonitor); } /** * Sets progress monitor to provide canceling of jobs that are not yet executed. * Provides an alternative approach to cancel() method. * Always sets the inner instance to a non-null value. * @param progressMonitor */ public JobChainBuilder setProgressMonitor(IProgressMonitor progressMonitor) { this.progressMonitor = (progressMonitor == null) ? new NullProgressMonitor() : progressMonitor; return this; } /** * Runs the given job if it's predecessor was executed (successfully or not) and the given condition is fullfilled. * * @param job to be scheduled if its predecessor was executed * @return */ public JobChainBuilder runWhenDoneIf(final ISchedulingCondition condition, Job constrainedJob) { job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { if(!progressMonitor.isCanceled() && (condition == null || condition.isFullfilled(job))) { constrainedJob.schedule(); } } }); return new JobConstraint(constrainedJob, this); } /** * Runs the given job if it's predecessor was executed (successfully or not). * * @param job to be scheduled if its predecessor was executed * @return */ public JobChainBuilder runWhenDone(final Job constrainedJob) { return runWhenDoneIf(new NullCondition(), constrainedJob); } /** * Runs the given job if it's predecessor executed successfully. * * @param job to be scheduled if its predecessor was executed successfully * @return */ public JobChainBuilder runWhenSuccessfullyDone(final Job constrainedJob) { return runWhenDoneIf(new SuccessfullyDoneCondition(), constrainedJob); } /** * Builds the chain of jobs. Wont schedule anything. * * @return */ public Job build() { return job; } /** * Schedules the whole chain of jobs */ public void schedule() { if(!progressMonitor.isCanceled()) { job.schedule(); } } /** * Cancels jobs that are not executed yet. */ public void cancel() { progressMonitor.setCanceled(true); } public class JobConstraint extends JobChainBuilder { private JobChainBuilder builder; private JobConstraint(Job job, JobChainBuilder builder) { super(job, builder.progressMonitor); this.builder = builder; } /** * Builds the chain of jobs. Wont schedule anything. * * @return */ public Job build() { return builder.build(); } /** * Schedules the whole chain of jobs */ public void schedule() { builder.schedule(); } } public static interface ISchedulingCondition { public boolean isFullfilled(Job preceedingJob); } }