blob: 018151abdb4a3b980e3c1fa0b3a6890030287ce8 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org" />
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<title>Generating an EMF Model from Annotated Java</title>
</head>
<body>
<h2>Generating an EMF Model from Annotated Java</h2>
<p>This tutorial is a step-by-step description of the process of
creating an EMF model and generating a simple model editor for it.
Following this tutorial will show how easy EMF makes it to go from
a simple model definition to a fully functioning editor for that
model.</p>
<p>The screenshots are based on version 2.0.1 of the Eclipse SDK
and version 1.0.1 (build 20021003_2227SL) of EMF.</p>
<p>The model we will generate looks like this in UML (see the
"Eclipse Modelling Framework Overview" paper for a description of
this model):</p>
<p><img src="libuml.gif" alt="Library UML model" height="273"
width="425" /></p>
<p>We will show how an EMF model can be generated from a set of
Java interfaces and classes that correspond to the classes and
enumerated types, respectively, in the library model. This code is
the bare minimum required to illustrate the desired features. Based
on it, an Ecore model and a GenModel will be constructed, which
will then drive generation of the remaining code. The code is
annotated with "@model" tags in javadoc comments, in order to
specify any non-default values for the attributes and references of
the Ecore objects.</p>
<blockquote><b><a target="_code"
href="images/../Library.java">Library.java</a></b><br />
<table summary="" border="1" frame="box">
<tr>
<td>
<pre>
<tt>package org.eclipse.example.library;
import java.util.List;
/**
* @model
*/
public interface Library
{
/**
* @model type="Book" containment="true"
*/
List getBooks();
/**
* @model type="Writer" containment="true"
*/
List getWriters();
/**
* @model
*/
String getName();
}</tt>
</pre>
</td>
</tr>
</table>
</blockquote>
<blockquote><b><a target="_code"
href="images/../Book.java">Book.java</a></b><br />
<table summary="" border="1" frame="box">
<tr>
<td>
<pre>
<tt>package org.eclipse.example.library;
/**
* @model
*/
public interface Book
{
/**
* @model
*/
String getTitle();
/**
* @model default="100"
*/
int getPages();
/**
* @model opposite="books"
*/
Writer getAuthor();
/**
* @model
*/
BookCategory getCategory();
}</tt>
</pre>
</td>
</tr>
</table>
</blockquote>
<blockquote><b><a target="_code"
href="images/../Writer.java">Writer.java</a></b><br />
<table summary="" border="1" frame="box">
<tr>
<td>
<pre>
<tt>package org.eclipse.example.library;
/**
* @model
*/
public interface Writer
{
/**
* @model
*/
String getName();
/**
* @model type="Book" opposite="author"
*/
java.util.List getBooks();
}</tt>
</pre>
</td>
</tr>
</table>
</blockquote>
<blockquote><b><a target="_code"
href="images/../BookCategory.java">BookCategory.java</a></b><br />
<table summary="" border="1" frame="box">
<tr>
<td>
<pre>
<tt>package org.eclipse.example.library;
/**
* @model
*/
public class BookCategory
{
/**
* @model name="Mystery"
*/
public static final int MYSTERY = 0;
/**
* @model name="ScienceFiction"
*/
public static final int SCIENCE_FICTION = 1;
/**
* @model name="Biography"
*/
public static final int BIOGRAPHY = 2;
}</tt>
</pre>
</td>
</tr>
</table>
</blockquote>
<h3>Step 0: Prerequisites</h3>
<p>The EMF Runtime package includes the EMF generator and a number
of related plugins. After installing the package, verify that they
are available in your Eclipse environment:</p>
<ul>
<li>Bring up the "Help/About Eclipse Platform" dialog.<br />
<img src="cg001.gif" alt="Help/About Eclipse Platform"
height="123" width="168" /><br />
&nbsp;</li>
<li>Click on "Plug-in Details".<br />
<img src="cg002.gif" alt="Plug-in Details" height="360"
width="486" /><br />
&nbsp;</li>
<li>Check that the highlighted set of plugins are present.<br />
<img src="cg003.gif" alt="Check EMF plugins" height="437"
width="550" /><br />
&nbsp;</li>
</ul>
<h3>Step 1: Define the Model Using Annotated Java</h3>
<p>Create a new Java project in the workspace:</p>
<ul>
<li>Bring up the "File/New/Project..." dialog.<br />
<img src="cg101.gif" alt="File/New/Project..." height="55"
width="341" /><br />
&nbsp;</li>
<li>Select "Java" and "Java Project". Click the "Next"
button.<br />
<img src="cg102.gif" alt="Java Project" height="182"
width="359" /><br />
&nbsp;</li>
<li>Give the project a name, say, "library". Then, click the "Next"
button.<br />
<img src="cg103.gif" alt="Name the project" height="221"
width="302" /><br />
&nbsp;</li>
<li>Select "Use source folders contained in the project", and then
click the "Create New Folder" button.<br />
<img src="cg104.gif" alt="Create a new source folder" height="225"
width="499" /><br />
&nbsp;</li>
<li>Type "src" and click the "OK" button.<br />
<img src="cg105.gif" alt="Name the folder" height="154"
width="437" /><br />
&nbsp;</li>
<li>When asked if you want to update the build output folder, click
the "No" button.<br />
<img src="cg106.gif" alt="Do not update build output folder"
height="124" width="436" /><br />
&nbsp;</li>
<li>Specify "library/runtime" as the build output folder. Click the
"Finish" button.<br />
<img src="cg107.gif" alt="Specify build output folder"
height="155" width="427" /><br />
&nbsp;</li>
<li>The newly created Java project can be seen in the Package
Explorer.<br />
<img src="cg108.gif" alt="Library Java project" height="117"
width="302" /><br />
&nbsp;</li>
</ul>
<p>Create the first Java interface:</p>
<ul>
<li>Right-click the "src" folder and select "New/Interface" from
the pop-up menu.<br />
<img src="cg109.gif" alt="New/Interface" height="152"
width="402" /><br />
&nbsp;</li>
<li>Fill in the package and interface name. Click the "Finish"
button.<br />
<img src="cg110.gif" alt="Create new interface" height="460"
width="500" /><br />
&nbsp;</li>
<li>A new Java interface file is created and opened in the main
view.<br />
<img src="cg111.gif" alt="Opened interface" height="219"
width="344" /><br />
&nbsp;</li>
<li>Type (or paste) in the interface code, as shown earlier in this
section. Pay special attention to the "@model" tags.<br />
<img src="cg112.gif" alt="Enter interface code" height="355"
width="412" /><br />
&nbsp;</li>
<li>Select "Save Library.java" from the "File" menu.<br />
<img src="cg113.gif" alt="File/Save Library.java" height="163"
width="285" /><br />
&nbsp;</li>
</ul>
<p>Create the other two interfaces and the class in the same way.
Of course, to create the class, select "New/Class" from the pop-up
menu, instead of "New/Interface".</p>
<p>Create the GenModel:</p>
<ul>
<li>In the Package Explorer view, right-click the "src" folder and
select "New/Other..." from the pop-up menu.<br />
<img src="cg115.gif" alt="New/Other..." height="250"
width="401" /><br />
&nbsp;</li>
<li>Select "Ecore Model Framework" and "GenModel Model". Click the
"Next" button.<br />
<img src="cg116.gif" alt="New/Other..." height="207"
width="388" /><br />
&nbsp;</li>
<li>Change the folder to "library/src/model".<br />
<img src="cg117.gif" alt="Change the folder" height="228"
width="350" /><br />
&nbsp;</li>
<li>Change the file name to "library.genmodel" and click the "Next"
button.<br />
<img src="cg118.gif" alt="Change the file name" height="135"
width="350" /><br />
&nbsp;</li>
<li>Select "Load from Java annotations" and click the "Finish"
button.<br />
<img src="cg119.gif" alt="Load from Java annotations" height="210"
width="259" /><br />
&nbsp;</li>
<li>An Ecore model and a GenModel will be created. The GenModel,
which controls code generation for the model, is opened in the main
view.<br />
<img src="cg120.gif" alt="Opened GenModel" height="210"
width="508" /><br />
&nbsp;</li>
</ul>
<h3>Step 2: Generate the EMF Model Code</h3>
<p>The GenModel shows a root object, representing the the whole
model. The model object has children that represent its packages,
whose children then represent classifiers (classes and datatypes,
including enumerated types). The children of classes are class
attributes, references, and operations; the children of enumerated
types are enum literals.</p>
<ul>
<li>The GenModel can be expanded to see its various elements.<br />
<img src="cg201.gif" alt="Expanded GenModel" height="190"
width="327" /><br />
&nbsp;</li>
<li>There are properties associated with each object. If the
Properties view isn't already showing, bring up "Window/Show
View/Other..."<br />
<img src="cg202.gif" alt="Window/Show View/Other..." height="257"
width="378" /><br />
&nbsp;</li>
<li>Expand the "Basic" set of views and choose "Properties".<br />
<img src="cg203.gif" alt="Chose Properties" height="164"
width="153" /><br />
&nbsp;</li>
<li>These properties control the behavior of the code
generator.<br />
<img src="cg204.gif" alt="GenModel properties" height="500"
width="540" /><br />
&nbsp;</li>
</ul>
<p>In most cases, the properites need not be changed from their
default values, but these options can provide a great deal of
control over the code that gets generated. This topic will be
explored more fully in future tutorial material; for now, select
several different GenModel objects, and observe their
properties.</p>
<p>The GenModel is also the place where you initiate the code
generation. By right-clicking on an object in the model, you can
generate code for it.</p>
<ul>
<li>Right-click the "/library/src/model/library.genmodel" model
object and select "Generate Model" from the pop-up menu.<br />
<img src="cg207.gif" alt="Generate Model" height="288"
width="350" /><br />
&nbsp;</li>
<li>Observe the generated files.<br />
<img src="cg208.gif" alt="Generated model code" height="203"
width="244" /><br />
<br />
</li>
</ul>
<p>After generation, the class interfaces and enum class will have
been created (if the model was imported from Rose) or completed (if
the model was defined using annotated Java), and a new pair of
interfaces will have been created for the package itself and for
the factory. There will also be two new packages, with "impl" and
"util" suffixes, which contain implementations of the interfaces
and additional utility classes, and a "plugin.xml" manifest file
for the model plugin.</p>
<p>If you change the model, you can regenerate it, and changes will
be merged with any hand modifications that may have been made to
the code. You can also selectively generate a subset of the model
code by right-clicking on a package, class, or enum object and
selecting "Generate Model" from the pop-up menu.</p>
<h3>Step 3: Generate an Editor for the Model</h3>
<p>A fully functional Eclipse editor can also be generated for any
model. By default, it is split between two plugins: an "edit"
plugin includes adapters that provide a structured view and perform
command-based editing of the model objects; an "editor" plugin
provides the UI for the editor and wizard.</p>
<ul>
<li>In the GenModel, right-click the
"/library/src/model/library.genmodel" model object and select
"Generate EMF.Edit" from the pop-up menu.<br />
<img src="cg301.gif" alt="Generate EMF.Edit" height="288"
width="351" /><br />
&nbsp;</li>
<li>Right-click the model object and select "Generate EMF.Editor"
from the pop-up menu.<br />
<img src="cg304.gif" alt="Generate EMF.Editor" height="240"
width="350" /><br />
&nbsp;</li>
<li>Observe the generated projects, with "edit" and "editor"
suffixes.<br />
<img src="cg302.gif" alt="Edit and editor projects" height="37"
width="118" /><br />
&nbsp;</li>
</ul>
<p>In general, if you wish to generate the model, edit, and editor
plugins in a single step, you can do so by selecting "Generate All"
from the pop-up menu.</p>
<p>The code should be compiled automatically as it is generated,
and should recompile whenever it is changed. If you have disabled
automatic building in the workbench preferences, you can initiate
compilation manually:</p>
<ul>
<li>Select "Rebuild All" from the "Project" menu.<br />
<img src="cg303.gif" alt="Project/Rebuild All" height="110"
width="377" /><br />
&nbsp;</li>
<li>There should no errors in the "library", "library.edit", and
"library.editor" projects.<br />
<img src="cg305.gif" alt="No errors" height="72"
width="247" /><br />
&nbsp;</li>
</ul>
<h3>Step 4: Run the Generated Editor</h3>
<p>In order to run plugins in a runtime workbench, a lunch
configuration must first be set up:</p>
<ul>
<li>Select "Run..." from the "Run" menu.<br />
<img src="cg401.gif" alt="Run/Run..." height="168"
width="375" /><br />
&nbsp;</li>
<li>Select "Run-time Workbench" and click the "New" button.<br />
<img src="cg402.gif" alt="New Run-time Workbench" height="349"
width="424" /><br />
&nbsp;</li>
<li>You may want to change the configuration's name to something
more recognizable. Then, switch to the "Plug-ins and Fragments"
tab.<br />
<img src="cg403.gif" alt="Name the configuration" height="238"
width="498" /><br />
&nbsp;</li>
<li>Pick "Choose plugin-ins and fragments to launch from the list",
and then select the top-level "External Plug-ins".<br />
<img src="cg404.gif" alt="Select all External Plugins"
height="331" width="444" /><br />
&nbsp;</li>
<li>Switch to the "Common" tab, select "Display in favorites menu:
Run", and click the "Apply" button.<br />
<img src="cg405.gif" alt="Display in favorites menu: Run"
height="368" width="447" /><br />
&nbsp;</li>
</ul>
<p>A runtime workbench can be launched from the "Launch
Configurations" dialog by clicking on the "Run" button. Once the
launch configuration has been set up, it can also be launched from
the "Run" button on the toolbar.</p>
<ul>
<li>Select the new launch configuration from the "Run" button
drop-down.<br />
<img src="cg406.gif" alt="Library Configuration" height="124"
width="355" /><br />
&nbsp;</li>
<li>Wait for a second instance of the Eclipse platform to come up.
Bring up the "Help/About Eclipse Platform" dialog, click on the
"Plug-in Details" button, and verify that the generated plugins are
there.<br />
<img src="cg407.gif" alt="Plug-in Details" height="437"
width="550" /><br />
&nbsp;</li>
</ul>
<p>The library model wizard can now be used to create a new
instance of the model.</p>
<ul>
<li>Bring up the "File/New/Project..." dialog.<br />
<img src="cg101.gif" alt="File/New/Project..." height="55"
width="341" /><br />
&nbsp;</li>
<li>Select "Simple" and "Project". Click the "Next" button.<br />
<img src="cg408.gif" alt="Simple Project" height="91"
width="333" /><br />
&nbsp;</li>
<li>Give the project a name and click the "Finish" button.<br />
<img src="cg409.gif" alt="Name the project" height="126"
width="213" /><br />
&nbsp;</li>
<li>Right-click the project and select "New/Other..." from the
pop-up menu.<br />
<img src="cg410.gif" alt="New/Other..." height="178"
width="387" /><br />
&nbsp;</li>
<li>Select "Example EMF Model Creation Wizards" and "Library
Model". Click the "Next" button.<br />
<img src="cg411.gif" alt="Library Model" height="195"
width="355" /><br />
&nbsp;</li>
<li>Enter a file name for the library model. Make sure it ends with
a ".library" extension.<br />
<img src="cg412.gif" alt="Name the library model file" height="46"
width="146" /><br />
&nbsp;</li>
<li>Select "Library" as the model object, and click the "Finish"
button.<br />
<img src="cg413.gif" alt="Select the Model Object" height="149"
width="218" /><br />
&nbsp;</li>
<li>The newly created library model is opened in the main
view.<br />
<img src="cg414.gif" alt="New library model" height="118"
width="482" /><br />
&nbsp;</li>
</ul>
<p>The root object in this editor corresponds to the "My.library"
resource. Under it lies a single library, the object which was
selected as the model object in the wizard.</p>
<ul>
<li>Expand the "platform:/resource/librarytest/My.library" resource
to see the library object. Select it.<br />
<img src="cg415.gif" alt="Expanded resource" height="193"
width="420" /><br />
&nbsp;</li>
<li>In the Properties view, click on the "Value" column of the
"Name" property, and give a name to the library. The label in the
main view will be updated when you hit Enter.<br />
<img src="cg416.gif" alt="Name the library" height="129"
width="420" /><br />
&nbsp;</li>
<li>Right-click on the library and select "New Child/Writer" from
the pop-up menu to add a new writer to the library.<br />
<img src="cg417.gif" alt="New Child/Writer" height="193"
width="420" /><br />
&nbsp;</li>
<li>Enter the name of the writer in the Properties view.<br />
<img src="cg418.gif" alt="Name the writer" height="267"
width="420" /><br />
&nbsp;</li>
<li>Similarly, a book can be added to the library.<br />
<img src="cg419.gif" alt="New Child/Book" height="193"
width="420" /><br />
&nbsp;</li>
<li>All the book's attributes and references can edited in the
Properties view.<br />
<img src="cg420.gif" alt="Book properties" height="325"
width="420" /><br />
&nbsp;</li>
<li>You can save, close, and then re-open the model using the text
editor if you wish to see the saved model in XMI format.<br />
<img src="cg421.gif" alt="Open With/Text Editor" height="213"
width="379" /><br />
&nbsp;</li>
</ul>
</body>
</html>