package com.dubture.composer.ui.job;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.io.FileUtils;
import org.eclipse.core.internal.resources.Project;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.pdtextensions.core.launch.ScriptLauncher;
import org.pdtextensions.core.launch.execution.ExecutionResponseListener;
import com.dubture.composer.core.log.Logger;
import com.dubture.getcomposer.packages.PharDownloader;
@SuppressWarnings("restriction")
public class CreateProjectJob extends ComposerJob {
private final String projectName;
private final String packageName;
private IPath composerPath;
private IPath path;
private JobListener initListener;
private String packageVersion;
private boolean startNotified = false;
private boolean existed;
private File composerFile;
public CreateProjectJob(IPath path, String projectName, String packageName, String packageVersion) {
super("Creating composer project");
this.projectName = projectName;
this.packageName = packageName;
this.packageVersion = packageVersion;
this.path = path;
Logger.debug("Creating new project " + projectName + " from package " + packageName + " / " + packageVersion);
ResourcesPlugin.getWorkspace();
DummyProject project = new DummyProject(path);
setProject(project);
try {
//TODO: cache the phar file locally
composerPath = path.append("composer.phar");
composerFile = composerPath.toFile();
existed = true;
if (!composerFile.exists()) {
existed = false;
PharDownloader downloader = new PharDownloader();
InputStream resource = downloader.download();
FileUtils.copyInputStreamToFile(resource, composerFile);
}
} catch (Exception e) {
Logger.logException(e);
}
}
@Override
protected void launch(ScriptLauncher launcher) throws ExecuteException, IOException, InterruptedException {
// cloning large projects can take a long time...
//TODO: make this configurable via preferences
launcher.setTimeout(5 * 60000);
launcher.addResponseListener(new ExecutionResponseListener() {
@Override
public void executionStarted() {
}
@Override
public void executionMessage(String message) {
try {
if(composerExists() /*message != null && message.equals("Loading composer repositories with package information")*/) {
notifyOnStart();
}
} catch (Exception e) {
Logger.logException(e);
}
}
@Override
public void executionFinished(String response, int exitValue) {
notifyOnFinish();
}
@Override
public void executionFailed(String response, Exception exception) {
notifyOnFail();
}
@Override
public void executionError(String message) {
notifyOnFail();
}
@Override
public void executionAboutToStart() {
}
});
launcher.launch("create-project", new String[]{"--no-interaction", packageName, projectName, packageVersion});
}
protected class DummyProject extends Project {
public DummyProject(IPath path) {
this(path, (Workspace) ResourcesPlugin.getWorkspace());
}
protected DummyProject(IPath path, Workspace container) {
super(path, container);
}
@Override
public IResource findMember(String path) {
return new DummyResource();
}
@Override
public IPath getLocation() {
return path;
}
}
private boolean composerExists() {
IPath projectPath = path.append(projectName).append("composer.json");
return projectPath.toFile().exists();
}
public class DummyResource extends org.eclipse.core.internal.resources.File {
protected DummyResource() {
super(new Path("/"), null);
}
public IPath getFullPath() {
return new Path("/dummy/composer.phar");
}
}
public void setJobListener(JobListener latch) {
this.initListener = latch;
}
private void notifyOnStart() {
try {
if (startNotified || initListener == null) {
return;
}
initListener.jobStarted();
startNotified = true;
} catch (Exception e) {
Logger.logException(e);
}
}
private void notifyOnFinish() {
try {
if (initListener == null) {
return;
}
initListener.jobFinished(projectName);
} catch (Exception e) {
Logger.logException(e);
}
}
private void notifyOnFail() {
try {
if (initListener == null) {
return;
}
initListener.jobFailed();
} catch (Exception e) {
Logger.logException(e);
}
}
public interface JobListener {
void jobStarted();
void jobFinished(String projectName);
void jobFailed();
}
protected void cleanup() {
if (existed == false && composerFile != null) {
composerFile.delete();
}
}
}