Skip to content

Commit 5b73422

Browse files
committed
Use linked resource instead of filesystem
For all metadata files, except the .project (which may be harder to move). This also copies some logic from the filesystem to ProjectsManager. We cannot have the filesystem bundle requiring and referencing the main jdt.ls bundle as this would cause classloading error.
1 parent 9f5abe3 commit 5b73422

File tree

8 files changed

+94
-61
lines changed

8 files changed

+94
-61
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/ProjectsManager.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@
2929
import java.util.stream.Stream;
3030

3131
import org.apache.commons.lang3.StringUtils;
32+
import org.eclipse.core.internal.preferences.EclipsePreferences;
3233
import org.eclipse.core.internal.resources.CharsetManager;
3334
import org.eclipse.core.internal.resources.Workspace;
3435
import org.eclipse.core.resources.FileInfoMatcherDescription;
36+
import org.eclipse.core.resources.IFile;
3537
import org.eclipse.core.resources.IFolder;
3638
import org.eclipse.core.resources.IMarker;
3739
import org.eclipse.core.resources.IProject;
@@ -52,6 +54,7 @@
5254
import org.eclipse.core.runtime.IProgressMonitor;
5355
import org.eclipse.core.runtime.IStatus;
5456
import org.eclipse.core.runtime.MultiStatus;
57+
import org.eclipse.core.runtime.NullProgressMonitor;
5558
import org.eclipse.core.runtime.OperationCanceledException;
5659
import org.eclipse.core.runtime.Platform;
5760
import org.eclipse.core.runtime.Status;
@@ -343,6 +346,43 @@ public static IProject createJavaProject(IProject project, IProgressMonitor moni
343346
return createJavaProject(project, null, "src", "bin", monitor);
344347
}
345348

349+
/**
350+
* The system property key to specify the file system mode.
351+
*/
352+
public static final String GENERATES_METADATA_FILES_AT_PROJECT_ROOT = "java.import.generatesMetadataFilesAtProjectRoot";
353+
public static final IPath METADATA_FOLDER_PATH = ResourcesPlugin.getPlugin().getStateLocation().append(".projects");
354+
355+
/**
356+
* Check whether the metadata files needs to be generated at project root.
357+
*/
358+
public static boolean generatesMetadataFilesAtProjectRoot() {
359+
String property = System.getProperty(GENERATES_METADATA_FILES_AT_PROJECT_ROOT);
360+
if (property == null) {
361+
return true;
362+
}
363+
return Boolean.parseBoolean(property);
364+
}
365+
366+
/**
367+
* Get the redirected path of the input path. The path will be redirected to
368+
* the workspace's metadata folder ({@link JLSFsUtils#METADATA_FOLDER_PATH}).
369+
* @param projectName name of the project.
370+
* @param path path needs to be redirected.
371+
* @return the redirected path.
372+
*/
373+
public static IPath getMetaDataFilePath(String projectName, IPath path) {
374+
if (path.segmentCount() == 1) {
375+
return METADATA_FOLDER_PATH.append(projectName).append(path);
376+
}
377+
378+
String lastSegment = path.lastSegment();
379+
if (IProjectDescription.DESCRIPTION_FILE_NAME.equals(lastSegment)) {
380+
return METADATA_FOLDER_PATH.append(projectName).append(lastSegment);
381+
}
382+
383+
return null;
384+
}
385+
346386
public static IProject createJavaProject(IProject project, IPath projectLocation, String src, String bin, IProgressMonitor monitor) throws CoreException, OperationCanceledException {
347387
if (project.exists()) {
348388
return project;
@@ -355,6 +395,20 @@ public static IProject createJavaProject(IProject project, IPath projectLocation
355395
}
356396
project.create(description, monitor);
357397
project.open(monitor);
398+
if (!generatesMetadataFilesAtProjectRoot()) {
399+
IFile classpathFile = project.getFile(IJavaProject.CLASSPATH_FILE_NAME);
400+
if (!classpathFile.exists()) {
401+
classpathFile.createLink(getMetaDataFilePath(classpathFile.getProject().getName(), classpathFile.getProjectRelativePath()).toFile().toURI(), IResource.ALLOW_MISSING_LOCAL, new NullProgressMonitor());
402+
}
403+
IFile factorypathFile = project.getFile(".factorypath");
404+
if (!factorypathFile.exists()) {
405+
factorypathFile.createLink(getMetaDataFilePath(classpathFile.getProject().getName(), factorypathFile.getProjectRelativePath()).toFile().toURI(), IResource.ALLOW_MISSING_LOCAL, new NullProgressMonitor());
406+
}
407+
IFolder settingsFolder = project.getFolder(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME);
408+
if (!settingsFolder.exists()) {
409+
settingsFolder.createLink(getMetaDataFilePath(classpathFile.getProject().getName(), settingsFolder.getProjectRelativePath()).toFile().toURI(), IResource.ALLOW_MISSING_LOCAL, new NullProgressMonitor());
410+
}
411+
}
358412

359413
//Turn into Java project
360414
description = project.getDescription();

org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.eclipse.core.filesystem.IFileStore;
2222
import org.eclipse.core.internal.filesystem.local.LocalFile;
23+
import org.eclipse.core.resources.IProjectDescription;
2324
import org.eclipse.core.runtime.IPath;
2425
import org.eclipse.core.runtime.IProgressMonitor;
2526
import org.eclipse.core.runtime.Path;
@@ -56,11 +57,9 @@ public String[] childNames(int options, IProgressMonitor monitor) {
5657
}
5758

5859
Set<String> childNameSet = new LinkedHashSet<>(Arrays.asList(childNames));
59-
for (String fileName : JLSFsUtils.METADATA_NAMES) {
60-
if (!childNameSet.contains(fileName) &&
61-
JLSFsUtils.METADATA_FOLDER_PATH.append(projectName).append(fileName).toFile().exists()) {
62-
childNameSet.add(fileName);
63-
}
60+
if (!childNameSet.contains(IProjectDescription.DESCRIPTION_FILE_NAME) &&
61+
JLSFsUtils.METADATA_FOLDER_PATH.append(projectName).append(IProjectDescription.DESCRIPTION_FILE_NAME).toFile().exists()) {
62+
childNameSet.add(IProjectDescription.DESCRIPTION_FILE_NAME);
6463
}
6564

6665
return childNameSet.toArray(String[]::new);

org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,6 @@ private JLSFsUtils() {}
4141

4242
static final String FACTORY_PATH = ".factorypath";
4343

44-
/**
45-
* The metadata files
46-
*/
47-
static final Set<String> METADATA_NAMES = new HashSet<>(Arrays.asList(
48-
IProjectDescription.DESCRIPTION_FILE_NAME,
49-
EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME,
50-
IJavaProject.CLASSPATH_FILE_NAME,
51-
FACTORY_PATH
52-
));
53-
5444
/**
5545
* Determine whether the resource should be stored in workspace's metadata folder.
5646
* <p>
@@ -77,9 +67,6 @@ static boolean shouldStoreInMetadataArea(IPath location) {
7767
// do not redirect if the file already exists on disk
7868
if (location.toFile().exists()) {
7969
return false;
80-
} else if (location.lastSegment().endsWith(EclipsePreferences.PREFS_FILE_EXTENSION)) {
81-
location = location.removeLastSegments(1);
82-
return !location.toFile().exists();
8370
}
8471

8572
return true;
@@ -95,15 +82,11 @@ static boolean isProjectMetadataFile(IPath location) {
9582
return false;
9683
}
9784

98-
if (location.lastSegment().endsWith(EclipsePreferences.PREFS_FILE_EXTENSION)) {
99-
location = location.removeLastSegments(1);
100-
}
101-
10285
if (location.segmentCount() < 2) {
10386
return false;
10487
}
10588

106-
if (!METADATA_NAMES.contains(location.lastSegment())) {
89+
if (IProjectDescription.DESCRIPTION_FILE_NAME.equals(location.lastSegment())) {
10790
return false;
10891
}
10992

@@ -116,9 +99,6 @@ static boolean isProjectMetadataFile(IPath location) {
11699
* @param filePath the file path.
117100
*/
118101
static IPath getContainerPath(IPath filePath) {
119-
if (filePath.lastSegment().endsWith(EclipsePreferences.PREFS_FILE_EXTENSION)) {
120-
filePath = filePath.removeLastSegments(1);
121-
}
122102
return filePath.removeLastSegments(1);
123103
}
124104

@@ -152,12 +132,8 @@ static IPath getMetaDataFilePath(String projectName, IPath path) {
152132
}
153133

154134
String lastSegment = path.lastSegment();
155-
if (METADATA_NAMES.contains(lastSegment)) {
135+
if (IProjectDescription.DESCRIPTION_FILE_NAME.equals(lastSegment)) {
156136
return METADATA_FOLDER_PATH.append(projectName).append(lastSegment);
157-
} else if (lastSegment.endsWith(EclipsePreferences.PREFS_FILE_EXTENSION)) {
158-
return METADATA_FOLDER_PATH.append(projectName)
159-
.append(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME)
160-
.append(lastSegment);
161137
}
162138

163139
return null;

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/EclipseProjectMetadataFileTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.eclipse.jdt.core.IJavaProject;
3232
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
3333
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
34+
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
35+
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManagerTest;
3436
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.CHANGE_TYPE;
3537
import org.junit.Before;
3638
import org.junit.Test;
@@ -51,7 +53,7 @@ public static Collection<String> data(){
5153

5254
@Before
5355
public void setUp() {
54-
System.setProperty(JLSFsUtils.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, fsMode);
56+
System.setProperty(ProjectsManager.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, fsMode);
5557
}
5658

5759
@Test

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/GradleProjectMetadataFileTest.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
4242
import org.eclipse.jdt.ls.core.internal.WorkspaceHelper;
4343
import org.eclipse.jdt.ls.core.internal.managers.AbstractGradleBasedTest;
44+
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
4445
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.CHANGE_TYPE;
4546
import org.eclipse.jdt.ls.core.internal.preferences.Preferences.FeatureStatus;
4647
import org.junit.Before;
@@ -62,7 +63,7 @@ public static Collection<String> data(){
6263

6364
@Before
6465
public void setup() throws Exception {
65-
System.setProperty(JLSFsUtils.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, fsMode);
66+
System.setProperty(ProjectsManager.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, fsMode);
6667
}
6768

6869
@Test
@@ -77,33 +78,33 @@ public void testMetadataFileLocation() throws Exception {
7778
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
7879
IPath projectDescriptionPath = FileUtil.toPath(projectDescription.getLocationURI());
7980
assertTrue(projectDescriptionPath.toFile().exists());
80-
assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
81+
assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
8182

8283
IFile preferencesFile = project.getFile(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME);
8384
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
8485
IPath preferencesPath = FileUtil.toPath(preferencesFile.getLocationURI());
8586
assertTrue(preferencesPath.toFile().exists());
86-
assertEquals(project.getLocation().isPrefixOf(preferencesPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
87+
assertEquals(project.getLocation().isPrefixOf(preferencesPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
8788

8889
// then we check the sub-module
8990
project = WorkspaceHelper.getProject("app");
9091
projectDescription = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME);
9192
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
9293
projectDescriptionPath = FileUtil.toPath(projectDescription.getLocationURI());
9394
assertTrue(projectDescriptionPath.toFile().exists());
94-
assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
95+
assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
9596

9697
IFile classpath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME);
9798
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
9899
IPath classpathPath = FileUtil.toPath(classpath.getLocationURI());
99100
assertTrue(classpathPath.toFile().exists());
100-
assertEquals(project.getLocation().isPrefixOf(classpathPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
101+
assertEquals(project.getLocation().isPrefixOf(classpathPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
101102

102103
preferencesFile = project.getFile(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME);
103104
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
104105
preferencesPath = FileUtil.toPath(preferencesFile.getLocationURI());
105106
assertTrue(preferencesPath.toFile().exists());
106-
assertEquals(project.getLocation().isPrefixOf(preferencesPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
107+
assertEquals(project.getLocation().isPrefixOf(preferencesPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
107108
}
108109

109110
@Test

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/InvisibleProjectMetadataFileTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.eclipse.jdt.launching.JavaRuntime;
3131
import org.eclipse.jdt.ls.core.internal.TestVMType;
3232
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
33+
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
3334
import org.junit.Before;
3435
import org.junit.Test;
3536
import org.junit.runner.RunWith;
@@ -49,7 +50,7 @@ public static Collection<String> data(){
4950

5051
@Before
5152
public void setUp() {
52-
System.setProperty(JLSFsUtils.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, fsMode);
53+
System.setProperty(ProjectsManager.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, fsMode);
5354
}
5455

5556
@Test
@@ -61,19 +62,17 @@ public void testMetadataFileLocation() throws Exception {
6162
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
6263
IPath projectDescriptionPath = FileUtil.toPath(projectDescription.getLocationURI());
6364
assertTrue(projectDescriptionPath.toFile().exists());
64-
assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
65+
assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
6566

6667
IFile classpath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME);
67-
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
68-
IPath classpathPath = FileUtil.toPath(classpath.getLocationURI());
68+
IPath classpathPath = classpath.getLocation();
6969
assertTrue(classpathPath.toFile().exists());
70-
assertEquals(project.getLocation().isPrefixOf(classpathPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
70+
assertEquals(project.getLocation().isPrefixOf(classpathPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
7171

7272
IFile preferencesFile = project.getFile(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME);
73-
// workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900
74-
IPath preferencesPath = FileUtil.toPath(preferencesFile.getLocationURI());
73+
IPath preferencesPath = preferencesFile.getLocation();
7574
assertTrue(preferencesPath.toFile().exists());
76-
assertEquals(project.getLocation().isPrefixOf(preferencesPath), JLSFsUtils.generatesMetadataFilesAtProjectRoot());
75+
assertEquals(project.getLocation().isPrefixOf(preferencesPath), ProjectsManager.generatesMetadataFilesAtProjectRoot());
7776
}
7877

7978
@Test

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtilsTest.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,24 @@
1616
import static org.junit.Assert.assertFalse;
1717
import static org.junit.Assert.assertTrue;
1818

19+
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
1920
import org.junit.Test;
2021

2122
public class JLSFsUtilsTest {
2223
@Test
2324
public void testGeneratesMetadataFilesAtProjectRoot() {
24-
System.setProperty(JLSFsUtils.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, "true");
25-
assertTrue(JLSFsUtils.generatesMetadataFilesAtProjectRoot());
25+
System.setProperty(ProjectsManager.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, "true");
26+
assertTrue(ProjectsManager.generatesMetadataFilesAtProjectRoot());
2627
}
2728

2829
@Test
2930
public void testNotGeneratesMetadataFilesAtProjectRoot() {
30-
System.setProperty(JLSFsUtils.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, "false");
31-
assertFalse(JLSFsUtils.generatesMetadataFilesAtProjectRoot());
31+
System.setProperty(ProjectsManager.GENERATES_METADATA_FILES_AT_PROJECT_ROOT, "false");
32+
assertFalse(ProjectsManager.generatesMetadataFilesAtProjectRoot());
3233
}
3334

3435
@Test
3536
public void testGeneratesMetadataFilesAtProjectRootWhenNotSet() {
36-
assertTrue(JLSFsUtils.generatesMetadataFilesAtProjectRoot());
37+
assertTrue(ProjectsManager.generatesMetadataFilesAtProjectRoot());
3738
}
3839
}

0 commit comments

Comments
 (0)