/*******************************************************************************
* Copyright (c) 2012, 2016, 2017 PDT Extension Group 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:
* PDT Extension Group - initial API and implementation
* Kaloyan Raev - [501269] externalize strings
* Kaloyan Raev - [511744] Wizard freezes if no PHP executable is configured
*******************************************************************************/
package org.eclipse.php.composer.ui.job;
import java.io.IOException;
import java.util.Objects;
import org.apache.commons.exec.ExecuteException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.window.Window;
import org.eclipse.php.composer.core.ComposerPlugin;
import org.eclipse.php.composer.core.launch.ExecutableNotFoundException;
import org.eclipse.php.composer.core.launch.ScriptLauncher;
import org.eclipse.php.composer.core.launch.ScriptNotFoundException;
import org.eclipse.php.composer.core.launch.environment.ComposerEnvironmentFactory;
import org.eclipse.php.composer.core.launch.environment.Environment;
import org.eclipse.php.composer.core.log.Logger;
import org.eclipse.php.composer.ui.ComposerUIPlugin;
import org.eclipse.php.composer.ui.job.runner.ComposerFailureMessageRunner;
import org.eclipse.php.composer.ui.job.runner.MissingExecutableRunner;
import org.eclipse.php.composer.ui.terminal.ComposerLauncher;
import org.eclipse.swt.widgets.Display;
abstract public class ComposerJob extends Job {
private IProject project;
private IProgressMonitor monitor;
private boolean cancelling = false;
private ScriptLauncher launcher;
protected static final IStatus ERROR_STATUS = new Status(Status.ERROR, ComposerPlugin.ID,
Messages.ComposerJob_ErrorMessage);
public ComposerJob(String name) {
super(name);
}
public ComposerJob(IProject project, String name) {
this(name);
this.setProject(project);
}
@Override
public boolean belongsTo(Object family) {
return Objects.equals(ComposerUIPlugin.FAMILY_COMPOSER, family) || Objects.equals(project, family)
|| (project != null && Objects.equals(project.getName(), family));
}
@Override
protected void canceling() {
if (cancelling || launcher == null || !monitor.isCanceled()) {
return;
}
launcher.abort();
monitor.done();
cancelling = true;
}
@Override
protected IStatus run(final IProgressMonitor monitor) {
boolean callDoOnLauncherRunException = false;
try {
this.monitor = monitor;
boolean tryAgain = false;
do {
try {
Environment env = new ComposerEnvironmentFactory().getEnvironment(getProject());
if (env == null) {
throw new ExecutableNotFoundException(Messages.ComposerJob_CannotFindExe);
}
launcher = new ComposerLauncher(env, getProject());
tryAgain = false;
} catch (ExecutableNotFoundException e) {
// inform the user of the missing executable
MissingExecutableRunner runner = new MissingExecutableRunner();
Display.getDefault().syncExec(runner);
if (runner.getReturnCode() == Window.OK) {
tryAgain = true;
} else {
callDoOnLauncherRunException = true;
doOnLauncherRunException(e);
return Status.OK_STATUS;
}
} catch (ScriptNotFoundException e) {
callDoOnLauncherRunException = true;
doOnLauncherRunException(e);
if (tryAgain) {
Display.getDefault().asyncExec(
new ComposerFailureMessageRunner(Messages.ComposerJob_DownloadErrorMessage, monitor));
return Status.OK_STATUS;
} else {
// run the downloader
DownloadJob job = new DownloadJob(getProject());
job.schedule();
job.join();
tryAgain = true;
}
}
} while (tryAgain);
monitor.beginTask(getName(), IProgressMonitor.UNKNOWN);
monitor.worked(1);
launch(launcher);
monitor.worked(1);
// refresh project
if (getProject() != null) {
getProject().refreshLocal(IProject.DEPTH_INFINITE, null);
monitor.worked(1);
}
} catch (Exception e) {
if (!callDoOnLauncherRunException) {
callDoOnLauncherRunException = true;
doOnLauncherRunException(e);
}
Logger.logException(e);
return ERROR_STATUS;
} finally {
monitor.done();
}
return Status.OK_STATUS;
}
protected void doOnLauncherRunException(Exception e) {
}
abstract protected void launch(ScriptLauncher launcher) throws ExecuteException, IOException, InterruptedException;
public IProject getProject() {
return project;
}
public void setProject(IProject project) {
this.project = project;
}
}