Enum for condition C01

invoice total c01 value table

Starting point

2 methods are gene­ra­ted by default for condition C01 for the first two condition values:

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * <b>C01/01: &lt; 20.00 - low</b>
 */
boolean isPurchaseOrderValue_Less2000();

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * <b>C01/02: 20.00 - 75.00 - normal</b>
 */
boolean isPurchaseOrderValue_20007500();

One method should only be gene­ra­ted now and values transferred as enums for this condition.

Extending the configuration

Since these configuration extensions are intended specifically for the decision table, they are defined for the decision table in a new configuration file for decision table. It has the same name as the decision table, however, with the extension ".yaml":

The configuration file for the deci­sion ta­ble resources/lfet/demo/invoicetotal.lfet.yaml contains thus new entries:
lfet:                          # 1)

  ide.java:

    interface.enum:            # 2)
      1:
        symbol: Interval
        include.tags.title: purchase order
        exclude.tags.title: discount

The entries in detail

1)  lfet:

The base entry in all YAML confi­gura­tion files for LF‑ET.

1:

Enum definitions are numbered, enum de­fi­ni­tion no. 1 starts here

symbol: interval

Enum should contain the symbol of a value, in addition, an interval is to be derived from the symbol in each case (lower and upper limit), including the matching getter and valuation methods.

include.tags.title: purchase order

A list of key­words of which at least one must appear in the title of the condition or action so that this enum de­fi­ni­tion is used during ge­ne­ra­tion.

C01 and C04 match the purchase order.:

invoice total 03

exclude.tags.title: discount

A list of key­words of which none is allowed to appear in the title of the condition or action so that this enum de­fi­ni­tion is used during ge­ne­ra­tion.

C04 is excluded with discount.
 

A matter of taste:

  • Since the lists of parameters (interval, order value, discount) only contain one element each time in this example, these were simply specified here as an argument

  • If the lists contain more than one element you can choose in LF‑ET whether elements of the list

    • are to be presented as a YAML enumeration, i.e. each preceded by a minus sign in a separate line,

    • or be separated with a comma as an argument in one line.

Results for C01

Only one method left

  • No longer a method for every condition value

  • But only one method for the condition

  • Values are passed as an enum in each case

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * The enum generation has been triggered in project.ini by:<br>
 * - <b>ide.java.interface.enum.1</b>: symbol=Interval; include.tags.title=purchase order; exclude.tags.title=discount
 */
boolean isEnum(InvoiceTotal_iFace.PurchaseOrderValue arg0);

 

An enum

  • An enum value for every condition value

  • For conditions not for the last value (here >75), since an ELSE branch is always gene­rated for this

  • If all values are required in the application, it can be determined with the key interface.enum​.options: allValues

  • In addition, in this example technical in­for­ma­tion is taken over from the deci­sion ta­ble during ge­ne­ra­tion:

    • value symbol as a string

    • upper and lower limits of intervals

    • including the associated GETTER and evaluation methods

  • Tech­nical data can be automa­tically machine processed

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * The enum generation has been triggered in project.ini by:<br>
 * - <b>ide.java.interface.enum.1</b>: symbol=Interval; include.tags.title=purchase order; exclude.tags.title=discount
 */
enum PurchaseOrderValue
{
    /**
     * <b>C01: Purchase order value</b><br>
     * <br>
     * <b>C01/01: &lt; 20.00 - low</b>
     */
    $001("< 20.00", Double.NEGATIVE_INFINITY, 19.99),

    /**
     * <b>C01: Purchase order value</b><br>
     * <br>
     * <b>C01/02: 20.00 - 75.00 - normal</b>
     */
    $002("20.00 - 75.00", 20.0, 75.0);

    private final String symbol;
    private final double symbolMin;
    private final double symbolMax;

    PurchaseOrderValue(String symbol, double symbolMin, double symbolMax)
    {
        this.symbol = symbol;
        this.symbolMin = symbolMin;
        this.symbolMax = symbolMax;
    }

    public String getSymbol()
    {
        return symbol;
    }

    public double getSymbolMin()
    {
        return symbolMin;
    }

    public double getSymbolMax()
    {
        return symbolMax;
    }

    public boolean isInSymbolInterval(double d)
    {
        return d >= symbolMin && d <= symbolMax;
    }

    public boolean isInSymbolInterval(int i)
    {
        return i >= symbolMin && i <= symbolMax;
    }
}

 

Implementation adjustment

This is the only manual adjustment, all the others are generated automatically.

Previously: 2 methods for C01

In the original version, 2 methods still had to be implemented for condition C01:

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * <b>C01/01: &lt; 20.00 - low</b>
 */
@Override
public boolean isPurchaseOrderValue_Less2000() {
    return model.getOrderValue().compareTo(bigDecimal(20.00)) < 0;
}

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * <b>C01/02: 20.00 - 75.00 - normal</b>
 */
@Override
public boolean isPurchaseOrderValue_20007500() {
    return model.getOrderValue().compareTo(bigDecimal(20.00)) >= 0 &&
            model.getOrderValue().compareTo(bigDecimal(75.00)) <= 0;
}

vertical space 05px

Now: Only one method

Thanks to enum generation only one method is necessary now.

/**
 * <b>C01: Purchase order value</b><br>
 * <br>
 * The enum generation has been triggered in project.ini by:<br>
 * - <b>ide.java.interface.enum.1</b>: symbol=Interval; include.tags.title=purchase order; exclude.tags.title=discount
 */
@Override
public boolean isEnum(InvoiceTotal_iFace.PurchaseOrderValue arg0) {
    return model.getOrderValue().compareTo(bigDecimal(arg0.getSymbolMin())) >= 0 &&
            model.getOrderValue().compareTo(bigDecimal(arg0.getSymbolMax())) <= 0;
}

vertical space 05px

Automatically customized method calls in the rules module

if (iface.isEnum(InvoiceTotal_iFace.PurchaseOrderValue.$001)) // < 20.00 - low
{
    // Rule R01 ---->

    iface.doTrace("InvoiceTotal", "20260215.065057", 7, 1);

    iface.doCalculateShippingCosts();
    iface.doInvoiceTotal_Upd();

    // Rule R01 <----
}
else if (iface.isEnum(InvoiceTotal_iFace.PurchaseOrderValue.$002)) // 20.00 - 75.00 - normal
{
    if (iface.isDiscount_Greater0())
    {

Advantages

  • Implementation and maintenance of methods for conditions and actions is considerably more efficient with enums:

    • instead of one implementation per value

    • now only one implementation per condition or action

  • In many cases, technical changes to the values in the deci­sion ta­ble can be mapped purely via the enums and the rules module so that implementation of methods is not affected

    • changing numerical values or other content

    • new or deleted values

    • etc.

  • Technical data, such as numbers, number series, intervals, texts, etc., can be transferred to the appli­cation securely and efficiently during gene­ra­tion.