loading table of contents...

4.1.5. Flow Control

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.

Example of a sequence diagram

Figure 4.5. Example of a sequence diagram


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.

Example of a choice diagram

Figure 4.6. Example of a choice diagram


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.

Example of an implicit choice

Figure 4.7. Example of an implicit choice


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.

Example of a loop

Figure 4.8. Example of a loop


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.

Example of a concurrency diagram

Figure 4.9. Example of a concurrency diagram


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