blob: 6afb2976376524fc466abc40c2a8518a161fc662 [file] [log] [blame]
<html>
<head>
<title>Code generation</title>
<link href="book.css" rel="stylesheet" type="text/css"/>
<meta content="DocBook XSL Stylesheets V1.75.1" name="generator"/>
<link rel="home" href="index.html" title="Xpand Documentation"/>
<link rel="up" href="uml2example.html" title="UML2 Example"/>
<link rel="prev" href="uml2example_create_model.html" title="Creating a UML2 Model"/>
<link rel="next" href="uml2example_profiles.html" title="Profile Support"/>
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<h1 xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">Code generation</h1>
<div class="section" title="Code generation">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a name="uml2example_codegen"/>Code generation</h2>
</div>
</div>
</div>
<div class="section" title="Defining the templates">
<div class="titlepage">
<div>
<div>
<h3 class="title">
<a name="uml2example_codegen_templates"/>Defining the templates</h3>
</div>
</div>
</div>
<p>Inside the source folder of our project, create a
<code class="filename">templates</code> package. Inside that package folder,
create a template file <code class="filename">Root.xpt</code> that has the
following content. First, we define the entry template that is called
<code class="classname">Root</code>. Since we expect a UML model element to be
the top element to the model, we define it for
<code class="classname">uml::Model</code>. Note the use of the
<code class="classname">uml</code> Namespace prefix, as defined in the UML2
metamodel. Inside that template, we iterate over all owned elements of
type <code class="classname">uml::Package</code> in the model and expand a
template for the packages defined in it.</p>
<pre class="programlisting">«DEFINE Root FOR uml::Model»
«EXPAND PackageRoot FOREACH allOwnedElements().typeSelect(uml::Package)»
«ENDDEFINE»
</pre>
<p>In the package template, we again iterate over all owned elements
and call a template that handles classes. Although we only have classes
in that package we could not rely on this in general. The package may
contain any other packageable element, so we need to filter classes
using <code class="methodname">typeSelect()</code>.</p>
<pre class="programlisting">«DEFINE PackageRoot FOR uml::Package»
«EXPAND ClassRoot FOREACH ownedType.typeSelect(uml::Class)»
«ENDDEFINE»
</pre>
<p>This template handles classes. It opens a file that has the same
name as the class, suffixed by <code class="filename">.java</code>. Into that
file, we generate an empty class body.</p>
<pre class="programlisting">«DEFINE ClassRoot FOR uml::Class»
«FILE name+".java"»
public class «name» {}
«ENDFILE»
«ENDDEFINE»</pre>
</div>
<div class="section" title="Defining the workflow">
<div class="titlepage">
<div>
<div>
<h3 class="title">
<a name="uml2example_codegen_workflow"/>Defining the workflow</h3>
</div>
</div>
</div>
<p>In order to generate code, we need a workflow definition. Here is
the workflow file; you should put it into the source folder. The file
should be generally understandable if you read the Getting Started
chapter.</p>
<pre class="programlisting">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;workflow&gt;
</pre>
<p>You need to setup the UML2 stuff (registering URI maps, Factories,
etc.). This can be done declaring a bean in before of the
<code class="classname">XmiReader</code>
<a name="N12F92" class="indexterm"/> component:</p>
<pre class="programlisting">&lt;bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" &gt;
&lt;platformUri value=".."/&gt;
&lt;/bean&gt;
&lt;!-- load model and store it in slot 'model' --&gt;
&lt;component class="org.eclipse.emf.mwe.utils.Reader"&gt;
&lt;uri value="platform:/resource/xpand.uml2.generator/src/example.uml" /&gt;
&lt;modelSlot value="model" /&gt;
&lt;/component&gt;</pre>
<p>The <code class="classname">XmiReader</code> reads the model and stores
the content (a list containing the model element) in a slot named
'<code class="varname">model</code>'. As usual, you might want to clean the target
directory<a name="N12FA1" class="indexterm"/>.</p>
<pre class="programlisting">&lt;component id="dirCleaner"
class="org.eclipse.emf.mwe.utils.DirectoryCleaner"
directory="src-gen"/&gt;</pre>
<p>and in the generator we also configure the UML2
metamodel<a name="N12FAA" class="indexterm"/>.</p>
<pre class="programlisting"> &lt;component id="generator" class="org.eclipse.xpand2.Generator" skipOnErrors="true"&gt;
&lt;metaModel class="org.eclipse.xtend.typesystem.uml2.UML2MetaModel"/&gt;
&lt;expand value="templates::Root::Root FOR model"/&gt;
&lt;fileEncoding value="ISO-8859-1"/&gt;
&lt;outlet path="src-gen"&gt;
&lt;postprocessor class="org.eclipse.xpand2.output.JavaBeautifier"/&gt;
&lt;/outlet&gt;
&lt;/component&gt;
&lt;/workflow&gt;</pre>
<p>If you run the workflow (by right clicking on the
<code class="filename">.mwe</code> file and select <span class="guiicon">Run As</span><span class="guimenuitem">MWE workflow</span>) the two Java classes should be generated.</p>
</div>
</div>
</body>
</html>