aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerry Parker2014-05-01 15:58:43 (EDT)
committerEric Moffatt2014-05-09 10:48:27 (EDT)
commite37da30b63cdd33dcf30eb6a5be12657b14a6fd0 (patch)
treef09b827c80b4baeb51e4fa1458a6f33da16f3196
parent8b82900a5b2629d4f417c486fa2308f7f96b849d (diff)
downloadeclipse.platform.ui-e37da30b63cdd33dcf30eb6a5be12657b14a6fd0.zip
eclipse.platform.ui-e37da30b63cdd33dcf30eb6a5be12657b14a6fd0.tar.gz
eclipse.platform.ui-e37da30b63cdd33dcf30eb6a5be12657b14a6fd0.tar.bz2
Fixes Bug 416673 - [Workbench] Corrupted workbench.xmi file causesrefs/changes/53/25853/5
silent Eclipse exit Added checks at workbench model serialization and deserialization, to make sure that the application model has top-level windows associated with it. For serialization, if the model has lost its windows, the serialization is skipped and an error is logged to the error log. For deserialization (at startup), if no windows are seen, the serialized data is discarded and the default template is used to restore the workbench. Change-Id: I6e010c4ef73447c1e67be61c6de083526f05d0fc Signed-off-by: Terry Parker <tparker@google.com>
-rw-r--r--bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java16
-rw-r--r--bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ResourceHandler.java44
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java19
3 files changed, 73 insertions, 6 deletions
diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java
index 605b441..790a065 100644
--- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java
+++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/E4Application.java
@@ -11,6 +11,7 @@
* Fix for Bug 2369 [Workbench] Would like to be able to save workspace without exiting
* Implemented workbench auto-save to correctly restore state in case of crash.
* Lars Vogel <Lars.Vogel@gmail.com> - Bug 366364
+ * Terry Parker <tparker@google.com> - Bug 416673
******************************************************************************/
package org.eclipse.e4.ui.internal.workbench.swt;
@@ -184,10 +185,19 @@ public class E4Application implements IApplication {
public void saveModel() {
try {
- handler.save();
+ if (!(handler instanceof ResourceHandler)
+ || ((ResourceHandler) handler).hasTopLevelWindows()) {
+ handler.save();
+ } else {
+ Logger logger = new WorkbenchLogger(PLUGIN_ID);
+ logger.error(
+ new Exception(), // log a stack trace for debugging
+ "Attempted to save a workbench model that had no top-level windows! " //$NON-NLS-1$
+ + "Skipped saving the model to avoid corruption."); //$NON-NLS-1$
+ }
} catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ Logger logger = new WorkbenchLogger(PLUGIN_ID);
+ logger.error(e, "Error saving the workbench model"); //$NON-NLS-1$
}
}
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ResourceHandler.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ResourceHandler.java
index daec67e..96784ec 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ResourceHandler.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ResourceHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 IBM Corporation and others.
+ * Copyright (c) 2009, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Tristan Hume - <trishume@gmail.com> -
* Fix for Bug 2369 [Workbench] Would like to be able to save workspace without exiting
* Implemented workbench auto-save to correctly restore state in case of crash.
+ * Terry Parker <tparker@google.com> - Bug 416673
******************************************************************************/
package org.eclipse.e4.ui.internal.workbench;
@@ -128,6 +129,26 @@ public class ResourceHandler implements IModelResourceHandler {
}
+ /**
+ * @return {@code true} if the current application model has top-level windows.
+ */
+ public boolean hasTopLevelWindows() {
+ return hasTopLevelWindows(resource);
+ }
+
+ /**
+ * @return {@code true} if the specified application model has top-level windows.
+ */
+ private boolean hasTopLevelWindows(Resource applicationResource) {
+ if (applicationResource == null || applicationResource.getContents() == null) {
+ // If the application resource doesn't exist or has no contents, then it has no
+ // top-level windows (and we are in an error state).
+ return false;
+ }
+ MApplication application = (MApplication) applicationResource.getContents().get(0);
+ return !application.getChildren().isEmpty();
+ }
+
@Override
public Resource loadMostRecentModel() {
// This is temporary code to migrate existing delta files into full models
@@ -173,8 +194,12 @@ public class ResourceHandler implements IModelResourceHandler {
logger.error(e);
}
}
- if (appElement != null)
+ if (appElement != null) {
resource.getContents().add((EObject) appElement);
+ if (!hasTopLevelWindows(resource) && logger != null) {
+ logger.error("No top-level windows seen when migrating from existing delta files"); //$NON-NLS-1$
+ }
+ }
return resource;
}
}
@@ -204,9 +229,24 @@ public class ResourceHandler implements IModelResourceHandler {
resource = null;
if (restore && saveAndRestore) {
resource = loadResource(restoreLocation);
+ // If the saved model does not have any top-level windows, Eclipse will exit
+ // immediately, so throw out the persisted state and reinitialize with the defaults.
+ if (!hasTopLevelWindows(resource)) {
+ if (logger != null) {
+ logger.error(new Exception(), // log a stack trace to help debug the corruption
+ "The persisted workbench has no top-level windows, so reinitializing with defaults."); //$NON-NLS-1$
+ }
+ resource = null;
+ }
}
if (resource == null) {
Resource applicationResource = loadResource(applicationDefinitionInstance);
+ if (!hasTopLevelWindows(applicationResource) && logger != null) {
+ logger.error(
+ new Exception(), // log a stack trace to help debug the corruption
+ "Initializing from the application definition instance yields no top-level windows! " //$NON-NLS-1$
+ + "Continuing execution, but the missing windows may cause other initialization failures."); //$NON-NLS-1$
+ }
MApplication theApp = (MApplication) applicationResource.getContents().get(0);
resource = createResourceWithApp(theApp);
context.set(E4Workbench.NO_SAVED_MODEL_FOUND, Boolean.TRUE);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
index 7946af5..695ed94 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
@@ -13,6 +13,7 @@
* Fix for Bug 2369 [Workbench] Would like to be able to save workspace without exiting
* Implemented workbench auto-save to correctly restore state in case of crash.
* Lars Vogel <Lars.Vogel@gmail.com> - Bug 422533
+ * Terry Parker <tparker@google.com> - Bug 416673
*******************************************************************************/
package org.eclipse.ui.internal;
@@ -1262,12 +1263,26 @@ public final class Workbench extends EventManager implements IWorkbench,
}
}
+ private boolean detectWorkbenchCorruption(MApplication application) {
+ if (application.getChildren().isEmpty()) {
+ WorkbenchPlugin.log(
+ "When auto-saving the workbench model, there were no top-level windows. " //$NON-NLS-1$
+ + " Skipped saving the model.", //$NON-NLS-1$
+ new Exception()); // log a stack trace to assist debugging
+ return true;
+ }
+ return false;
+ }
+
/**
* Copy the model, clean it up and write it out to workbench.xmi. Called as
* part of persist(false) during auto-save.
*/
private void persistWorkbenchModel() {
final MApplication appCopy = (MApplication) EcoreUtil.copy((EObject) application);
+ if (detectWorkbenchCorruption(appCopy)) {
+ return;
+ }
final IModelResourceHandler handler = e4Context.get(IModelResourceHandler.class);
Job cleanAndSaveJob = new Job("Workbench Auto-Save Background Job") { //$NON-NLS-1$
@@ -1276,7 +1291,9 @@ public final class Workbench extends EventManager implements IWorkbench,
final Resource res = handler.createResourceWithApp(appCopy);
cleanUpCopy(appCopy, e4Context);
try {
- res.save(null);
+ if (!detectWorkbenchCorruption((MApplication) res.getContents().get(0))) {
+ res.save(null);
+ }
} catch (IOException e) {
// Just auto-save, we don't really care
} finally {