Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix jar detection on windows #998

Merged
merged 1 commit into from
Apr 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ public static IPath canonicalFilePathFromURI(String uriStr) {
}

public static boolean isContainedIn(IPath location, Collection<IPath> paths) {
if (location == null || paths == null || paths.isEmpty()) {
return false;
}
for (IPath path : paths) {
if (path.isPrefixOf(location)) {
return true;
Expand All @@ -234,4 +237,27 @@ public static String expandPath(String path) {
return path;
}

/**
* Convert an {@link IPath} to a glob pattern (i.e. ending with /**)
*
* @param path
* the path to convert
* @return a glob pattern prefixed with the path
*/
public static String toGlobPattern(IPath path) {
if (path == null) {
return null;
}
String globPattern = path.toPortableString();
if (path.getDevice() != null) {
//This seems pretty hack-ish: need to remove device as it seems to break
// file detection, at least on vscode
globPattern = globPattern.replace(path.getDevice(), "**");
}
if (!globPattern.endsWith("/")) {
globPattern += "/";
}
return globPattern + "**";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static java.util.Arrays.asList;
import static org.eclipse.jdt.ls.core.internal.JVMConfigurator.configureJVMSettings;
import static org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin.logInfo;
import static org.eclipse.jdt.ls.core.internal.ResourceUtils.isContainedIn;

import java.io.File;
import java.net.MalformedURLException;
Expand All @@ -25,6 +26,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -53,6 +55,7 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
Expand Down Expand Up @@ -89,20 +92,20 @@
public class ProjectsManager implements ISaveParticipant {

public static final String DEFAULT_PROJECT_NAME = "jdt.ls-java-project";
private static final Set<String> watchers = new HashSet<>();
private static final Set<String> watchers = new LinkedHashSet<>();
private PreferenceManager preferenceManager;
private JavaLanguageClient client;
//@formatter:off
private static final String[] basicWatchers = new String[] {
private static final List<String> basicWatchers = Arrays.asList(
"**/*.java",
"**/pom.xml",
"**/*.gradle",
"**/gradle.properties",
"**/.project",
"**/.classpath",
"**/settings/*.prefs",
"**/.settings/*.prefs",
"**/src/**"
};
);
//@formatter:on

public enum CHANGE_TYPE {
Expand Down Expand Up @@ -562,7 +565,7 @@ public boolean setAutoBuilding(boolean enable) throws CoreException {
public List<FileSystemWatcher> registerWatchers() {
logInfo(">> registerFeature 'workspace/didChangeWatchedFiles'");
if (preferenceManager.getClientPreferences().isWorkspaceChangeWatchedFilesDynamicRegistered()) {
Set<String> sources = new HashSet<>();
Set<IPath> sources = new HashSet<>();
try {
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for (IProject project : projects) {
Expand All @@ -579,8 +582,8 @@ public List<FileSystemWatcher> registerWatchers() {
IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
if (folder.exists() && !folder.isDerived()) {
IPath location = folder.getLocation();
if (location != null) {
sources.add(location.toString() + "/**");
if (location != null && !isContainedIn(location, sources)) {
sources.add(location);
}
}

Expand All @@ -592,7 +595,9 @@ public List<FileSystemWatcher> registerWatchers() {
IPath realFolderPath = project.getFolder(ProjectUtils.WORKSPACE_LINK).getLocation();
if (realFolderPath != null) {
IPath libFolderPath = realFolderPath.append(InvisibleProjectBuildSupport.LIB_FOLDER);
sources.add(libFolderPath.toString() + "/**");
if (!isContainedIn(libFolderPath, sources)) {
sources.add(libFolderPath);
}
}
}
}
Expand All @@ -608,24 +613,27 @@ public List<FileSystemWatcher> registerWatchers() {
file = findFile(formatterUrl);
}
if (file != null && file.isFile()) {
sources.add(file.getAbsolutePath());
IPath formatterPath = new Path(file.getAbsolutePath());
if (!isContainedIn(formatterPath, sources)) {
sources.add(formatterPath);
}
}
}
for (String pattern : basicWatchers) {
sources.add(pattern);
}
for (String pattern : sources) {
Set<String> patterns = new LinkedHashSet<>(basicWatchers);
patterns.addAll(sources.stream().map(ResourceUtils::toGlobPattern).collect(Collectors.toList()));

for (String pattern : patterns) {
FileSystemWatcher watcher = new FileSystemWatcher(pattern);
fileWatchers.add(watcher);
}

if (!sources.equals(watchers)) {
if (!patterns.equals(watchers)) {
logInfo(">> registerFeature 'workspace/didChangeWatchedFiles'");
DidChangeWatchedFilesRegistrationOptions didChangeWatchedFilesRegistrationOptions = new DidChangeWatchedFilesRegistrationOptions(fileWatchers);
JavaLanguageServerPlugin.getInstance().unregisterCapability(Preferences.WORKSPACE_WATCHED_FILES_ID, Preferences.WORKSPACE_WATCHED_FILES);
JavaLanguageServerPlugin.getInstance().registerCapability(Preferences.WORKSPACE_WATCHED_FILES_ID, Preferences.WORKSPACE_WATCHED_FILES, didChangeWatchedFilesRegistrationOptions);
watchers.clear();
watchers.addAll(sources);
watchers.addAll(patterns);
}
return fileWatchers;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* 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:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ls.core.internal;

import static org.eclipse.jdt.ls.core.internal.ResourceUtils.toGlobPattern;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import org.eclipse.core.runtime.Path;
import org.junit.Test;

public class ResourceUtilsTest {

@Test
public void testToGlobPattern() {
assertNull(toGlobPattern(null));
assertEquals("/foo/bar/**", toGlobPattern(Path.forPosix("/foo/bar")));
assertEquals("/foo/bar/**", toGlobPattern(Path.forPosix("/foo/bar/")));
assertEquals("**/foo/bar/**", toGlobPattern(Path.forWindows("c:/foo/bar/")));
assertEquals("**/foo/bar/**", toGlobPattern(Path.forWindows("c:\\foo\\bar")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,14 @@ public int compare(FileSystemWatcher o1, FileSystemWatcher o2) {
}
});
assertEquals("Unexpected watchers:\n" + toString(watchers), 8, watchers.size());
assertEquals(watchers.get(0).getGlobPattern(), "**/*.gradle");
assertEquals(watchers.get(1).getGlobPattern(), "**/*.java");
assertEquals(watchers.get(2).getGlobPattern(), "**/.classpath");
assertEquals(watchers.get(3).getGlobPattern(), "**/.project");
assertEquals(watchers.get(4).getGlobPattern(), "**/gradle.properties");
assertEquals(watchers.get(5).getGlobPattern(), "**/pom.xml");
assertEquals(watchers.get(6).getGlobPattern(), "**/settings/*.prefs");
assertEquals(watchers.get(7).getGlobPattern(), "**/src/**");
assertEquals("**/*.gradle", watchers.get(0).getGlobPattern());
assertEquals("**/*.java", watchers.get(1).getGlobPattern());
assertEquals("**/.classpath", watchers.get(2).getGlobPattern());
assertEquals("**/.project", watchers.get(3).getGlobPattern());
assertEquals("**/.settings/*.prefs", watchers.get(4).getGlobPattern());
assertEquals("**/gradle.properties", watchers.get(5).getGlobPattern());
assertEquals("**/pom.xml", watchers.get(6).getGlobPattern());
assertEquals("**/src/**", watchers.get(7).getGlobPattern());
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("salut");
String location = project.getLocation().toString();
IJavaProject javaProject = JavaCore.create(project);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,19 @@ protected File createSourceFolderWithMissingLibs(String name) throws Exception {
}

protected File createSourceFolderWithLibs(String name, boolean addLibs) throws Exception {
return createSourceFolderWithLibs(name, null, addLibs);
}

protected File createSourceFolderWithLibs(String name, String srcDir, boolean addLibs) throws Exception {
java.nio.file.Path projectPath = Files.createTempDirectory(name);
File projectFolder = projectPath.toFile();
FileUtils.copyDirectory(new File(getSourceProjectDirectory(), "eclipse/source-attachment/src"), projectFolder);
File sourceFolder;
if (org.apache.commons.lang3.StringUtils.isBlank(srcDir)) {
sourceFolder = projectFolder;
} else {
sourceFolder = new File(projectFolder, srcDir);
}
FileUtils.copyDirectory(new File(getSourceProjectDirectory(), "eclipse/source-attachment/src"), sourceFolder);
if (addLibs) {
addLibs(projectPath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,37 @@ public void importCompleteFolderWithoutTriggerFile() throws Exception {
}

@Test
public void automaticJarDetectionLibUnderSource() throws Exception {
ClientPreferences mockCapabilies = mock(ClientPreferences.class);
when(mockCapabilies.isWorkspaceChangeWatchedFilesDynamicRegistered()).thenReturn(Boolean.TRUE);
when(preferenceManager.getClientPreferences()).thenReturn(mockCapabilies);

File projectFolder = createSourceFolderWithLibs("automaticJarDetectionLibUnderSource");

IProject invisibleProject = importRootFolder(projectFolder, "Test.java");
assertNoErrors(invisibleProject);

IJavaProject javaProject = JavaCore.create(invisibleProject);
IClasspathEntry[] classpath = javaProject.getRawClasspath();
assertEquals("Unexpected classpath:\n" + JavaProjectHelper.toString(classpath), 3, classpath.length);
assertEquals("foo.jar", classpath[2].getPath().lastSegment());
assertEquals("foo-sources.jar", classpath[2].getSourceAttachmentPath().lastSegment());

List<FileSystemWatcher> watchers = projectsManager.registerWatchers();
watchers.sort((a, b) -> a.getGlobPattern().compareTo(b.getGlobPattern()));
assertEquals(9, watchers.size());
String srcGlobPattern = watchers.get(7).getGlobPattern();
assertTrue("Unexpected source glob pattern: " + srcGlobPattern, srcGlobPattern.equals("**/src/**"));
String libGlobPattern = watchers.get(8).getGlobPattern();
assertTrue("Unexpected project glob pattern: " + libGlobPattern, libGlobPattern.endsWith(projectFolder.getName() + "/**"));
}

public void automaticJarDetection() throws Exception {
ClientPreferences mockCapabilies = mock(ClientPreferences.class);
when(mockCapabilies.isWorkspaceChangeWatchedFilesDynamicRegistered()).thenReturn(Boolean.TRUE);
when(preferenceManager.getClientPreferences()).thenReturn(mockCapabilies);

File projectFolder = createSourceFolderWithLibs("automaticJarDetection");
File projectFolder = createSourceFolderWithLibs("automaticJarDetection", "src", true);

IProject invisibleProject = importRootFolder(projectFolder, "Test.java");
assertNoErrors(invisibleProject);
Expand Down