Child pages
  • The Eclipse Modeling Framework
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Warning

This tutorial is a work-in-progress. Don't start with it yet!

This tutorial will be all about the Eclipse Modeling Framework, one of the core technologies in the Eclipse universe. You will learn what metamodels are and how to create them, how to generate an editor for instances of your metamodels, and how to load and save such instances. We will of course continue our example from the last tutorial: the metamodel you will create will be one for models that specify Turing Machines. To learn about using EMF models programmatically, you will also implement a head controller that executes a Turing Machine given to it in terms of a Turing Machine model.

Once you're done with this tutorial, you will have an application that looks something like this:

ToDo

Insert screenshot of final application.

ToDo

Insert link to presentation slides.

Preliminaries

The Eclipse Modeling Framework (EMF) belongs to the most important technologies in the Eclipse world. One of the more recent indicators of this is its being used to describe the very foundation of Eclipse 4 (or e4, which of course sounds way cooler) applications: the application model. We might come back to the application model in the project phase of our practical. Another indication is that EMF has come to be the foundation of most other modeling-related Eclipse projects. Thus, there is important stuff to be learned in this tutorial!

Let's try to get a first idea of what EMF does. Essentially, EMF helps you to write the code necessary to represent models (or domain models, as they are also called). So, what are models? An example of a model that you have all encountered before is a UML class diagram. In such a model, classes are related to one another using different types of relations: inheritance relations, associations, aggregations, compositions,... Working on such a model requires code that represents the model and that allows you to change its structure. EMF can help you write that code.

However, EMF can do that for all kinds of models. To generate the code for a specific kind of models, EMF needs to know what kinds of entities and relationships between the entities there are in those models. This is where a metamodel comes into play: metamodels describe the structure of your models. They are to your models what grammar is to your programming languages. When working with EMF, you usually start by defining the metamodel (syntax of your models), and then proceed to let EMF generate the code required to represent such models.

You can also have EMF generate simple editors to load, edit, and save models corresponding to your metamodel.

EMF also contains a bunch of tools that can help you with everything surrounding modeling, such as loading and saving models. EMF usually serializes models using the XMI (XML Metadata Interchange) format, which is an XML file geared towards the representation of models. The classes generated by EMF also have built-in facilities to, for instance, help you observe changes in the model instances.

Required Software

Your Eclipse installation already has everything we need for this tutorial. In fact, that's one reason why we suggested you install the Eclipse Modeling Tools. You will again be working on your branch of our tutorials Git repository.

Finding Documentation

For an introduction to EMF, here's a few suggestions to get you started:

  • The Wikipedia article on metamodeling may be i
  • The Eclipse online help system contains a section on EMF, complete with an introduction and tutorials.
  • There is a book on EMF, which is a great resource. The library may have copies available. We also have at least one copy at our office, so feel free to drop in and read it. (We also have tea and a sofa, so there's no lack of proper reading atmosphere... (wink) )
  • Among many other helpful tutorials, Lars Vogel, an active Eclipse developer, has also written a tutorial on EMF.

Creating a Metamodel

As we have already seen, everything in EMF begins with the metamodel. Metamodels can be imported from different formats: XSD (XML Schema Definition), UML, Ecore models,... In this tutorial, we will be using Ecore diagrams to specify our metamodels. Take a moment to think about this: we're creating an Ecore model by drawing a diagram, and this model will then be used as the metamodel for our Turing Machine models. So, let's start by creating an Ecore diagram.

  1. Create a new Empty EMF Project named de.cau.cs.rtprak.login.turingmodel. Remember to create the project in your Git repository. Once you click the Finish button, the Empty EMF Project wizard creates a new plug-in project for you, complete with a src folder for Java source files, the MANIFEST.MF file we have encountered before, and, most importantly, a models folder that you will store your modeling files in. If you open the manifest file in the Plugin Manifest Editor, you will see that the wizard already added a dependency to org.eclipse.emf.ecore, which all EMF projects depend on.
  2. Create a new Ecore diagram in the models folder by right-clicking the folder and clicking New -> Other..., and then selecting Ecore Diagram from the Ecore Tools category. Note that the category Other also contains an entry Ecore Diagram. However, the editor we will be using has more features and is more user-friendly than the one in the Other category.
  3. In the New Ecore Diagram wizard, check Create a new model and choose turingmachine.ecore as the Domain file name. Once you click Finish, the wizard will generate two files for you:
    • turingmachine.ecore contains the information about the data structures in your Turing Machine models. In effect, it is your metamodel in Ecore format.
    • turingmachine.ecorediag is the diagram you're editing and contains things like coordinates of the different data structures, and bend points of the relations between them – in short, everything the graphical editor needs to know to display the diagram.
  4. You will need the Properties view to edit your model properly. This view shows detailed information about the currently selected model element and lets you edit them. It also shows general information about the model if no specific element it selected. Summon the Properties view now by right-clicking into your diagram and selecting Show Properties View.
  5. Now that the Properties view is visible, switch to its Model tab and set the following properties:
    • Name: Model elements are grouped into packages, and this is the package name. Set to turingmachine.
    • Ns Prefix: Namespace prefix that will be used in the XML representation of your models later on. Use something short, e.g. turing.
    • Ns URI: While the package name need not be unique, namespace URI's are used to uniquely identify stuff. The usual convention is to use a name following the format http://project_name_part/packagename. Thus, set this to something like http://de.cau.cs.rtprak.login/turingmachine.

Modeling Your Turing Machines

Now that we have an empty Ecore diagram it's time to get to the interesting part: defining the metamodel for your Turing Machines. This is a complex and interesting task that will require some thought on your part. Feel free to discuss this with other participants: talking about a problem with other people usually leads to better designs and helps you think about problems that you might have overlooked otherwise. Here's some first suggestions for design decisions you're facing to get you started:

  • Do you model the state machine? If so, what distinguishes initial states from regular states?
  • Do you model the Turing Machine's tape?
  • In what detail do you model transition labels? Simple Strings, or more complex expressions over the input alphabet?

Model Elements

You will need the following Ecore model elements:

  • EClass – Create one for every item that you want to be in your model. Make sure that you have exactly one root element, that is, an element that represents your Turing Machine (perhaps TuringMachine would actually be a good name for it...) and provides access to other elements.
  • EAttribute – Add attributes to classes to give them properties, e.g. a name attribute for states in state machines. The most important property of attributes is their type, which you can configure in the Properties view.
  • EEnum – Create enumerations to define simple enumeration types that you can then use as the type of attributes. Each item of the enumeration is an EEnumLiteral.
  • Inheritance Relations – Use these as you would in UML class diagrams or ye plain ol' Java.
  • EReference – Use references to provide links between classes. Here's a few things about references:
    • Every class (except the root class) requires exactly one Containment reference that specifies where it belongs to and where it will be stored later on when you save your models to XML files.
    • Set lower and upper bounds on references to control how many instances of a class can be referenced (just like multiplicities in UML class diagram associations).
    • Consider whether a reference should have an opposite reference: a second reference in the other direction to be able to navigate back and forth between the model objects. Let's take two classes as an example to illustrate this: Parent and Child, where Parent can reference multiple Child objects. To be able to ask the Parent about all its children, we would add a reference children from Parent to Child with the containment flag active (that is, Child is part of its Parent). To be able to ask a Child about its Parent, we would add a second reference from Child to Parent with the EOpposite set to the children reference.

For this task, you won't need any more model elements.

One last thing before you get started: While working on your model, save and validate it regularly (Edit -> Validate). This will help you find potential problems with your model while you're still able to fix them easily.

Code Generation

 

 

 

 

Saving and Loading Models

 

 

 

 

 

Implementing a Head Controller

This is where all the model design and model generation pays off and where we will establish the link to the first tutorial: you will write an IHeadController implementation that can simulate Turing Machines specified as models following the metamodel you just designed. Your simulator should be able to execute arbitrary instances of your metamodel.

Simulating Turing Machines

Right, time to write some simulation code. Go grab a cup of coffee and start working through the following steps:

  1. Add a new class to one of your plug-ins named TuringHeadController. Make sure it implements the IHeadController interface we defined in the first tutorial and register it with the appropriate extension point.
  2. Add a new method initialize() to your controller that loads a Turing Machine model from a fixed path.
  3. Implement the nextCommand() and reset() methods:
    • You can access all references and attributes of model elements using generated getter methods.
    • reset() selects a state that is marked as being an initial state of the Turing Machine and saves it as the current state in a private field of the controller. (You did think about modeling initial states, right? If not, don't be frustrated, that's not too big of a deal. Just make the necessary changes to your metamodel and regenerate the code.)
    • nextCommand() analyzes the outgoing transitions of the currently active state and takes the first one that matches the current character. It then selects the target state of that transition as the new active state and returns the actions of the transition as HeadCommand. If there is no transition that matches the current input, return a command that does nothing.
    • At the beginning of nextCommand(), check if there is an active state. If not, call initialize() and reset() before doing the simulation.
    • Remember that if you add the new controller to the de.cau.cs.rtprak.login.simple plug-in, you will have to add a dependency to the ...turingmodel plug-in and make sure the latter exports the required packages.

Testing Your Head Controller

It's time to test the head controller. Here's one way you can go about it:

  1. Create a Turing Machine model using the tree editor. Assuming that the initial head position is 1, the machine shall copy the input text infinitely often. That is, if the tape initially contains the word "hello", the machine should generate "hellohellohellohe..." You might remember this task from the first tutorial. To avoid an explosion of the number of states, select a rather small input alphabet for your machine, e.g. h, e, l, and o.

  2. Save the model to the fixed path defined in your controller.

  3. Select the new head controller in the Tape view and test it with input from your editor.

EMF Notifications (Optional)

 

 

 

 

  • No labels