Skip to content

Commit 954cc49

Browse files
committed
Prompt user when switching to a locked workspace in Eclipse
Prompts user on attempting to switch to a workspace that is currently locked by another Eclipse instance, a prompt dialog is now shown informing the user about the lock details and preventing Eclipse from exiting
1 parent 37ad17d commit 954cc49

File tree

3 files changed

+103
-3
lines changed

3 files changed

+103
-3
lines changed

bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/WorkbenchSWTMessages.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2005, 2019 IBM Corporation and others.
2+
* Copyright (c) 2005, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -42,6 +42,17 @@ public class WorkbenchSWTMessages extends NLS {
4242
public static String InternalError;
4343
public static String IDEApplication_versionTitle;
4444
public static String IDEApplication_versionMessage;
45+
public static String IDEApplication_workspaceLockMessage;
46+
47+
public static String IDEApplication_workspaceLockOwner;
48+
49+
public static String IDEApplication_workspaceLockHost;
50+
51+
public static String IDEApplication_workspaceLockDisplay;
52+
53+
public static String IDEApplication_workspaceLockPID;
54+
55+
public static String IDEApplication_workspaceCannotLockMessage2;
4556

4657
static {
4758
// load message values from bundle file

bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/messages.properties

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
# Copyright (c) 2000, 2019 IBM Corporation and others.
2+
# Copyright (c) 2000, 2025 IBM Corporation and others.
33
#
44
# This program and the accompanying materials
55
# are made available under the terms of the Eclipse Public License 2.0
@@ -42,3 +42,9 @@ This workspace was written with a different version of the product and needs to
4242
{0}\n\n\
4343
Updating the workspace may make it incompatible with other versions of the product.\n\
4444
Press OK to update the workspace and open it. Press Cancel to select a different workspace.
45+
IDEApplication_workspaceLockOwner=User:\t\t{0}\n
46+
IDEApplication_workspaceLockHost=Host:\t\t{0}\n
47+
IDEApplication_workspaceLockDisplay=Display:\t\t{0}\n
48+
IDEApplication_workspaceLockPID=Process ID:\t{0}\n
49+
IDEApplication_workspaceLockMessage=Workspace lock is currently held by:\n{0}
50+
IDEApplication_workspaceCannotLockMessage2=Could not switch to the selected workspace ''{0}'' because it is currently in use by another Eclipse instance.

bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/Workbench.java

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@
3535
import java.io.InputStream;
3636
import java.io.StringReader;
3737
import java.io.StringWriter;
38+
import java.net.MalformedURLException;
3839
import java.net.URI;
3940
import java.net.URISyntaxException;
4041
import java.net.URL;
42+
import java.nio.file.Files;
43+
import java.nio.file.Path;
4144
import java.util.ArrayList;
4245
import java.util.Arrays;
4346
import java.util.Collection;
@@ -49,6 +52,7 @@
4952
import java.util.List;
5053
import java.util.Map;
5154
import java.util.Objects;
55+
import java.util.Properties;
5256
import java.util.Set;
5357
import java.util.UUID;
5458
import java.util.concurrent.atomic.AtomicReference;
@@ -80,6 +84,7 @@
8084
import org.eclipse.core.runtime.SafeRunner;
8185
import org.eclipse.core.runtime.Status;
8286
import org.eclipse.core.runtime.SubMonitor;
87+
import org.eclipse.core.runtime.URIUtil;
8388
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
8489
import org.eclipse.core.runtime.jobs.Job;
8590
import org.eclipse.core.runtime.preferences.ConfigurationScope;
@@ -114,6 +119,7 @@
114119
import org.eclipse.e4.ui.workbench.modeling.EModelService;
115120
import org.eclipse.e4.ui.workbench.modeling.EPartService;
116121
import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
122+
import org.eclipse.e4.ui.workbench.swt.internal.copy.WorkbenchSWTMessages;
117123
import org.eclipse.emf.ecore.EObject;
118124
import org.eclipse.emf.ecore.resource.Resource;
119125
import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -2699,7 +2705,8 @@ private static String buildCommandLine(String workspace) {
26992705
* as the workspace location.
27002706
*
27012707
* @param workspacePath the new workspace location
2702-
* @return {@link IApplication#EXIT_OK} or {@link IApplication#EXIT_RELAUNCH}
2708+
* @return {@link IApplication#EXIT_OK} or {@link IApplication#EXIT_RELAUNCH} or
2709+
* <code>null</code>
27032710
*/
27042711
@SuppressWarnings("restriction")
27052712
public static Object setRestartArguments(String workspacePath) {
@@ -2714,12 +2721,88 @@ public static Object setRestartArguments(String workspacePath) {
27142721
if (command_line == null) {
27152722
return IApplication.EXIT_OK;
27162723
}
2724+
Path selectedWorkspace = Path.of(workspacePath);
2725+
try {
2726+
String workspaceLock = getWorkspaceLockDetails(selectedWorkspace.toUri().toURL());
2727+
if (workspaceLock != null && !workspaceLock.isEmpty()) {
2728+
String lockMessage = NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceCannotLockMessage2,
2729+
workspacePath);
2730+
String wsLockedError = lockMessage + System.lineSeparator() + System.lineSeparator()
2731+
+ NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockMessage,
2732+
workspaceLock);
2733+
2734+
MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
2735+
WorkbenchSWTMessages.IDEApplication_workspaceCannotLockTitle,
2736+
wsLockedError);
2737+
return null;
2738+
}
2739+
} catch (MalformedURLException e) {
2740+
return null;
2741+
}
27172742

27182743
System.setProperty(Workbench.PROP_EXIT_CODE, IApplication.EXIT_RELAUNCH.toString());
27192744
System.setProperty(IApplicationContext.EXIT_DATA_PROPERTY, command_line);
27202745
return IApplication.EXIT_RELAUNCH;
27212746
}
27222747

2748+
/**
2749+
* Extract the lock details of the selected workspace if it is locked by another
2750+
* Eclipse application
2751+
*
2752+
* @param workspaceUrl the <code>URL</code> of selected workspace
2753+
* @return <code>String</code> details of lock owned workspace,
2754+
* <code>null or Empty</code> if not locked
2755+
*/
2756+
@SuppressWarnings("restriction")
2757+
private static String getWorkspaceLockDetails(URL workspaceUrl) {
2758+
Path lockFile = getLockInfoFile(workspaceUrl);
2759+
if (lockFile != null && Files.exists(lockFile)) {
2760+
StringBuilder lockDetails = new StringBuilder();
2761+
Properties properties = new Properties();
2762+
try (InputStream is = Files.newInputStream(lockFile)) {
2763+
properties.load(is);
2764+
String prop = properties.getProperty("user"); //$NON-NLS-1$
2765+
if (prop != null) {
2766+
lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockOwner, prop));
2767+
}
2768+
prop = properties.getProperty("host"); //$NON-NLS-1$
2769+
if (prop != null) {
2770+
lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockHost, prop));
2771+
}
2772+
prop = properties.getProperty("display"); //$NON-NLS-1$
2773+
if (prop != null) {
2774+
lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockDisplay, prop));
2775+
}
2776+
prop = properties.getProperty("process-id"); //$NON-NLS-1$
2777+
if (prop != null) {
2778+
lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockPID, prop));
2779+
}
2780+
2781+
} catch (IOException e) {
2782+
WorkbenchPlugin.log(e);
2783+
}
2784+
return lockDetails.toString();
2785+
}
2786+
return null;
2787+
}
2788+
2789+
/**
2790+
* Returns the lock file.
2791+
*
2792+
* @param workspaceUrl the <code>URL</code> of selected workspace
2793+
* @return the path to the <code>.lock_info</code> file within the specified
2794+
* workspace, or <code> null</code> if the workspace URL cannot be
2795+
* converted to a valid URI
2796+
*/
2797+
private static Path getLockInfoFile(URL workspaceUrl) {
2798+
Path lockFile = Path.of(".metadata", ".lock_info"); //$NON-NLS-1$ //$NON-NLS-2$
2799+
try {
2800+
return Path.of(URIUtil.toURI(workspaceUrl)).resolve(lockFile);
2801+
} catch (URISyntaxException e) {
2802+
return null;
2803+
}
2804+
}
2805+
27232806
/**
27242807
* Returns the ids of all plug-ins that extend the
27252808
* <code>org.eclipse.ui.startup</code> extension point.

0 commit comments

Comments
 (0)