To run the Xpand generator, you have to define a workflow. It controls which steps (loading models, checking them, generating code) the generator executes. For details on how workflow files work, please take a look at the Modeling Workflow Engine Reference Documentation .
Create a workflow.mwe
and a
workflow.properties
in the src
folder. The contents of these files is
shown below:
<workflow> <property file="workflow.properties"/> <bean class="org.eclipse.emf.mwe.utils.StandaloneSetup" > <platformUri value=".."/> <registerGeneratedEPackage value="data.DataPackage"/> </bean> <component class="org.eclipse.emf.mwe.utils.Reader"> <uri value="platform:/resource/${modelFile}" /> <modelSlot value="model" /> </component> </workflow>
workflow.properties
:
modelFile=platform:/resource/xpand.demo.emf.datamodel/src/example.data srcGenPath=src-gen fileEncoding=ISO-8859-1
The workflow tries to load stuff from
the classpath; so, for example, the
data.DataPackage
class is resolved from the
classpath, as is the model file specified in the properties
(modelFile=example.data
)
This instantiates the example model and stores in a workflow slot
named model. Note that in the
metamodelPackage
slot, you have to specify the EMF package object (here:
data.DataPackage
), not the Java package (which
would be data here).
Before you actually run the workflow, make sure your metamodel can
be found on the classpath. In our case, this can be achieved by adding
the xpand.demo.emf.datamodel
project to the plug-in
dependencies of xpand.demo.emf.datamodel.generator
.
To do this, double click the file
xpand.demo.emf.datamodel.generator/META-INF/MANIFEST.MF
.
The manifest editor will appear. Go to the
tab and click on
to add a few new dependencies.
xpand.demo.emf.datamodel
org.eclipse.emf.mwe.utils
org.eclipse.emf.ecore.xmi
org.eclipse.jface.text
org.antlr.runtime
com.ibm.icu
org.eclipse.jdt.core
Do not forget to save the manifest file!
Now, you can run the workflow from within Eclipse:
The following should be the output:
INFO: -------------------------------------------------------------------------------------- INFO: EMF Modeling Workflow Engine 0.7.2, Build v200908120417 INFO: (c) 2005-2009 openarchitectureware.org and contributors INFO: -------------------------------------------------------------------------------------- INFO: running workflow: ../xpand.demo.emf.datamodel.generator/src/workflow.mwe INFO: 14.04.2010 15:49:18 org.eclipse.emf.mwe.utils.StandaloneSetup setPlatformUri INFO: Registering platform uri '..' 14.04.2010 15:49:18 org.eclipse.emf.mwe.utils.StandaloneSetup addRegisterGeneratedEPackage INFO: Adding generated EPackage 'data.DataPackage' 14.04.2010 15:49:18 org.eclipse.emf.mwe.core.container.CompositeComponent internalInvoke INFO: Reader: Loading model from platform:/resource/xpand.demo.emf.datamodel.generator/src/example.data 14.04.2010 15:49:19 org.eclipse.emf.mwe.core.WorkflowRunner executeWorkflow INFO: workflow completed in 116ms!
No code is generated yet. This is not surprising, since we did not
yet add any templates. Let us change this. Create a package
templates in the src
folder and within the package a file
called Root.xpt
.
The Root.xpt
looks as follows. By the way, if
you need to type the
guillemets
(« and »), the editor provides keyboard shortcuts with
Ctrl
+
<
and
Ctrl
+
>
.
«DEFINE Root FOR data::DataModel» «EXPAND Entity FOREACH entity» «ENDDEFINE» «DEFINE Entity FOR data::Entity» «FILE name + ".java"» public class «name» { «FOREACH attribute AS a» // bad practice private «a.type» «a.name»; «ENDFOREACH» } «ENDFILE» «ENDDEFINE»
We have to extend the workflow.mwe
file, in
order to use the template just written:
<workflow> <property file="workflow.properties"/> .. <component class="org.eclipse.emf.mwe.utils.Reader"> <uri value="platform:/resource/${modelFile}" /> .. </workflow>
First, we clean up the directory where we want to put the generated code.
<component class="org.eclipse.emf.mwe.utils.DirectoryCleaner"> <directory value="${srcGenPath}" /> </component>
Then, we start the generator component. Its configuration is slightly involved.
<component class="org.eclipse.xpand2.Generator">
First of all, you have to define the metamodel. In our case, we
use the EmfMetaModel
since we want to work with EMF models. Also, you have to
specific the class name of the EMF package that represents that
metamodel. It has to be on the classpath.
<metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"> </metaModel>
Then, you have to define the
entry statement
for
Xpand
. Knowing that the model slot contains an
instance of data.DataModel
(the XmiReader had put
the first element of the model into that slot, and we know from the data
that it is a DataModel
), we can write the
following statement. Again, notice that model refers to a slot name
here!
<expand value="templates::Root::Root FOR model"/>
We then specify where the generator should put the generated code and that this generated code should be processed by a code beautifier:
<outlet path="${srcGenPath}/"> <postprocessor class="org.eclipse.xpand2.output.JavaBeautifier"/> </outlet>
Now, we are almost done.
</component> </workflow>
You also need to add the
srcGenPath
to the
workflow.properties
file.
modelFile=example.data srcGenPath=src-gen