JBoss JBPM SVN: r6164 - projects/migration_tool/trunk.
by do-not-reply@jboss.org
Author: eschabell
Date: 2010-02-05 05:50:17 -0500 (Fri, 05 Feb 2010)
New Revision: 6164
Added:
projects/migration_tool/trunk/readme.txt
Log:
Added initial placeholder readme file.
Added: projects/migration_tool/trunk/readme.txt
===================================================================
--- projects/migration_tool/trunk/readme.txt (rev 0)
+++ projects/migration_tool/trunk/readme.txt 2010-02-05 10:50:17 UTC (rev 6164)
@@ -0,0 +1,5 @@
+This is the start sign for the jBPM migration tool that should provide us with a path to migrate from jBPM v3.2.x jPDL -> BPMN2 as
+supported in jBPM v4.x. Stay tuned as this will be expanded with the projects guidelines and goals.
+
+Eric D. Schabell
+
16 years, 2 months
JBoss JBPM SVN: r6163 - projects/migration_tool.
by do-not-reply@jboss.org
Author: eschabell
Date: 2010-02-05 05:43:51 -0500 (Fri, 05 Feb 2010)
New Revision: 6163
Added:
projects/migration_tool/branches/
Log:
Setup initial project directory structure.
16 years, 2 months
JBoss JBPM SVN: r6162 - projects/migration_tool.
by do-not-reply@jboss.org
Author: eschabell
Date: 2010-02-05 05:41:01 -0500 (Fri, 05 Feb 2010)
New Revision: 6162
Added:
projects/migration_tool/tags/
Log:
Setup initial project directory structure.
16 years, 2 months
JBoss JBPM SVN: r6161 - projects/migration_tool.
by do-not-reply@jboss.org
Author: eschabell
Date: 2010-02-05 05:38:07 -0500 (Fri, 05 Feb 2010)
New Revision: 6161
Added:
projects/migration_tool/trunk/
Log:
Setup initial project directory structure.
16 years, 2 months
JBoss JBPM SVN: r6160 - projects.
by do-not-reply@jboss.org
Author: eschabell
Date: 2010-02-05 05:37:29 -0500 (Fri, 05 Feb 2010)
New Revision: 6160
Added:
projects/migration_tool/
Log:
Setup initial project directory structure.
16 years, 2 months
JBoss JBPM SVN: r6158 - jbpm4/trunk/modules/userguide/src/main/docbook/en/modules.
by do-not-reply@jboss.org
Author: koen.aers(a)jboss.com
Date: 2010-02-03 11:22:58 -0500 (Wed, 03 Feb 2010)
New Revision: 6158
Modified:
jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml
Log:
Document how getWebServiceHost and getWebServicePort have to be configured: JBPM-2562
Modified: jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml
===================================================================
--- jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml 2010-02-03 13:19:58 UTC (rev 6157)
+++ jbpm4/trunk/modules/userguide/src/main/docbook/en/modules/ch09-Configuration.xml 2010-02-03 16:22:58 UTC (rev 6158)
@@ -28,6 +28,29 @@
</section>
<section>
+
+ <title>Console</title>
+ <para>By default the server host and port of the console
+ webapplication are respectively <literal>localhost</literal>
+ and <literal>8080</literal>. It is not hard to imagine
+ situations where it is needed to change those defaults.
+ Hence they are made configurable. To customize,
+ change the values of the default configuration
+ (e.g. in the file "jbpm.console.cfg.xml")
+ and replace them with the values you want.</para>
+
+ <programlisting><jbpm-configuration>
+
+ <process-engine-context>
+ <string name="jbpm.console.server.host" value="myNewHost">
+ <string name="jbpm.console.server.port" value="9191">
+ </process-engine-context>
+
+</jbpm-configuration></programlisting>
+
+ </section>
+
+ <section>
<title>Email</title>
<para>TODO document supported config customization
of the jbpm.mail.properties</para>
16 years, 2 months
JBoss JBPM SVN: r6157 - in jbpm4/trunk/modules: bpmn/src/main/java/org/jbpm/bpmn/parser and 3 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-02-03 08:19:58 -0500 (Wed, 03 Feb 2010)
New Revision: 6157
Added:
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.collapsed.subprocess.png
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.embedded.subprocess.png
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.nested.png
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.parallel.paths.png
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.two.endevents.png
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessBinding.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java
Log:
JBPM-2740: added doc/example for embedded subprocess
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java 2010-02-02 17:32:58 UTC (rev 6156)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java 2010-02-03 13:19:58 UTC (rev 6157)
@@ -29,7 +29,6 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.api.model.Activity;
-import org.jbpm.api.model.OpenExecution;
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessBinding.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessBinding.java 2010-02-02 17:32:58 UTC (rev 6156)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessBinding.java 2010-02-03 13:19:58 UTC (rev 6157)
@@ -69,7 +69,8 @@
ActivityBehaviour activityBehaviour = ((ActivityImpl) childActivity).getActivityBehaviour();
if ( (activityBehaviour instanceof BpmnEvent)
&& !(activityBehaviour instanceof NoneStartEventActivity) ) {
- parse.addProblem("Only none start events are allowed in an embedded sub process");
+ parse.addProblem("Only none start events are allowed in an embedded sub process. " +
+ "Event " + childActivity.getName() + " has no incoming sequence flow.");
}
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-02-02 17:32:58 UTC (rev 6156)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-02-03 13:19:58 UTC (rev 6157)
@@ -152,8 +152,6 @@
// bind activities to their destinations
parseSequenceFlow(processElement, parse, processDefinition);
-
- postParsingValidations(parse, processDefinition);
} finally {
parse.contextStackPop();
@@ -474,84 +472,4 @@
}
- /**
- * Validations that are called at the end of the parsing: all activities,
- * sequence flow, etc are fully available to allow detailed validations.
- */
- public void postParsingValidations(Parse parse, BpmnProcessDefinition processDefinition) {
- validateSubProcessBoundaryNotCrossed(parse, processDefinition);
- }
-
- /* ---------------------
- * SUBPROCESS VALIDATION
- * --------------------- */
-
- /**
- * Validates that the boundary of a sub-process isn't crossed.
- */
- protected void validateSubProcessBoundaryNotCrossed(Parse parse, BpmnProcessDefinition processDefinition) {
- for (Activity activity : processDefinition.getActivities()) {
- ActivityImpl activityImpl = (ActivityImpl) activity;
- if ( activityImpl.getActivityBehaviour() instanceof SubProcessActivity) {
- validateSubProcessStartActivities(activityImpl, parse);
- validateSubProcessAllSequenceFlow(activityImpl, parse);
- }
- }
- }
-
- /**
- * Only none start activities and activities without incoming sequence flow
- * are allowed as start activities in a sub-process.
- */
- protected void validateSubProcessStartActivities(ActivityImpl subProcessActivity, Parse parse) {
- for (Activity childActivity : subProcessActivity.getActivities()) {
- if (childActivity.getIncomingTransitions().isEmpty()) {
-
- ActivityBehaviour activityBehaviour = ((ActivityImpl) childActivity).getActivityBehaviour();
- if ( (activityBehaviour instanceof BpmnEvent)
- && !(activityBehaviour instanceof NoneStartEventActivity) ) {
- parse.addProblem("Only none start events are allowed in an embedded sub process");
- }
-
- }
- }
- }
-
- /**
- * Sequence flow are not allowed to cross the sub-process boundary.
- * Exception to that rule is sequence flow which have as target a none start event (which actually
- * could graphically be viewed as boundary events).
- */
- protected void validateSubProcessAllSequenceFlow(ActivityImpl subProcessActivity, Parse parse) {
-
- // collect all child activity ids
- Set<String> childActivityIds = new HashSet<String>();
- for (Activity childActivity : subProcessActivity.getActivities()) {
- childActivityIds.add(childActivity.getName());
- }
-
- // Verify source/target of all sequenceflow
- for (Activity childActivity : subProcessActivity.getActivities()) {
- for (Transition incomingTransition : childActivity.getIncomingTransitions()) {
- validateSubProcessSequenceFlow(incomingTransition, childActivityIds, parse);
- }
- for (Transition outgoingTransition : childActivity.getOutgoingTransitions()) {
- validateSubProcessSequenceFlow(outgoingTransition, childActivityIds, parse);
- }
- }
- }
-
- protected void validateSubProcessSequenceFlow(Transition transition, Set<String> subProcessActivityIds, Parse parse) {
- if (!subProcessActivityIds.contains(transition.getSource().getName())) {
- parse.addProblem("Invalid sequence flow " + transition.getName()
- + ": cannot cross sub-process boundaries from " + transition.getSource().getName()
- + " into the sub process activity.");
- }
- if (!subProcessActivityIds.contains(transition.getDestination().getName())) {
- parse.addProblem("Invalid sequence flow " + transition.getName()
- + ": cannot cross sub-process boundaries to " + transition.getSource().getName()
- + " from within the sub process activity.");
- }
- }
-
}
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.collapsed.subprocess.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.collapsed.subprocess.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.embedded.subprocess.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.embedded.subprocess.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.nested.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.nested.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.parallel.paths.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.parallel.paths.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.two.endevents.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.subprocess.two.endevents.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml
===================================================================
--- jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-02-02 17:32:58 UTC (rev 6156)
+++ jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-02-03 13:19:58 UTC (rev 6157)
@@ -1219,6 +1219,100 @@
<title>Advanced constructs</title>
+ <section id="embeddedSubProcess">
+
+ <title>Embedded sub-process</title>
+
+ <para>
+ Subprocesses are in the first place a way of making a process "hierarchical", meaning that
+ a modeller can create several 'levels' of detail. The top level view then explains the
+ high-level way of doing things, while the lowest level focusses on the nitty gritty
+ details.
+ </para>
+
+ <para>
+ Take for example the following diagram. In this model, only the high level steps are shown.
+ The actual implementation of the "Check credit" step is hidden behind a
+ <emphasis role="bold">collapsed subprocess</emphasis>, which may be the perfect level
+ of detail to discuss business processes with end-users.
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.collapsed.subprocess.png"/></imageobject></mediaobject>
+ </para>
+
+ <para>
+ The second major use case for sub-processes is that the sub-process "container"
+ acts as a scope for events. When an event is fired from within the sub-process, the catch
+ events on the boundary of the sub-process will be the first to receive this event.
+ </para>
+
+ <para>
+ A sub-process that is defined within a top-level process is called an <emphasis role="bold">
+ embeddable sub-process</emphasis>. All process data that is available in the parent
+ process is also available in the sub-process. The following diagram shows the expanded
+ version of the model above.
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.embedded.subprocess.png"/></imageobject></mediaobject>
+ The XML counterpart of this model looks as follows:$
+ <programlisting>
+<process id="embeddedSubprocess">
+
+ <startEvent id="theStart" />
+ <sequenceFlow id="flow1" sourceRef="theStart" targetRef="receiveOrder" />
+ <receiveTask name="Receive order" id="receiveOrder" />
+ <sequenceFlow id="flow2" sourceRef="receiveOrder" targetRef="checkCreditSubProcess" />
+ <emphasis role="bold"><subProcess id="checkCreditSubProcess" name="Credit check"></emphasis>
+
+ ...
+
+ <emphasis role="bold"></subProcess></emphasis>
+
+ <sequenceFlow id="flow9" sourceRef="checkCreditSubProcess" targetRef="theEnd" />
+ <endEvent id="theEnd" />
+
+</process>
+ </programlisting>
+ Note that inside the sub-process, events, activities, tasks are defined as if it were
+ a top-level process (hence the three "..." within the XML example above. Sub-processes
+ are <emphasis role="bold">only allowed to have a none start event</emphasis>.
+ </para>
+
+ <para>
+ Conceptually an embedded sub-process works as follows: when an execution arrives
+ at the subprocess, a child execution is created. The child execution can then later create
+ other (sub-)child executions, for example when a parallel gateway is used whithin the
+ sub-process. The sub-process however, is only completed when no executions are active anymore
+ within the subprocess. In that case, the parent execution is taken for further continuation
+ of the process.
+ </para>
+ <para>
+ For example, in the following diagram, the "Third task"
+ will only be reached after both the "First task" and the "Second task"
+ are completed. Completing one of the tasks in the sub-process, will not trigger the
+ continuation of the sub-process, since one execution is still active within the sub-process.
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.subprocess.two.endevents.png"/></imageobject></mediaobject>
+ </para>
+
+ <para>
+ Sub-processes can have multiple start events. In that case, multiple parallel paths
+ will exist within the sub-process. The rules for sub-process completion are unchanged:
+ the sub-process will only be left when all the executions of the parallel paths are
+ ended.
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.subprocess.parallel.paths.png"/></imageobject></mediaobject>
+ </para>
+
+ <para>
+ Nested sub-processes are also possible. This way, the process can be divided into several
+ levels of detail. There is no limitation on the levels of nesting.
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.subprocess.nested.png"/></imageobject></mediaobject>
+ </para>
+
+ <para>
+ Implementation note: According to the BPMN 2 specification, an activity without ougoing sequence
+ flow implicitly ends the current execution. However currently, it is necessary for a correct functioning to
+ specifically use an end event within the sub-process to end a certain path. This will
+ be enhanced in the future to be specification-compliant.
+ </para>
+
+ </section> <!-- End of embedded subprocess -->
+
<section id="Timer start event">
<title>Timer start event</title>
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java 2010-02-02 17:32:58 UTC (rev 6156)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java 2010-02-03 13:19:58 UTC (rev 6157)
@@ -138,6 +138,33 @@
" </process>" +
"</definitions>";
+ private static final String SUBPROCESS_WITH_UNJOINED_PATHS =
+ "<definitions>" +
+ " <process id='unjoinedPaths'>" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='mySubProcess' />" +
+ " <subProcess id='mySubProcess'>" +
+ " <startEvent id='subProcessStart' />" +
+ " <sequenceFlow id='subFlow1' sourceRef='subProcessStart' targetRef='splitInSubProcess' />" +
+ " <parallelGateway id='splitInSubProcess' />" +
+ " <sequenceFlow id='subFlow2' sourceRef='splitInSubProcess' targetRef='subTask1' />" +
+ " <sequenceFlow id='subFlow3' sourceRef='splitInSubProcess' targetRef='subTask2' />" +
+ " <sequenceFlow id='subFlow4' sourceRef='splitInSubProcess' targetRef='subTask3' />" +
+ " <userTask id='subTask1' name='firstTask' />" +
+ " <userTask id='subTask2' name='secondTask' />" +
+ " <userTask id='subTask3' name='thirdTask' />" +
+ " <sequenceFlow id='subFlow4' sourceRef='subTask1' targetRef='subEnd1' />" +
+ " <endEvent id='subEnd1' />" +
+ " <sequenceFlow id='subFlow5' sourceRef='subTask2' targetRef='subEnd2' />" +
+ " <endEvent id='subEnd2' />" +
+ " <sequenceFlow id='subFlow6' sourceRef='subTask3' targetRef='subEnd3' />" +
+ " <endEvent id='subEnd3' />" +
+ " </subProcess>" +
+ " <sequenceFlow id='flow2' sourceRef='mySubProcess' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
/**
* Tests a simple sub process with sequentially one start, a user task and an end.
*/
@@ -241,5 +268,26 @@
taskService.completeTask(tasks.get(0).getId());
assertProcessInstanceEnded(pi);
}
+
+ /**
+ * Tests a process that has a sub-process which has a splitting parallelgatway without
+ * a merging parallel gateway later on. This way, execution state juggling gets a bit trickier.
+ */
+ public void testSubProcessWithUnjoinedPaths() {
+ deployBpmn2XmlString(SUBPROCESS_WITH_UNJOINED_PATHS);
+ ProcessInstance pi = executionService.startProcessInstanceByKey("unjoinedPaths");
+
+ TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderAsc(TaskQuery.PROPERTY_NAME);
+ List<Task> tasks = query.list();
+ assertEquals(3, tasks.size());
+ assertEquals("firstTask", tasks.get(0).getName());
+ assertEquals("secondTask", tasks.get(1).getName());
+ assertEquals("thirdTask", tasks.get(2).getName());
+
+ taskService.completeTask(tasks.get(0).getId());
+ taskService.completeTask(tasks.get(1).getId());
+ taskService.completeTask(tasks.get(2).getId());
+ assertProcessInstanceEnded(pi);
+ }
}
16 years, 2 months
JBoss JBPM SVN: r6156 - in jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test: subprocess and 1 other directory.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-02-02 12:32:58 -0500 (Tue, 02 Feb 2010)
New Revision: 6156
Added:
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java
Log:
JBPM-2740: work on embedded subprocess
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/subprocess/SubProcessTest.java 2010-02-02 17:32:58 UTC (rev 6156)
@@ -0,0 +1,245 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.bpmn.test.subprocess;
+
+import java.util.List;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.TaskQuery;
+import org.jbpm.api.task.Task;
+import org.jbpm.test.JbpmTestCase;
+import org.jbpm.test.assertion.CollectionAssertions;
+
+/**
+ * @author Joram Barrez
+ */
+public class SubProcessTest extends JbpmTestCase {
+
+ private static final String SIMPLE_SUBPROCESS =
+ "<definitions>" +
+ " <process id='simpleSubProcess'>" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='mySubProcess' />" +
+ " <subProcess id='mySubProcess'>" +
+ " <startEvent id='subProcessStart' />" +
+ " <sequenceFlow id='subFlow1' sourceRef='subProcessStart' targetRef='subTask' />" +
+ " <userTask id='subTask' name='importantTask' />" +
+ " <sequenceFlow id='subFlow2' sourceRef='subTask' targetRef='subEnd' />" +
+ " <endEvent id='subEnd' />" +
+ " </subProcess>" +
+ " <sequenceFlow id='flow2' sourceRef='mySubProcess' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String SIMPLE_PARALLEL_SUBPROCESS =
+ "<definitions>" +
+ " <process id='simpleParallelSubProcess'>" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='mySubProcess' />" +
+ " <subProcess id='mySubProcess'>" +
+ " <startEvent id='subProcessStart1' />" +
+ " <sequenceFlow id='subFlow1' sourceRef='subProcessStart1' targetRef='subTask1' />" +
+ " <userTask id='subTask1' name='importantTask1' />" +
+ " <sequenceFlow id='subFlow2' sourceRef='subTask1' targetRef='subEnd1' />" +
+ " <endEvent id='subEnd1' />" +
+ " <startEvent id='subProcessStart2' />" +
+ " <sequenceFlow id='subFlow3' sourceRef='subProcessStart2' targetRef='subTask2' />" +
+ " <userTask id='subTask2' name='importantTask2' />" +
+ " <sequenceFlow id='subFlow4' sourceRef='subTask2' targetRef='subEnd2' />" +
+ " <endEvent id='subEnd2' />" +
+ " </subProcess>" +
+ " <sequenceFlow id='flow2' sourceRef='mySubProcess' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String TWO_PARALLEL_SUBPROCESSES =
+ "<definitions>" +
+ " <process id='twoParallelSubProcesses'>" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='subProcess1' />" +
+ " <sequenceFlow id='flow2' sourceRef='theStart' targetRef='subProcess2' />" +
+ " <subProcess id='subProcess1'>" +
+ " <startEvent id='subProcessStart1' />" +
+ " <sequenceFlow id='subFlow1' sourceRef='subProcessStart1' targetRef='subTask1' />" +
+ " <userTask id='subTask1' name='importantTask' />" +
+ " <sequenceFlow id='subFlow2' sourceRef='subTask1' targetRef='subEnd1' />" +
+ " <endEvent id='subEnd1' />" +
+ " </subProcess>" +
+ " <subProcess id='subProcess2'>" +
+ " <startEvent id='subProcessStart2' />" +
+ " <sequenceFlow id='subFlow3' sourceRef='subProcessStart2' targetRef='subTask2' />" +
+ " <userTask id='subTask2' name='evenMoreImportantTask' />" +
+ " <sequenceFlow id='subFlow4' sourceRef='subTask2' targetRef='subEnd2' />" +
+ " <endEvent id='subEnd2' />" +
+ " <startEvent id='subProcessStart3' />" +
+ " <sequenceFlow id='subFlow5' sourceRef='subProcessStart3' targetRef='subTask3' />" +
+ " <userTask id='subTask3' name='possiblyTheMostImportantTask' />" +
+ " <sequenceFlow id='subFlow6' sourceRef='subTask3' targetRef='subEnd3' />" +
+ " <endEvent id='subEnd3' />" +
+ " </subProcess>" +
+ " <sequenceFlow id='flow3' sourceRef='subProcess1' targetRef='taskAfterSubProcess1' />" +
+ " <userTask id='taskAfterSubProcess1' name='taskAfterSubProcess1' />" +
+ " <sequenceFlow id='flow5' sourceRef='taskAfterSubProcess1' targetRef='theEnd' />" +
+ " <sequenceFlow id='flow4' sourceRef='subProcess2' targetRef='taskAfterSubProcess2' />" +
+ " <userTask id='taskAfterSubProcess2' name='taskAfterSubProcess2' />" +
+ " <sequenceFlow id='flow5' sourceRef='taskAfterSubProcess2' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String NESTED_SUBPROCESS =
+ "<definitions>" +
+ " <process id='nestedSubProcess'>" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='mySubProcess' />" +
+ " <subProcess id='mySubProcess'>" +
+ // First path of subprocess is just a sequential start-task-end
+ " <startEvent id='subProcessStart1' />" +
+ " <sequenceFlow id='subFlow1' sourceRef='subProcessStart1' targetRef='subTask1' />" +
+ " <userTask id='subTask1' name='task1' />" +
+ " <sequenceFlow id='subFlow2' sourceRef='subTask1' targetRef='subEnd1' />" +
+ " <endEvent id='subEnd1' />" +
+ // Second path has a nested subprocess
+ " <startEvent id='subProcessStart2' />" +
+ " <sequenceFlow id='subFlow3' sourceRef='subProcessStart2' targetRef='nestedSubProcess' />" +
+ " <subProcess id='nestedSubProcess'>" +
+ " <userTask id='subTask3' name='task2' />" +
+ " <sequenceFlow id='subFlow4' sourceRef='subTask3' targetRef='subTask4' />" +
+ " <userTask id='subTask4' name='task3' />" +
+ " <sequenceFlow id='subFlow5' sourceRef='subTask4' targetRef='nestedEnd' />" +
+ " <endEvent id='nestedEnd' />" +
+ " </subProcess>" +
+ " <sequenceFlow id='subFlow6' sourceRef='nestedSubProcess' targetRef='subEnd2' />" +
+ " <endEvent id='subEnd2' />" +
+ " </subProcess>" +
+ " <sequenceFlow id='flow3' sourceRef='mySubProcess' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ /**
+ * Tests a simple sub process with sequentially one start, a user task and an end.
+ */
+ public void testSimpleSubProcess() {
+ deployBpmn2XmlString(SIMPLE_SUBPROCESS);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("simpleSubProcess");
+
+ Task task = taskService.createTaskQuery().uniqueResult();
+ assertEquals("importantTask", task.getName());
+ taskService.completeTask(task.getId());
+
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ /**
+ * Tests a simple sub process that has 2 parallel paths which are sequential on itself.
+ */
+ public void testSimpleParallelSubProcess() {
+ deployBpmn2XmlString(SIMPLE_PARALLEL_SUBPROCESS);
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("simpleParallelSubProcess");
+
+ TaskQuery query = taskService.createTaskQuery().processInstanceId(processInstance.getId()).orderAsc(TaskQuery.PROPERTY_NAME);
+ List<Task> tasks = query.list();
+ assertEquals(2, tasks.size());
+ assertEquals("importantTask1", tasks.get(0).getName());
+ assertEquals("importantTask2", tasks.get(1).getName());
+
+ // After task completion, the subprocess should still be active
+ taskService.completeTask(tasks.get(0).getId());
+ processInstance = executionService.findProcessInstanceById(processInstance.getId());
+ CollectionAssertions.assertContainsSameElements(processInstance.findActiveActivityNames(), "subTask2");
+
+ taskService.completeTask(tasks.get(1).getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ /**
+ * Tests a process that splits after process start in two separate sub-processes
+ */
+ public void testTwoParallelSubProcesses() {
+ deployBpmn2XmlString(TWO_PARALLEL_SUBPROCESSES);
+ ProcessInstance pi = executionService.startProcessInstanceByKey("twoParallelSubProcesses");
+
+ TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderAsc(TaskQuery.PROPERTY_NAME);
+ List<Task> tasks = query.list();
+ assertEquals(3, tasks.size());
+ assertEquals("evenMoreImportantTask", tasks.get(0).getName());
+ assertEquals("importantTask", tasks.get(1).getName());
+ assertEquals("possiblyTheMostImportantTask", tasks.get(2).getName());
+
+ // complete evenMoreImportantTask
+ taskService.completeTask(tasks.get(0).getId());
+ pi = executionService.findProcessInstanceById(pi.getId());
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "subTask1", "subTask3");
+
+ // complete possiblyTheMostImportantTask
+ taskService.completeTask(tasks.get(2).getId());
+ pi = executionService.findProcessInstanceById(pi.getId());
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "subTask1", "taskAfterSubProcess2");
+
+ // complete importantTask
+ taskService.completeTask(tasks.get(1).getId()); // complete importantTask
+ pi = executionService.findProcessInstanceById(pi.getId());
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "taskAfterSubProcess1", "taskAfterSubProcess2");
+
+ // Complete 2 tasks after subprocesses
+ tasks = query.list();
+ assertEquals(2, tasks.size());
+ taskService.completeTask(tasks.get(0).getId());
+ assertProcessInstanceActive(pi);
+ taskService.completeTask(tasks.get(1).getId());
+ assertProcessInstanceEnded(pi);
+ }
+
+ public void testNestedSubProcess() {
+ deployBpmn2XmlString(NESTED_SUBPROCESS);
+ ProcessInstance pi = executionService.startProcessInstanceByKey("nestedSubProcess");
+
+ TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderAsc(TaskQuery.PROPERTY_NAME);
+ List<Task> tasks = query.list();
+ assertEquals(2, tasks.size());
+ assertEquals("task1", tasks.get(0).getName());
+ assertEquals("task2", tasks.get(1).getName());
+
+ // Complete task2 -> will activate task3
+ taskService.completeTask(tasks.get(1).getId());
+ tasks = query.list();
+ assertEquals(2, tasks.size());
+ assertEquals("task1", tasks.get(0).getName());
+ assertEquals("task3", tasks.get(1).getName());
+
+ // Complete task3 -> will finish nested subprocess
+ taskService.completeTask(tasks.get(1).getId());
+ tasks = query.list();
+ assertEquals(1, tasks.size());
+ assertEquals("task1", tasks.get(0).getName());
+ pi = executionService.findProcessInstanceById(pi.getId());
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), "subTask1");
+
+ // Complete task 1 -> complete process is finished
+ taskService.completeTask(tasks.get(0).getId());
+ assertProcessInstanceEnded(pi);
+ }
+
+}
16 years, 2 months
JBoss JBPM SVN: r6155 - jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-02-02 12:32:09 -0500 (Tue, 02 Feb 2010)
New Revision: 6155
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/EndActivity.java
Log:
JBPM-2740: work on embedded subprocess
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/EndActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/EndActivity.java 2010-02-02 12:00:18 UTC (rev 6154)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/EndActivity.java 2010-02-02 17:32:09 UTC (rev 6155)
@@ -23,6 +23,7 @@
import java.util.List;
+import org.jbpm.api.Execution;
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.api.model.Activity;
import org.jbpm.api.model.OpenExecution;
@@ -72,12 +73,22 @@
executionToEnd = execution;
}
+ ExecutionImpl parent = (ExecutionImpl) executionToEnd.getParent(); // save parent before it is nullified
+
if (state==null) {
execution.end(executionToEnd);
} else {
execution.end(executionToEnd, state);
}
- }
+
+ // Special case: if during concurrent execution all child executions are ended,
+ // then the parent execution must be ended too.
+ if (parent != null && parent.getExecutions().isEmpty()
+ && Execution.STATE_INACTIVE_CONCURRENT_ROOT.equals(parent.getState()) ) {
+ parent.end();
+ }
+ }
+
}
public void setEndProcessInstance(boolean endProcessInstance) {
16 years, 2 months
JBoss JBPM SVN: r6154 - in jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn: parser and 1 other directory.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-02-02 07:00:18 -0500 (Tue, 02 Feb 2010)
New Revision: 6154
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
Log:
JBPM-2740: added parallel test case +impl
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java 2010-02-01 21:48:29 UTC (rev 6153)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java 2010-02-02 12:00:18 UTC (rev 6154)
@@ -70,7 +70,7 @@
*/
protected void proceed(ExecutionImpl execution, List<Transition> transitions) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Proceeding from execution " + execution.getActivityName());
+ LOG.debug("Proceeding from execution in " + execution.getActivityName());
}
Activity activity = execution.getActivity();
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java 2010-02-01 21:48:29 UTC (rev 6153)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/SubProcessActivity.java 2010-02-02 12:00:18 UTC (rev 6154)
@@ -29,6 +29,9 @@
import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.api.model.Activity;
+import org.jbpm.api.model.OpenExecution;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.model.ActivityImpl;
import org.jbpm.pvm.internal.model.ExecutionImpl;
/**
@@ -38,26 +41,18 @@
public class SubProcessActivity extends BpmnExternalActivity {
private static final long serialVersionUID = 1L;
+
+ private static final Log LOG = Log.getLog(SubProcessActivity.class.getName());
public void execute(ExecutionImpl execution) {
List<Activity> startActivities = findStartActivities(execution);
- if (startActivities.size() == 1) {
-
- execution.execute(startActivities.get(0));
-
- } else if (startActivities.size() > 1) {
-
- ExecutionImpl concurrentRoot = null;
- if (Execution.STATE_ACTIVE_ROOT.equals(execution.getState())) {
- concurrentRoot = execution;
- } else if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
- concurrentRoot = execution.getParent();
- } else {
- throw new JbpmException("illegal state for execution :" + execution.getState());
- }
-
+
+ if (!startActivities.isEmpty()) {
+ ExecutionImpl parent = execution.createScope(execution.getActivity());
+
for (Activity startActivity: startActivities) {
- ExecutionImpl concurrentExecution = concurrentRoot.createExecution();
+ parent.setState(Execution.STATE_INACTIVE_CONCURRENT_ROOT);
+ ExecutionImpl concurrentExecution = parent.createExecution();
concurrentExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
concurrentExecution.execute(startActivity);
}
@@ -84,9 +79,32 @@
return startActivities;
}
- public void signal(ActivityExecution execution, String signalName, Map<String, ? > parameters) throws Exception {
- ExecutionImpl executionImpl = (ExecutionImpl) execution;
- proceed(executionImpl, findOutgoingSequenceFlow(executionImpl, CONDITIONS_CHECKED));
+ public void signal(ActivityExecution execution, String signalName, Map<String, ? > parameters) throws Exception {
+ ActivityImpl activity = (ActivityImpl) execution.getActivity();
+
+ ExecutionImpl scopedExecution = (ExecutionImpl) execution.getParent();
+
+ // If there are still active paths in the sub-process
+ if ( (scopedExecution.getExecutions() != null)
+ && (scopedExecution.getExecutions().size() > 1) ) { // not > 0 -> current execution is still a child
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Scoped execution " + scopedExecution.getId() + " has active child executions." +
+ "Ending current execution, but scoped execution is not yet continued");
+ }
+ execution.end();
+
+ // If no other paths are active in the sub-process
+ } else {
+
+ ExecutionImpl parent = scopedExecution.destroyScope(activity); // child execution will be ended automatically when parent ends
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Scoped execution " + scopedExecution.getId() + " has no active child executions." +
+ "Destroying scope and proceeding from parent execution " + parent.getId());
+ }
+ proceed(parent, findOutgoingSequenceFlow(parent, CONDITIONS_CHECKED));
+
+ }
}
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-02-01 21:48:29 UTC (rev 6153)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-02-02 12:00:18 UTC (rev 6154)
@@ -257,7 +257,7 @@
// Parse attributes
String transitionName = XmlUtil.attribute(transitionElement, "name", false, parse);
- String transitionId = XmlUtil.attribute(transitionElement, "id", false, parse);
+ String transitionId = XmlUtil.attribute(transitionElement, "id", true, parse);
String sourceRef = XmlUtil.attribute(transitionElement, "sourceRef", true, parse);
String targetRef = XmlUtil.attribute(transitionElement, "targetRef", true, parse);
16 years, 2 months