Version 2.6
Copyright © 2007, 2008, 2009, 2010, 2011, 2012 Lars Vogel
29.12.2012
| Revision History | |||
|---|---|---|---|
| Revision 0.1 | 12.08.2007 | Lars Vogel |
Created |
| Revision 0.2 - 2.6 | 30.07.2008 - 29.12.2012 | Lars Vogel |
bug fixes and enhancements |
Table of Contents
A data model, sometimes also called domain model, represents
the data
you want to work with. For example if you develop
an online flight
booking application you might model your
domain model with objects
like
Person,
Flight,
Booking
etc. The general recommendation is to model your data model
independent of the application logic. This approach leads to
classes
with almost no logic and a lot of properties, e.g.
Person
would have the properties
firstName,
lastName,
Address, etc.
Eclipse EMF can be used to model your domain model. EMF has a distinction between the meta-model and the actual model. The meta-model describes the structure of the model. A model is then the instance of this meta-model. EMF provides a plugable framework to store the model information, the default uses XMI (XML Metadata Interchange) to persists the model definition.
EMF allows to create the meta-model via different means, e.g. XMI, Java annotations, UML or an XML Schema. The following description will use the EMF tools directly to create a EMF model.
Once the EMF meta-model is specified you can generate the corresponding Java implementations classes from this model. EMF provides the possibility that the generated code can be safely extended by hand.
We said earlier that EMF has a meta-model. Actually EMF is based on two meta-models; the Ecore and the Genmodel model. The Ecore metamodel contains the information about the defined classes. The Genmodel contains additional information for the codegeneration, e.g. the path and file information. The genmodel contains also the control parameter how the coding should be generated.
The Ecore model allows to define different elements.
EClass : represents a class, with zero or more attributes and zero or more references.
EAttribute : represents an attribute which has a name and a type.
EReference : represents one end of an association between two classes. It has flag to indicate if it represent a containment and a reference class to which it points.
EDataType : represents the type of an attribute, e.g. int, float or java.util.Date
The Ecore model shows a root object representing the whole model. This model has children which represents the packages, whose children represents the classes, while the children of the classes represents the attributes of these classes.
With EMF you make your domain model explicit which helps to provide clear visibility of the model. EMF also provides change notification functionality to the model in case of model changes. EMF will generate interfaces and factory to create your objects; therefore it helps you to keep your application clean from the individual implementaiton classes.
Another advantages is that you can regenerate the Java code from the model at any point in time.
Install EMF via the Eclipse Update manager . Select Modeling and install EMF - Eclipse Modeling Framework SDK . Also select the Ecore Tools SDK these will allow you to models based on diagrams.

Select the
model
folder, right-click on it
and select
→ → → .

Enter
webpage.ecore
as the
Domain File Name
parameter.

This should open a visual editor for creating EMF models.

Open the Properties view via the menu → → → . This view allows you to modify the attributes of your model elements.
Click on EClass and click into the editor to create a new
class.
Create the
MyWeb,
Webpage,
Category
and
Article
EClasses.

Use the
EAttribute
node to assign to each object the atttribute
called
name. This attribute should have the
EString
type.


Add the
title,
description
and
keywords
attributes
to the
MyWeb
and
Webpage
model elements.

We want to use the data type calendar in our model. Select "EDataType" and give it the name "calendar" and type "java.util.Calendar". Add the EAttribute "created" to "Article" and use your new type.

Select EReferences and create an arrow similar to the following picture. Make sure the upper bound is set to "*" and that the "Is Containment" property is flagged.

Close the diagram and open the
webpage.ecore
file. The result
should look like the following screenshot.

Right-click your
webpage.ecore
file and select
→ → → .
Create the
webpage.genmodel
file based on your
Ecore model.



Select your model and press load.


You have created two model files, the
.ecore
and the
.genmodel
model.
Based on these two model files you can generate
Java
code.
Right-click
on the root node of the
.genmodel
file
and select
Generate
Model
Code
. This
will create the
Java
implementation of the
EMF model in
the
current
project.

The generated code will consists of the following:
model -- Interfaces and the Factory to create the Java classes
model.impl -- Concrete implementation of the interfaces defined in model
model.util -- The AdapterFactory
The central factory has methods for creating all defined
objects
via
createObjectName()
methods.
For each attribute the generated interface and its
implementation
contains
getter
and (if allowed in the model
definition)
setter
methods. Each setter has also a generated
notification to observers of
the model. This mean that other object
can attach them to
the model
and
react to changes in the model.
Each generated interface extends the
EObject
interface .
EObject
is the
base of every EMF class and is the EMF
equivalent of
java.lang.Object.
EObject
and its corresponding
implementation class
EObjectImpl
provide a lightweight base
class that
lets the generated
interfaces and
classes
participate in the EMF
notification and
persistence
frameworks.
Every generated method is tagged with
@generated. If you
want to
manually adjust the method you want to prevent that
EMF overwrites the
method during the next generation run you
have to
remove this tag.
EMF can generate plug-ins which provide wizards for creating new model instances and an editor which allows you to enter your model information.
The following assumes that you have already have knowledge in developing Eclipse plug-ins. For more information about Eclipse plug-in development please see Eclipse Plugin Tutorial
Eclipse EMF allow you to create a editor for your model. Select
your
.genmodel
file
, right-click on it and select
Generate Edit
Code
and
afterwards
Generate
Editor Code
.

Two Eclipse plugin projects have been created, "de.vogella.emf.webpage.model.edit" and "de.vogella.emf.webpage.model.editor".
Select the
*.editor
project and start a new Eclipse instance with your
new
plug-in via
right mouse-click on it and by selecting
→ .
This should start a new Eclipse runtime instance.
In new Eclipse instance create a new project of type
General
called
testing
and a
folder called
website.
Select this folder, right click on it, select → → → .

Name your model My.webpage.

Select as the Model Object "My Web" and press finish.

The generated model code is standard Java code and can be used as such. The following demonstrates how you create objects based on the generated code.
Create a new plug-in project called
de.vogella.emf.webpage.usingmodel.
Add the following dependency to your
MANIFEST.MF.
Create the following class.
package de.vogella.emf.webpage.usingmodel; import de.vogella.emf.webpage.model.webpage.MyWeb; import de.vogella.emf.webpage.model.webpage.Webpage; import de.vogella.emf.webpage.model.webpage.WebpageFactory; import de.vogella.emf.webpage.model.webpage.impl.WebpagePackageImpl; public class UsingEMFModel { public static void main(String[] args) { WebpagePackageImpl.init(); // Retrieve the default factory singleton WebpageFactory factory = WebpageFactory .eINSTANCE; // Create an instance of myWeb MyWeb myWeb = factory.createMyWeb(); myWeb.setName("Hallo"); myWeb.setDescription("This is a description"); // Create a page Webpage webpage = factory.createWebpage(); webpage.setTitle("This is a title"); // Add the page to myWeb myWeb.getPages().add(webpage); // and so on, and so on // as you can see the EMF model can be (more or less) used as standard Java } }
*PackageImpl.init()
method needs
to
be
called before doing
anything else as this
method
initializes the
model
and the listeners.
You can also generate Javadoc for your classes and methods. EMF uses annotations for this with a certain property key. The easiest way of adding this is again the diagram. Select a class and maintain the documentation in the "GenModel Doc".

The ecore model looks now like the following. The key in the annotation "http://www.eclipse.org/emf/2002/GenModel" is necessary and the key on the details enty must be "documentation".

By default EMF generates getter and setter for every class. You
can also add Operations or for example overwrite methods, e.g. the
toString()
method. For Article the following toString method was generated
in "ArticleImpl
* @generated */ @Override public String toString() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (name: "); result.append(name); result.append(", created: "); result.append(created); result.append(')'); return result.toString(); }
To overwrite this, add a "EOperation" to your model with the name toString. Maintain in the properties "EType" EString as return type.

Add an annotation with the source "http://www.eclipse.org/emf/2002/GenModel" and maintain an entry with the key "body", the value is the code that will be generated in to the method, you find it listed below.

if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append("Article: "); result.append(name); return result.toString();
You can also generate methods with input parameter, just add parameter with their type to your EOperation.


EMF allows to extend existing models via inheritance. The following will define a base model and an extension based on this base model. This can for example be used to extend the Eclipse e4 application model. It will also demonstrate how to work with EMF ecore models directly without using the ecore tools.
Create a new EMF project "de.vogella.emf.inheritance". Create a new model by selecting File -> New -> "Eclipse Modeling Framework" -> "Ecore Model". Name the model "base.ecore". Select "EPackage" as the basis and maintain the following properties for this package.

Right-click on the package and select New Child -> EClass. Maintain the class "MyBaseClass" with two "EAttributes" of type "EString". Create a new "Ecore" model "extendedmodel.ecore". Maintain "extended" as the package name. Right-click your model and select "Load resource".



Create a new class "MyExtendedClass" and press "ESuperType".

Add your "MyBaseClass".


Maintain a new EAtribute "detailedField" on "MyExtendedClass".

Create a new genmodel "extended.genmodel" based on extended.ecore. Generated Java code and you will see that the "MyExtendedClass" has extended "MyBaseClass".
It is not obvious how to set an empty string as a default value for an EMF string attribute. To set an empty string as default value do the following.
Select the Attribute
Im the Property View click into the value field of "Default Value Literal"
Do not enter something.
To remove this empty value again, click "Restore Default Value" in the toolbar.
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.
http://www.eclipse.org/modeling/emf Eclipse EMF Homepage
http://www.eclipse.org/modeling/emf/docs/ EMF Documentation
http://www.ibm.com/developerworks/opensource/library/os-ecemf1 Model with the Eclipse Modeling Framework, Part 1: Create UML models and generate code
http://www.ibm.com/developerworks/opensource/library/os-ecemf2 Model with the Eclipse Modeling Framework, Part 2: Generate code with Eclipse's Java Emitter Templates
http://www.raceeend.demon.nl/ How to extend / inheritant from an existing EMF model
http://www.eclipse.org/m2m/atl/ ATL allows model to model transformation for EMF
vogella Training Android and Eclipse Training from the vogella team
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system