3535import java .io .InputStream ;
3636import java .io .StringReader ;
3737import java .io .StringWriter ;
38+ import java .net .MalformedURLException ;
3839import java .net .URI ;
3940import java .net .URISyntaxException ;
4041import java .net .URL ;
42+ import java .nio .file .Files ;
43+ import java .nio .file .Path ;
4144import java .util .ArrayList ;
4245import java .util .Arrays ;
4346import java .util .Collection ;
4952import java .util .List ;
5053import java .util .Map ;
5154import java .util .Objects ;
55+ import java .util .Properties ;
5256import java .util .Set ;
5357import java .util .UUID ;
5458import java .util .concurrent .atomic .AtomicReference ;
8084import org .eclipse .core .runtime .SafeRunner ;
8185import org .eclipse .core .runtime .Status ;
8286import org .eclipse .core .runtime .SubMonitor ;
87+ import org .eclipse .core .runtime .URIUtil ;
8388import org .eclipse .core .runtime .dynamichelpers .IExtensionTracker ;
8489import org .eclipse .core .runtime .jobs .Job ;
8590import org .eclipse .core .runtime .preferences .ConfigurationScope ;
114119import org .eclipse .e4 .ui .workbench .modeling .EModelService ;
115120import org .eclipse .e4 .ui .workbench .modeling .EPartService ;
116121import org .eclipse .e4 .ui .workbench .modeling .ISaveHandler ;
122+ import org .eclipse .e4 .ui .workbench .swt .internal .copy .WorkbenchSWTMessages ;
117123import org .eclipse .emf .ecore .EObject ;
118124import org .eclipse .emf .ecore .resource .Resource ;
119125import 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