The control flow between the tasks can be defined by Unified Modeling Language (UML) activity diagrams using the following schemes:
Sequence
When tasks are arranged in a sequence, a successor task may start just after its predecessor task has been completed. Since the workflow server uses a pull approach, the task does not run immediately after the predecessor has been completed, as this is delayed until a user accepts it (except for automated tasks). The very first task of a process always runs immediately.
Respective elements and attributes of the workflow definition:
successor
attribute of all task XML elements.
Example:
<UserTask name="task1" successor="task2"> . . </UserTask> <UserTask name="task2"> . . </UserTask>
Example 4.2. Example listing of a sequence
Choice
Based upon a condition, the control flow continues at exactly one of two or more followup tasks. This is also called an or-split, since only one task will be performed.
Respective elements of the workflow definition: <If>[<Condition>
,
<Then>
, <Else>], <Switch>[<Case>]
Example:
<UserTask name="task1" successor="choice"> <!-- Code --> </UserTask> <If name="choice"> <Condition> <!-- expr --> </Condition> <Then successor="task2"/> <Else successor="task3"/> </If> <UserTask name="task2" successor="task4"> <!-- Code --> </UserTask> <UserTask name="task3" successor="task4"> <!-- Code --> </UserTask>
Example 4.3. Example listing of a choice
Implicit Choice
If a choice is used (see above), the workflow engine decides where to continue the control flow based on an explicit expression. An implicit choice lets the workflow users decide where to continue, simply by offering two or more user tasks, from which only one may be accepted. As soon as this one task is accepted, the other task(s) is/are automatically withdrawn and may not be accepted anymore. The notation is to draw two or more outgoing control flow edges without a condition inscription. The decision node may be omitted, as in the example diagram.
Respective elements of the workflow definition:
<Choice>[<Successor>]
Example:
<UserTask name="task1" successor="implicitChoice"> <!-- Code --> </UserTask> <Choice name="implicitChoice"> <Successor name="task2"/> <Successor name="task3"/> </Choice> <UserTask name="task2" successor="task4"> <!-- Code --> </UserTask> <UserTask name="task3" successor="task4"> <!-- Code --> </UserTask>
Example 4.4. Example listing of an implicit choice
Loop
The loop is a special case of a choice, where one of the successor tasks is a predecessor of the current task. Thus, a task may be repeatedly performed.
Respective elements of the workflow definition: <If>[<Condition>
,
<Then>
, <Else>]
Example:
<UserTask name="task2" successor="loopCondition"> <!-- Code --> </UserTask> <If name="loopCondition"> <Condition> <!-- expr --> </Condition> <Then successor="task2"/> <Else successor="task3"/> </If> <UserTask name="task3"> <!-- Code --> </UserTask>
Example 4.5. Example listing of a loop
Concurrency/Parallel Execution
After the task before the synchronization bar is completed, all followup tasks are activated. This is called a fork of the control flow. The resynchronization of parallel executing tasks is called a join. This is also called an and-split, since all followup tasks are performed. Each fork must be matched by exactly one join that joins all previously forked tasks.
Respective elements of the workflow definition: <Fork>[
,
<Join>]
Example:
<Fork name="fork"> <Successor name="task2a"/> <Successor name="task3"/> </Fork> <UserTask name="task2a" successor="task2b"> <!-- Code --> </UserTask> <UserTask name="task2b" successor="join"> <!-- Code --> </UserTask> <UserTask name="task3" successor="join"> <!-- Code --> </UserTask> <Join name="join" successor="task4"> <Predecessor name="task2b"/> <Predecessor name="task3"/> </Join>
Example 4.6. Example listing of concurrency