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.