What every Eclipse developer should know about EMF – Part 2

March 31, 2011 | 7 min Read

This is the second part of the tutorial presented at EclipseCon. We’ll be building on the model created in the first part of the tutorial, which you can find  in this blog post.   We’ll give you an overview of available technologies through links to several Ignite talks that introduced various frameworks building on EMF.  If you would like to have your framework included, please let me know.

4 EMF API

In this part of the tutorial, we will explore EMF’s API, including the generated code, as well as EMF’s utility classes. Let’s have a look at the generated code first. In the model plugin from our tutorial org.eclipse.example.bowling you will find interfaces and implementations for all entities of the model. A look at the outline of an entity’s interface reveals that it contains getters and setters for the attributes we have defined in the model, as well as access to the references. All entities of the generated EMF model are sub-classes of EObject. EObject contains basic functionality - for example, a change notification mechanism.

5 Import Sample Solution

Before we continue with the tutorial, please import the sample solution. Please switch to an empty workspace (File => Switch Workspace), select “Import” => ”General” => ”Existing Projects into Workspace”. Please select “exampleSolution.zip” and import all projects.

6 AdapterFactories

For the next steps of the tutorial it is important to understand the concept of AdapterFactories. We will give a quick introduction and you can see this documentation for more information. The basic idea of AdapterFactories is to provide you with an interface IX you need for an arbitrary purpose, e.g. a LabelProvider needed in the UI. EMF generates a lot of these classes for you. To retrieve the right class you can use an AdapterFactoryX, which implements the interface you need. The AdapterFactoryX will retrieve the generated classes using an AdapterFactory.

7 EMF Data-Management

In the previous sections we have shown how to generate a structured data model with EMF. In a typical application, these data models have to be stored and maybe even versioned or distributed. There are a couple of frameworks that support different use cases. By default EMF provides the ability to serialize EObjects to XMI files. In the following example, we will load EObjects from a file and save them afterwards. EMF also offers commands to make modifications on the model. Commands can be easily undone. In the example we will load a XMI file containing a Tournament. The user can add new Matchups to that Tournament and undo these changes. At the end, the user can save the changes back to the file. For the tutorial, we have prepared an example dialog in the plugin org.eclipse.example.bowling.tutorial, which should be imported from the example solution. You can open this dialog by right-clicking a file and selecting “Tutorial”=>“Open Example Dialog”. After implementing the following two parts of the tutorial, it will look like this: Everything that is not relevant for this tutorial is implemented in an abstract base class called AbstractExampleDialog. In the subclass ExampleDialog, there are empty method stubs to be implemented in this tutorial. The dialog can be shown in the runtime Eclipse instance by right-clicking on a file and selecting “Open Tournament Example view”. (Please note that for the tutorial we have focused on simplicity over perfect design.)

Please open the class ExampleDialog. We will implement the loadContent method, which is triggered by opening the example view. The purpose of this method is to get a Tournament from the file which is then displayed in the example view.  To keep it simple, we assume that the file contains a Tournament and this Tournament is the first element in the file. You can easily create a file like this with the generated example editor. First we create an editing domain. An editing domain manages a set of interrelated models and the commands that are run to modify them. For example, it contains the stack of all former commands. An editing domain can create a resource, which is a container for storing EObjects. Resources can be saved and loaded and contents can be added to them. In the example we get the first EObject in the resource, assume it is a tournament and make it a member of our superclass. [ ”Open Example Tournament View”. In this view you can add new Tournaments, undo this operation and save by clicking on “OK”. You can validate the result by opening the file in the Ecore editor. Please note again, that the UI of the View will not be updated yet, but we will initialize the UI also in the next step of the tutorial.

Additional Information

EMFStore - A Model Repository (Server for EMF Model instances)

CDO (coming soon)

8 EMF UI

In this step we will fill the example view with two basic UI elements. First, we will bind the Label on top showing the number of Matchups in the opened Tournament to the model. We will use the notification mechanism to update the Label whenever the number of Matchups changes. Second we will fill the TreeViewer with a list of the Matchups also displaying their Games as children. For updating the Label we will register a listener on the Tournament EObject, which is opened in the view. This listener will always be notified by the EMF runtime if there is a change in the Tournament EObject. Please note that this is how you manually implement listeners. For creating UIs with bi-directional updates between UI elements and data-models, we recommend using data-binding that’s also available for EMF. In Eclipse databinding, you can bind a certain UI element to a certain EAttribute or EReference and it will take care of bi-directional updates.

Finally, we will initialize the TreeViewer to display the Matchups of the current Tournament and their Games as children. A TreeViewer needs three things to be initialized. The ContentProvider is responsible for the structure of the Tree by providing the method getChildren(). The LabelProvider is called to get an Icon and the displayed text for one node. The input of a TreeViewer is the invisible root element of the Tree. The elements displayed in the root of the tree are the children of that element. In our case, the input is the Tournament.

ContentProvider and especially LabelProvider usually depend on a certain EClass. EMF generates providers for several purposes including Content- and LabelProvider. We will use the AdapterFactory concept explained previously to retrieve the right provider for every element. Finally we set the Input to the Tournament which is currently open.

Now you’ll need to re-start the bowling example application to test the implemented UI features. To modify the appearance of a Label you can simply modify the ItemProvider of the respective class. Let’s modify the LabelProvider for Matchup. To modify the appearance of EObjects in the TreeViewer you can adapt the generated ItemProvider GameItemProvider. In the example, we will show the number of Games contained in a Matchup Game. Mark the method as “generated NOT” to prevent it from being overridden during the next generation.

In the running application, the new LabelProvider is displayed in the Example view as well as in the Ecore Editor:

As a last step, you should remove all listeners when closing the view. Please note that LabelProvider and ContentProvider are registered listeners on the model, so you should delete them.

Additional UI Frameworks

There are several frameworks for displaying data from an EMF model instance. In this tutorial, the following were introduced in Ignite talks:

9 Additional EMF-based Technologies

In this last part of the tutorial we want to give you a short overview of additional EMF-based technologies for different purposes:

I hope you found the tutorial helpful. In case you have any feedback or you are missing a certain framework or part, please feel free to contact me or leave a comment. omment.

Jonas Helming

Jonas Helming

Dr. Jonas Helming is CEO of EclipseSource as well as consultant, trainer and software engineer. His focus is on web-based tools, IDEs, and tailored AI assistance in tools …