Interface IWorkflowExecutor
-
public interface IWorkflowExecutor
Handler for affecting how the workflow is executed. Contains method to run other nodes during the execution of a task, methods for triggering other events, and methods for special flow control operations such as looping and exception stack handling.- Since:
- 7.0.0
- Author:
- XIMA MEDIA GmbH
-
-
Method Summary
All Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description IWorkflowNodeResult
attemptToExecute(WorkflowNode node)
For advanced usage only.IWorkflowNodeResult
attemptToExecuteChild(WorkflowNode parentNode, int childIndex)
For advanced usage only.INormalCompletionResult
execute(WorkflowNode node)
Executes the given node.INormalCompletionResult
executeChild(WorkflowNode parentNode, int childIndex)
Executes the given child of the node.boolean
executeLoopBody(WorkflowNode parentNode, int childIndex)
Executes the given child of the given node.boolean
isValidControlTransferTarget(WorkflowNode node, IControlTransferringCompletionResult controlTransfer)
Whether the node is a valid target for the given control transfer, i.e.boolean
isValidControlTransferTarget(WorkflowNode node, IControlTransferringCompletionResult controlTransfer, String... types)
Whether the node is a valid target for the given control transfer, i.e.void
loopEnd(WorkflowNode node)
Ends a loop started byloopStart()
.void
loopNext(WorkflowNode node)
Moves to the next iteration of a loop started withloopStart()
.void
loopStart(WorkflowNode node)
Begins a new loop.void
popException()
Pops the exception on top of the exception stack, seeIWorkflowVariableHandler.getException(int)
.default void
provideExecutionData(WorkflowNode node, INodeExecutionData data)
Sets additional data available while the node is executed , which can be accessed viagetExecutionDataForNode(node)
.void
provideExecutionData(WorkflowNode node, Iterable<? extends INodeExecutionData> data)
Sets additional data available while the node is executed , which can be accessed viagetExecutionDataForNode(node)
.void
pushException(NodeThrewException exception)
Pushes the given exception to the exception stack, seeIWorkflowVariableHandler.getException(int)
.List<IWorkflowQueueItem>
triggerEvent(IWorkflowEventData event, EWorkflowEventLoopTiming timing)
Triggers the given event.
-
-
-
Method Detail
-
attemptToExecute
IWorkflowNodeResult attemptToExecute(WorkflowNode node)
For advanced usage only. Similar toexecute
, see their for more details. This method wraps the outcome in aresult
wrapper, never throwing when the node completes abruptly.Usually you should use
execute
, this method is intended for advanced use cases when you need to handle different completion types, such as needed by try-catch-finally statements.- Parameters:
node
- The node to execute.- Returns:
- A wrapped result with either the normal or abrupt completion result from the
execute
method. - Throws:
ExecutionAbortedError
- When the execution of the task was aborted, such as when certain limits were exceeded. Usually you should not catch this exception and allow it to propagate upwards.- Since:
- 8.1.0
- See Also:
execute(WorkflowNode)
-
attemptToExecuteChild
IWorkflowNodeResult attemptToExecuteChild(WorkflowNode parentNode, int childIndex)
For advanced usage only. Similar toexecuteChild
, see their for more details. This method wraps the outcome in aresult
wrapper, never throwing when the node completes abruptly.Usually you should use
executeChild
, this method is intended for advanced use cases when you need to handle different completion types, such as needed by try-catch-finally statements.- Parameters:
parentNode
- A node with one or more children.childIndex
- 0-based index of the child to execute- Returns:
- A wrapped result with either the normal or abrupt completion result from the
execute
method. - Throws:
ExecutionAbortedError
- When the execution of the task was aborted, such as when certain limits were exceeded. Usually you should not catch this exception and allow it to propagate upwards.- Since:
- 8.1.0
- See Also:
executeChild(WorkflowNode, int)
-
execute
@Nullable INormalCompletionResult execute(WorkflowNode node) throws AbstractAbruptCompletionException
Executes the given node. This should be used by workflow nodes that contain children, such as selection nodes (if-else, switch etc), iteration nodes (for-each-loop, while-loop, etc.), or error handler nodes (try-catch block etc.).Loops are allowed in general - but execution may be terminated when a certain limit (instruction count or time-based) is reached.
Please note that you should usually NOT catch
ExecutionAbortedError
unless you have a very special reason to do so. Subclasses ofAbstractAbruptCompletionException
should also not be caught usually, but certain subclasses may be caught by control flow nodes.For example, an error handling node like a try-catch block might catch
NodeThrewException
and delegate control to the error handler. Iteration nodes such as a while-loop block might catchNodeTransferredControlException
oftype
break
orcontinue
and adjust the loop execution accordingly. Simple action nodes, or selection nodes such as an if-else or switch block, should not catch any errors and simply allow any exceptions thrown by child nodes to propagate upwards.- Parameters:
node
- The node to execute.- Returns:
- The result returned by the given node. In case the execution of the node was skipped (such as because the
node is not active),
null
is returned. - Throws:
AbstractAbruptCompletionException
- When the node's execution did not finish normally, see below for subclasses.NodeThrewException
- If this exception was thrown by theexecute
method of the given node. Indicates that a node could not be completed successfully. This exception can be caught by control flow nodes with custom error handling, such as a try-catch node.NodeReturnedException
- If this exception was thrown by theexecute
method of the given node. Indicates that the node wishes to return, i.e. to stop the execution of the current processing chain (="function"). This exception can be caught by control flow nodes with custom finalization handling, such as a try-finally node (which should rethrow this exception afterwards).NodeTransferredControlException
- If this exception was thrown by theexecute
method of the given node. Indicates that a control transfer should take place. The matching node for thecontrol transfer target
should catch this exception and proceed according to thetype of the control transfer
.ExecutionAbortedError
- When the execution of the task was aborted, such as when certain limits were exceeded. Usually you should not catch this exception and allow it to propagate upwards.RuntimeException
- A runtime exception may be thrown to indicate an unforeseen error, such as general database errors. For all errors you expect to happen, you should throw an appropriateNodeThrewException
with the details of the exception. When a runtime exception is thrown, it is wrapped in aNodeThrewException
and treated as if that exception had been thrown.- See Also:
executeChild(WorkflowNode, int)
-
executeChild
@Nullable INormalCompletionResult executeChild(WorkflowNode parentNode, int childIndex) throws AbstractAbruptCompletionException
Executes the given child of the node. This should be used by workflow nodes that contain children, such as selection nodes (if-else, switch etc), iteration nodes (for-each-loop, while-loop etc), or error handler nodes (try-catch block etc.).Loops are allowed in general - but execution may be terminated when a certain limit (instruction count or time-based) is reached.
Please note that you should usually NOT catch
ExecutionAbortedError
unless you have a very special reason to do so. Subclasses ofAbstractAbruptCompletionException
should also not be caught usually, but certain subclasses may be caught by control flow nodes.For example, an error handling node like a try-catch block might catch
NodeThrewException
and delegate control to the error handler. Iteration nodes such as a while-loop block might catchNodeTransferredControlException
oftype
break
orcontinue
and adjust the loop execution accordingly. Simple action nodes, or selection nodes such as an if-else or switch block, should not catch any errors and simply allow any exceptions thrown by child nodes to propagate upwards.- Parameters:
parentNode
- A node with one or more children.childIndex
- 0-based index of the child to execute- Returns:
- The result returned by the given node. In case the execution of the node was skipped (such as because the
node is not active),
null
is returned. - Throws:
AbstractAbruptCompletionException
- When the node's execution did not finish normally, see below for subclasses.NodeThrewException
- If this exception was thrown by theexecute
method of the given node. Indicates that a node could not be completed successfully. This exception can be caught by control flow nodes with custom error handling, such as a try-catch node.NodeReturnedException
- If this exception was thrown by theexecute
method of the given node. Indicates that the node wishes to return, i.e. to stop the execution of the current processing chain (="function"). This exception can be caught by control flow nodes with custom finalization handling, such as a try-finally node (which should rethrow this exception afterwards).NodeTransferredControlException
- If this exception was thrown by theexecute
method of the given node. Indicates that a control transfer should take place. The matching node for thecontrol transfer target
should catch this exception and proceed according to thetype of the control transfer
.ExecutionAbortedError
- When the execution of the task was aborted, such as when certain limits were exceeded. Usually you should not catch this exception and allow it to propagate upwards.- See Also:
execute(WorkflowNode)
-
executeLoopBody
boolean executeLoopBody(WorkflowNode parentNode, int childIndex) throws AbstractAbruptCompletionException
Executes the given child of the given node. This is a convenience method intended only for iteration nodes that wish to execute the child representing the loop body. If you need more control, useexecute
orexecuteChild
directly and handle theNodeTransferredControlException
exception accordingly.This method handles
NodeTransferredControlException
oftype
break
andcontinue
by checking whether the loop node is avalid target
. If so, this method returnstrue
if the node completed normally or abruptly by issuing a continue statement; and false if then node completed abruptly by issuing a break statement. Otherwise the exception is propagated upwards.- Parameters:
parentNode
- The loop node with a loop body.childIndex
- Index of the node representing the loop body.- Returns:
true
if the loop body completed normally or abruptly by issuing a continue statement, andfalse
otherwise.- Throws:
AbstractAbruptCompletionException
- When the node's execution did not finish normally, other than by issuing a break or continue statement that targets the given parent node.ExecutionAbortedError
- When the execution of the task was aborted, such as when certain limits were exceeded. Usually you should not catch this exception and allow it to propagate upwards.
-
isValidControlTransferTarget
boolean isValidControlTransferTarget(WorkflowNode node, IControlTransferringCompletionResult controlTransfer)
Whether the node is a valid target for the given control transfer, i.e. whether it matches thetarget
and supports thetransfer type
.- Parameters:
node
- Node to check against the control transfer.controlTransfer
- Control transfer to check against the current node.- Returns:
true
if the given node is a valid target for the given control transfer,false
otherwise.
-
isValidControlTransferTarget
boolean isValidControlTransferTarget(WorkflowNode node, IControlTransferringCompletionResult controlTransfer, String... types)
Whether the node is a valid target for the given control transfer, i.e. whether it matches thetarget
and supports both thetransfer type
as well as one of the given types.- Parameters:
node
- Node to check against the control transfer.controlTransfer
- Control transfer to check against the current node.types
- Types to which to limit the check.- Returns:
true
if the given node is a valid target for the given control transfer,false
otherwise.
-
loopEnd
void loopEnd(WorkflowNode node)
Ends a loop started byloopStart()
. Each call toloopStart()
must be followed with a call toloopEnd
.loopNext()
must be called in between.The intended flow for executing a loop is as follows:
- Call loopStart() to initialize the loop
- Repeat for each loop iteration
- Optionally, set additionally data accessible during the execution of the loop node via
params.currentValue()
. Data provided viacurrentValue().withBuilder(...)
can be accessed by other other nodes in the workflow designer via placeholders, such as the current index or the current iteration value. Data provided viaprovideExecutionData()
can be accessed internally e.g. by placeholder replacer plugins. Execute the child
workflow node which should be run for the loop iteration.- Call loopNext() before the next loop iteration to increment the index.
- Optionally, set additionally data accessible during the execution of the loop node via
- Always call loopEnd() once the loop is done. Usually this should be done inside a
finally {}
block.
- Parameters:
node
- The node which controls the loop, e.g. a while-loop node or a for-of-loop node.- Throws:
IllegalStateException
- When no loop is active, e.g. loopEnd() was already called at least as often as loopStart() was called.- Since:
- 8.1.0
-
loopNext
void loopNext(WorkflowNode node)
Moves to the next iteration of a loop started withloopStart()
. Must be called after a loop iteration is done, before the next one starts to increment the index.The intended flow for executing a loop is as follows:
- Call loopStart() to initialize the loop
- Repeat for each loop iteration
- Optionally, set additionally data accessible during the execution of the loop node via
params.currentValue()
. Data provided viacurrentValue().withBuilder(...)
can be accessed by other other nodes in the workflow designer via placeholders, such as the current index or the current iteration value. Data provided viaprovideExecutionData()
can be accessed internally e.g. by placeholder replacer plugins. Execute the child
workflow node which should be run for the loop iteration.- Call loopNext() before the next loop iteration to increment the index.
- Optionally, set additionally data accessible during the execution of the loop node via
- Always call loopEnd() once the loop is done. Usually this should be done inside a
finally {}
block.
- Parameters:
node
- The node which controls the loop, e.g. a while-loop node or a for-of-loop node.- Throws:
IllegalStateException
- When no loop is active, e.g. loopEnd() was already called at least as often as loopStart() was called.- Since:
- 8.1.0
-
loopStart
void loopStart(WorkflowNode node)
Begins a new loop. Should be called by control flow nodes such as while or for-of loops before executing the loop children.loopEnd()
must be called once the loop body is done, andloopNext()
must be called in between.The intended flow for executing a loop is as follows:
- Call loopStart() to initialize the loop
- Repeat for each loop iteration
- Optionally, set additionally data accessible during the execution of the loop node via
params.currentValue()
. Data provided viacurrentValue().withBuilder(...)
can be accessed by other other nodes in the workflow designer via placeholders, such as the current index or the current iteration value. Data provided viaprovideExecutionData()
can be accessed internally e.g. by placeholder replacer plugins. Execute the child
workflow node which should be run for the loop iteration.- Call loopNext() before the next loop iteration to increment the index.
- Optionally, set additionally data accessible during the execution of the loop node via
- Always call loopEnd() once the loop is done. Usually this should be done inside a
finally {}
block.
- Parameters:
node
- The node which controls the loop, e.g. a while-loop node or a for-of-loop node.- Throws:
IllegalStateException
- When loopStart() was previously called and not yet followed-up by a call to loopNext() or loopEnd().- Since:
- 8.1.0
-
popException
void popException()
Pops the exception on top of the exception stack, seeIWorkflowVariableHandler.getException(int)
. This method should only be used by workflow nodes that represent atry-catch
block.- Since:
- 8.1.0
-
provideExecutionData
default void provideExecutionData(WorkflowNode node, INodeExecutionData data)
Sets additional data available while the node is executed , which can be accessed viagetExecutionDataForNode(node)
. When called with a node that is currently not being executed, this is a no-op.You can set multiple data objects for the same node. Each call to this method clears the existing data and sets the data to a singleton set. Execution data is cleared when a node finishes execution.
- Parameters:
node
- Node for which to set the data.data
- Data associated with the node's execution.- Since:
- 8.2.0
-
provideExecutionData
void provideExecutionData(WorkflowNode node, Iterable<? extends INodeExecutionData> data)
Sets additional data available while the node is executed , which can be accessed viagetExecutionDataForNode(node)
. When called with a node that is currently not being executed, this is a no-op.You can set multiple data objects for the same node. Each call to this method clears the existing data and sets the data to the given set. Execution data is cleared when a node finishes execution.
- Parameters:
node
- Node for which to set the data.data
- Data associated with the node's execution.- Since:
- 8.2.0
-
pushException
void pushException(NodeThrewException exception)
Pushes the given exception to the exception stack, seeIWorkflowVariableHandler.getException(int)
. This method should only be used by workflow nodes that represent atry-catch
block.- Parameters:
exception
- Exception to push to the stack.- Since:
- 8.1.0
-
triggerEvent
List<IWorkflowQueueItem> triggerEvent(IWorkflowEventData event, EWorkflowEventLoopTiming timing) throws WorkflowEventRunnerException
Triggers the given event. This method returns immediately, the tasks are run either after the current task is done, or after all tasks are done, depending on the giventiming
value.The given event should either
IFormRecordProvidingEvent
or otherwise make sure it applies only to the current form record that is being processed.The given events are assumed to have occurred simultaneously. Therefore, when a multiple triggers of a task react to the given events, the task is run only once.
- Parameters:
event
- Events that has occurred.timing
- Whether the events should be processed immediately, or later.- Returns:
- A list of all workflow tasks that were added to the event queue.
- Throws:
WorkflowEventRunnerException
- When the event could not be added to the queue, such as due to a database failure when trying to find matching tasks etc. Also thrown when the event applies to a form record different from the one currently being processed.
-
-