/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.redhat.ceylon.eclipse.core.classpath; import static com.redhat.ceylon.eclipse.core.classpath.CeylonClasspathUtil.getCeylonClasspathEntry; import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.modelJ2C; import static org.eclipse.core.resources.ResourcesPlugin.getWorkspace; import static org.eclipse.jdt.core.JavaCore.getClasspathContainer; import static org.eclipse.jdt.core.JavaCore.setClasspathContainer; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; 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.ClasspathContainerInitializer; import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.internal.ui.InitializeAfterLoadJob; import org.eclipse.jdt.ui.JavaUI; import com.redhat.ceylon.eclipse.core.classpath.InitDependenciesJob; /** * Initializes the Ceylon class path container. It will create * a container from the persisted class path entries (the * .classpath file), and then schedule the refresh of the * container. */ public class CeylonProjectModulesInitializer extends ClasspathContainerInitializer { /** * Initialize the container with the "persisted" classpath * entries, and then schedule the refresh. */ public void initialize(IPath containerPath, final IJavaProject project) throws CoreException { int size = containerPath.segmentCount(); if (size > 0) { if (containerPath.segment(0).equals(CeylonProjectModulesContainer.CONTAINER_ID)) { modelJ2C().ceylonModel().addProject(project.getProject()); IClasspathContainer c = getClasspathContainer(containerPath, project); CeylonProjectModulesContainer container; if (c instanceof CeylonProjectModulesContainer) { container = (CeylonProjectModulesContainer) c; } else { IClasspathEntry entry = getCeylonClasspathEntry(containerPath, project); IClasspathAttribute[] attributes = entry == null ? new IClasspathAttribute[0] : entry.getExtraAttributes(); if (c == null) { container = new CeylonProjectModulesContainer(project, containerPath, new IClasspathEntry[0], attributes); } else { // this might be the persisted one: reuse the persisted entries container = new CeylonProjectModulesContainer(project, containerPath, c.getClasspathEntries(), attributes); } } setClasspathContainer(containerPath, new IJavaProject[] { project }, new IClasspathContainer[] {container}, null); final Job initDependenciesJob = new InitDependenciesJob("Initializing dependencies for project " + project.getElementName(), container); initDependenciesJob.setUser(false); initDependenciesJob.setPriority(Job.BUILD); initDependenciesJob.setRule(getWorkspace().getRoot()); // Before scheduling the InitDependenciesJob, we will wait for the end of the Java Tooling initialization Job final long waitUntil = System.currentTimeMillis() + 120000; Job initDependenciesWhenJavaToolingIsInitialized = new Job("Waiting for the end of the Java Tooling Initialization before initializing Ceylon dependencies for project " + project.getElementName() + " ...") { private Job initJavaToolingJob = null; @Override protected IStatus run(IProgressMonitor monitor) { if (initJavaToolingJob == null) { Job[] jobs = getJobManager().find(JavaUI.ID_PLUGIN); for (Job job : jobs) { if (job.getClass().getEnclosingClass().equals(InitializeAfterLoadJob.class)) { initJavaToolingJob = job; } } } if (initJavaToolingJob != null) { if (initJavaToolingJob.getState() == Job.WAITING || initJavaToolingJob.getState() == Job.RUNNING) { if (System.currentTimeMillis() < waitUntil) { // System.out.println("Waiting 1 seconde more for the end of the Java Tooling Initialization before initializing Ceylon dependencies for project " + project.getElementName() + " ..."); schedule(1000); return Status.OK_STATUS; } else { // System.out.println("The Java Tooling is not initialized after 2 minutes, so start initializing Ceylon dependencies for project " + project.getElementName() + " anyway !"); } } } boolean shouldSchedule = true; for (Job job : getJobManager().find(initDependenciesJob)) { if (job.getState() == Job.WAITING) { // System.out.println("An InitDependenciesJob for project " + project.getElementName() + " is already scheduled. Finally don't schedule a new one after the Java Tooling has initialized"); shouldSchedule = false; break; } } if (shouldSchedule) { // System.out.println("Scheduling the initialization of the Ceylon dependencies for project " + project.getElementName() + " after the Java Tooling has been initialized"); initDependenciesJob.schedule(); } return Status.OK_STATUS; } }; initDependenciesWhenJavaToolingIsInitialized.setPriority(Job.BUILD); initDependenciesWhenJavaToolingIsInitialized.setSystem(true); initDependenciesWhenJavaToolingIsInitialized.schedule(); } } } public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) { return false; } public Object getComparisonID(IPath containerPath, IJavaProject project) { return project.getProject().getName() + "/" + containerPath; } }