Interface IWorkflowExecutor
-
public interface IWorkflowExecutorHandler 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 IWorkflowNodeResultattemptToExecute(WorkflowNode node)For advanced usage only.IWorkflowNodeResultattemptToExecuteChild(WorkflowNode parentNode, int childIndex)For advanced usage only.INormalCompletionResultexecute(WorkflowNode node)Executes the given node.INormalCompletionResultexecuteChild(WorkflowNode parentNode, int childIndex)Executes the given child of the node.booleanexecuteLoopBody(WorkflowNode parentNode, int childIndex)Executes the given child of the given node.booleanisValidControlTransferTarget(WorkflowNode node, IControlTransferringCompletionResult controlTransfer)Whether the node is a valid target for the given control transfer, i.e.booleanisValidControlTransferTarget(WorkflowNode node, IControlTransferringCompletionResult controlTransfer, String... types)Whether the node is a valid target for the given control transfer, i.e.voidloopEnd(WorkflowNode node)Ends a loop started byloopStart().voidloopNext(WorkflowNode node)Moves to the next iteration of a loop started withloopStart().voidloopStart(WorkflowNode node)Begins a new loop.voidpopException()Pops the exception on top of the exception stack, seeIWorkflowVariableHandler.getException(int).default voidprovideExecutionData(WorkflowNode node, INodeExecutionData data)Sets additional data available while the node is executed , which can be accessed viagetExecutionDataForNode(node).voidprovideExecutionData(WorkflowNode node, Iterable<? extends INodeExecutionData> data)Sets additional data available while the node is executed , which can be accessed viagetExecutionDataForNode(node).voidpushException(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 aresultwrapper, 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
executemethod. - 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 aresultwrapper, 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
executemethod. - 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
ExecutionAbortedErrorunless you have a very special reason to do so. Subclasses ofAbstractAbruptCompletionExceptionshould 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
NodeThrewExceptionand delegate control to the error handler. Iteration nodes such as a while-loop block might catchNodeTransferredControlExceptionoftypebreakorcontinueand 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),
nullis returned. - Throws:
AbstractAbruptCompletionException- When the node's execution did not finish normally, see below for subclasses.NodeThrewException- If this exception was thrown by theexecutemethod 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 theexecutemethod 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 theexecutemethod of the given node. Indicates that a control transfer should take place. The matching node for thecontrol transfer targetshould 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 appropriateNodeThrewExceptionwith the details of the exception. When a runtime exception is thrown, it is wrapped in aNodeThrewExceptionand 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
ExecutionAbortedErrorunless you have a very special reason to do so. Subclasses ofAbstractAbruptCompletionExceptionshould 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
NodeThrewExceptionand delegate control to the error handler. Iteration nodes such as a while-loop block might catchNodeTransferredControlExceptionoftypebreakorcontinueand 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),
nullis returned. - Throws:
AbstractAbruptCompletionException- When the node's execution did not finish normally, see below for subclasses.NodeThrewException- If this exception was thrown by theexecutemethod 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 theexecutemethod 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 theexecutemethod of the given node. Indicates that a control transfer should take place. The matching node for thecontrol transfer targetshould 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, useexecuteorexecuteChilddirectly and handle theNodeTransferredControlExceptionexception accordingly.This method handles
NodeTransferredControlExceptionoftypebreakandcontinueby checking whether the loop node is avalid target. If so, this method returnstrueif 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:
trueif the loop body completed normally or abruptly by issuing a continue statement, andfalseotherwise.- 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 thetargetand supports thetransfer type.- Parameters:
node- Node to check against the control transfer.controlTransfer- Control transfer to check against the current node.- Returns:
trueif the given node is a valid target for the given control transfer,falseotherwise.
-
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 thetargetand supports both thetransfer typeas 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:
trueif the given node is a valid target for the given control transfer,falseotherwise.
-
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 childworkflow 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 childworkflow 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 childworkflow 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-catchblock.- 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-catchblock.- 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 giventimingvalue.The given event should either
IFormRecordProvidingEventor 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.
-
-