package LinGUIne.lifecycle;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.LinkedList;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.runtime.Platform;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.lifecycle.PostContextCreate;
import org.eclipse.e4.ui.workbench.lifecycle.PreSave;
import org.eclipse.e4.ui.workbench.lifecycle.ProcessAdditions;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.swt.widgets.Display;
import LinGUIne.model.ProjectManager;
import LinGUIne.model.SoftwareModuleManager;
import LinGUIne.model.VisualizationPluginManager;
import LinGUIne.parts.advanced.DataEditorManager;
import LinGUIne.utilities.ClassUtils;
import LinGUIne.utilities.FileUtils;
/**
* Hooks into the Eclipse life cycle to perform operations at startup.
*
* @author Kyle Mullins
*/
public class LifeCycleManager {
private static final String REMOVE_ON_EXIT_TAG = "RemoveOnExit";
private String projectManagerProjectList;
/**
* Called after the application context is created, but before anything is
* added to it and before the application model is loaded.
*
* @param context The application's context.
*/
@PostContextCreate
public void postContextCreate(IEclipseContext context){
//TODO: Prompt user for workspace location
//Workaround for Eclipse Persisted State bug: load the data directly
//from the workbench.xmi file and put it into the Persisted State later
File workbenchXMI = Platform.getLocation().append(".metadata").append(
".plugins").append("org.eclipse.e4.workbench").append(
"workbench.xmi").toFile();
File workbenchBackup = FileUtils.appendPath(workbenchXMI.getParentFile(),
"workbench.bak");
boolean restoredFromBackup = false;
//If there is no workbench.xmi but there is a backup, restore the backup
if(!workbenchXMI.exists() && workbenchBackup.exists()){
try(OutputStream outStream = Files.newOutputStream(
workbenchXMI.toPath())){
Files.copy(workbenchBackup.toPath(), outStream);
restoredFromBackup = true;
}
catch(IOException ioe){
ioe.printStackTrace();
}
}
if(workbenchXMI.exists()){
if(!restoredFromBackup){
//Backup the workbench.xmi file in case we terminate unusually
try(OutputStream outStream = Files.newOutputStream(
workbenchBackup.toPath())){
Files.copy(workbenchXMI.toPath(), outStream);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
try(BufferedReader reader = Files.newBufferedReader(
workbenchXMI.toPath(), Charset.defaultCharset())){
readPersistedStateFromWorkbench(reader);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
/**
* Called after the application context is populated, but before any parts
* are initialized.
*
* @param context The application's context.
* @param application The application.
*/
@ProcessAdditions
public void processAdditions(IEclipseContext context,
MApplication application){
//Workaround for Eclipse Persisted State bug: put data into Persisted
//State map after it has been loaded from the workbench.xmi file
application.getPersistedState().put(ProjectManager.PROJECT_LIST_KEY,
projectManagerProjectList);
SoftwareModuleManager softwareModuleMan = new SoftwareModuleManager();
ProjectManager projectMan = new ProjectManager(Platform.getLocation(),
application);
VisualizationPluginManager visualisationPluginMan = new VisualizationPluginManager();
DataEditorManager dataEditorMan = new DataEditorManager();
context.set(SoftwareModuleManager.class, softwareModuleMan);
context.set(ProjectManager.class, projectMan);
context.set(VisualizationPluginManager.class, visualisationPluginMan);
ContextInjectionFactory.inject(projectMan, context);
ContextInjectionFactory.inject(dataEditorMan, context);
//Workaround for Activator not getting called
ClassUtils.setBundleContext(InternalPlatform.getDefault().getBundleContext());
projectMan.loadProjects();
}
/**
* Called before the application model is saved when the application is
* closing.
*
* @param application The application.
* @param modelService
* @param partService
*/
@PreSave
public void preSave(MApplication application, EModelService modelService,
EPartService partService){
LinkedList<String> tags = new LinkedList<String>();
tags.add(REMOVE_ON_EXIT_TAG);
//Remove all Parts from the model which have the REMOVE_ON_EXIT_TAG
for(MPart part: modelService.findElements(application, null,
MPart.class, tags)){
part.getParent().getChildren().remove(part);
}
}
private void readPersistedStateFromWorkbench(BufferedReader reader)
throws IOException{
String persistedStateLineStart = "<persistedState key=\"" +
ProjectManager.PROJECT_LIST_KEY + "\" value=\"";
String persistedStateLineEnd = "\"/>";
while(reader.ready()){
String line = reader.readLine().trim();
if(line.startsWith(persistedStateLineStart)){
int beginIndex = persistedStateLineStart.length();
int endIndex = line.length() -
persistedStateLineEnd.length();
projectManagerProjectList = line.substring(beginIndex,
endIndex);
}
}
}
public static Display getDisplay() {
Display display = Display.getCurrent();
//may be null if outside the UI thread
if (display == null){
display = Display.getDefault();
}
return display;
}
}