Code generation

Code generation

Inside the source folder of our project, create a templates package. Inside that package folder, create a template file Root.xpt that has the following content. First, we define the entry template that is called Root. Since we expect a UML model element to be the top element to the model, we define it for uml::Model. Note the use of the uml Namespace prefix, as defined in the UML2 metamodel. Inside that template, we iterate over all owned elements of type uml::Package in the model and expand a template for the packages defined in it.

«DEFINE Root FOR uml::Model»
  «EXPAND PackageRoot FOREACH allOwnedElements().typeSelect(uml::Package)»
«ENDDEFINE»

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 typeSelect().

«DEFINE PackageRoot FOR uml::Package»
  «EXPAND ClassRoot FOREACH ownedType.typeSelect(uml::Class)»
«ENDDEFINE»  

This template handles classes. It opens a file that has the same name as the class, suffixed by .java. Into that file, we generate an empty class body.

«DEFINE ClassRoot FOR uml::Class»
  «FILE name+".java"»
    public class «name» {}
  «ENDFILE»
«ENDDEFINE»

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.

<?xml version="1.0" encoding="ISO-8859-1"?>
<workflow>

You need to setup the UML2 stuff (registering URI maps, Factories, etc.). This can be done declaring a bean in before of the XmiReader component:

<bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" >
  <platformUri value=".."/>
</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.uml" />
  <modelSlot value="model" />
</component>

The XmiReader reads the model and stores the content (a list containing the model element) in a slot named 'model'. As usual, you might want to clean the target directory.

<component id="dirCleaner"
  class="org.eclipse.emf.mwe.utils.DirectoryCleaner"
  directory="src-gen"/>

and in the generator we also configure the UML2 metamodel.

 <component id="generator" class="org.eclipse.xpand2.Generator" skipOnErrors="true">
	  <metaModel class="org.eclipse.xtend.typesystem.uml2.UML2MetaModel"/>
	  <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>

If you run the workflow (by right clicking on the .mwe file and select Run AsMWE workflow) the two Java classes should be generated.