From 74d0c5699a552f99813976236e26f48f1fd7f88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Tue, 10 May 2022 07:35:14 +0200 Subject: [PATCH] Initialize the ProjectPreferences with the workspace This makes the current Workspace visible to the ProjectPreferences right after we change the search order. Beside that, the workspace is passed / fetched from known sources if possible Fix https://github.com/eclipse-platform/eclipse.platform.resources/issues/124 --- .../resources/ProjectPreferences.java | 33 ++++++++++++++----- .../core/internal/resources/Workspace.java | 16 +++++++-- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java index 567801013..85c8e59e6 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java @@ -13,6 +13,7 @@ * Markus Schorn (Wind River) - [108066] Project prefs marked dirty on read * James Blackburn (Broadcom Corp.) - ongoing development * Lars Vogel - Bug 473427, 483529 + * Christoph Läubrich - Issue #124 *******************************************************************************/ package org.eclipse.core.internal.resources; @@ -66,6 +67,7 @@ public class ProjectPreferences extends EclipsePreferences { // cache private int segmentCount; + private Workspace workspace; static void deleted(IFile file) throws CoreException { IPath path = file.getFullPath(); @@ -191,7 +193,7 @@ private static Properties loadProperties(IFile file) throws BackingStoreExceptio } private static void preferencesChanged(IProject project) { - Workspace workspace = ((Workspace) ResourcesPlugin.getWorkspace()); + Workspace workspace = (Workspace) project.getWorkspace(); workspace.getCharsetManager().projectPreferencesChanged(project); workspace.getContentDescriptionManager().projectPreferencesChanged(project); } @@ -361,8 +363,9 @@ public ProjectPreferences() { super(null, null); } - private ProjectPreferences(EclipsePreferences parent, String name) { + private ProjectPreferences(EclipsePreferences parent, String name, Workspace workspace) { super(parent, name); + setWorkspace(workspace); // cache the segment count String path = absolutePath(); @@ -374,7 +377,7 @@ private ProjectPreferences(EclipsePreferences parent, String name) { // cache the project name String projectName = getSegment(path, 1); if (projectName != null) - project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + project = getWorkspace().getRoot().getProject(projectName); // cache the qualifier if (segmentCount > 2) @@ -486,7 +489,7 @@ protected IPath getLocation() { @Override protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String nodeName, Object context) { - return new ProjectPreferences(nodeParent, nodeName); + return new ProjectPreferences(nodeParent, nodeName, workspace); } @Override @@ -507,7 +510,7 @@ protected String internalPut(String key, String newValue) { silentLoad(); if ((segmentCount == 3) && PREFS_REGULAR_QUALIFIER.equals(qualifier) && (project != null)) { if (ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS.equals(key)) { - CharsetManager charsetManager = ((Workspace) ResourcesPlugin.getWorkspace()).getCharsetManager(); + CharsetManager charsetManager = getWorkspace().getCharsetManager(); if (Boolean.parseBoolean(newValue)) charsetManager.splitEncodingPreferences(project); else @@ -621,7 +624,7 @@ public boolean nodeExists(String path) throws BackingStoreException { return super.nodeExists(path); // if we are checking existance of a single segment child of /project, base the answer on // whether or not it exists in the workspace. - return ResourcesPlugin.getWorkspace().getRoot().getProject(path).exists() || super.nodeExists(path); + return getWorkspace().getRoot().getProject(path).exists() || super.nodeExists(path); } @Override @@ -632,7 +635,7 @@ public void remove(String key) { super.remove(key); if ((segmentCount == 3) && PREFS_REGULAR_QUALIFIER.equals(qualifier) && (project != null)) { if (ResourcesPlugin.PREF_SEPARATE_DERIVED_ENCODINGS.equals(key)) { - CharsetManager charsetManager = ((Workspace) ResourcesPlugin.getWorkspace()).getCharsetManager(); + CharsetManager charsetManager = getWorkspace().getCharsetManager(); if (ResourcesPlugin.DEFAULT_PREF_SEPARATE_DERIVED_ENCODINGS) charsetManager.splitEncodingPreferences(project); else @@ -720,8 +723,8 @@ protected void save() throws BackingStoreException { }; //don't bother with scheduling rules if we are already inside an operation try { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - if (((Workspace) workspace).getWorkManager().isLockAlreadyAcquired()) { + Workspace workspace = getWorkspace(); + if (workspace.getWorkManager().isLockAlreadyAcquired()) { operation.run(null); } else { IResourceRuleFactory factory = workspace.getRuleFactory(); @@ -756,4 +759,16 @@ private void silentLoad() { node.setLoading(false); } } + + void setWorkspace(Workspace workspace) { + this.workspace = workspace; + } + + private Workspace getWorkspace() { + if (workspace != null) { + return workspace; + } + // last resort... + return (Workspace) ResourcesPlugin.getWorkspace(); + } } diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java index 2df1c7292..2eb336232 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java @@ -15,8 +15,7 @@ * Serge Beauchamp (Freescale Semiconductor) - [229633] Group and Project Path Variable Support * Broadcom Corporation - ongoing development * Lars Vogel - Bug 473427 - * Christoph Läubrich - Issue #77 - SaveManager access the ResourcesPlugin.getWorkspace at init phase - * - Issue #86 - Cyclic dependency between ProjectPreferences and Workspace init + * Christoph Läubrich - Issue #77, Issue #86, Issue #124 *******************************************************************************/ package org.eclipse.core.internal.resources; @@ -25,6 +24,7 @@ import java.lang.management.ManagementFactory; import java.net.URI; import java.net.URISyntaxException; +import java.text.MessageFormat; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicLong; @@ -50,6 +50,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.osgi.util.NLS; import org.osgi.framework.Bundle; +import org.osgi.service.prefs.Preferences; import org.xml.sax.InputSource; /** @@ -1861,7 +1862,7 @@ protected void initializeMoveDeleteHook() { * Add the project scope to the preference service's default look-up order so * people get it for free */ - private void initializePreferenceLookupOrder() { + private void initializePreferenceLookupOrder() throws CoreException { PreferencesService service = PreferencesService.getDefault(); String[] original = service.getDefaultDefaultLookupOrder(); List newOrder = new ArrayList<>(); @@ -1869,6 +1870,15 @@ private void initializePreferenceLookupOrder() { newOrder.add(ProjectScope.SCOPE); newOrder.addAll(Arrays.asList(original)); service.setDefaultDefaultLookupOrder(newOrder.toArray(new String[newOrder.size()])); + Preferences node = service.getRootNode().node(ProjectScope.SCOPE); + if (node instanceof ProjectPreferences) { + ProjectPreferences projectPreferences = (ProjectPreferences) node; + projectPreferences.setWorkspace(this); + } else { + throw new CoreException(Status.error(MessageFormat.format( + "Internal error while open workspace, expected ProjectPreferences for the scope {0} but got {1}", //$NON-NLS-1$ + ProjectScope.SCOPE, node.getClass().getSimpleName()))); + } } /**