<commit_before>/*
 *  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.core.classpath.CeylonClasspathUtil.isCeylonClasspathContainer;
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.SubProgressMonitor;
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.core.JavaCore;
import org.eclipse.jdt.internal.ui.InitializeAfterLoadJob;
import org.eclipse.jdt.ui.JavaUI;

import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder;
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)) {
                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 + " ...") {
                    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 + " ...");
                                    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 + " anyway !");
                                }
                            }
                        }
                        
                        boolean shouldSchedule = true;
                        for (Job job : getJobManager().find(initDependenciesJob)) {
                            if (job.getState() == Job.WAITING) {
                                System.out.println("An InitDependenciesJob for project " + project + " 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 + " after the Java Tooling has been initialized");
                            initDependenciesJob.schedule();
                        }   
                        return Status.OK_STATUS;
                    }
                };
                
                initDependenciesWhenJavaToolingIsInitialized.setPriority(Job.BUILD);
                initDependenciesWhenJavaToolingIsInitialized.setSystem(true);
                initDependenciesWhenJavaToolingIsInitialized.schedule(1000);
            }
        }
    }

    public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
        return false;
    }

    public Object getComparisonID(IPath containerPath, IJavaProject project) {
        return project.getProject().getName() + "/" + containerPath;
    }
}
<commit_msg>Wait the end of the Java Tooling Initialization Job before starting Ceylon classpath container initialization Jobs<commit_after>/*
 *  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.core.classpath.CeylonClasspathUtil.isCeylonClasspathContainer;
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.SubProgressMonitor;
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.core.JavaCore;
import org.eclipse.jdt.internal.ui.InitializeAfterLoadJob;
import org.eclipse.jdt.ui.JavaUI;

import com.redhat.ceylon.eclipse.core.builder.CeylonBuilder;
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)) {
                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;
    }
}

{'fraction_non_alphanumeric': 0.07072127139364304, 'fraction_numerical': 0.0026894865525672372, 'mean_word_length': 1.8608148277670922, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '382988', 'n_tokens_mistral': 3845, 'n_tokens_neox': 3621, 'n_words': 995}