Author: alex.guizar(a)jboss.com
Date: 2010-06-10 08:36:42 -0400 (Thu, 10 Jun 2010)
New Revision: 6399
Modified:
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/concurrency/foreach/ForEachTest.java
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/concurrency/foreach/process.jpdl.xml
jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
Log:
JBPM-2414: document foreach activity
Modified:
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/concurrency/foreach/ForEachTest.java
===================================================================
---
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/concurrency/foreach/ForEachTest.java 2010-06-10
11:10:39 UTC (rev 6398)
+++
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/concurrency/foreach/ForEachTest.java 2010-06-10
12:36:42 UTC (rev 6399)
@@ -24,6 +24,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.task.Task;
@@ -74,14 +75,11 @@
}
public void testForEachCompleteAll() {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("departments", new String[] { "sales-dept",
"hr-dept", "finance-dept" });
+ variables.put("quorum", 3);
- HashMap<String, Object> variables = new HashMap<String, Object>();
- variables.put("listOfDepartments", new String[] { "sales-dept",
"hr-dept", "finance-dept" });
- variables.put("joinAt", 3);
-
- ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ForEachFork", variables);
- String processInstanceId = processInstance.getId();
-
+ ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ForEach", variables);
// there should be 3 forked executions - same as number of departments
assertEquals(3, processInstance.getExecutions().size());
@@ -119,18 +117,15 @@
taskService.completeTask(taskListFinance.get(0).getId());
Date endTime =
historyService.createHistoryProcessInstanceQuery().processInstanceId(processInstance.getId()).uniqueResult().getEndTime();
-
assertNotNull(endTime);
}
public void testForEachCompleteAfterTwoJoined() {
+ Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("departments", new String[] { "sales-dept",
"hr-dept", "finance-dept" });
+ variables.put("quorum", 2);
+ ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ForEach", variables);
- HashMap<String, Object> variables = new HashMap<String, Object>();
- variables.put("listOfDepartments", new String[] { "sales-dept",
"hr-dept", "finance-dept" });
- variables.put("joinAt", 2);
-
- ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ForEachFork", variables);
-
// there should be 3 forked executions - same as number of departme!
nts
assertEquals(3, processInstance.getExecutions().size());
@@ -160,7 +155,6 @@
taskService.completeTask(taskListSales.get(0).getId());
Date endTime =
historyService.createHistoryProcessInstanceQuery().processInstanceId(processInstance.getId()).uniqueResult().getEndTime();
-
assertNotNull(endTime);
}
}
Modified:
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/concurrency/foreach/process.jpdl.xml
===================================================================
---
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/concurrency/foreach/process.jpdl.xml 2010-06-10
11:10:39 UTC (rev 6398)
+++
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/concurrency/foreach/process.jpdl.xml 2010-06-10
12:36:42 UTC (rev 6399)
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
-<process name="ForEachFork"
xmlns="http://jbpm.org/4.3/jpdl">
+<process name="ForEach"
xmlns="http://jbpm.org/4.4/jpdl">
<start g="28,61,48,48" name="start1">
<transition to="foreach1"/>
</start>
- <foreach var="department" in="#{listOfDepartments}"
g="111,60,48,48" name="foreach1">
+ <foreach var="department" in="#{departments}"
g="111,60,48,48" name="foreach1">
<transition to="Collect data"/>
</foreach>
<task candidate-groups="#{department}" g="201,58,92,52"
name="Collect data">
<transition to="join1"/>
</task>
- <join g="343,59,48,48" multiplicity="#{joinAt}"
name="join1">
+ <join g="343,59,48,48" multiplicity="#{quorum}"
name="join1">
<transition to="end1"/>
</join>
<end g="433,60,48,48" name="end1"/>
Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml 2010-06-10
11:10:39 UTC (rev 6398)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch06-Jpdl.xml 2010-06-10
12:36:42 UTC (rev 6399)
@@ -495,9 +495,43 @@
<section id="concurrency">
<title><literal>concurrency</literal></title>
- <para>With the <literal>fork</literal> and
<literal>join</literal> activities,
- concurrent paths of executions can be modeled.
- </para>
+ <para>With the <literal>fork</literal>,
<literal>foreach</literal> and
+ <literal>join</literal> activities, concurrent paths of executions can
be modeled.
+ The next two tables describe the <literal>foreach</literal> and
<literal>join</literal>
+ attributes; <literal>fork</literal> has no specific
attributes.</para>
+ <table><title><literal>foreach</literal>
attributes:</title>
+ <tgroup cols="5" rowsep="1" colsep="1">
+ <thead>
+ <row>
+ <entry>Attribute</entry>
+ <entry>Type</entry>
+ <entry>Default</entry>
+ <entry>Required?</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>in</literal></entry>
+ <entry>expression or text</entry>
+ <entry></entry>
+ <entry>required</entry>
+ <entry>The collection to be iterated. Each item in the collection
spawns a new
+ concurrent execution leaving over the default transition.
<literal>in</literal>
+ supports collections of any kind, arrays and comma separated
strings.</entry>
+ </row>
+ <row>
+ <entry><literal>var</literal></entry>
+ <entry>text</entry>
+ <entry></entry>
+ <entry>required</entry>
+ <entry>The variable where the current item of the collection is
stored.
+ This variable is set in the concurrent execution and is visible only to
that
+ execution.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
<table><title><literal>join</literal>
attributes:</title>
<tgroup cols="5" rowsep="1" colsep="1">
<thead>
@@ -512,7 +546,7 @@
<tbody>
<row>
<entry><literal>multiplicity</literal></entry>
- <entry>integer</entry>
+ <entry>integer or expression</entry>
<entry>nbr of incoming transitions</entry>
<entry>optional</entry>
<entry>The number of executions that should arrive in this join
@@ -533,14 +567,17 @@
</tbody>
</tgroup>
</table>
- <para>For example:</para>
- <figure id="process.concurrency">
- <title>The concurrency example process</title>
- <mediaobject><imageobject><imagedata align="center"
fileref="images/process.concurrency.png"/></imageobject></mediaobject>
- </figure>
-
- <programlisting><process
name="ConcurrencyGraphBased"
xmlns="http://jbpm.org/4.3/jpdl">
+ <section>
+ <title>Parallel split with
<literal>fork</literal></title>
+ <para>The <literal>fork</literal> activity allows a single path
of execution to be
+ split into two or more branches which can execute activities
concurrently.</para>
+ <figure id="process.concurrency">
+ <title>Parallel split example process</title>
+ <mediaobject><imageobject><imagedata align="center"
fileref="images/process.concurrency.png"/></imageobject></mediaobject>
+ </figure>
+ <programlisting><process
name="ConcurrencyGraphBased"
xmlns="http://jbpm.org/4.3/jpdl">
+
<start>
<transition to="fork"/>
</start>
@@ -578,6 +615,50 @@
<end name="end" />
</process></programlisting>
+ </section>
+
+ <section>
+ <title>Iterative split with
<literal>foreach</literal></title>
+ <para>At a given point in a process, several paths of execution can be
initiated
+ in a single branch of the same process instance. In the example, there is a need
+ to collect time sheet reports (called data) from different departments. With
+ <literal>foreach</literal> this can be quite easily achieved. The
same task
+ is to be performed by different groups. Process variable
<literal>departments</literal>
+ provides the group names, whereas the variable
<literal>quota</literal> indicates
+ how many tasks must be completed before execution will leave the
<literal>join</literal>
+ activity.</para>
+ <programlisting><![CDATA[<process name="ForEach"
xmlns="http://jbpm.org/4.4/jpdl">
+
+ <start g="28,61,48,48" name="start1">
+ <transition to="foreach1"/>
+ </start>
+
+ <foreach var="department" in="#{departments}"
g="111,60,48,48" name="foreach1">
+ <transition to="Collect data"/>
+ </foreach>
+
+ <task candidate-groups="#{department}" g="201,58,92,52"
name="Collect data">
+ <transition to="join1"/>
+ </task>
+
+ <join g="343,59,48,48" multiplicity="#{quorum}"
name="join1">
+ <transition to="end1"/>
+ </join>
+
+ <end g="433,60,48,48" name="end1"/>
+
+</process>]]></programlisting>
+ <important><para>When using foreach, the corresponding join must have
the
+ multiplicity attribute set. In general, join continues execution based on its
+ incoming transitions. When using foreach, join has a single incoming transition.
+ If multiplicity is not specified, the first execution that reaches the join
+ activity will trigger continuation.</para></important>
+ <para>Here is how to initialize the iterative process
variables.</para>
+ <programlisting><![CDATA[Map<String, Object> variables = new
HashMap<String, Object>();
+variables.put("departments", new String[] { "sales-dept",
"hr-dept", "finance-dept" });
+variables.put("quorum", 3);
+ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ForEach",
variables);]]></programlisting>
+ </section>
</section>
<!-- ### END ########################################################### -->