Understanding Flow Control Statements
Tasks use general statements and expressions to handle specific data flows.
-
The
IfStatement.of(Expression test, Statement thenBranch, Statement elseBranch)
method creates a statement that, when executed, first evaluates thetest
expression. This expression must evaluate to a Boolean value. If it evaluates to true, then thethenBranch
statement is executed; otherwise, theelseBranch
statement is executed. TheIfStatement.of(Expression test, Statement thenBranch)
method is a variant for an empty "else" branch.For example, the following sample task takes a number as input, then uses
IfStatement
to:-
log a different message when the number is odd or even.
-
set the task output value to " odd" or "even".
@Configuration public class Tasks { @Bean public ScriptedTaskDescription evenOrOddTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("evenOrOddTask", "Is that number even or odd?"); VariableAccessExpression n = VariableAccessExpression.of("A number"); NumericExpression zero = NumericExpression.ZERO; NumericExpression two = NumericExpression.of(2); task.getScript() .addStatement(AskInputStatement.of(n.getVariableName(), true, JobInputType.INTEGER)) .addStatement(LogStatement.info(StringExpression.concat(StringExpression.of("Is "), n, StringExpression.of(" even or odd?")))) .addStatement(IfStatement.of(BooleanExpression.eq(NumericExpression.minus(n, NumericExpression.times(NumericExpression.divide(n, two), two)), zero), Block.of( LogStatement.info(StringExpression.concat(n, StringExpression.of(" is even"))), SetTaskOutputStatement.of("Even or odd?", StringExpression.of("even")) ), Block.of( LogStatement.info(StringExpression.concat(n, StringExpression.of(" is odd"))), SetTaskOutputStatement.of("Even or odd?", StringExpression.of("odd")) ))); return task; } }
The generated web client component for this task is the following:
EvenOrOdd
-
-
The
RepeatStatement.of(String loopVariableName, Expression nbLoops, Statement... statements)
method creates a statement that, when executed, first evaluates thenbLoops
expression. This expression must evaluate to a number. Then thestatements
are executed as many times. If a variable name is provided asloopVariableName
, a variable is set with this name to an increasing value on each loop execution, starting with one. If you do not need a loop index variable, you can pass null as the first argument to theof
method.For example, the following task takes a number as input, then uses
RepeatStatement
to compute its factorial; finally, it sets the task output to the result.@Configuration public class Tasks { @Bean public ScriptedTaskDescription factorialTask() { ScriptedTaskDescription task = new ScriptedTaskDescription("FactTask", "Factorial"); VariableAccessExpression n = VariableAccessExpression.of("n"); VariableAccessExpression fact = VariableAccessExpression.of("n!"); VariableAccessExpression index = VariableAccessExpression.of("index"); task.getScript() .addStatement(AskInputStatement.of(n.getVariableName(), true, JobInputType.INTEGER, "The number to compute the factorial of")) .addStatement(SetVariableStatement.of(fact.getVariableName(), NumericExpression.ONE)) .addStatement(RepeatStatement.of(index.getVariableName(), n, SetVariableStatement.of(fact.getVariableName(), NumericExpression.times(fact, index)))) .addStatement(SetTaskOutputStatement.of("result", fact)); return task; } }
Here is an example of job computing 4! = 24.
4! = 24
-
The
ForeachStatement.of(String elementVariableName, Expression elementsExpression, Statement... statements)
method creates a statement that, when executed, first evaluates theelementsExpression
expression. This expression must evaluate to a homogeneous list of values (they must all have the same type). Then for each element in that list, thestatements
are executed. IfelementVariableName
is not null, a variable with this name is set to the current list element during the execution of the statements. ThebreakOnError(boolean)
method can be applied to a for-each statement to set the behavior of the loop if one of the statements in its body terminates with a non-zero exit code. When called withtrue
, the loop will exit on the first (top-level) statement that exits/terminates with a non-zero exit code. When called withfalse
(the default), exit codes do not influence the loop. In all cases, the exit code of the loop is the one of the last executed statement.
Anywhere a statement is expected, and typically as the "then" or "else" branch of an "if" statement, a block can be provided using the Block.of(Statement...)
method.
Note that variables have a global scope, even if first set in a block.
If the execution of a statement terminates normally, i.e. not interrupted by an exception, the statement has an exit code, which is an integer (a Java int
) . As per Unix convention, "zero" means "everything is normal".
Other exit code values must be defined by each statement. In addition:
-
The
NoopStatement.ok()
method creates a statement that, when executed, terminates immediately with exit code zero. -
The
NoopStatement.withExitCode(Expression)
method creates a statement that, when executed, terminates immediately with the value of the provided expression as its exit code. It terminates with an exception if this expression does not evaluate to a number.
If a statement terminates normally, i.e. not interrupted by an exception, and with a non-zero exit code, the execution of the rest of the script is not impacted and the next statement is executed.
However, the script itself can test the exit code of the last executed statement to determine its behavior, using the following expressions:
-
NumericExpression.LAST_STATEMENT_EXIT_CODE
is a numeric expression that, when evaluated, provides the value of the exit code of the last executed statement. -
Statement.OK_EXIT_CODE
is a numeric expression that, when evaluated, yields the exit code of " everything ok", that is, zero. -
BooleanExpression.LAST_STATEMENT_EXIT_CODE_OK
andBooleanExpression.LAST_STATEMENT_EXIT_CODE_NOT_OK
are Boolean expressions that, when evaluated, return respectively "true" or "false" if the exit code of the last executed statement is, respectively, zero or non-zero.
If a statement throws an exception, specific termination statements are executed. For more details, please refer to Section Understanding Job Termination Statements.