Constructing the Eclipse application model. This tutorial given an introduction how to use the EMF API to persist part of the application model.
1. Influence the application model persistence
1.1. Specifying the location of the application model file
The file name and location of the application model can be specified in the plugin.xml file.
This is done via the applicationXMI
property.
The path to the file follows the "bundleSymbolicName"/"filename" pattern, e.g., test/ApplicationDifferent.e4xmi.
To do this open the plugin.xml file.
Select the Extensions tab and open the org.eclipse.core.runtime.products
contribution.
Right-click on the product entry and select menu:New [Property].
Use applicationXMI as parameter name and com.vogella.tasks.ui/ApplicationNew.e4xmi as value.
This value consists of the BundleSymbolicName
of the corresponding plug-in and the application model file name.
2. Custom application model persistence handler
Eclipse uses an instance of the IModelResourceHandler
interface to load and save the application model at startup and shutdown.
The default implementation is provided by the ResourceHandler
class from the org.eclipse.e4.ui.internal.workbench
package.
You can specify the modelResourceHandler as parameter on your product extension to use another class to construct the initial application model.
This allows you to construct the initial application model from any source you desire. For example, you could use property files orconstruct the application model based on information from a database.
Implementing this interface requires knowledge about the Eclipse Modeling Framework (EMF).
You can use the ResourceHandler
as a template to see how the IModelResourceHandler
interface could be implemented.
3. Optional exercise - Saving and restoring a perspective of the application model
This exercise implements the option to persist your currently perspective in an external file. This requires, of course, that your application model uses perspectives. |
3.1. Add manifest dependencies
Ensure that the following dependencies are entered in the manifest.
-
org.eclipse.emf.ecore
-
org.eclipse.emf.ecore.xmi
3.2. Implement a persistence handler
The following snippet shows a handler implementation. The hander persists the model elements of the active perspective in an xmi file.
The following assumes that you are doing the implementation in a plug-in called |
package com.vogella.rcp.persistence.handlers;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
public class SavePerspectiveHandler {
@Execute
public void execute(EModelService modelService, MWindow window, Shell shell) {
// store model of the active perspective
MPerspective activePerspective = modelService.getActivePerspective(window);
if (activePerspective == null) {
MessageDialog.openInformation(shell, "No perspective found", "Are you using perspectives?");
// no perspective found, return
return;
}
// create a resource, which is able to store e4 model elements
E4XMIResourceFactory e4xmiResourceFactory = new E4XMIResourceFactory();
Resource resource = e4xmiResourceFactory.createResource(null);
// You must clone the perspective as snippet, otherwise the running
// application would break, because the saving process of the resource
// removes the element from the running application model
MUIElement clonedPerspective = modelService.cloneElement(activePerspective, window);
// add the cloned model element to the resource so that it may be stored
resource.getContents().add((EObject) clonedPerspective);
try (FileOutputStream outputStream = new FileOutputStream(getFileNameForPersistence())) {
resource.save(outputStream, null);
MessageDialog.openInformation(shell, "Persisted perspective", "Persisted as " + getFileNameForPersistence());
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
static String getFileNameForPersistence() {
String currentUsersHomeDir = System.getProperty("user.home");
return currentUsersHomeDir + File.separator + ".eclipse/perspective.xml";
}
}
3.3. Load stored model elements
The created xmi file can be loaded via the load
method of the Resource
class.
The following snippet is an example, where a stored perspective is applied to an existing application model. In case an existing perspective with the same elementId as the one of the loaded perspective is found, it is removed. Afterwards the code adds and switches to the loaded perspective.
package com.vogella.rcp.persistence.handlers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
public class ConstructPerspectiveFromExternalSource {
@Execute
public void execute(EPartService partService, EModelService modelService, MWindow window, Shell shell) throws IOException {
// create a resource, which is able to store e4 model elements
@SuppressWarnings("restriction")
E4XMIResourceFactory e4xmiResourceFactory = new E4XMIResourceFactory();
@SuppressWarnings("restriction")
Resource resource = e4xmiResourceFactory.createResource(null);
try (FileInputStream inputStream = new FileInputStream(SavePerspectiveHandler.getFileNameForPersistence())) {
// load the stored model element
resource.load(inputStream, null);
if (!resource.getContents().isEmpty()) {
// after the model element is loaded it can be obtained from the
// contents of the resource
MPerspective loadedPerspective = (MPerspective) resource.getContents().get(0);
// get the parent perspective stack, so that the loaded
// perspective can be added to it.
MPerspective activePerspective = modelService.getActivePerspective(window);
MElementContainer<MUIElement> perspectiveParent = activePerspective.getParent();
// remove the current perspective, which should be replaced by
// the loaded one
List<MPerspective> alreadyPresentPerspective = modelService.findElements(window,
loadedPerspective.getElementId(), MPerspective.class, null);
for (MPerspective perspective : alreadyPresentPerspective) {
modelService.removePerspectiveModel(perspective, window);
}
// add the loaded perspective and switch to it
perspectiveParent.getChildren().add(loadedPerspective);
partService.switchPerspective(loadedPerspective);
MessageDialog.openInformation(shell, "Perspective resetted", "Resetted perspective");
}
}
}
}
4. Learn more and get support
This tutorial continues on Eclipse RCP online training or Eclipse IDE extensions with lots of video material, additional exercises and much more content.
5. Links and Literature
5.1. vogella Java example code
If you need more assistance we offer Online Training and Onsite training as well as consulting