diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/META-INF/MANIFEST.MF index 00d9a8579..312fb2727 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/META-INF/MANIFEST.MF @@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.8.0", com.google.guava, org.eclipse.debug.ui, org.eclipse.ui.console, - org.springframework.tooling.jdt.ls.commons + org.springframework.tooling.jdt.ls.commons, + org.eclipse.ui.ide Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: org.springframework.tooling.ls.eclipse.commons, diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/ProjectSorter.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/ProjectSorter.java new file mode 100644 index 000000000..9ac2e05f1 --- /dev/null +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/ProjectSorter.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2018 Pivotal, Inc. + * 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: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.tooling.ls.eclipse.commons; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; + +public class ProjectSorter implements Comparator { + + private IProject activeProject; + private Set projectsWithEditors; + + public ProjectSorter() { + + this.projectsWithEditors = new HashSet(); + + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + @Override + public void run() { + IEditorPart activeEditor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); + IEditorInput editorInput = activeEditor.getEditorInput(); + activeProject = getProject(editorInput); + + IWorkbenchPage[] pages = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPages(); + for (IWorkbenchPage page : pages) { + IEditorReference[] references = page.getEditorReferences(); + for (IEditorReference editorReference : references) { + try { + IEditorInput additionalInput = editorReference.getEditorInput(); + IProject additionalProject = getProject(additionalInput); + + if (additionalProject != null && additionalProject != activeProject) { + projectsWithEditors.add(additionalProject); + } + } catch (PartInitException e) { + // ignore this editor + } + } + } + } + }); + } + + private IProject getProject(IEditorInput editorInput) { + if (editorInput != null && editorInput instanceof FileEditorInput) { + FileEditorInput fileInput = (FileEditorInput) editorInput; + return fileInput.getFile() != null ? fileInput.getFile().getProject() : null; + } + else { + return null; + } + } + + @Override + public int compare(IProject o1, IProject o2) { + return score(o2) - score(o1); + } + + private int score(IProject project) { + if (project == null) return 0; + + if (project == activeProject) return 10; + if (projectsWithEditors.contains(project)) return 5; + + return 0; + } + +} diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java index 48db9fcb3..487570209 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java @@ -50,9 +50,10 @@ import com.google.common.collect.ImmutableMap; @SuppressWarnings("restriction") public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4LanguageClient { - private static ReusableClasspathListenerHandler classpathService = new ReusableClasspathListenerHandler( + private static ReusableClasspathListenerHandler classpathService = new ReusableClasspathListenerHandler ( Logger.forEclipsePlugin(LanguageServerCommonsActivator::getInstance), - new LSP4ECommandExecutor() + new LSP4ECommandExecutor(), + () -> new ProjectSorter() ); public STS4LanguageClientImpl() { diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java index d58f71e5a..a9bf01005 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons.test/src/org/springframework/tooling/jdt/ls/commons/test/ClasspathListenerHandlerTest.java @@ -42,8 +42,6 @@ import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.springframework.tooling.jdt.ls.commons.Logger; -import org.springframework.tooling.jdt.ls.commons.Logger.DefaultLogger; import org.springframework.tooling.jdt.ls.commons.Logger.TestLogger; import org.springframework.tooling.jdt.ls.commons.classpath.Classpath; import org.springframework.tooling.jdt.ls.commons.classpath.Classpath.CPE; diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java index c40515140..e8ec4c53b 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java @@ -10,6 +10,10 @@ *******************************************************************************/ package org.springframework.tooling.jdt.ls.commons.classpath; +import java.util.Arrays; +import java.util.Comparator; +import java.util.function.Supplier; + import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -21,8 +25,6 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.springframework.tooling.jdt.ls.commons.Logger; -import static org.springframework.tooling.jdt.ls.commons.Logger.*; - /** * An instance of this class provides a means to register * listeners that get notified when classpath for a IJavaProject @@ -91,14 +93,20 @@ public class ClasspathListenerManager { * This allows clients to become aware of all classpaths from the start and * continually monitor them for changes from that point onward. */ - public ClasspathListenerManager(Logger logger, ClasspathListener listener, boolean initialEvent) { + public ClasspathListenerManager(Logger logger, ClasspathListener listener, boolean initialEvent, Supplier> projectSorterFactory) { this.logger = logger; logger.log("Setting up ClasspathListenerManager"); this.listener = listener; JavaCore.addElementChangedListener(myListener=new MyListener(), ElementChangedEvent.POST_CHANGE); if (initialEvent) { logger.log("Sending initial event for all projects ..."); - for (IProject p : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { + + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + if (projectSorterFactory != null) { + Arrays.sort(projects, projectSorterFactory.get()); + } + + for (IProject p : projects) { logger.log("project "+p.getName() +" ..." ); try { if (p.isAccessible() && p.hasNature(JavaCore.NATURE_ID)) { @@ -116,7 +124,7 @@ public class ClasspathListenerManager { } public ClasspathListenerManager(Logger logger, ClasspathListener listener) { - this(logger, listener, false); + this(logger, listener, false, null); } public void dispose() { diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ReusableClasspathListenerHandler.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ReusableClasspathListenerHandler.java index 5cd3a0b21..ce2b3d24e 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ReusableClasspathListenerHandler.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ReusableClasspathListenerHandler.java @@ -12,9 +12,12 @@ package org.springframework.tooling.jdt.ls.commons.classpath; import java.io.File; import java.net.URI; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; +import java.util.function.Supplier; +import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -30,10 +33,16 @@ public class ReusableClasspathListenerHandler { private final ClientCommandExecutor conn; private final Logger logger; + private final Supplier> projectSorterFactory; public ReusableClasspathListenerHandler(Logger logger, ClientCommandExecutor conn) { + this(logger, conn, null); + } + + public ReusableClasspathListenerHandler(Logger logger, ClientCommandExecutor conn, Supplier> projectSorterFactory) { this.conn = conn; this.logger = logger; + this.projectSorterFactory = projectSorterFactory; logger.log("Instantiating ReusableClasspathListenerHandler"); } @@ -89,7 +98,7 @@ public class ReusableClasspathListenerHandler { public void classpathChanged(IJavaProject jp) { sendNotification(callbackCommandId, jp); } - }, true)); + }, true, projectSorterFactory)); logger.log("subsribers = " + subscribers.keySet()); }