Creating mapping file
The mapping file can contain a number of different mappings. This guide will show some mapping examples, to help you get started.
Expressions in mapping files are written in OGNL.
For a more extensive explanation on expanderExpanderA unit of generation that combines a data tree instance (functional M1 model) with a template to generate an artifact. mapping, check the reference guide: Expander Mapping
Value
<value name="component" eval="dataElement.component.name"/>
ConditionalValue
In this example, the value fileName can be overwritten by defining the option 'demo.filename'.
<conditionalValue name="fileName">
<option if="dataElement.getOption('demo.fileName').defined" eval="dataElement.getOption('demo.fileName').value"/>
<defaultOption eval="dataElement.name"/>
</conditionalValue>
Group
E.g. in this example the values in the group can be accessed in the template as <targetElement.packageName> and <targetElement.name>:
<group name="targetElement" if="field.linkField neq null">
<value name="name" eval="field.linkField.targetElement.name"/>
<value name="packageName" eval="field.linkField.targetElement.packageName"/>
</group>
List
<!--
Get a list containing the names of the Fields in a DataElement.
-->
<list name="fields">
<foreach name="field" in="dataElement.fields"/>
<value name="name" eval="field.name"/>
</list>
A list mapping can contain multiple <foreach> mappings.
The iterations will be nested, but the end result will be a single flat list.
<!--
Obtain every field in a component.
-->
<list name="fields">
<foreach name="dataElement" in="component.dataElements"/>
<foreach name="field" in="dataElement.fields"/>
<value name="dataElementName" eval="dataElement.name"/>
<value name="name" eval="field.name"/>
</list>
Filtering List
<list name="fields">
<foreach name="field" in="dataElement.fields"/>
<!-- Only take fields where the valueField is defined. -->
<filter name="isValueField" eval="field.valueField neq null"/>
<value name="name" eval="field.name"/>
</list>
Duplicates can be removed by using <distinct>.
<list name="fieldTypes">
<foreach name="field" in="dataElement.fields"/>
<filter name="isValueField" eval="field.valueField neq null"/>
<!-- Remove all items that are duplicates based on the value presented in the eval. -->
<distinct name="distinctTypes" eval="field.valueField.type"/>
<value name="name" eval="field.valueField.type.name"/>
</list>
Sorting
<list name="fields">
<foreach name="field" in="dataElement.fields"/>
<value name="name" eval="field.name"/>
<!-- Sort by field name -->
<sorted eval="field.name"/>
</list>
List Composition
<list name="fields">
<!-- Always add an id field -->
<item>
<value name="name" eval="'id'"/>
</item>
<foreach name="field" in="dataElement.fields"/>
<value name="name" eval="field.name"/>
</list>
Use <items> to combine lists.
<!--
Create a separate mapping for LinkFields and ValueFields and then combine them.
-->
<list name="fields">
<items>
<foreach name="field" in="dataElement.fields"/>
<filter name="isValueField" eval="field.valueField neq null"/>
<value name="name" eval="field.name"/>
<value name="type" eval="field.valueField.javaType"/>
</items>
<items>
<foreach name="field" in="dataElement.fields"/>
<filter name="isLinkField" eval="field.linkField neq null"/>
<value name="name" eval="field.name"/>
<value name="type" eval="field.linkField.linkFieldType.dataType"/>
</items>
</list>
Assert
You can check if the model is valid by using asserts:
<assert name="versionField_isValueFieldType" message="Option `isVersion` can only be used in combination with a valueFieldType"
eval="field.valueField neq null"/>
Include
Lastly, the include mapping will include another mapping file and add it to the mapping.
<include path="SomeCommonMapping.xml"/>
<!-- or -->
<include path="/path/to/SomeCommonMapping.xml"/>
Extending the scope
It is possible to define new variables in the mapping scope, which can be used in other mapping statements.
For this you can use a let statement:
The mapping
<value name="name" eval="field.linkField.targetElement.name"/>
<value name="packageName" eval="field.linkField.targetElement.packageName"/>
can be simplified to:
<let name="targetElement" eval="field.linkField.targetElement"/>
<value name="name" eval="targetElement.name"/>
<value name="packageName" eval="targetElement.packageName"/>
Let statements can also be used to instantiate helper classes:
<let name="nameConverter" eval="new net.democritus.naming.ElementNameConverter()"/>
<value name="nameDashed" eval="nameConverter.getDashed(dataElement.name)"/>
In both list and group statements, the variables defined with let statements within the list or group mapping cannot be accessed from outside these mappings.