blob: 48f34c8748edc2da9c7973bb70393fadacc5ed38 [file] [log] [blame]
<html>
<head>
<title>Profile Support</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_codegen.html" title="Code generation"/>
<link rel="next" href="xsd_tutorial.html" title="XSD Tutorial"/>
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<h1 xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">Profile Support</h1>
<div class="section" title="Profile Support">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both">
<a name="uml2example_profiles"/>Profile Support</h2>
</div>
</div>
</div>
<p>Xpand is shipped with a special <span class="emphasis">
<em>UML2 profiles</em>
</span>
metamodel implementation. The implementation maps Stereotypes<a name="N12FC5" class="indexterm"/> to Types and Tagged Values<a name="N12FC9" class="indexterm"/> to simple properties. It also supports
Enumerations<a name="N12FCD" class="indexterm"/> defined in the profile and Stereotype hierarchies.</p>
<div class="section" title="Defining a Profile">
<div class="titlepage">
<div>
<div>
<h3 class="title">
<a name="uml2example_profiles_define"/>Defining a Profile</h3>
</div>
</div>
</div>
<p>To define a profile, you can use a variety of UML2-based modelling
tools. Assuming they do actually correctly create profile definitions
(which is not always the case, as we had to learn painfully), creating a
profile and exporting it correctly is straight forward.</p>
<p>In this section, we explain the "manual way", which is good for
explaining what happens, but completely useless for practical use. You
do not want to build models of realistic sizes using the mechanisms
explained below.</p>
<p>You start be creating a new UML2 file (as shown above). In the
example we will call it <code class="filename">test.profile.uml</code>. The root
element, however, will be a <span class="emphasis">
<em>Profile</em>
</span>, not a
<span class="emphasis">
<em>Package</em>
</span>. Don't forget to actually assign a name to
the profile! It should be <code class="literal">test</code>, too.</p>
<p>The created <span class="emphasis">
<em>Profile</em>
</span> we call
<code class="literal">test</code>. In our case, we want to make the stereotype be
applicable to UML classes – they are defined as part of the UML2
metamodel. So we have to import that metamodel first. So what you do is
to select your profile object, and then go to the UML2 Editor menu (in
the Eclipse menu bar) and select <span class="emphasis">
<em>Profile -&gt; Reference
Metaclass</em>
</span>. Select <code class="classname">uml::Class</code>. Then,
add a stereotype to your profile (right mouse click on the profile -&gt;
<span class="emphasis">
<em>New Child</em>
</span> -&gt; <span class="emphasis">
<em>Owned
Stereotype</em>
</span> -&gt; <span class="emphasis">
<em>Stereotype).</em>
</span> Now you
can define your stereotype: select <span class="emphasis">
<em>Stereotype -&gt; Create
Extension</em>
</span> from the UML2 Editor menu. Select
<code class="classname">uml::Class</code>. This should lead to the following
model. Save it and you are done with the profile definition.</p>
<div class="figure">
<a name="uml2example_profile"/>
<p class="title">
<b>Figure 5. Modelling a Profile</b>
</p>
<div class="figure-contents">
<div class="mediaobject">
<img src="images/uml2_example/profile.png" alt="Modelling a Profile"/>
</div>
</div>
</div>
<br class="figure-break"/>
</div>
<div class="section" title="Applying the Profile">
<div class="titlepage">
<div>
<div>
<h3 class="title">
<a name="uml2example_profile_apply"/>Applying the Profile</h3>
</div>
</div>
</div>
<p>To make any use of the profile, we have to apply it to some kind
of model. To do that, we copy the <code class="filename">example.uml</code> model
to a <code class="filename">example-profiled.uml</code>. We then open that file
and load a resource, namely the profile we just defined. This then looks
somewhat like this:</p>
<div class="figure">
<a name="uml2example_profileApp1"/>
<p class="title">
<b>Figure 6. Loading the Profile</b>
</p>
<div class="figure-contents">
<div class="mediaobject">
<img src="images/uml2_example/profileApp1.gif" alt="Loading the Profile"/>
</div>
</div>
</div>
<br class="figure-break"/>
<p>Now, to make the following stuff work, you first have to select
the profile and select the <span class="emphasis">
<em>Profile -&gt; Define</em>
</span>
operation from the UML2 Editor menu. This creates all kinds of
additional model elements, about which you should not care for the
moment.</p>
<p>Now, finally, you can select your <code class="literal">cars</code> package
(the one from the example model) and select <span class="emphasis">
<em>Package -&gt;
Apply Profile</em>
</span> from the UML2 Editor menu. Select your test
profile to be applied.</p>
<p>For the purpose of this example, you should now apply the test
stereotype to the <code class="classname">PersonCar</code> class. Select the
class, and the select <span class="emphasis">
<em>Element -&gt; Apply
Stereotype</em>
</span> from the UML2 Editor menu. This should result in
the following model:</p>
<div class="figure">
<a name="uml2example_profileApp2"/>
<p class="title">
<b>Figure 7. Defining the Profile</b>
</p>
<div class="figure-contents">
<div class="mediaobject">
<img src="images/uml2_example/profileApp2.png" alt="Defining the Profile"/>
</div>
</div>
</div>
<br class="figure-break"/>
</div>
<div class="section" title="Generating Code">
<div class="titlepage">
<div>
<div>
<h3 class="title">
<a name="uml2example_profiles_codegen"/>Generating Code</h3>
</div>
</div>
</div>
<p>Note that all the stuff above was not in any way related to Xpand,
it was just the "bare bones" means of creating and applying a profile to
a UML2 model. Having an UML2 tool capable of storing models as EMF UML2
XMI<a name="N13055" class="indexterm"/> would make the creation of the model far more easier.
Since we cannot assume which UML2 tool you are using this tutorial shows
you this way, which would always work without further tooling
installed.</p>
<p>There are two things we have to change: The workflow
(specifically, the configuration of the generator component) needs to
know about the profile, and the template needs to generate different
code if a class has the test stereotype applied. Let us look at the
second aspect first. Here is the modified template (in
<code class="filename">RootWithProfile.xpt</code>):</p>
<pre class="programlisting">«DEFINE Root FOR uml::Model»
«EXPAND PackageRoot FOREACH allOwnedElements().typeSelect(uml::Package)»
«ENDDEFINE»
«DEFINE PackageRoot FOR uml::Package»
«EXPAND ClassRoot FOREACH ownedType.typeSelect(uml::Class)»
«ENDDEFINE»
«DEFINE ClassRoot FOR uml::Class»
«FILE name+".java"»
public class «name» {}
«ENDFILE»
«ENDDEFINE»
«DEFINE ClassRoot FOR test::test»
«FILE name+".java"»
public class «name» {} // stereotyped
«ENDFILE»
«ENDDEFINE» </pre>
<p>As you can see, <span class="bold">
<strong>the stereotype acts just
like a type</strong>
</span>, and even the polymorphic dispatch between the
base type (<code class="classname">uml::Class</code>) and the stereotype
works!</p>
<p>Adapting the workflow file is also straight forward
(<code class="filename">workflowWithProfile.mwe</code>). Here is the modified
model component with the new model
<code class="filename">example-profiled.uml</code> and a extended setup:</p>
<pre class="programlisting">&lt;?xml version="1.0"?&gt;
&lt;workflow&gt;
&lt;!-- set up EMF for standalone execution --&gt;
&lt;bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" platformUri=".." /&gt;
&lt;!-- prepare for performing uml --&gt;
&lt;bean class="org.eclipse.xtend.typesystem.uml2.Setup" standardUML2Setup="true" /&gt;
&lt;!--UML2 Profile - Metamodell--&gt;
&lt;bean id="mm_profile" class="org.eclipse.xtend.typesystem.uml2.profile.ProfileMetaModel"&gt;
&lt;profile value="platform:/resource/xpand.uml2.generator/src/test.profile.uml"/&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-profiled.uml" /&gt;
&lt;modelSlot value="model" /&gt;
&lt;/component&gt;</pre>
<p>And here is the modified generator component:</p>
<pre class="programlisting">&lt;component id="generator" class="org.eclipse.xpand2.Generator" skipOnErrors="true"&gt;
&lt;metaModel idRef="mm_profile"/&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>The only thing, we have to do is to add a new metamodel that
references the profile we just created.</p>
</div>
</div>
</body>
</html>