Skip to content

Commit 711168f

Browse files
committed
[WIP] Remove filesystem plugin
Linked resource for .project works more reliably
1 parent c7f6ac0 commit 711168f

File tree

23 files changed

+141
-484
lines changed

23 files changed

+141
-484
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2023 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License 2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*******************************************************************************/
10+
package org.eclipse.jdt.ls.core.internal;
11+
12+
import java.io.IOException;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
import java.nio.file.attribute.BasicFileAttributeView;
16+
import java.nio.file.attribute.BasicFileAttributes;
17+
import java.time.Instant;
18+
import java.util.Arrays;
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
22+
import org.eclipse.core.internal.events.ILifecycleListener;
23+
import org.eclipse.core.internal.events.LifecycleEvent;
24+
import org.eclipse.core.resources.IFile;
25+
import org.eclipse.core.resources.IProject;
26+
import org.eclipse.core.resources.IProjectDescription;
27+
import org.eclipse.core.resources.IResource;
28+
import org.eclipse.core.resources.IResourceChangeEvent;
29+
import org.eclipse.core.resources.IResourceChangeListener;
30+
import org.eclipse.core.resources.WorkspaceJob;
31+
import org.eclipse.core.runtime.CoreException;
32+
import org.eclipse.core.runtime.ICoreRunnable;
33+
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
34+
35+
public class FixDotProjectPathResourceListener implements IResourceChangeListener, ILifecycleListener {
36+
37+
private Map<IProject, Instant> createdProjects = new HashMap<>();
38+
39+
@Override
40+
public void resourceChanged(IResourceChangeEvent event) {
41+
if (ProjectsManager.generatesMetadataFilesAtProjectRoot() || event.getDelta() == null) {
42+
return;
43+
}
44+
try {
45+
event.getDelta().accept(delta -> {
46+
if (delta.getResource() instanceof IProject project && //
47+
project.isOpen() && //
48+
createdProjects.containsKey(project)) {
49+
Instant projectCreation = createdProjects.remove(project);
50+
Path dotProjectOnDisk = project.getLocation().append(IProjectDescription.DESCRIPTION_FILE_NAME).toPath();
51+
try {
52+
BasicFileAttributes attributes = Files.getFileAttributeView(dotProjectOnDisk, BasicFileAttributeView.class).readAttributes();
53+
if (attributes.creationTime().toInstant().isAfter(projectCreation)) {
54+
// cannot link to resource in current workspace task, plan it next
55+
WorkspaceJob.createSystem("Use linked .project for " + project, (ICoreRunnable) (monitor -> {
56+
ProjectsManager.linkDotProject(project);
57+
ProjectsManager.linkResources(project);
58+
})).schedule();
59+
}
60+
} catch (IOException ex) {
61+
JavaLanguageServerPlugin.logException(ex);
62+
}
63+
}
64+
return delta.getResource().getType() == IResource.ROOT;
65+
});
66+
} catch (CoreException e) {
67+
JavaLanguageServerPlugin.logException(e);
68+
}
69+
}
70+
71+
@Override
72+
public void handleEvent(LifecycleEvent event) throws CoreException {
73+
if (event.kind == LifecycleEvent.PRE_PROJECT_CREATE) {
74+
if (event.resource instanceof IProject project) {
75+
createdProjects.put(project, Instant.now());
76+
}
77+
} else if (event.kind == LifecycleEvent.PRE_REFRESH) {
78+
unlinkIfLocal(event.resource);
79+
}
80+
}
81+
82+
private void unlinkIfLocal(IResource resource) {
83+
if (resource instanceof IProject project && project.isOpen()) {
84+
try {
85+
Arrays.stream(project.members())
86+
.filter(IFile.class::isInstance)
87+
.map(IFile.class::cast)
88+
.filter(IFile::isLinked)
89+
.filter(file -> file.getProject().getLocation().append(file.getProjectRelativePath()).toFile().isFile())
90+
.forEach(file -> {
91+
try {
92+
file.delete(false, false, null);
93+
} catch (CoreException e) {
94+
JavaLanguageServerPlugin.logException(e);
95+
}
96+
});
97+
} catch (CoreException e) {
98+
JavaLanguageServerPlugin.logException(e);
99+
}
100+
}
101+
}
102+
103+
}

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JavaLanguageServerPlugin.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828

2929
import org.apache.commons.lang3.StringUtils;
3030
import org.eclipse.core.internal.net.ProxySelector;
31+
import org.eclipse.core.internal.resources.Workspace;
3132
import org.eclipse.core.net.proxy.IProxyData;
3233
import org.eclipse.core.net.proxy.IProxyService;
34+
import org.eclipse.core.resources.IResourceChangeEvent;
3335
import org.eclipse.core.resources.ResourcesPlugin;
3436
import org.eclipse.core.runtime.CoreException;
3537
import org.eclipse.core.runtime.IStatus;
@@ -113,7 +115,7 @@ public class JavaLanguageServerPlugin extends Plugin {
113115
private ProjectsManager projectsManager;
114116
private DigestStore digestStore;
115117
private ContentProviderManager contentProviderManager;
116-
118+
private FixDotProjectPathResourceListener fixDotProjectListener;
117119
private BaseJDTLanguageServer protocol;
118120

119121
private PreferenceManager preferenceManager;
@@ -155,6 +157,9 @@ public void start(BundleContext bundleContext) throws Exception {
155157
preferenceManager = new StandardPreferenceManager();
156158
projectsManager = new StandardProjectsManager(preferenceManager);
157159
}
160+
fixDotProjectListener = new FixDotProjectPathResourceListener();
161+
ResourcesPlugin.getWorkspace().addResourceChangeListener(fixDotProjectListener, IResourceChangeEvent.POST_CHANGE);
162+
((Workspace)ResourcesPlugin.getWorkspace()).addLifecycleListener(fixDotProjectListener);
158163
digestStore = new DigestStore(getStateLocation().toFile());
159164
try {
160165
ResourcesPlugin.getWorkspace().addSaveParticipant(IConstants.PLUGIN_ID, projectsManager);
@@ -365,6 +370,7 @@ public void stop(BundleContext bundleContext) throws Exception {
365370
JavaLanguageServerPlugin.pluginInstance = null;
366371
JavaLanguageServerPlugin.context = null;
367372
ResourcesPlugin.getWorkspace().removeSaveParticipant(IConstants.PLUGIN_ID);
373+
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fixDotProjectListener);
368374
projectsManager = null;
369375
contentProviderManager = null;
370376
languageServer = null;

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.File;
2020
import java.io.IOException;
2121
import java.net.URI;
22+
import java.nio.file.Files;
2223
import java.util.ArrayList;
2324
import java.util.Arrays;
2425
import java.util.Collection;
@@ -486,6 +487,25 @@ public static void linkResources(IProject project) throws CoreException {
486487
}
487488
}
488489

490+
public static void linkDotProject(IProject project) throws CoreException {
491+
IFile dotProject = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME);
492+
if (dotProject.isLinked()) {
493+
return;
494+
}
495+
File targetDiskFile = getMetaDataFilePath(project.getName(), dotProject.getProjectRelativePath()).toFile();
496+
if (!targetDiskFile.exists()) {
497+
try {
498+
targetDiskFile.getParentFile().mkdirs();
499+
Files.copy(dotProject.getLocation().toPath(), targetDiskFile.toPath());
500+
} catch (Exception ex) {
501+
throw new CoreException(Status.error(targetDiskFile + " cannot be created", ex)); //$NON-NLS-1$
502+
}
503+
}
504+
File sourceDiskFile = dotProject.getLocation().toFile();
505+
dotProject.createLink(IPath.fromFile(targetDiskFile), IResource.FORCE | IResource.REPLACE, null);
506+
sourceDiskFile.delete();
507+
}
508+
489509
@Override
490510
public Job updateProject(IProject project, boolean force) {
491511
if (project == null || ProjectUtils.isInternalBuildSupport(BuildSupportManager.find(project).orElse(null))) {

org.eclipse.jdt.ls.filesystem/.classpath

Lines changed: 0 additions & 7 deletions
This file was deleted.

org.eclipse.jdt.ls.filesystem/.project

Lines changed: 0 additions & 45 deletions
This file was deleted.

org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.core.resources.prefs

Lines changed: 0 additions & 2 deletions
This file was deleted.

org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.jdt.core.prefs

Lines changed: 0 additions & 9 deletions
This file was deleted.

org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.m2e.core.prefs

Lines changed: 0 additions & 4 deletions
This file was deleted.

org.eclipse.jdt.ls.filesystem/META-INF/MANIFEST.MF

Lines changed: 0 additions & 16 deletions
This file was deleted.

org.eclipse.jdt.ls.filesystem/build.properties

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)