diff options
author | Terry Parker | 2014-05-01 19:58:43 +0000 |
---|---|---|
committer | Markus Keller | 2015-11-13 20:26:41 +0000 |
commit | f175f935db10ad5020662c64ed00cec44ec4dff8 (patch) | |
tree | 1f862dc470a21d5cb3df14080617b86a98ea3cb5 | |
parent | 8955eeca53af81244ce0d8315c5b09108bbed7fb (diff) | |
download | eclipse.platform.ui-f175f935db10ad5020662c64ed00cec44ec4dff8.tar.gz eclipse.platform.ui-f175f935db10ad5020662c64ed00cec44ec4dff8.tar.xz eclipse.platform.ui-f175f935db10ad5020662c64ed00cec44ec4dff8.zip |
Fixes Bug 416673 - [Workbench] Corrupted workbench.xmi file causes
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.
Signed-off-by: Terry Parker <tparker@google.com>
2 files changed, 55 insertions, 5 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 c344cc75d8c..62a4282dd16 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Terry Parker <tparker@google.com> - Bug 416673 ******************************************************************************/ package org.eclipse.e4.ui.internal.workbench.swt; @@ -167,10 +168,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 cb957739472..7e65236f115 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, 2012 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Terry Parker <tparker@google.com> - Bug 416673 ******************************************************************************/ package org.eclipse.e4.ui.internal.workbench; @@ -121,6 +122,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(); + } + public Resource loadMostRecentModel() { File baseLocation; try { @@ -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; } } @@ -200,9 +225,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); if (restoreLocation == null) restoreLocation = URI.createFileURI(workbenchData.getAbsolutePath()); |