| <!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 /> |
| </li> |
| |
| <li>Click on "Plug-in Details".<br /> |
| <img src="cg002.gif" alt="Plug-in Details" height="360" |
| width="486" /><br /> |
| </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 /> |
| </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 /> |
| </li> |
| |
| <li>Select "Java" and "Java Project". Click the "Next" |
| button.<br /> |
| <img src="cg102.gif" alt="Java Project" height="182" |
| width="359" /><br /> |
| </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 /> |
| </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 /> |
| </li> |
| |
| <li>Type "src" and click the "OK" button.<br /> |
| <img src="cg105.gif" alt="Name the folder" height="154" |
| width="437" /><br /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </li> |
| |
| <li>Change the folder to "library/src/model".<br /> |
| <img src="cg117.gif" alt="Change the folder" height="228" |
| width="350" /><br /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </li> |
| |
| <li>Expand the "Basic" set of views and choose "Properties".<br /> |
| <img src="cg203.gif" alt="Chose Properties" height="164" |
| width="153" /><br /> |
| </li> |
| |
| <li>These properties control the behavior of the code |
| generator.<br /> |
| <img src="cg204.gif" alt="GenModel properties" height="500" |
| width="540" /><br /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </li> |
| |
| <li>Select "Simple" and "Project". Click the "Next" button.<br /> |
| <img src="cg408.gif" alt="Simple Project" height="91" |
| width="333" /><br /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </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 /> |
| </li> |
| </ul> |
| </body> |
| </html> |
| |