| <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 -> Reference |
| Metaclass</em> |
| </span>. Select <code class="classname">uml::Class</code>. Then, |
| add a stereotype to your profile (right mouse click on the profile -> |
| <span class="emphasis"> |
| <em>New Child</em> |
| </span> -> <span class="emphasis"> |
| <em>Owned |
| Stereotype</em> |
| </span> -> <span class="emphasis"> |
| <em>Stereotype).</em> |
| </span> Now you |
| can define your stereotype: select <span class="emphasis"> |
| <em>Stereotype -> 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 -> 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 -> |
| 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 -> 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"><?xml version="1.0"?> |
| <workflow> |
| <!-- set up EMF for standalone execution --> |
| <bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" platformUri=".." /> |
| |
| <!-- prepare for performing uml --> |
| <bean class="org.eclipse.xtend.typesystem.uml2.Setup" standardUML2Setup="true" /> |
| |
| <!--UML2 Profile - Metamodell--> |
| <bean id="mm_profile" class="org.eclipse.xtend.typesystem.uml2.profile.ProfileMetaModel"> |
| <profile value="platform:/resource/xpand.uml2.generator/src/test.profile.uml"/> |
| </bean> |
| |
| <!-- load model and store it in slot 'model' --> |
| <component class="org.eclipse.emf.mwe.utils.Reader"> |
| <uri value="platform:/resource/xpand.uml2.generator/src/example-profiled.uml" /> |
| <modelSlot value="model" /> |
| </component></pre> |
| <p>And here is the modified generator component:</p> |
| <pre class="programlisting"><component id="generator" class="org.eclipse.xpand2.Generator" skipOnErrors="true"> |
| <metaModel idRef="mm_profile"/> |
| <expand value="templates::Root::Root FOR model"/> |
| <fileEncoding value="ISO-8859-1"/> |
| <outlet path="src-gen"> |
| <postprocessor class="org.eclipse.xpand2.output.JavaBeautifier"/> |
| </outlet> |
| </component> |
| </workflow></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> |