package com.redhat.ceylon.eclipse.core.classpath;
import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.utilJ2C;
import static com.redhat.ceylon.eclipse.ui.CeylonPlugin.PLUGIN_ID;
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.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder;
import com.redhat.ceylon.ide.common.util.ProgressMonitor$impl;
public class InitDependenciesJob extends Job {
private final CeylonProjectModulesContainer container;
private boolean retriedAfterAddingTheLanguageModuleEntry = false;
public InitDependenciesJob(String name, CeylonProjectModulesContainer container) {
super(name);
this.container = container;
}
@Override
protected IStatus run(IProgressMonitor monitor) {
ProgressMonitor$impl<IProgressMonitor>.Progress progress =
utilJ2C().wrapProgressMonitor(monitor)
.Progress$new$(1000, null);
try {
final IJavaProject javaProject = container.getJavaProject();
final IProject project = javaProject.getProject();
boolean languageModuleContainerFound = false;
IClasspathEntry[] entries = javaProject.getRawClasspath();
for (int i = 0; i < entries.length; i++) {
IClasspathEntry entry = entries[i];
if (entry != null && entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
if (CeylonClasspathUtil.isLanguageModuleClasspathContainer(entry.getPath())) {
languageModuleContainerFound = true;
break;
}
}
}
if (!languageModuleContainerFound && !retriedAfterAddingTheLanguageModuleEntry) {
retriedAfterAddingTheLanguageModuleEntry = true;
new CeylonLanguageModuleContainer(project).install();
schedule(1000);
return Status.OK_STATUS;
}
boolean changed = container.resolveClasspath(progress.newChild(800), true);
if(changed) {
container.refreshClasspathContainer(progress.newChild(200));
}
// Schedule a build of the project :
// - with referenced projects
// - with referencing projects (TODO : not sure it's really useful
// in the context of the project initialization,
// but let's not change for the moment)
// - and don't rebuild if the model is already typechecked
final Job buildJob = new BuildProjectAfterClasspathChangeJob("Initial build of project " +
project.getName(), project, true, true, false);
buildJob.setRule(project.getWorkspace().getRoot());
buildJob.setPriority(Job.BUILD);
// Before scheduling the Build Job, we will wait for the end of the classpath container initialization for 2 minutes
final long waitUntil = System.currentTimeMillis() + 120000;
Job buildWhenAllContainersAreInitialized = new Job("Waiting for all dependencies to be initialized before building project " + project + " ...") {
@Override
protected IStatus run(IProgressMonitor monitor) {
if (! CeylonBuilder.allClasspathContainersInitialized()) {
if (System.currentTimeMillis() < waitUntil) {
//System.out.println("Waiting 1 seconde more for classpath container initialization before building project " + project + " ...");
schedule(1000);
return Status.OK_STATUS;
}
else {
//System.out.println("All the classpath containers are not initialized after 1 minute, so build project " + project + " anyway !");
}
}
boolean shouldSchedule = true;
for (Job job : getJobManager().find(buildJob)) {
if (job.getState() == Job.WAITING) {
//System.out.println("A build of project " + project + " is already scheduled. Finally don't schedule a new one after all classpath containers have been initialized");
shouldSchedule = false;
break;
}
}
if (shouldSchedule) {
//System.out.println("Scheduling build of project " + project + " after all classpath containers have been initialized");
buildJob.schedule();
}
return Status.OK_STATUS;
}
};
buildWhenAllContainersAreInitialized.setPriority(BUILD);
buildWhenAllContainersAreInitialized.setSystem(true);
buildWhenAllContainersAreInitialized.schedule();
CeylonBuilder.setContainerInitialized(project);
return Status.OK_STATUS;
}
catch (JavaModelException ex) {
// unless there are issues with the JDT, this should never happen
return new Status(IStatus.ERROR, PLUGIN_ID,
"could not get container", ex);
}
finally {
progress.destroy(null);
}
}
@Override
public boolean belongsTo(Object family) {
if (family instanceof InitDependenciesJob) {
InitDependenciesJob otherJob = (InitDependenciesJob) family;
return container.getJavaProject().getProject().equals(otherJob.container.getJavaProject().getProject());
}
return false;
}
}