Add a script to handle relation multiplicity

In the previous step, we generated a Java field for each relation, regardless of its multiplicity. For example the relation items of the Class Order in the sample model has a multiplicity *. Its corresponding Java field type should be java.util.Collection, not LineItem.

The type Relation has an attribute multiplicity that contains this information. We have to update the generation to introduce an if directive to test the multiplicity value for each Relation. If the multiplicity is not equal to 1, we will consider the relation to be multivalued. We could add this logic directly inside the text template, but because the text to generate depends on each Relation, we will introduce two scripts to maintain the readability of the script. A script is a method dynamically added to a metatype.

The first script we will add will be called isMultivalued.

To add a script:

  1. Click File > New > Script.
  2. Type JavaGeneration/src in the Source folder field.
  3. Type tutorial.java in the Package field.
  4. Type rhapsody.Relation in the Type field.
  5. Type isMultivalued in the Name field.
  6. Click MQL in the Language group.

  7. Click Finish.

A file rhapsody_Relation.mqs is created: it allows us to define MQL scripts on the metatype Relation. Change its contents to:

package tutorial.java;

metatype rhapsody.Relation;

public script isMultivalued() : boolean {
    if (self.multiplicity == "1") {
        return false;
    } else {
        return true;
    }
}

The self variable is available in the script contents. This variable is the instance the script is evaluated on (instance of the script's metatype).

Now we will add the javaType script.

  1. Click File > New > Script.
  2. Type JavaGeneration/src in the Source folder field.
  3. Type tutorial.java in the Package field.
  4. Type rhapsody.Relation in the Type field.
  5. Type javaType in the Name field.
  6. Click MQL in the Language group.

  7. Click Finish.

A new script has been created in the rhapsody_Relation.mqs file. Change its contents to:

public script javaType() : String {
    if (self.isMultivalued()) {
        return "java.util.Collection";
    } else {
        // if the otherClass is not set, returns "Object"
        return self.otherClass.name ? "Object";
    }
}

The script behavior is the following:

  1. If the isMultivalued() method answers true, the String "java.util.Collection" is returned.
  2. Otherwise the expression self.otherClass.name is evaluated. The String "Object" is returned if the otherClass reference returns null, due to the default value expression and the null management of RulesComposer.

Now the script javaType can be used in a text template, as you do with any predefined feature of the type Relation (e.g. $(myRelation.javaType}).

Relaunch the generation and open the file Order.java:

public class Order {

    private RhpString date;

    private Customer customer;
    private java.util.Collection items;
}

Next Section: Call the script from the template
Prev Section: Add a field for relations

Related reference
method call
default value expression
null management