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

Compare with Current View Page History

« Previous Version 16 Next »

The Eclipse Modelling Framework (EMF) supports model-driven engineering by providing a simple object-oriented modelling language for modelling data, a code generator for producing corresponding Java classes, and tools and runtime support for building views and editors for the data.

Introduction

When building data-oriented application, you will find that some code is obviously specific for the domain, some is domain-specific but following coding patterns that make the coding pretty trivial and some is completely generic. For instance, suppose you are writing a form-based application for personell data. This will include

  • writing classes for OrgUnit, Person and Role and providing get, set, add and remove methods for accessing and mutator the structure of OrgUnit, Person and Role instances
  • implementing validation for attributes like name (no digits or special characters) and date of birth (no employee is 200 years old), as well as structural validation, e.g. every OrgUnit must have a Person with a manager Role
  • ensuring consistency, e.g. that if a Person belongs to an OrgUnit, both objects refer to each other, and if a Person is removed from an OrgUnit, none of them refer to the other
  • supporting the UI by making the domain objects observable, i.e. provide a mechanism to listen for changes
  • selecting form elements based on attribute types and multiplicity
  • triggering appropriate validation during editing
  • persisting the data, perhaps in a file using XML or JSON format, or in a database

The accessor and mutator methods are trivial, once you know the attribute and association names and multiplicities. The validation code is domain specific, but how it is used by the UI isn't. Consistency of such opposite relations is difficult to code, but always follow the same patterns. Observability is trivial usage of coding patterns. Form element selection is rule-based, with a few options pr. type. Serializing (saving) and parsing (loading) data is a systematic and well-understood process.

We see that only part of the code is domain-specific, but it will be entangled with other code. When writing code by hand, you combine domain-specific and knowledge of coding conventions and patterns. The idea behind EMF, and model-driven development in general, is to separate the domain knowledge from the coding knowledge. The domain knowledge is captured in a domain model, while the coding knowledge (conventions, patterns, architecture, ...) is part of the framework and tools, using a combination of code generation and generic and so-called reflective code. This relieves the developer from a lot of tedious work, but requires stronger modelling skills and an understanding of how the framework utilises the model. Once mastered, it provides opportunities for developing with greater agility, efficiency and quality.

Overview

Ecore

The core of EMF is an object-oriented modelling language called Ecore, and a supporting runtime. Ecore can be thought of as a subset of UML class diagrams (without the graphical notation), that is big enough to support basic domain modelling and small enough to allow for an efficient and lean framework. Ecore supports classes with attributes (properties of simple types), associations (references to other modelled classes) and operations, and multiple inheritance.

Ecore models may be edited using different tools and syntaxes. EMF itself provides a tree-based editor and an XML-based format (mostly for serialisation e.g. to files), EMFJSON provides a JSON format, Ecore tools (based on Sirius) provides a diagram notation and Xcore a textual syntax similar to Java classes. However, all support the same abstract language of classes, attributes, associations, operations and inheritance and any Ecore-supporting tool may use the resulting Ecore model.

A plethora of other tools and frameworks utilise Ecore models to provide important and time-saving functionality, either part of the Eclipse Modelling project or the surrounding eco-system.

Genmodel

To turn an Ecore model into executable Java code, you need to configure a generator model called genmodel and run EMF's code generator. A default genmodel is provided automatically, so the only thing you normally need to do is name the Java package (prefix) of the generated Java classes. The generator may generate Java classes corresponding directly to the Ecore classes, like OrgUnit and Person. If your Ecore classes include operations, you will need to add custom code to the generated classes (methods stubs). 

In addition to domain classes, you may generate an Eclipse-based editor for your model, which you can install into Eclipse to make it easier to edit your domain data.

Validation

An Ecore model will to a certain extent constrain the structure of domain objects you can create, e.g. based on the multiplicity of attributes and association. However, not all such constraints are considered hard in the sense that they are enforced by the generated classes. E.g. if an attribute's multiplicity has a lower bound of two, it will always be possible to add only one value. Instead, you may ask EMF to validate your model, and a set of diagnostic objects will tell which (if any) constraints are violated. You may add your own custom validation rules, e.g. to limit the range of integer values or characters in a String, or ensure more structural constraints are met, like an OrgUnit always having a Person with a manager Role. The generated editor will automatically use the validation mechanism to indicate violated constraints, so you can avoid illegal domain data.

Reflective editor

Although you can generate a complete editor for you domain data, you will find it cumbersome to have to regenerate and reinstall it, to create and edit domain data, e.g. to provide sample data for testing. Instead you may use a so-called reflective editor, which provides generic editing support for any Ecore model without code generation. You just indicate for which model you want to create and edit data, and the editor will let you create domain objects, edit their attribute values and assemble them into object structures within the constraints of your model. This allows you to test your model immediately without generating code, e.g. instantiate domain object corresponding to a scenario and use it as initial state for test cases.

Persistance

Being able to store domain data is fundamental to any application, and there are many choices for persisting Ecore-based data. EMF provides XML-based persistance of any legal structure of domain objects to file, and other projects supports other formats, e.g. EMFJSON supports JSON, and ESON a more human-friendly JSON-like syntax. There are lots of ways of tweaking the XML format used by default, or customise how the generated code handles persistance, e.g. switch to JSON or a completely custom format. In the latter case, you can implement the serialiser and parser by hand or use DSL frameworks like Xtext and EMFText to generate them from a grammar.

If you prefer persisting to a database, Teneo supports mapping Ecore models to database tables and relations (so-called Object-Relation Mapping (ORM)) using Hibernate. The CDO project also supports several relational databases. If you prefer NoSQL storage, EMFJSON supports the increasingly popular MongoDB.

Learning goals of this step-by-step guideline and exercise:

  • Learn how to generate code using EMF.
  • Understand how to use containment / container and regular relations in EMF.
  • Learn how to instantiate your models in EMF and by Java code.

Prerequisites

  • You need Eclipse Modeling Tools. Installation guidelines.

Part #1: Modelling a library.

To get a modelling kickstart, we will start using an existing domain model from a library. This model consists of the following main concepts:

Do the following to get started with this example model in your Eclipse environment:

  1. Go into "File > New > Example... > Eclipse Modeling Framework > Extended Library Model Example"
  2. Select "org.eclipse.emf.examples.library" and press "Finish".
  3. Double click on the extlibrary.ecore file, and you will see an editor with a hierarchical breakdown of the domain model.




Part #2: Concepts and Relations

  1. Find examples of EClasses and EDataTypes
  2. Find examples of containment / container and ordinary relations in the model.
  3. Try to find features properties such as:
    1. multiplicity – lower and upper bound
    2. changeable – allows being set (using setter)
    3. derived – computed from other values 
    4. transient – should not be stored in external resource
    5. volatile – should not need to be stored in memory
    6. order – not used in practice, but good to know if order is important


Part #3: Extending the model

Use the model editor to add a new BookCategory. Hint: right-click on BookCategory > New Child... > Select EEnum Literal

Fill out "Literal", "Name" and "Value" properties for our new category.

Remember to save our ecore file, after the new category is added.

 

Part #4: Generating Java Code

First we want to validate our ecore model.

Right click on the root element and select "Validate"

When the model validates successfully, we can generate Java code from it. Properties describing what code to generate is described in a separate .genmodel file. By double clicking on the extlibrary.genmodel file you will see the following in the Properties View:

To generate Java code for our library model, right click on the root element in the editor for the .genmodel file and select Generate Model Code.

When the code generation completes successfully, you will be able to see Java code in terms of Interfaces and Classes for our library example in the package explorer:

As we see in the package explorer, each EClass "Xyz" will (by default) become one interface Xyz and one implementation class XyzImpl.

By double clicking on the BookCategory.java file you see a enum implementation where Computer Science (the modification we made to the domain model) is added as a literal object:

 

Part #5 Instantiating from Java

Now, with Java code for our domain model automatically generated, it is time to learn how to use and instantiate the model.

Add a new Java Project to your workspace. Give it any name, for instance "My Library Test"

In order to make use of the generated code, we need specify a dependency to the generated code.

  1. In the Package Explorer view, right-click the project that you added.
  2. Click Build Path > Configure Build Path.
  3. Click the Projects tab.
  4. Click Add.
  5. Select the project that you want this project to depend on (select "org.eclipse.emf.examples.library").
  6. Click OK.

 

Add a java package under the src folder and give it any useful name, for instance "edu.ntnu.mycode".

Add a new java class to this package and give it a name, for instance "TestingEMF".

Add a main-method to your class. Within the main method you can play with the generated code and create objects instantiate your first library.

Note how you use the EXTLibraryFactory.eINSTANCE to create java objects.

 

Part #6 Instantiating from an Editor

With the ecore model we have for the library domain, we can also use EMF to generate an editor that we can use for instantiation.

In your workspace you will also see that we have two other projects - the edit and the editor projects. These are both generated from our extlibrary.genmodel file. 

The edit project contains generic reusable classes for building an editor.

The editor project contains a eclipse plugin that allow you to instantiate a library model graphically.

As we made changes in the original ecore file we should regenerate the edit and the editor projects. We generate these by right clicking on the root element in the editor for our extlibrary.genmodel.  Run both "Generate Edit Code" and "Generate Editor Code".

Now, to see what this editor looks like we can open the plugin.xml file in the editor project. Under the overview tab you will find a Launch an Eclipse application link.


By pressing this link, Eclipse will fire up a new Eclipse environment with the Library editor plugin added. 

In order to get started modeling instances, we need a workspace project where we can place our model files. Go into "File > New > Project" and create a general project with a name, for instance, "My Library Project".

If you right click on your new project and select "New > Other > Example EMF Model Creation Wizards", you will find an entry labeled "EXTLibrary Model". Press this link and give your model file a name, for instance "MyFirstLibrary.extlibrary". Now you need to select what kind of object you want to model. Here you can select "Library". Keep UTF-8 as encoding and press "finish".

A new .extlibrary file appears now in your project and by opening it you will be able to add children and specify model properties. The things you are able to do in this generated editor is all constrained by the structure of your original ecore file.

Other Eclipse projects (like Sirius) allow you to customize and generate even cooler and more graphical editors for your domain.

 

 

 

  • No labels