Bug 373294 - Improve startup time
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 b841b74..3acb26c 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
@@ -22,10 +22,6 @@
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 import org.eclipse.core.internal.runtime.PlatformURLPluginConnection;
 import org.eclipse.core.runtime.URIUtil;
 import org.eclipse.e4.core.contexts.ContextInjectionFactory;
@@ -59,12 +55,8 @@
  */
 public class ResourceHandler implements IModelResourceHandler {
 
-	private File workbenchData;
-
 	private ResourceSetImpl resourceSetImpl;
-	private URI restoreLocation;
 	private Resource resource;
-	private ModelReconciler reconciler;
 
 	@Inject
 	private Logger logger;
@@ -80,17 +72,22 @@
 	@Named(E4Workbench.INSTANCE_LOCATION)
 	private Location instanceLocation;
 
-	private boolean saveAndRestore;
-
-	private boolean clearPersistedState;
-
 	/**
 	 * Dictates whether the model should be stored using EMF or with the merging algorithm.
 	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=295524
 	 * 
 	 */
-	private boolean deltaRestore = true;
+	final private boolean deltaRestore;
+	final private boolean saveAndRestore;
+	final private boolean clearPersistedState;
 
+	/**
+	 * Constructor.
+	 * 
+	 * @param saveAndRestore
+	 * @param clearPersistedState
+	 * @param deltaRestore
+	 */
 	@Inject
 	public ResourceHandler(@Named(E4Workbench.PERSIST_STATE) boolean saveAndRestore,
 			@Named(E4Workbench.CLEAR_PERSISTED_STATE) boolean clearPersistedState,
@@ -122,132 +119,44 @@
 				.put(org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eNS_URI,
 						org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl.eINSTANCE);
 
-		// this.registry = registry;
-		try {
-			workbenchData = new File(URIUtil.toURI(instanceLocation.getURL()));
-		} catch (URISyntaxException e) {
-			throw new RuntimeException(e);
-		}
-		workbenchData = new File(workbenchData, ".metadata"); //$NON-NLS-1$
-		workbenchData = new File(workbenchData, ".plugins"); //$NON-NLS-1$
-		workbenchData = new File(workbenchData, "org.eclipse.e4.workbench"); //$NON-NLS-1$
-
-		if (deltaRestore) {
-			workbenchData = new File(workbenchData, "deltas.xml"); //$NON-NLS-1$	
-		} else {
-			workbenchData = new File(workbenchData, "workbench.xmi"); //$NON-NLS-1$			
-		}
-
-		if (workbenchData != null && clearPersistedState) {
-			if (workbenchData.exists()) {
-				workbenchData.delete();
-			}
-		}
-
-		if (workbenchData != null && saveAndRestore) {
-			restoreLocation = URI.createFileURI(workbenchData.getAbsolutePath());
-		}
-	}
-
-	public long getLastStoreDatetime() {
-		long restoreLastModified = restoreLocation == null ? 0L : new File(
-				restoreLocation.toFileString()).lastModified();
-		return restoreLastModified;
-	}
-
-	public Resource loadRestoredModel() {
-		Activator.trace(Policy.DEBUG_WORKBENCH, "Restoring workbench: " + restoreLocation, null); //$NON-NLS-1$
-		resource = loadResource(restoreLocation);
-		return resource;
-	}
-
-	public Resource loadBaseModel() {
-		Activator.trace(Policy.DEBUG_WORKBENCH,
-				"Initializing workbench: " + applicationDefinitionInstance, null); //$NON-NLS-1$
-		if (deltaRestore) {
-			resource = loadResource(applicationDefinitionInstance);
-		} else {
-			MApplication theApp = loadDefaultModel(applicationDefinitionInstance);
-			resource = resourceSetImpl.createResource(restoreLocation);
-			resource.getContents().add((EObject) theApp);
-		}
-		return resource;
-	}
-
-	private MApplication loadDefaultModel(URI defaultModelPath) {
-		Resource resource = loadResource(defaultModelPath);
-		MApplication app = (MApplication) resource.getContents().get(0);
-		return app;
-	}
-
-	// Ensures that even models with error are loaded!
-	private Resource loadResource(URI uri) {
-		Resource resource;
-		try {
-			resource = resourceSetImpl.getResource(uri, true);
-		} catch (Exception e) {
-			// TODO We could use diagnostics for better analyzing the error
-			logger.error(e);
-			resource = resourceSetImpl.getResource(uri, false);
-		}
-
-		String contributorURI = URIHelper.EMFtoPlatform(uri);
-		if (contributorURI != null) {
-			TreeIterator<EObject> it = EcoreUtil.getAllContents(resource.getContents());
-			while (it.hasNext()) {
-				EObject o = it.next();
-				if (o instanceof MApplicationElement) {
-					((MApplicationElement) o).setContributorURI(contributorURI);
-				}
-			}
-		}
-		return resource;
-	}
-
-	public void save() throws IOException {
-		if (saveAndRestore) {
-			if (deltaRestore && reconciler != null) {
-				try {
-					Document document = (Document) reconciler.serialize();
-
-					// Use a Transformer for output
-					TransformerFactory tFactory = TransformerFactory.newInstance();
-					Transformer transformer = tFactory.newTransformer();
-
-					DOMSource source = new DOMSource(document);
-					File f = new File(restoreLocation.toFileString());
-					f.getParentFile().mkdirs();
-					StreamResult result = new StreamResult(f);
-					transformer.transform(source, result);
-				} catch (Exception e) {
-					if (logger != null) {
-						logger.error(e);
-					}
-				}
-			} else {
-				resource.save(null);
-			}
-		}
 	}
 
 	public Resource loadMostRecentModel() {
-		if (deltaRestore) {
-			try {
-				Resource resource = loadBaseModel();
-				MApplication appElement = (MApplication) resource.getContents().get(0);
-				// Add model items described in the model extension point
-				// This has to be done before commands are put into the context
-				// ModelExtensionProcessor extProcessor = new ModelExtensionProcessor(appElement);
-				// extProcessor.addModelExtensions();
+		File baseLocation;
+		try {
+			baseLocation = new File(URIUtil.toURI(instanceLocation.getURL()));
+		} catch (URISyntaxException e) {
+			throw new RuntimeException(e);
+		}
+		baseLocation = new File(baseLocation, ".metadata"); //$NON-NLS-1$
+		baseLocation = new File(baseLocation, ".plugins"); //$NON-NLS-1$
+		baseLocation = new File(baseLocation, "org.eclipse.e4.workbench"); //$NON-NLS-1$
 
-				this.context.set(MApplication.class, appElement);
-				ModelAssembler contribProcessor = ContextInjectionFactory.make(
-						ModelAssembler.class, context);
-				contribProcessor.processModel();
+		// This is temporary code to migrate existing delta files into full models
+		if (deltaRestore && saveAndRestore && !clearPersistedState) {
+			File deltaFile = new File(baseLocation, "deltas.xml"); //$NON-NLS-1$
+			if (deltaFile.exists()) {
+				MApplication appElement = null;
+				try {
+					// create new resource in case code below fails somewhere
+					File workbenchData = new File(baseLocation, "workbench.xmi"); //$NON-NLS-1$			
+					URI restoreLocationNew = URI.createFileURI(workbenchData.getAbsolutePath());
+					resource = resourceSetImpl.createResource(restoreLocationNew);
 
-				if (restoreLocation != null) {
+					Resource oldResource = loadResource(applicationDefinitionInstance);
+					appElement = (MApplication) oldResource.getContents().get(0);
+
+					context.set(MApplication.class, appElement);
+					ModelAssembler contribProcessor = ContextInjectionFactory.make(
+							ModelAssembler.class, context);
+					contribProcessor.processModel();
+
+					File deltaOldFile = new File(baseLocation, "deltas_42M7migration.xml"); //$NON-NLS-1$
+					deltaFile.renameTo(deltaOldFile);
+					URI restoreLocation = URI.createFileURI(deltaOldFile.getAbsolutePath());
+
 					File file = new File(restoreLocation.toFileString());
-					reconciler = new XMLModelReconciler();
+					ModelReconciler reconciler = new XMLModelReconciler();
 					reconciler.recordChanges(appElement);
 
 					if (file.exists()) {
@@ -257,29 +166,45 @@
 						ModelReconciler modelReconciler = modelReconcilingService
 								.createModelReconciler();
 						document.normalizeDocument();
-						Collection<ModelDelta> deltas = modelReconciler.constructDeltas(resource
+						Collection<ModelDelta> deltas = modelReconciler.constructDeltas(oldResource
 								.getContents().get(0), document);
 						modelReconcilingService.applyDeltas(deltas);
 					}
+				} catch (Exception e) {
+					if (logger != null) {
+						logger.error(e);
+					}
 				}
-			} catch (Exception e) {
-				if (logger != null) {
-					logger.error(e);
-				}
+				if (appElement != null)
+					resource.getContents().add((EObject) appElement);
+				return resource;
 			}
-			return resource;
 		}
 
-		long restoreLastModified = getLastStoreDatetime();
+		File workbenchData = new File(baseLocation, "workbench.xmi"); //$NON-NLS-1$			
+
+		if (clearPersistedState && workbenchData.exists())
+			workbenchData.delete();
+
+		URI restoreLocation = null;
+		if (saveAndRestore)
+			restoreLocation = URI.createFileURI(workbenchData.getAbsolutePath());
+
+		// last stored time-stamp
+		long restoreLastModified = restoreLocation == null ? 0L : new File(
+				restoreLocation.toFileString()).lastModified();
+
 		long lastApplicationModification = getLastApplicationModification();
 
 		boolean restore = restoreLastModified > lastApplicationModification;
 
-		Resource resource;
 		if (restore && saveAndRestore) {
-			resource = loadRestoredModel();
+			resource = loadResource(restoreLocation);
 		} else {
-			resource = loadBaseModel();
+			Resource applicationResource = loadResource(applicationDefinitionInstance);
+			MApplication theApp = (MApplication) applicationResource.getContents().get(0);
+			resource = resourceSetImpl.createResource(restoreLocation);
+			resource.getContents().add((EObject) theApp);
 		}
 
 		// Add model items described in the model extension point
@@ -294,11 +219,37 @@
 		return resource;
 	}
 
-	/**
-	 * @param applicationDefinitionInstance2
-	 * @return
-	 */
-	public long getLastApplicationModification() {
+	public void save() throws IOException {
+		if (saveAndRestore)
+			resource.save(null);
+	}
+
+	// Ensures that even models with error are loaded!
+	private Resource loadResource(URI uri) {
+		Resource resource;
+		try {
+			resource = resourceSetImpl.getResource(uri, true);
+		} catch (Exception e) {
+			// TODO We could use diagnostics for better analyzing the error
+			logger.error(e);
+			resource = resourceSetImpl.getResource(uri, false);
+		}
+
+		// TODO once we switch from deltas, we only need this once on the default model?
+		String contributorURI = URIHelper.EMFtoPlatform(uri);
+		if (contributorURI != null) {
+			TreeIterator<EObject> it = EcoreUtil.getAllContents(resource.getContents());
+			while (it.hasNext()) {
+				EObject o = it.next();
+				if (o instanceof MApplicationElement) {
+					((MApplicationElement) o).setContributorURI(contributorURI);
+				}
+			}
+		}
+		return resource;
+	}
+
+	private long getLastApplicationModification() {
 		long appLastModified = 0L;
 		ResourceSetImpl resourceSetImpl = new ResourceSetImpl();
 
diff --git a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/ResourceHandlerTest.java b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/ResourceHandlerTest.java
index 4fa5a62..f380deb 100644
--- a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/ResourceHandlerTest.java
+++ b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/ResourceHandlerTest.java
@@ -78,17 +78,6 @@
 		checkData(resource);
 	}
 
-	public void testLoadBaseModel() {
-		URI uri = URI.createPlatformPluginURI(
-				"org.eclipse.e4.ui.tests/xmi/InvalidContainment.e4xmi", true);
-
-		ResourceHandler handler = createHandler(uri);
-		Resource resource = handler.loadBaseModel();
-		assertNotNull(resource);
-		assertEquals(E4XMIResource.class, resource.getClass());
-		checkData(resource);
-	}
-
 	private void checkData(Resource resource) {
 		assertNotNull(resource);
 		assertEquals(1, resource.getContents().size());