/*
* Copyright (c) 2015 the original author or authors.
* 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:
* Etienne Studer & Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation
*/
package org.eclipse.buildship.core.launch;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.buildship.core.CorePlugin;
/**
* Execute Gradle tasks from the run configurations.
* <p>
* The delegate invokes the {@link RunGradleBuildLaunchRequestJob} job to do the actual execution
* and waits until it finishes. It also propagates the cancellation to that job.
*/
public final class GradleRunConfigurationDelegate extends LaunchConfigurationDelegate {
// configuration type id declared in the plugin.xml
public static final String ID = "org.eclipse.buildship.core.launch.runconfiguration";
@Override
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) {
monitor.beginTask("Launch Gradle tasks", IProgressMonitor.UNKNOWN);
try {
// schedule the task
final CountDownLatch latch = new CountDownLatch(1);
RunGradleBuildLaunchRequestJob job = new RunGradleBuildLaunchRequestJob(launch);
job.addJobChangeListener(new JobChangeAdapter() {
@Override
public void done(IJobChangeEvent event) {
latch.countDown();
}
});
job.schedule();
// block until the task execution job has finished successfully or failed,
// periodically check if this launch has been cancelled, and if so, cancel
// the task execution job
try {
boolean cancelRequested = false;
while (!latch.await(500, TimeUnit.MILLISECONDS)) {
// regularly check if the job was cancelled
// until the job is either finished or failed
if (monitor.isCanceled() && !cancelRequested) {
// cancel the job only once
job.cancel();
cancelRequested = true;
}
}
} catch (InterruptedException e) {
CorePlugin.logger().error("Failed to launch Gradle tasks.", e);
}
} finally {
monitor.done();
// explicitly remove the launch since the code in DebugPlugin never removes the launch
// (we depend on the removal event being sent in the 'close console actions' since no
// other events of interest to us get ever fired)
DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
}
}
}