We now want to set the type of each Column.
Change the UML2Relational ruleset code to:
package tutorial.uml2relational;
public ruleset UML2Relational(in source : uml21, out target : relational) {
public rule main() {
@createTypes();
// create a Table for each Class
foreach (class : uml21.Class in source.getInstances("Class")) {
@createTable(class, target.create("Table"));
}
}
private rule createTypes() {
// create a Relational Type for each UML DataType
foreach (dataType : uml21.DataType in source.getInstances("DataType")) {
var type : relational.Type = target.create("Type");
if (dataType.name.equalsIgnoreCase("int"))
type.name = "INT";
else if (dataType.name.equalsIgnoreCase("string"))
type.name = "VARCHAR(255)";
else
type.name = dataType.name;
dataType#coref.add(type);
}
}
...
The rule createTypes creates a Relational Type for each UML DataType.
In addition, it creates a transient link to keep track
of the mapping between the UML and Relational types.
The statement dataType#coref.add(type) adds
a link from the variable dataType to the variable type
using the transient link named coref (for co-reference).
Having this, we are then able to query the transient links of a DataType (see below).
Change the code of the rule createColumn to:
private rule createTable::createColumn(attribute : uml21.Property,
column : relational.Column) {
// set the name
column.name = attribute.name;
// set the owner of the column
column.owner = table;
// set the type
column.type = attribute.type#coref.first();
}
We ask the coref transient link of the attribute's type,
which returns an MDWList,
and keep only the first value.
If the type of the attribute is not set or if it is not a DataType (so no coref transient link),
the expression attribute.type#coref.first() returns null
due to MDWorkbench null management.
If you relaunch the transformation and browse the Relational output model, you see that the Columns now have associated types.
