2020
2121import static org .eclipse .jface .util .Util .isValid ;
2222
23+ import java .io .BufferedWriter ;
2324import java .io .File ;
2425import java .io .FileInputStream ;
2526import java .io .FileOutputStream ;
27+ import java .io .FileWriter ;
2628import java .io .IOException ;
2729import java .io .OutputStream ;
2830import java .net .InetAddress ;
2931import java .net .MalformedURLException ;
3032import java .net .URL ;
31- import java .net .UnknownHostException ;
33+ import java .nio .file .Files ;
34+ import java .nio .file .Paths ;
3235import java .util .LinkedHashMap ;
3336import java .util .Map ;
3437import java .util .Properties ;
@@ -89,6 +92,8 @@ public class IDEApplication implements IApplication, IExecutableExtension {
8992
9093 private static final String DISPLAY_VAR = "DISPLAY" ; //$NON-NLS-1$
9194
95+ private static final String HOSTNAME_VAR = "HOSTNAME" ; //$NON-NLS-1$
96+
9297 private static final String PROCESS_ID = "process-id" ; //$NON-NLS-1$
9398
9499 private static final String DISPLAY = "display" ; //$NON-NLS-1$
@@ -127,6 +132,8 @@ public class IDEApplication implements IApplication, IExecutableExtension {
127132 */
128133 public static final String PLUGIN_ID = "org.eclipse.ui.ide.application" ; //$NON-NLS-1$
129134
135+ private String lockFileBackup = null ;
136+
130137 /**
131138 * Creates a new IDE application.
132139 */
@@ -243,12 +250,21 @@ protected Object checkInstanceLocation(Shell shell, Map applicationArguments) {
243250 // at this point its valid, so try to lock it and update the
244251 // metadata version information if successful
245252 try {
253+ // Check if the workspace is locked. If not then write who is going to lock now.
254+ if (!instanceLoc .isLocked ()) {
255+ lockFileBackup = readLockFile (instanceLoc .getURL ());
256+ writeWsLockInfo ();
257+ }
258+
246259 if (instanceLoc .lock ()) {
247260 writeWorkspaceVersion ();
248- writeWsLockInfo ();
249261 return null ;
250262 }
251263
264+ // We wrote to lock file assuming we can will acquire lock. For some unknown
265+ // reasons we could not acquire lock. Then write back what was there before.
266+ writeBackLockFileBackup (instanceLoc .getURL ());
267+
252268 // we failed to create the directory.
253269 // Two possibilities:
254270 // 1. directory is already in use
@@ -258,10 +274,19 @@ protected Object checkInstanceLocation(Shell shell, Map applicationArguments) {
258274 if (isDevLaunchMode (applicationArguments )) {
259275 return EXIT_WORKSPACE_LOCKED ;
260276 }
277+
278+ String wsLockedError = NLS .bind (IDEWorkbenchMessages .IDEApplication_workspaceCannotLockMessage ,
279+ workspaceDirectory .getAbsolutePath ());
280+ // check if there is a lock info then append it to error message.
281+ String lockInfo = getWorkspaceLockInfo (instanceLoc .getURL ());
282+ if (lockInfo != null && !lockInfo .isBlank ()) {
283+ wsLockedError = wsLockedError + System .lineSeparator () + System .lineSeparator ()
284+ + NLS .bind (IDEWorkbenchMessages .Workspace_Lock_Owner , lockInfo );
285+ }
261286 MessageDialog .openError (
262287 shell ,
263288 IDEWorkbenchMessages .IDEApplication_workspaceCannotLockTitle ,
264- NLS . bind ( IDEWorkbenchMessages . IDEApplication_workspaceCannotLockMessage , workspaceDirectory . getAbsolutePath ()) );
289+ wsLockedError );
265290 } else {
266291 MessageDialog .openError (
267292 shell ,
@@ -331,11 +356,21 @@ protected Object checkInstanceLocation(Shell shell, Map applicationArguments) {
331356
332357 // the operation will fail if the url is not a valid
333358 // instance data area, so other checking is unneeded
334- if (instanceLoc .set (workspaceUrl , true )) {
359+ if (instanceLoc .set (workspaceUrl , false )) {
335360 launchData .writePersistedData ();
336- writeWorkspaceVersion ();
337- writeWsLockInfo ();
338- return null ;
361+
362+ if (!instanceLoc .isLocked ()) {
363+ lockFileBackup = readLockFile (workspaceUrl );
364+ writeWsLockInfo ();
365+ }
366+ if (instanceLoc .lock ()) {
367+ writeWorkspaceVersion ();
368+ return null ;
369+ }
370+ // We wrote to lock file assuming we can will acquire lock. For some unknown
371+ // reasons we could not acquire lock. Then write back what was there before.
372+ writeBackLockFileBackup (workspaceUrl );
373+
339374 }
340375 } catch (IllegalStateException e ) {
341376 MessageDialog
@@ -367,13 +402,11 @@ protected Control createCustomArea(Composite parent) {
367402 return null ;
368403 }
369404
370- String displayText = "Workspace lock is held by the following owner:\n " .concat (lockInfo ); //$NON-NLS-1$
371-
372405 Composite container = new Composite (parent , SWT .NONE );
373406 container .setLayout (new FillLayout ());
374407
375408 Label multiLineText = new Label (container , SWT .NONE );
376- multiLineText .setText (displayText );
409+ multiLineText .setText (NLS . bind ( IDEWorkbenchMessages . Workspace_Lock_Owner , lockInfo ) );
377410
378411 return container ;
379412 }
@@ -394,25 +427,28 @@ protected Control createCustomArea(Composite parent) {
394427 */
395428 private String getWorkspaceLockInfo (URL workspaceUrl ) {
396429 File lockFile = getLockFile (workspaceUrl );
430+ if (lockFile == null ) {
431+ return null ;
432+ }
397433 StringBuilder sb = new StringBuilder ();
398434 Properties props = new Properties ();
399435 try (FileInputStream is = new FileInputStream (lockFile )) {
400436 props .load (is );
401437 String prop = props .getProperty (USER );
402438 if (prop != null ) {
403- sb .append ("user: " ). append ( prop ). append ( System . lineSeparator ()); //$NON-NLS-1$
439+ sb .append (NLS . bind ( IDEWorkbenchMessages . User , prop ));
404440 }
405441 prop = props .getProperty (HOST );
406442 if (prop != null ) {
407- sb .append ("host: " ). append ( prop ). append ( System . lineSeparator ()); //$NON-NLS-1$
443+ sb .append (NLS . bind ( IDEWorkbenchMessages . Host , prop ));
408444 }
409445 prop = props .getProperty (DISPLAY );
410446 if (prop != null ) {
411- sb .append ("display: " ). append ( prop ). append ( System . lineSeparator ()); //$NON-NLS-1$
447+ sb .append (NLS . bind ( IDEWorkbenchMessages . Display , prop ));
412448 }
413449 prop = props .getProperty (PROCESS_ID );
414450 if (prop != null ) {
415- sb .append ("process-id: " ). append ( prop ). append ( System . lineSeparator ()); //$NON-NLS-1$
451+ sb .append (NLS . bind ( IDEWorkbenchMessages . Process_Id , prop ));
416452 }
417453 return sb .toString ();
418454 } catch (Exception e ) {
@@ -425,17 +461,7 @@ private String getWorkspaceLockInfo(URL workspaceUrl) {
425461 * Write lock owner details onto workspace lock file. Data includes user, host,
426462 * display and current java process id.
427463 */
428- private void writeWsLockInfo () {
429- Location instanceLoc = Platform .getInstanceLocation ();
430- if (instanceLoc == null || instanceLoc .isReadOnly ()) {
431- return ;
432- }
433-
434- File lockFile = getLockFile (instanceLoc .getURL ());
435- if (lockFile == null ) {
436- return ;
437- }
438-
464+ protected void writeWsLockInfo () {
439465 Properties props = new Properties ();
440466
441467 String user = System .getProperty (USER_NAME );
@@ -455,13 +481,65 @@ private void writeWsLockInfo() {
455481 props .setProperty (PROCESS_ID , pid );
456482 }
457483
484+ if (props .isEmpty ()) {
485+ return ;
486+ }
487+
488+ Location instanceLoc = Platform .getInstanceLocation ();
489+ if (instanceLoc == null || instanceLoc .isReadOnly ()) {
490+ return ;
491+ }
492+
493+ File lockFile = getLockFile (instanceLoc .getURL ());
494+ if (lockFile == null ) {
495+ return ;
496+ }
497+
498+ if (lockFile == null || !lockFile .exists ()) {
499+ return ;
500+ }
501+
458502 try (OutputStream output = new FileOutputStream (lockFile )) {
459503 props .store (output , null );
460504 } catch (IOException e ) {
461505 IDEWorkbenchPlugin .log ("Could not modify lock file" , e ); //$NON-NLS-1$
462506 }
463507 }
464508
509+ private String readLockFile (URL workspaceUrl ) {
510+ File lockFile = getLockFile (workspaceUrl );
511+
512+ if (lockFile == null ) {
513+ return null ;
514+ }
515+
516+ if (lockFile .exists () && lockFile .isFile ()) {
517+ try {
518+ return new String (Files .readAllBytes (Paths .get (lockFile .getPath ())));
519+ } catch (IOException e ) {
520+ IDEWorkbenchPlugin .log ("Could not read lock file" , e ); //$NON-NLS-1$
521+ }
522+ }
523+ return null ;
524+ }
525+
526+ private void writeBackLockFileBackup (URL workspaceUrl ) {
527+ if (lockFileBackup == null || lockFileBackup .isEmpty ()) {
528+ return ;
529+ }
530+ File lockFile = getLockFile (workspaceUrl );
531+
532+ if (lockFile == null ) {
533+ return ;
534+ }
535+
536+ try (BufferedWriter writer = new BufferedWriter (new FileWriter (lockFile , false ))) {
537+ writer .write (lockFileBackup );
538+ } catch (IOException e ) {
539+ IDEWorkbenchPlugin .log ("Could not write back backup data to lock file" , e ); //$NON-NLS-1$
540+ }
541+ }
542+
465543 private String getDisplay () {
466544 String displayEnv = null ;
467545 try {
@@ -484,14 +562,32 @@ private String getProcessId() {
484562
485563 private String getHostName () {
486564 String hostName = null ;
565+
566+ // Try fast approach first. Some OS(Like Linux) has HOSTNAME environment
567+ // variable set.
568+ try {
569+ hostName = System .getenv (HOSTNAME_VAR );
570+ if (hostName != null && !hostName .isEmpty ()) {
571+ return hostName ;
572+ }
573+ } catch (Exception e ) {
574+ // Ignore here because we will try another method in the next step.
575+ }
576+
487577 try {
488578 hostName = InetAddress .getLocalHost ().getHostName ();
489- } catch (UnknownHostException e ) {
579+ } catch (Exception e ) {
490580 IDEWorkbenchPlugin .log ("Failed to read host name." , e ); //$NON-NLS-1$
491581 }
492582 return hostName ;
493583 }
494584
585+ /**
586+ * Returns the lock file if it is present or it will create a lock file.
587+ *
588+ * @param workspaceUrl
589+ * @return Create .lock file if it does not present and return.
590+ */
495591 private File getLockFile (URL workspaceUrl ) {
496592 if (workspaceUrl == null ) {
497593 return null ;
@@ -500,13 +596,17 @@ private File getLockFile(URL workspaceUrl) {
500596 // make sure the directory exists
501597 File metaDir = new File (workspaceUrl .getPath (), METADATA_FOLDER );
502598 if (!metaDir .exists ()) {
503- return null ;
599+ metaDir . mkdirs () ;
504600 }
505601
506- // make sure the file exists
507602 File lockFile = new File (metaDir , LOCK_FILENAME );
508603 if (!lockFile .exists ()) {
509- return null ;
604+ try {
605+ lockFile .createNewFile ();
606+ } catch (IOException e ) {
607+ IDEWorkbenchPlugin .log ("Failed to create workspace lock file." , e ); //$NON-NLS-1$
608+ return null ;
609+ }
510610 }
511611
512612 return lockFile ;
0 commit comments