diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/FixDotProjectPathResourceListener.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/FixDotProjectPathResourceListener.java new file mode 100644 index 0000000000..48efb92a05 --- /dev/null +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/FixDotProjectPathResourceListener.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2023 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 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.jdt.ls.core.internal; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.internal.events.ILifecycleListener; +import org.eclipse.core.internal.events.LifecycleEvent; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.WorkspaceJob; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ICoreRunnable; +import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager; + +public class FixDotProjectPathResourceListener implements IResourceChangeListener, ILifecycleListener { + + private Map createdProjects = new HashMap<>(); + + @Override + public void resourceChanged(IResourceChangeEvent event) { + if (ProjectsManager.generatesMetadataFilesAtProjectRoot() || event.getDelta() == null) { + return; + } + try { + event.getDelta().accept(delta -> { + if (delta.getResource() instanceof IProject project && // + project.isOpen() && // + createdProjects.containsKey(project)) { + Instant projectCreation = createdProjects.remove(project); + Path dotProjectOnDisk = project.getLocation().append(IProjectDescription.DESCRIPTION_FILE_NAME).toPath(); + try { + BasicFileAttributes attributes = Files.getFileAttributeView(dotProjectOnDisk, BasicFileAttributeView.class).readAttributes(); + if (attributes.creationTime().toInstant().isAfter(projectCreation)) { + // cannot link to resource in current workspace task, plan it next + WorkspaceJob.createSystem("Use linked .project for " + project, (ICoreRunnable) (monitor -> { + ProjectsManager.linkDotProject(project); + ProjectsManager.linkResources(project); + })).schedule(); + } + } catch (IOException ex) { + JavaLanguageServerPlugin.logException(ex); + } + } + return delta.getResource().getType() == IResource.ROOT; + }); + } catch (CoreException e) { + JavaLanguageServerPlugin.logException(e); + } + } + + @Override + public void handleEvent(LifecycleEvent event) throws CoreException { + if (event.kind == LifecycleEvent.PRE_PROJECT_CREATE) { + if (event.resource instanceof IProject project) { + createdProjects.put(project, Instant.now()); + } + } else if (event.kind == LifecycleEvent.PRE_REFRESH) { + unlinkIfLocal(event.resource); + } + } + + private void unlinkIfLocal(IResource resource) { + if (resource instanceof IProject project && project.isOpen()) { + try { + Arrays.stream(project.members()) + .filter(IFile.class::isInstance) + .map(IFile.class::cast) + .filter(IFile::isLinked) + .filter(file -> file.getProject().getLocation().append(file.getProjectRelativePath()).toFile().isFile()) + .forEach(file -> { + try { + file.delete(false, false, null); + } catch (CoreException e) { + JavaLanguageServerPlugin.logException(e); + } + }); + } catch (CoreException e) { + JavaLanguageServerPlugin.logException(e); + } + } + } + +} diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JavaLanguageServerPlugin.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JavaLanguageServerPlugin.java index 95973f0e73..374167e212 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JavaLanguageServerPlugin.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JavaLanguageServerPlugin.java @@ -28,8 +28,10 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.core.internal.net.ProxySelector; +import org.eclipse.core.internal.resources.Workspace; import org.eclipse.core.net.proxy.IProxyData; import org.eclipse.core.net.proxy.IProxyService; +import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; @@ -113,7 +115,7 @@ public class JavaLanguageServerPlugin extends Plugin { private ProjectsManager projectsManager; private DigestStore digestStore; private ContentProviderManager contentProviderManager; - + private FixDotProjectPathResourceListener fixDotProjectListener; private BaseJDTLanguageServer protocol; private PreferenceManager preferenceManager; @@ -155,6 +157,9 @@ public void start(BundleContext bundleContext) throws Exception { preferenceManager = new StandardPreferenceManager(); projectsManager = new StandardProjectsManager(preferenceManager); } + fixDotProjectListener = new FixDotProjectPathResourceListener(); + ResourcesPlugin.getWorkspace().addResourceChangeListener(fixDotProjectListener, IResourceChangeEvent.POST_CHANGE); + ((Workspace)ResourcesPlugin.getWorkspace()).addLifecycleListener(fixDotProjectListener); digestStore = new DigestStore(getStateLocation().toFile()); try { ResourcesPlugin.getWorkspace().addSaveParticipant(IConstants.PLUGIN_ID, projectsManager); @@ -365,6 +370,7 @@ public void stop(BundleContext bundleContext) throws Exception { JavaLanguageServerPlugin.pluginInstance = null; JavaLanguageServerPlugin.context = null; ResourcesPlugin.getWorkspace().removeSaveParticipant(IConstants.PLUGIN_ID); + ResourcesPlugin.getWorkspace().removeResourceChangeListener(fixDotProjectListener); projectsManager = null; contentProviderManager = null; languageServer = null; diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/ProjectsManager.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/ProjectsManager.java index a52eff6d77..b01d7e01bf 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/ProjectsManager.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/ProjectsManager.java @@ -19,6 +19,7 @@ import java.io.File; import java.io.IOException; import java.net.URI; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -486,6 +487,25 @@ public static void linkResources(IProject project) throws CoreException { } } + public static void linkDotProject(IProject project) throws CoreException { + IFile dotProject = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); + if (dotProject.isLinked()) { + return; + } + File targetDiskFile = getMetaDataFilePath(project.getName(), dotProject.getProjectRelativePath()).toFile(); + if (!targetDiskFile.exists()) { + try { + targetDiskFile.getParentFile().mkdirs(); + Files.copy(dotProject.getLocation().toPath(), targetDiskFile.toPath()); + } catch (Exception ex) { + throw new CoreException(Status.error(targetDiskFile + " cannot be created", ex)); //$NON-NLS-1$ + } + } + File sourceDiskFile = dotProject.getLocation().toFile(); + dotProject.createLink(IPath.fromFile(targetDiskFile), IResource.FORCE | IResource.REPLACE, null); + sourceDiskFile.delete(); + } + @Override public Job updateProject(IProject project, boolean force) { if (project == null || ProjectUtils.isInternalBuildSupport(BuildSupportManager.find(project).orElse(null))) { diff --git a/org.eclipse.jdt.ls.filesystem/.classpath b/org.eclipse.jdt.ls.filesystem/.classpath deleted file mode 100644 index 5508535a40..0000000000 --- a/org.eclipse.jdt.ls.filesystem/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/org.eclipse.jdt.ls.filesystem/.project b/org.eclipse.jdt.ls.filesystem/.project deleted file mode 100644 index d34fd35ec5..0000000000 --- a/org.eclipse.jdt.ls.filesystem/.project +++ /dev/null @@ -1,45 +0,0 @@ - - - org.eclipse.jdt.ls.filesystem - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - - - 1675270185050 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c0203..0000000000 --- a/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 62ef3488cc..0000000000 --- a/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb..0000000000 --- a/org.eclipse.jdt.ls.filesystem/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/org.eclipse.jdt.ls.filesystem/META-INF/MANIFEST.MF b/org.eclipse.jdt.ls.filesystem/META-INF/MANIFEST.MF deleted file mode 100644 index 6fed55d678..0000000000 --- a/org.eclipse.jdt.ls.filesystem/META-INF/MANIFEST.MF +++ /dev/null @@ -1,16 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-SymbolicName: org.eclipse.jdt.ls.filesystem;singleton:=true -Bundle-Name: %Bundle-Name -Bundle-Version: 1.25.0.qualifier -Export-Package: org.eclipse.jdt.ls.core.internal.filesystem;x-friends:="org.eclipse.jdt.ls.tests" -Bundle-Localization: plugin -Bundle-Activator: org.eclipse.jdt.ls.core.internal.filesystem.JDTLSFilesystemActivator -Bundle-Vendor: %Bundle-Vendor -Require-Bundle: org.eclipse.core.runtime, - org.eclipse.core.filesystem;bundle-version="1.9.500", - org.eclipse.core.resources;bundle-version="3.18.100", - org.eclipse.jdt.core;bundle-version="3.32.0" -Bundle-RequiredExecutionEnvironment: JavaSE-17 -Automatic-Module-Name: org.eclipse.jdt.ls.application -Bundle-ActivationPolicy: lazy diff --git a/org.eclipse.jdt.ls.filesystem/build.properties b/org.eclipse.jdt.ls.filesystem/build.properties deleted file mode 100644 index 0dc34f7833..0000000000 --- a/org.eclipse.jdt.ls.filesystem/build.properties +++ /dev/null @@ -1,6 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - plugin.properties diff --git a/org.eclipse.jdt.ls.filesystem/plugin.properties b/org.eclipse.jdt.ls.filesystem/plugin.properties deleted file mode 100644 index 1f57838980..0000000000 --- a/org.eclipse.jdt.ls.filesystem/plugin.properties +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################### -# Copyright (c) 2016-2017 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 2.0 -# which accompanies this distribution, and is available at -# https://www.eclipse.org/legal/epl-2.0/ -# -# SPDX-License-Identifier: EPL-2.0 -# -# Contributors: -# Red Hat Inc. - initial API and implementation -############################################################################### -Bundle-Vendor = Eclipse.org -Bundle-Name = JDT Language Server - Core \ No newline at end of file diff --git a/org.eclipse.jdt.ls.filesystem/plugin.xml b/org.eclipse.jdt.ls.filesystem/plugin.xml deleted file mode 100644 index 986a53bee5..0000000000 --- a/org.eclipse.jdt.ls.filesystem/plugin.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/org.eclipse.jdt.ls.filesystem/pom.xml b/org.eclipse.jdt.ls.filesystem/pom.xml deleted file mode 100644 index 5fdd7cb065..0000000000 --- a/org.eclipse.jdt.ls.filesystem/pom.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - 4.0.0 - - org.eclipse.jdt.ls - parent - 1.25.0-SNAPSHOT - - org.eclipse.jdt.ls.filesystem - eclipse-plugin - ${base.name} :: Filesystem - diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java deleted file mode 100644 index 6b930e88fc..0000000000 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JDTLSFilesystemActivator.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.eclipse.jdt.ls.core.internal.filesystem; - -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -/******************************************************************************* - * Copyright (c) 2022 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 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ -public class JDTLSFilesystemActivator implements BundleActivator { - - private static BundleContext context; - - static BundleContext getContext() { - return context; - } - - public void start(BundleContext bundleContext) throws Exception { - JDTLSFilesystemActivator.context = bundleContext; - } - - public void stop(BundleContext bundleContext) throws Exception { - JDTLSFilesystemActivator.context = null; - } - -} diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java deleted file mode 100644 index 4875bc6c7f..0000000000 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFile.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2021 Microsoft Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Microsoft Corporation - *******************************************************************************/ - -package org.eclipse.jdt.ls.core.internal.filesystem; - -import java.io.File; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.internal.filesystem.local.LocalFile; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; - -/** - * JDT.LS's own implementation of files in the local operating system's file system. - * The instance of this class will be returned by {@link JLSFileSystem}. - */ -public class JLSFile extends LocalFile { - - public JLSFile(File file) { - super(file); - } - - /** - * {@inheritDoc} - * - *

- * Since the metadata files may be redirected into the workspace, - * we override the method to make sure those files are not missed. - *

- */ - @Override - public String[] childNames(int options, IProgressMonitor monitor) { - String[] childNames = super.childNames(options, monitor); - if (JLSFsUtils.generatesMetadataFilesAtProjectRoot()) { - return childNames; - } - - IPath filePath = new Path(this.filePath); - String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(filePath); - if (projectName == null) { - return childNames; - } - - Set childNameSet = new LinkedHashSet<>(Arrays.asList(childNames)); - if (!childNameSet.contains(IProjectDescription.DESCRIPTION_FILE_NAME) && - JLSFsUtils.METADATA_FOLDER_PATH.append(projectName).append(IProjectDescription.DESCRIPTION_FILE_NAME).toFile().exists()) { - childNameSet.add(IProjectDescription.DESCRIPTION_FILE_NAME); - } - - return childNameSet.toArray(String[]::new); - } - - @Override - public IFileStore getChild(String name) { - IPath path = new Path(this.filePath).append(name); - if (JLSFsUtils.shouldStoreInMetadataArea(path)) { - IPath containerPath = JLSFsUtils.getContainerPath(path); - String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(containerPath); - if (projectName == null) { - return new JLSFile(new File(file, name)); - } - IPath redirectedPath = JLSFsUtils.getMetaDataFilePath(projectName, new Path(name)); - if (redirectedPath != null) { - return new JLSFile(redirectedPath.toFile()); - } - } - - return new JLSFile(new File(file, name)); - } - - @Override - public IFileStore getFileStore(IPath path) { - IPath fullPath = new Path(this.filePath).append(path); - if (JLSFsUtils.shouldStoreInMetadataArea(fullPath)) { - IPath containerPath = JLSFsUtils.getContainerPath(fullPath); - String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(containerPath); - if (projectName == null) { - return new JLSFile(fullPath.toFile()); - } - IPath redirectedPath = JLSFsUtils.getMetaDataFilePath(projectName, path); - if (redirectedPath != null) { - return new JLSFile(redirectedPath.toFile()); - } - } - - return new JLSFile(fullPath.toFile()); - } -} diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFileSystem.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFileSystem.java deleted file mode 100644 index 96562c19d2..0000000000 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFileSystem.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2021 Microsoft Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Microsoft Corporation - *******************************************************************************/ - -package org.eclipse.jdt.ls.core.internal.filesystem; - -import java.net.URI; -import java.nio.file.Paths; - -import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.internal.filesystem.local.LocalFileSystem; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; - -/** - * JDT.LS's own implementation of file system to handle the 'file' scheme uri. - * The purpose of this implementation is to allow the .project files can be - * persisted out of the project root, since for the moment using linked resources - * seem not possible. - */ -public class JLSFileSystem extends LocalFileSystem { - - @Override - public IFileStore getStore(IPath path) { - if (JLSFsUtils.shouldStoreInMetadataArea(path)) { - IPath containerPath = JLSFsUtils.getContainerPath(path); - String projectName = JLSFsUtils.getProjectNameIfLocationIsProjectRoot(containerPath); - if (projectName == null) { - return new JLSFile(path.toFile()); - } - IPath redirectedPath = JLSFsUtils.getMetaDataFilePath(projectName, path); - if (redirectedPath != null) { - return new JLSFile(redirectedPath.toFile()); - } - } - return new JLSFile(path.toFile()); - } - - @Override - public IFileStore getStore(URI uri) { - IPath path = filePathFromURI(uri.toString()); - return path == null ? super.getStore(uri) : getStore(path); - } - - public static IPath filePathFromURI(String uriStr) { - URI uri = URI.create(uriStr); - return "file".equals(uri.getScheme()) ? - Path.fromOSString(Paths.get(uri).toString()) : - null; - } - -} diff --git a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java b/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java deleted file mode 100644 index 8831e4621b..0000000000 --- a/org.eclipse.jdt.ls.filesystem/src/org/eclipse/jdt/ls/core/internal/filesystem/JLSFsUtils.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2021-2022 Microsoft Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Microsoft Corporation - *******************************************************************************/ - -package org.eclipse.jdt.ls.core.internal.filesystem; - -import java.util.Objects; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IPath; - -/** - * Utilities of the file system implementation. - */ -public class JLSFsUtils { - private JLSFsUtils() {} - - /** - * ⚠ This value is duplicated in ProjectsManager as both bundles must remain independent, - * but the same dir should be used for .project or .settings/.classpath. - * So when updating one, think about updating the other. - **/ - static final IPath METADATA_FOLDER_PATH = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(".projects");; - /** - * The system property key to specify the file system mode. - * - * This value is duplicated in ProjectsManager as both bundles must remain independent, - * but the same dir should be used for .project or .settings/.classpath. - * So when updating one, think about updating the other. - */ - static final String GENERATES_METADATA_FILES_AT_PROJECT_ROOT = "java.import.generatesMetadataFilesAtProjectRoot"; - - /** - * Determine whether the resource should be stored in workspace's metadata folder. - *

- * The file will be stored in workspace's metadata folder when following conditions meet: - *

    - *
  • The system property shows that it's allowed to store them in workspace.
  • - *
  • The file belongs to the metadata file defined in {@link JLSFsUtils#METADATA_NAMES}.
  • - *
  • The project's root path does not contain the metadata file with the same name.
  • - *
- *

- * - * @param location the path of the resource. - * @return whether the resource needs to be stored in workspace's metadata folder. - */ - static boolean shouldStoreInMetadataArea(IPath location) { - if (generatesMetadataFilesAtProjectRoot()) { - return false; - } - - if (!isProjectMetadataFile(location)) { - return false; - } - - // do not redirect if the file already exists on disk - if (location.toFile().exists()) { - return false; - } - - return true; - } - - /** - * Check whether the given location points to a metadata file. - * @param location file location. - * @return whether the given location points to a metadata file. - */ - static boolean isProjectMetadataFile(IPath location) { - return location != null && // - location.segmentCount() != 2 && // - IProjectDescription.DESCRIPTION_FILE_NAME.equals(location.lastSegment()); - } - - /** - * Get the container path of the given file path. - * If the file path is a preferences file, the grand-parent container will be returned. - * @param filePath the file path. - */ - static IPath getContainerPath(IPath filePath) { - return filePath.removeLastSegments(1); - } - - /** - * Get the project name if the given path is a project root, or null if - * no project root can match the path. - * @param location the location path. - * @return The project name - */ - static String getProjectNameIfLocationIsProjectRoot(IPath location) { - IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(IContainer.INCLUDE_HIDDEN); - for (IProject project : projects) { - IPath projectLocation = project.getLocation(); - if (Objects.equals(projectLocation, location)) { - return project.getName(); - } - } - return null; - } - - /** - * Get the redirected path of the input path. The path will be redirected to - * the workspace's metadata folder ({@link JLSFsUtils#METADATA_FOLDER_PATH}). - * @param projectName name of the project. - * @param path path needs to be redirected. - * @return the redirected path. - */ - static IPath getMetaDataFilePath(String projectName, IPath path) { - if (path.segmentCount() == 1) { - return METADATA_FOLDER_PATH.append(projectName).append(path); - } - - String lastSegment = path.lastSegment(); - if (IProjectDescription.DESCRIPTION_FILE_NAME.equals(lastSegment)) { - return METADATA_FOLDER_PATH.append(projectName).append(lastSegment); - } - - return null; - } - - /** - * Check whether the metadata files needs to be generated at project root. - */ - public static boolean generatesMetadataFilesAtProjectRoot() { - String property = System.getProperty(GENERATES_METADATA_FILES_AT_PROJECT_ROOT); - if (property == null) { - return true; - } - return Boolean.parseBoolean(property); - } -} diff --git a/org.eclipse.jdt.ls.product/languageServer.product b/org.eclipse.jdt.ls.product/languageServer.product index 71edf46a64..36c4b06b4f 100644 --- a/org.eclipse.jdt.ls.product/languageServer.product +++ b/org.eclipse.jdt.ls.product/languageServer.product @@ -53,7 +53,6 @@ - diff --git a/org.eclipse.jdt.ls.product/syntaxServer.product b/org.eclipse.jdt.ls.product/syntaxServer.product index b4eed3bd6d..5dbaa8eb8c 100644 --- a/org.eclipse.jdt.ls.product/syntaxServer.product +++ b/org.eclipse.jdt.ls.product/syntaxServer.product @@ -27,7 +27,6 @@ - diff --git a/org.eclipse.jdt.ls.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.ls.tests/META-INF/MANIFEST.MF index 96aca4c458..fb9f941e17 100644 --- a/org.eclipse.jdt.ls.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.ls.tests/META-INF/MANIFEST.MF @@ -33,7 +33,6 @@ Require-Bundle: org.eclipse.jdt.ls.core, org.eclipse.jdt.apt.pluggable.core, org.eclipse.m2e.apt.core, org.eclipse.buildship.core, - org.mockito.mockito-core;bundle-version="4.3.1", - org.eclipse.jdt.ls.filesystem;bundle-version="1.0.0" + org.mockito.mockito-core;bundle-version="4.3.1" Bundle-Vendor: %Bundle-Vendor Bundle-Activator: org.eclipse.jdt.ls.core.internal.JavaLanguageServerTestPlugin diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/GradleProjectMetadataFileTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/GradleProjectMetadataFileTest.java index 62b1df32e8..2b5556d35a 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/GradleProjectMetadataFileTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/GradleProjectMetadataFileTest.java @@ -15,6 +15,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -23,6 +24,7 @@ import java.io.InputStream; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.eclipse.buildship.core.internal.CorePlugin; @@ -88,10 +90,10 @@ public void testMetadataFileLocation() throws Exception { // then we check the sub-module project = WorkspaceHelper.getProject("app"); projectDescription = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 - projectDescriptionPath = FileUtil.toPath(projectDescription.getLocationURI()); + projectDescriptionPath = projectDescription.getLocation(); assertTrue(projectDescriptionPath.toFile().exists()); assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), ProjectsManager.generatesMetadataFilesAtProjectRoot()); + assertEquals(project.getLocation().append(IProjectDescription.DESCRIPTION_FILE_NAME).toFile().exists(), ProjectsManager.generatesMetadataFilesAtProjectRoot()); IFile classpath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME); IPath classpathPath = classpath.getLocation(); @@ -113,7 +115,7 @@ public void testMetadataFileLocation2() throws Exception { waitForBackgroundJobs(); List markers = ResourceUtils.findMarkers(project, IMarker.SEVERITY_ERROR); - assertTrue(markers.isEmpty()); + assertEquals(Collections.emptyList(), markers); } @Test diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/MavenProjectMetadataFileTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/MavenProjectMetadataFileTest.java index 853c8e6ecc..ddf9ceeb78 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/MavenProjectMetadataFileTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/filesystem/MavenProjectMetadataFileTest.java @@ -16,6 +16,7 @@ import static org.eclipse.jdt.ls.core.internal.WorkspaceHelper.getProject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import java.io.File; @@ -25,7 +26,6 @@ import org.apache.commons.io.FileUtils; import org.eclipse.core.internal.preferences.EclipsePreferences; -import org.eclipse.core.internal.utils.FileUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; @@ -72,9 +72,10 @@ public void testMetadataFileLocation() throws Exception { IFile projectDescription = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 - IPath projectDescriptionPath = FileUtil.toPath(projectDescription.getLocationURI()); + IPath projectDescriptionPath = projectDescription.getLocation(); assertTrue(projectDescriptionPath.toFile().exists()); assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), ProjectsManager.generatesMetadataFilesAtProjectRoot()); + assertEquals(project.getLocation().append(IProjectDescription.DESCRIPTION_FILE_NAME).toFile().exists(), ProjectsManager.generatesMetadataFilesAtProjectRoot()); IFile classpath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME); IPath classpathPath = classpath.getLocation(); @@ -116,7 +117,7 @@ public void testInvalidProject() throws Exception { IFile projectFile = invalid.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); assertTrue(projectFile.exists()); // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 - File file = FileUtil.toPath(projectFile.getLocationURI()).toFile(); + File file = projectFile.getLocation().toFile(); invalid.close(new NullProgressMonitor()); assertTrue(file.exists()); file.delete(); @@ -135,7 +136,6 @@ public void testDeleteClasspath() throws Exception { assertIsJavaProject(project); assertIsMavenProject(project); IFile dotClasspath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 File file = dotClasspath.getLocation().toFile(); assertTrue(file.exists()); file.delete(); @@ -155,24 +155,21 @@ public void testFactoryPathFileLocation() throws Exception { IFile projectDescription = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 - IPath projectDescriptionPath = FileUtil.toPath(projectDescription.getLocationURI()); + IPath projectDescriptionPath = projectDescription.getLocation(); assertTrue(projectDescriptionPath.toFile().exists()); assertEquals(project.getLocation().isPrefixOf(projectDescriptionPath), ProjectsManager.generatesMetadataFilesAtProjectRoot()); IFile classpath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 IPath classpathPath = classpath.getLocation(); assertTrue(classpathPath.toFile().exists()); assertEquals(project.getLocation().isPrefixOf(classpathPath), ProjectsManager.generatesMetadataFilesAtProjectRoot()); IFile preferencesFile = project.getFile(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 IPath preferencesPath = preferencesFile.getLocation(); assertTrue(preferencesPath.toFile().exists()); assertEquals(project.getLocation().isPrefixOf(preferencesPath), ProjectsManager.generatesMetadataFilesAtProjectRoot()); IFile factoryPathFile = project.getFile(".factorypath"); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 IPath factoryPathFilePath = factoryPathFile.getLocation(); assertTrue(factoryPathFilePath.toFile().exists()); assertEquals(project.getLocation().isPrefixOf(factoryPathFilePath), ProjectsManager.generatesMetadataFilesAtProjectRoot()); @@ -187,13 +184,10 @@ public void testMultipleMetadataFile() throws Exception { importProjects("maven/" + name); IProject project = getProject(name); IFile projectDescription = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 File projectDescriptionFile = projectDescription.getLocation().toFile(); IFile classpath = project.getFile(IJavaProject.CLASSPATH_FILE_NAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 File classpathPathFile = classpath.getLocation().toFile(); IFile preferencesFile = project.getFile(EclipsePreferences.DEFAULT_PREFERENCES_DIRNAME); - // workaround to get the correct path, see: https://github.com/eclipse/eclipse.jdt.ls/pull/1900 File preferencesPathFile = preferencesFile.getLocation().toFile(); FileUtils.copyFile(projectDescriptionFile, project.getLocation().append(IProjectDescription.DESCRIPTION_FILE_NAME).toFile()); FileUtils.copyFile(classpathPathFile, project.getLocation().append(IJavaProject.CLASSPATH_FILE_NAME).toFile()); diff --git a/pom.xml b/pom.xml index 778c33bf19..e187ed7d10 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,6 @@ org.eclipse.jdt.ls.target org.eclipse.jdt.ls.core - org.eclipse.jdt.ls.filesystem org.eclipse.jdt.ls.tests org.eclipse.jdt.ls.logback.appender org.eclipse.jdt.ls.tests.syntaxserver