Posted on June 14, 2013 by Paolo Predonzani

What is the simplest way to implement a workflow? The minimum requirements would be a user intereface (one or more buttons) and the application logic (one or more methods that respond to the buttons). The correspondence between button and method is intuitive. In Portofino 4 it is also explicit at the code level through Java annotations.

The following code fragment

@Button(list="crud-read", key="my.label", order=10.0d)
public Resolution myWorkflowAction() {
    /* button logic here*/

is responsible for both the generation of the button and and the logic that is executed when the button is pressed. The secret is in the @Button annotation which specifies the position, label and order, in addition to identifying the method to which it will be attached.

The correspondence between the user interface and the action method is even more evident when the buttons are enabled conditionally. If a certain condition is verified, then the button is displayed and the method is enabled. Otherwise the button must be hidden and the method inhibited from being invoked. In Portofino 4 this is managed by the @Guard annotation:

@Button(list="crud-read", key="my.label", order=10.0d)
public Resolution myWorkflowAction() {
    /* button logic here */

boolean myWorkflowCondition() {
    if (/* condition verified*/)
        return true;
        return false;

The condition myWorkflowCondition() controls both the visualization of the button and the possibility to invoke myWorkflowAction().

In this video I use the CRUD created in the previous tutorial and extend it with a simple workflow based on buttons. I've considered the 'm_product' table, in particular the 'isactive' column. Isactive determines if a product in the catalog is active or not. I've designed a simple workflow where isactive works as the state. If a product is active, I can deactivate it (i.e. exclude it from the catalog of current products), if it is inactive I can re-activate it.

Some highlights from the video

In square brackets is the minute/second which I refer to:

[0:12] In the CRUD, I filter the active products through an HQL query

[1:22] I connect a Java IDE to the running instance of Portofino 4

[3:51] I use the @Button annotation on the deactivate() method

[4:45] I use Hibernate to make state changes persistent

[5:47] I create a new "All products" CRUD as a copy of the "Current catalog" CRUD

[7:49] I use the @Guard annotation to enable/disable the buttons conditionally

[9:38] Internationalization of the buttons' labels


comments powered by Disqus