JBoss JBPM SVN: r6091 - projects/jsf-console/branches/jsf-console-3.2-soa/console.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-01-18 16:58:11 -0500 (Mon, 18 Jan 2010)
New Revision: 6091
Modified:
projects/jsf-console/branches/jsf-console-3.2-soa/console/pom.xml
Log:
remove extraneous whitespace
Modified: projects/jsf-console/branches/jsf-console-3.2-soa/console/pom.xml
===================================================================
--- projects/jsf-console/branches/jsf-console-3.2-soa/console/pom.xml 2010-01-18 21:02:28 UTC (rev 6090)
+++ projects/jsf-console/branches/jsf-console-3.2-soa/console/pom.xml 2010-01-18 21:58:11 UTC (rev 6091)
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
- <!-- ====================================================================== -->
- <!-- jBPM: Workflow in Java -->
- <!-- -->
- <!-- Distributable under LGPL license. -->
- <!-- See terms of license at http://www.gnu.org. -->
- <!-- ====================================================================== -->
+<!-- ====================================================================== -->
+<!-- jBPM: Workflow in Java -->
+<!-- -->
+<!-- Distributable under LGPL license. -->
+<!-- See terms of license at http://www.gnu.org. -->
+<!-- ====================================================================== -->
- <!-- $Id$ -->
+<!-- $Id$ -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
16 years, 3 months
JBoss JBPM SVN: r6090 - projects/jsf-console/branches.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-01-18 16:02:28 -0500 (Mon, 18 Jan 2010)
New Revision: 6090
Added:
projects/jsf-console/branches/jsf-console-3.3.1.SP/
Log:
SOA-1586: create branch jsf-console-3.3.1.SP
Copied: projects/jsf-console/branches/jsf-console-3.3.1.SP (from rev 6089, projects/jsf-console/tags/jsf-console-3.3.1.GA)
16 years, 3 months
JBoss JBPM SVN: r6089 - in jbpm4/trunk/modules: devguide/src/main/docbook/en/images and 7 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-18 15:15:23 -0500 (Mon, 18 Jan 2010)
New Revision: 6089
Added:
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.inclusive.gateway.merging.and.splitting.png
jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.inclusive.gateway.png
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/gateway/inclusive/
jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/gateway/inclusive/InclusiveGatewayTest.java
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/inclusive/
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/inclusive/inclusive_gateway.bpmn.xml
jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/bpmn/nested_inclusive_gateway_test.png
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.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/gateway/InclusiveGatewayTest.java
Log:
JBPM-2738: added documentation for inclusive gateway. Worked on the nested inclusive gateway test case (not yet functioning - commented out)
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java 2010-01-18 15:01:34 UTC (rev 6088)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java 2010-01-18 20:15:23 UTC (rev 6089)
@@ -33,6 +33,7 @@
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.Transition;
/**
* Superclass for gateway activities that wait on multiple incoming executions before merging
@@ -105,13 +106,11 @@
session.lock(execution.getParent(), lockMode);
execution.setState(Execution.STATE_INACTIVE_JOIN);
- execution.waitForSignal();
-
- return isComplete(execution);
- } else {
- throw new JbpmException("invalid execution state: " + execution.getState());
}
+
+ execution.waitForSignal();
+ return isComplete(execution);
}
/**
@@ -123,8 +122,12 @@
protected ExecutionImpl join(ExecutionImpl execution) {
Activity activity = execution.getActivity();
ExecutionImpl concurrentRoot = execution.getParent();
+
+ if (concurrentRoot == null) {
+ return execution;
+ }
+
List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
-
endJoinedExecutions(joinedExecutions);
ExecutionImpl outgoingExecution = null;
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-18 15:01:34 UTC (rev 6088)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-18 20:15:23 UTC (rev 6089)
@@ -40,19 +40,19 @@
private static final Log LOG = Log.getLog(InclusiveGatewayActivity.class.getName());
public void fork(ExecutionImpl execution) {
- List<Transition> outgointSeqFlow = findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED);
+ List<Transition> outgoingSeqFlow = findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED);
- if (outgointSeqFlow.isEmpty()) {
+ if (outgoingSeqFlow.isEmpty()) {
Transition defaultSeqFlow = execution.getActivity().getDefaultOutgoingTransition();
if (defaultSeqFlow != null) {
- outgointSeqFlow.add(defaultSeqFlow);
+ outgoingSeqFlow.add(defaultSeqFlow);
} else {
throw new JbpmException("No sequenceFlow condition evaluated to true for " +
execution.getActivity() + " and no default sequenceFlow was speficied");
}
}
- proceed(execution, outgointSeqFlow);
+ proceed(execution, outgoingSeqFlow);
}
/**
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.inclusive.gateway.merging.and.splitting.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.inclusive.gateway.merging.and.splitting.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.inclusive.gateway.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/devguide/src/main/docbook/en/images/bpmn2.inclusive.gateway.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-01-18 15:01:34 UTC (rev 6088)
+++ jbpm4/trunk/modules/devguide/src/main/docbook/en/modules/ch03-Bpmn2.xml 2010-01-18 20:15:23 UTC (rev 6089)
@@ -598,7 +598,7 @@
<section id="parallelGateway">
- <title>Gateway: parallel Gateway</title>
+ <title>Gateway: Parallel Gateway</title>
<para>
A parallel gateway is used to split or synchronize the respectively incoming or outgoing
@@ -688,6 +688,139 @@
</section>
+ <section id="inclusiveGateway">
+
+ <title>Gateway: Inclusive Gateway</title>
+
+ <para>
+ An inclusive gateway - also called an <emphasis role="bold">OR-gateway</emphasis> - is used
+ to 'conditionally' split or merge sequence flow. It basically behaves as a parallel
+ gateway, but it also takes in account conditions on the outgoing sequence flow (split behaviour)
+ and calculates if there are executions left that could reach the gateway (merge behaviour).
+ </para>
+
+ <para>
+ The inclusive gateway is depicted as a typical gateway shape with a circle inside (referring to 'OR' semantics).
+ Unlike the exclusive gateway, all condition expressions are evaluated (diverging or 'split' behaviour).
+ For every expression that evaluates to true, a new child execution is created.
+ Sequence flow without a condition will always be taken (ie. a child execution will always be
+ created in that case).
+ </para>
+
+ <para>
+ A converging inclusive gateway ('merge' behaviour) has a somewhat more difficult execution logic.
+ When an execution (Token in BPMN 2.0 terminology) arrives at the merging inclusive gateway,
+ the following is checked (quoting the specification literally):
+
+ <programlisting>
+For each empty incoming sequence flow, there is no
+Token in the graph anywhere upstream of this sequence flow, i.e., there is no directed path
+(formed by Sequence Flow) from a Token to this sequence flow unless
+a) the path visits the inclusive gateway or
+b) the path visits a node that has a directed path to a non-empty
+ incoming sequence flow of the inclusive gateway. "
+ </programlisting>
+
+ In more simple words: when an execution arrives at the gateway, all active execution are
+ checked if they can reach the inclusive gateway, by only taking in account the sequence flow
+ (note: conditions are not evaluated!). When the inclusive gateway is used, it is usally
+ used in a pair of splitting/merging inclusive gateways. In those cases, the execution
+ behaviour is easy enough to grasph by just looking at the model.
+
+ </para>
+
+ <para>
+ Of course, it is not hard to imagine situations where the executions are split and merged
+ in complex combinations using a variety of constructs including the inclusive gateway.
+ In those cases, it could very well be that the actual execution behaviour might not be what
+ the modelers' expects. So be careful when using the inclusive gateway and keep in mind
+ that it is often the best practice to use inclusive gateways just in pairs.
+ </para>
+
+ <para>
+ The following diagram shows how the inclusive gateway can be used.
+ (example taken from "BPMN method and style" by Bruce Silver)
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.inclusive.gateway.png"/></imageobject></mediaobject>
+ We can distinguish following cases:
+ <itemizedlist>
+ <listitem>
+ <emphasis role="bold">Cash more than 10000 and not a foreign bank: </emphasis>Only the
+ "Large deposit" task will be active.
+ </listitem>
+ <listitem>
+ <emphasis role="bold">Cash more than 10000 and a foreign bank: </emphasis> Both the
+ "Large deposit" and "Foreign deposit" task will be active.
+ </listitem>
+ <listitem>
+ <emphasis role="bold">Cash lower than 10000 and a foreign bank: </emphasis> Only the
+ "Foreign deposit" task will be active.
+ </listitem>
+ <listitem>
+ <emphasis role="bold">Cash lower than 10000 and not a foreign bank: </emphasis> In this
+ case, both expressions evaluate to false. The default sequence flow will now be chosen.
+ In this example, this means that the "Standard deposit" task is active.
+ </listitem>
+ </itemizedlist>
+ No matter how many tasks are active after going through the inclusive gateway, the converging
+ inclusive gateway on the right will wait until all outgoing sequence flow of the inclusive
+ gateway on the left have reached the merging gateway (sometimes only one, sometimes two). Take a look at
+ <emphasis role="bold">org.jbpm.examples.bpmn.gateway.inclusive.InclusiveGatewayTest</emphasis>
+ to see how this example reflects in a unit test.
+ </para>
+
+ <para>
+ The XML version of the example above looks as follows:
+ <programlisting>
+<process id="inclusiveGateway" name="BPMN2 Example inclusive gateway">
+
+ <startEvent id="start" />
+
+ <sequenceFlow id="flow1" sourceRef="start" targetRef="inclusiveGatewaySplit" />
+
+ <emphasis role="bold"><inclusiveGateway id="inclusiveGatewaySplit" default="flow3"/></emphasis>
+
+ <sequenceFlow id="flow2" sourceRef=<emphasis role="bold">"inclusiveGatewaySplit"</emphasis> targetRef="largeDeposit">
+ <conditionExpression xsi:type="tFormalExpression">${cash > 10000}</conditionExpression>
+ </sequenceFlow>
+
+ <sequenceFlow id="flow3" sourceRef=<emphasis role="bold">"inclusiveGatewaySplit"</emphasis> targetRef="standardDeposit" />
+
+ <sequenceFlow id="flow4" sourceRef=<emphasis role="bold">"inclusiveGatewaySplit"</emphasis> targetRef="foreignDeposit">
+ <conditionExpression xsi:type="tFormalExpression">${bank == 'foreign'}</conditionExpression>
+ </sequenceFlow>
+
+ <userTask id="largeDeposit" name="Large deposit" />
+
+ <sequenceFlow id="flow5" sourceRef="largeDeposit" targetRef=<emphasis role="bold">"inclusiveGatewayMerge"</emphasis> />
+
+ <userTask id="standardDeposit" name="Standard deposit" />
+
+ <sequenceFlow id="flow6" sourceRef="standardDeposit" targetRef=<emphasis role="bold">"inclusiveGatewayMerge"</emphasis> />
+
+ <userTask id="foreignDeposit" name="Foreign deposit" />
+
+ <sequenceFlow id="flow7" sourceRef="foreignDeposit" targetRef=<emphasis role="bold">"inclusiveGatewayMerge"</emphasis> />
+
+ <emphasis role="bold"><inclusiveGateway id="inclusiveGatewayMerge" /></emphasis>
+
+ <sequenceFlow id="flow8" sourceRef="inclusiveGatewayMerge" targetRef="theEnd" />
+
+ <endEvent id="theEnd" />
+
+</process>
+ </programlisting>
+ </para>
+
+ <para>
+ As with any gateway type, the inclusive gateway type can have both merging and splitting
+ behaviour. In that case, the inclusive gateway will first wait until all executions
+ have arrived, before splitting again for every sequence flow that has a condition
+ that evauluates to true (or doesn't have a condition).
+ <mediaobject><imageobject><imagedata align="center" fileref="images/bpmn2.inclusive.gateway.merging.and.splitting.png"/></imageobject></mediaobject>
+ </para>
+
+ </section>
+
<section id="task">
<title>Tasks</title>
Added: jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/gateway/inclusive/InclusiveGatewayTest.java
===================================================================
--- jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/gateway/inclusive/InclusiveGatewayTest.java (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/java/org/jbpm/examples/bpmn/gateway/inclusive/InclusiveGatewayTest.java 2010-01-18 20:15:23 UTC (rev 6089)
@@ -0,0 +1,75 @@
+package org.jbpm.examples.bpmn.gateway.inclusive;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jbpm.api.NewDeployment;
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.api.TaskQuery;
+import org.jbpm.api.task.Task;
+import org.jbpm.test.JbpmTestCase;
+
+
+public class InclusiveGatewayTest extends JbpmTestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ NewDeployment deployment = repositoryService.createDeployment();
+ deployment.addResourceFromClasspath("org/jbpm/examples/bpmn/gateway/inclusive/inclusive_gateway.bpmn.xml");
+ registerDeployment(deployment.deploy());
+ }
+
+ public void testLargeDeposit() {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("cash", 15000);
+ vars.put("bank", "local");
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("inclusiveGateway", vars);
+
+ TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
+ assertEquals(1, taskQuery.count());
+ Task largeDepositTask = taskQuery.uniqueResult();
+ assertEquals("Large deposit", largeDepositTask.getName());
+
+ taskService.completeTask(largeDepositTask.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testLargeForeignDeposit() {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("cash", 20000);
+ vars.put("bank", "foreign");
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("inclusiveGateway", vars);
+
+ TaskQuery taskQuery = taskService.createTaskQuery()
+ .processInstanceId(processInstance.getId()).orderAsc(TaskQuery.PROPERTY_NAME);
+ List<Task> tasks = taskQuery.list();
+ assertEquals(2, tasks.size());
+ assertEquals("Foreign deposit", tasks.get(0).getName());
+ assertEquals("Large deposit", tasks.get(1).getName());
+
+ for (Task task : tasks) {
+ taskService.completeTask(task.getId());
+ }
+
+ assertProcessInstanceEnded(processInstance);
+ }
+
+ public void testStandardDeposit() {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("cash", 7000);
+ vars.put("bank", "local");
+ ProcessInstance processInstance = executionService.startProcessInstanceByKey("inclusiveGateway", vars);
+
+ TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstance.getId());
+ assertEquals(1, taskQuery.count());
+ Task standardDeposit = taskQuery.uniqueResult();
+ assertEquals("Standard deposit", standardDeposit.getName());
+
+ taskService.completeTask(standardDeposit.getId());
+ assertProcessInstanceEnded(processInstance);
+ }
+
+
+}
Added: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/inclusive/inclusive_gateway.bpmn.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/inclusive/inclusive_gateway.bpmn.xml (rev 0)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/inclusive/inclusive_gateway.bpmn.xml 2010-01-18 20:15:23 UTC (rev 6089)
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://schema.omg.org/spec/BPMN/2.0 ../../../../../../../../../../bpmn/src/main/resources/BPMN20.xsd"
+ xmlns="http://schema.omg.org/spec/BPMN/2.0"
+ typeLanguage="http://www.w3.org/2001/XMLSchema"
+ expressionLanguage="http://www.w3.org/1999/XPath"
+ targetNamespace="http://jbpm.org/example/bpmn2/inclusive_gatewat"
+ xmlns:jbpm="http://jbpm.org/bpmn2">
+
+ <process id="inclusiveGateway" name="BPMN2 Example inclusive gateway">
+
+ <startEvent id="start" />
+
+ <sequenceFlow id="flow1" sourceRef="start" targetRef="inclusiveGatewaySplit" />
+
+ <inclusiveGateway id="inclusiveGatewaySplit" default="flow3"/>
+
+ <sequenceFlow id="flow2" sourceRef="inclusiveGatewaySplit" targetRef="largeDeposit">
+ <conditionExpression xsi:type="tFormalExpression">${cash > 10000}</conditionExpression>
+ </sequenceFlow>
+
+ <sequenceFlow id="flow3" sourceRef="inclusiveGatewaySplit" targetRef="standardDeposit" />
+
+ <sequenceFlow id="flow4" sourceRef="inclusiveGatewaySplit" targetRef="foreignDeposit">
+ <conditionExpression xsi:type="tFormalExpression">${bank == 'foreign'}</conditionExpression>
+ </sequenceFlow>
+
+ <userTask id="largeDeposit" name="Large deposit" />
+
+ <sequenceFlow id="flow5" sourceRef="largeDeposit" targetRef="inclusiveGatewayMerge" />
+
+ <userTask id="standardDeposit" name="Standard deposit" />
+
+ <sequenceFlow id="flow6" sourceRef="standardDeposit" targetRef="inclusiveGatewayMerge" />
+
+ <userTask id="foreignDeposit" name="Foreign deposit" />
+
+ <sequenceFlow id="flow7" sourceRef="foreignDeposit" targetRef="inclusiveGatewayMerge" />
+
+ <inclusiveGateway id="inclusiveGatewayMerge" />
+
+ <sequenceFlow id="flow8" sourceRef="inclusiveGatewayMerge" targetRef="theEnd" />
+
+ <endEvent id="theEnd" />
+
+ </process>
+
+</definitions>
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java 2010-01-18 15:01:34 UTC (rev 6088)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java 2010-01-18 20:15:23 UTC (rev 6089)
@@ -120,6 +120,9 @@
" </process>" +
"</definitions>";
+ /*
+ * See test/resources/nested_inclusive_gateway_test.png
+ */
private static final String NESTED_INCLUSIVE_SPLIT =
"<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
" <process id='nestedInclusiveSplit' name='nestedInclusiveSplit' >" +
@@ -225,8 +228,8 @@
// If var == 9, the inclusive split will be reached and it will produce 2 outgoing sequence flow.
// The inclusive merge will have to merge three incoming sequence flow
- ProcessInstance pi = startAndVerifySimpleSplitProcess("nestedInclusiveSplit", 9, "wait1", "wait2");
- /*pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait1").getId());
+ /*ProcessInstance pi = startAndVerifySimpleSplitProcess("nestedInclusiveSplit", 9, "wait1", "wait2");
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait1").getId());
assertActivitiesActive(pi.getId(), "wait2", "wait5", "wait6");
pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait5").getId());
pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait6").getId());
Added: jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/bpmn/nested_inclusive_gateway_test.png
===================================================================
(Binary files differ)
Property changes on: jbpm4/trunk/modules/test-db/src/test/resources/org/jbpm/bpmn/nested_inclusive_gateway_test.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
16 years, 3 months
JBoss JBPM SVN: r6088 - in jbpm4/trunk/modules: bpmn/src/main/java/org/jbpm/bpmn/model and 3 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-18 10:01:34 -0500 (Mon, 18 Jan 2010)
New Revision: 6088
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ReceiveActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java
jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/JbpmTestCase.java
jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java
Log:
Intermediate commit for JBPM-2738
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -75,10 +75,14 @@
} else {
if (LOG.isDebugEnabled()) {
- LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
+ LOG.debug("Multiple incoming sequence flow found. Handling incoming execution.");
}
boolean allExecutionsArrived = handleIncomingExecution(execution);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("All executions arrived at the gateway: " + allExecutionsArrived);
+ }
+
// After executing the join functionality, it could be that all executions have arrived
// at the gateway. In that case, the gateway can be left.
if (allExecutionsArrived) {
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -21,19 +21,12 @@
*/
package org.jbpm.bpmn.flownodes;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.jbpm.api.Execution;
import org.jbpm.api.JbpmException;
-import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.bpmn.model.BpmnProcessDefinition;
import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.env.EnvironmentImpl;
-import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.Transition;
@@ -80,10 +73,12 @@
BpmnProcessDefinition processDefinition = (BpmnProcessDefinition) incomingExecution.getProcessDefinition();
for (ExecutionImpl execution : allExecutions) {
- String activityId = execution.getActivityName(); // id is stored in the name attribute
- if (activityId != null && !currentActivityId.equals(activityId)) {
- if (processDefinition.isReachable(activityId, currentActivityId)) {
- return false;
+ if (incomingExecution.getParent().equals(execution.getParent())) {
+ String activityId = execution.getActivityName(); // id is stored in the name attribute
+ if (activityId != null && !currentActivityId.equals(activityId)) {
+ if (processDefinition.isReachable(activityId, currentActivityId)) {
+ return false;
+ }
}
}
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ReceiveActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ReceiveActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ReceiveActivity.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -21,29 +21,41 @@
*/
package org.jbpm.bpmn.flownodes;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
+import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.Transition;
+/**
+ * Java version of the Receive activity.
+ *
+ * @author Joram Barrez
+ */
public class ReceiveActivity extends BpmnExternalActivity {
private static final long serialVersionUID = 1L;
+ private static final Log LOG = Log.getLog(ReceiveActivity.class.getName());
+
public void execute(ActivityExecution execution) {
execute((ExecutionImpl)execution);
}
+
public void execute(ExecutionImpl execution) {
execution.historyActivityStart();
-
execution.waitForSignal();
}
public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters) {
signal((ExecutionImpl) execution, signalName, parameters);
}
+
public void signal(ExecutionImpl execution, String signalName, Map<String, ?> parameters) {
Activity activity = execution.getActivity();
@@ -51,23 +63,19 @@
execution.setVariables(parameters);
}
- execution.fire(signalName, activity);
-
- Transition transition = null;
- if ( (signalName==null)
- && (activity.getOutgoingTransitions()!=null)
- && (activity.getOutgoingTransitions().size()==1)
- ) {
- transition = activity.getOutgoingTransitions().get(0);
+ List<Transition> outgoingTransitions = new ArrayList<Transition>();
+ if (signalName != null) {
+ Transition transition = activity.findOutgoingTransition(signalName);
+ if (transition == null) {
+ throw new JbpmException("Cannot find an outgoing transition for " + activity.getName() +
+ " named " + signalName);
+ }
+ outgoingTransitions.add(transition);
+ execution.fire(signalName, activity);
} else {
- transition = activity.findOutgoingTransition(signalName);
+ outgoingTransitions.addAll(findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED));
}
- if (transition!=null) {
- execution.historyActivityEnd(signalName);
- execution.take(transition);
- } else {
- execution.waitForSignal();
- }
+ proceed(execution, outgoingTransitions);
}
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -140,10 +140,13 @@
return true;
} else {
alreadyVisited.add(srcActivityId);
- for (String destinationId : sourceToTargetMapping.get(srcActivityId)) {
- if (!alreadyVisited.contains(destinationId)) {
- if (isReachable(destinationId, dstActivityId, alreadyVisited)) {
- return true;
+ Set<String> directReachable = sourceToTargetMapping.get(srcActivityId);
+ if (directReachable != null) {
+ for (String destinationId : sourceToTargetMapping.get(srcActivityId)) {
+ if (!alreadyVisited.contains(destinationId)) {
+ if (isReachable(destinationId, dstActivityId, alreadyVisited)) {
+ return true;
+ }
}
}
}
Modified: jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/JbpmTestCase.java
===================================================================
--- jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/JbpmTestCase.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/JbpmTestCase.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -39,6 +39,7 @@
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskService;
import org.jbpm.api.task.Task;
+import org.jbpm.test.assertion.CollectionAssertions;
/** base class for persistent jBPM tests.
*
@@ -295,9 +296,8 @@
}
public void assertActivitiesActive(String executionId, String ... activityNames) {
- for (String activityName : activityNames) {
- assertActivityActive(executionId, activityName);
- }
+ CollectionAssertions.assertContainsSameElements(
+ executionService.findExecutionById(executionId).findActiveActivityNames(), activityNames);
}
/** Checks if the given execution is active in one (or more) of the given activities */
Modified: jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java
===================================================================
--- jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -37,6 +37,9 @@
*/
public class CollectionAssertions {
+ // No need to instantiate
+ private CollectionAssertions() {}
+
/**
* Compares the elements of the two given collections.
* The order of elements is not checked.
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java 2010-01-18 10:56:59 UTC (rev 6087)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java 2010-01-18 15:01:34 UTC (rev 6088)
@@ -33,6 +33,9 @@
*/
public class InclusiveGatewayTest extends JbpmTestCase {
+ /*
+ * Process with a simple inclusive split: 3 outgoing sequence flow (incl. 1 that always will be taken)
+ */
private static final String SIMPLE_SPLIT =
"<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
" <process id='simpleInclusiveSplit' name='inclusiveSplit' >" +
@@ -87,6 +90,11 @@
" </process>" +
"</definitions>";
+ /*
+ * Simple process testing split and merge behaviour of the inclusive gateway.
+ * The first inclusive gateway has 3 outgoing sequence flow, that are merged later by
+ * a merging sequence flow.
+ */
private static final String SIMPLE_SPLIT_AND_MERGE =
"<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
" <process id='simpleSplitAndMerge' name='inclusiveSplitAndMerge' >" +
@@ -112,6 +120,61 @@
" </process>" +
"</definitions>";
+ private static final String NESTED_INCLUSIVE_SPLIT =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='nestedInclusiveSplit' name='nestedInclusiveSplit' >" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='inclusiveSplit' />" +
+ // Inclusive Split
+ " <inclusiveGateway id='inclusiveSplit' />" +
+ " <sequenceFlow id='flow2' sourceRef='inclusiveSplit' targetRef='wait1' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 5}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow3' sourceRef='inclusiveSplit' targetRef='wait2' />" +
+ " <sequenceFlow id='flow4' sourceRef='inclusiveSplit' targetRef='wait3' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 10}</conditionExpression>" +
+ " </sequenceFlow>" +
+ // var > 5
+ " <receiveTask id='wait1' />" +
+ " <sequenceFlow id='flow5' sourceRef='wait1' targetRef='wait4' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var == 6}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow6a' sourceRef='wait1' targetRef='innerInclusiveSplit' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var >= 7}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow6b' sourceRef='wait1' targetRef='innerInclusiveSplit' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var >= 9}</conditionExpression>" +
+ " </sequenceFlow>" +
+ // var == 6
+ " <receiveTask id='wait4' />" +
+ " <sequenceFlow id='flow7' sourceRef='wait4' targetRef='inclusiveMerge' />" +
+ // var >= 7 -> nested inclusive split
+ " <inclusiveGateway id='innerInclusiveSplit' default='flow10'/>" +
+ " <sequenceFlow id='flow8' sourceRef='innerInclusiveSplit' targetRef='wait5' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var >= 8}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow9' sourceRef='innerInclusiveSplit' targetRef='wait6' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var >= 9}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow10' sourceRef='innerInclusiveSplit' targetRef='wait7' />" +
+ " <receiveTask id='wait5' />" +
+ " <sequenceFlow id='flow11' sourceRef='wait5' targetRef='inclusiveMerge' />" +
+ " <receiveTask id='wait6' />" +
+ " <sequenceFlow id='flow12' sourceRef='wait6' targetRef='inclusiveMerge' />" +
+ " <receiveTask id='wait7' />" +
+ " <sequenceFlow id='flow13' sourceRef='wait7' targetRef='inclusiveMerge' />" +
+ // 'always' sequence flow on outer inclusive split
+ " <receiveTask id='wait2' />" +
+ " <sequenceFlow id='flow14' sourceRef='wait2' targetRef='inclusiveMerge' />" +
+ " <receiveTask id='wait3' />" +
+ // var > 10
+ " <sequenceFlow id='flow15' sourceRef='wait3' targetRef='inclusiveMerge' />" +
+ " <inclusiveGateway id='inclusiveMerge' />" +
+ " <sequenceFlow id='flow16' sourceRef='inclusiveMerge' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
public void testSimpleSplit() {
deployBpmn2XmlString(SIMPLE_SPLIT);
@@ -148,6 +211,29 @@
assertProcessInstanceEnded(pi);
}
+ public void testNestedInclusiveSplit() {
+ deployBpmn2XmlString(NESTED_INCLUSIVE_SPLIT);
+
+ // If var == 6, then the nested inclusive split will not be reached
+ // The inclusive merge will then have to merge two incoming sequence flow
+ /*ProcessInstance pi = startAndVerifySimpleSplitProcess("nestedInclusiveSplit", 6, "wait1", "wait2");
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait1").getId());
+ assertActivitiesActive(pi.getId(), "wait2", "wait4");
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait2").getId());
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait4").getId());
+ assertProcessInstanceEnded(pi);*/
+
+ // If var == 9, the inclusive split will be reached and it will produce 2 outgoing sequence flow.
+ // The inclusive merge will have to merge three incoming sequence flow
+ ProcessInstance pi = startAndVerifySimpleSplitProcess("nestedInclusiveSplit", 9, "wait1", "wait2");
+ /*pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait1").getId());
+ assertActivitiesActive(pi.getId(), "wait2", "wait5", "wait6");
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait5").getId());
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait6").getId());
+ pi = executionService.signalExecutionById(pi.findActiveExecutionIn("wait2").getId());
+ assertProcessInstanceEnded(pi);*/
+ }
+
private ProcessInstance startAndVerifySimpleSplitProcess(String processKey, Integer varValue, String ... expectedActivities) {
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("var", varValue);
16 years, 3 months
JBoss JBPM SVN: r6087 - 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-01-18 05:56:59 -0500 (Mon, 18 Jan 2010)
New Revision: 6087
Added:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
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/InclusiveGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
Log:
Refactored gateway types: moved common operations to AbstractMergingGatewayActivity for both Parallel and Inclusive Gateway
Added: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractMergingGatewayActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
@@ -0,0 +1,182 @@
+/*
+ * 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.flownodes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.jbpm.api.Execution;
+import org.jbpm.api.JbpmException;
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.Activity;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+
+/**
+ * Superclass for gateway activities that wait on multiple incoming executions before merging
+ * them together.
+ *
+ * The {@link InclusiveGatewayActivity} and {@link ParallelGatewayActivity} are examples of such
+ * gateways which have merge behaviour.
+ *
+ * @author Joram Barrez
+ */
+public abstract class AbstractMergingGatewayActivity extends AbstractGatewayActivity {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Log LOG = Log.getLog(AbstractMergingGatewayActivity.class.getName());
+
+ protected LockMode lockMode = LockMode.UPGRADE;
+
+ public void execute(ActivityExecution execution) {
+ execute((ExecutionImpl) execution);
+ }
+
+ /**
+ * Executing the actvity logic is common for all gateway types that have merge/split behaviour.
+ *
+ * For all incoming sequence flow, the gateway will handle the executions. When all sequence
+ * flow have arrived at the gateway, the fork logic is executed (a gateway can have both
+ * merging and splitting behaviour).
+ */
+ public void execute(ExecutionImpl execution) {
+ int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
+
+ if (nrOfIncoming == 1) { // no join behaviour needed, save some time and do a fork immediately
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Only one incoming sequence flow found. Executing fork logic.");
+ }
+ fork(execution);
+
+ } else {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
+ }
+ boolean allExecutionsArrived = handleIncomingExecution(execution);
+
+ // After executing the join functionality, it could be that all executions have arrived
+ // at the gateway. In that case, the gateway can be left.
+ if (allExecutionsArrived) {
+ ExecutionImpl outgoingExecution = join(execution);
+ fork(outgoingExecution);
+ }
+
+ }
+ }
+
+ /**
+ * Joins the incoming executions.
+ * Returns true if all executions have reached the gateway.
+ */
+ protected boolean handleIncomingExecution(ExecutionImpl execution) {
+ if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
+
+ // force version increment in the parent execution
+ Session session = EnvironmentImpl.getFromCurrent(Session.class);
+ session.lock(execution.getParent(), lockMode);
+
+ execution.setState(Execution.STATE_INACTIVE_JOIN);
+ execution.waitForSignal();
+
+ return isComplete(execution);
+
+ } else {
+ throw new JbpmException("invalid execution state: " + execution.getState());
+ }
+ }
+
+ /**
+ * Joins all the incoming executions currently waiting at the gateway.
+ *
+ * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
+ * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
+ */
+ protected ExecutionImpl join(ExecutionImpl execution) {
+ Activity activity = execution.getActivity();
+ ExecutionImpl concurrentRoot = execution.getParent();
+ List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
+
+ endJoinedExecutions(joinedExecutions);
+
+ ExecutionImpl outgoingExecution = null;
+ if (concurrentRoot.getExecutions().size() == 0) {
+ outgoingExecution = concurrentRoot;
+ outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
+ } else {
+ outgoingExecution = concurrentRoot.createExecution();
+ outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
+ }
+
+ outgoingExecution.setActivity(activity);
+ return outgoingExecution;
+ }
+
+ /**
+ * @return All executions currently waiting at the gateway.
+ */
+ protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
+ List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
+ List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
+ for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
+ if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
+ && (concurrentExecution.getActivity()==activity)
+ ) {
+ joinedExecutions.add(concurrentExecution);
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
+ }
+
+ return joinedExecutions;
+ }
+
+ /**
+ * Ends all executions in the given list.
+ */
+ protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
+ for (ExecutionImpl joinedExecution: joinedExecutions) {
+ joinedExecution.end();
+ }
+ }
+
+ /*
+ * Fork (or 'split') behaviour is dependent on the actual gateway type and cannot be
+ * generalized.
+ */
+ protected abstract void fork(ExecutionImpl execution);
+
+ /*
+ * Checking if all incoming sequence flow have arrived at the gateway is gateway type dependent.
+ * Eg for the parallel gateway, all incoming sequence flow need to arrive at the gateway, while
+ * for the inclusive gateway it depends on the remaining executions in the process instance.
+ */
+ protected abstract boolean isComplete(ExecutionImpl executionImpl);
+
+}
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-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
@@ -35,7 +35,7 @@
import org.jbpm.pvm.internal.model.Transition;
/**
- * Basic activity for BPMN activities (tasks, gateways and event)
+ * Basic activity for BPMN activities (tasks, gateways)
*
* @author bernd.ruecker(a)camunda.com
* @author Ronald van Kuijk (kukeltje)
@@ -49,6 +49,8 @@
protected static final boolean CONDITIONS_CHECKED = true;
protected static final boolean CONDITIONS_IGNORED = !CONDITIONS_CHECKED;
+
+ protected String default_;
protected List<ActivityResource> activityResources = new ArrayList<ActivityResource>();
@@ -140,5 +142,22 @@
public void addActivityResource(ActivityResource activityResource) {
this.activityResources.add(activityResource);
}
+
+ /**
+ * Most of the BPMN activities allow to specify a default outgoing sequence
+ * flow. Subclasses must override this method when the default definition does
+ * not make sense (eg. ParallelGateway)
+ */
+ public boolean isDefaultEnabled() {
+ return true;
+ }
+
+ public String getDefault() {
+ return default_;
+ }
+ public void setDefault(String default_) {
+ this.default_ = default_;
+ }
+
}
\ No newline at end of file
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
@@ -40,46 +40,12 @@
/**
* @author Joram Barrez
*/
-public class InclusiveGatewayActivity extends DatabasedGatewayActivity {
+public class InclusiveGatewayActivity extends AbstractMergingGatewayActivity {
private static final long serialVersionUID = 1L;
private static final Log LOG = Log.getLog(InclusiveGatewayActivity.class.getName());
- protected LockMode lockMode = LockMode.UPGRADE;
-
- public void execute(ActivityExecution execution) throws Exception {
- execute((ExecutionImpl) execution);
- }
-
- public void execute(ExecutionImpl execution) {
- int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
-
- if (nrOfIncoming == 1) { // no merge behaviour needed, save some time and do a fork immediately
- if (LOG.isDebugEnabled()) {
- LOG.debug("Only one incoming sequence flow found. Executing fork logic only.");
- }
- fork(execution);
- } else {
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
- }
- boolean allExecutionsArrived = handleIncomingExecution(execution);
-
- if (allExecutionsArrived) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("All executions have reached the inclusive join. Executing fork logic.");
- }
- ExecutionImpl outgoingExecution = join(execution);
- fork(outgoingExecution);
- }
-
- }
-
-
- }
-
public void fork(ExecutionImpl execution) {
List<Transition> outgointSeqFlow = findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED);
@@ -97,53 +63,6 @@
}
/**
- * Joins the incoming executions.
- * Returns true if all executions have reached the gateway.
- */
- protected boolean handleIncomingExecution(ExecutionImpl execution) {
- if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
-
- // force version increment in the parent execution
- Session session = EnvironmentImpl.getFromCurrent(Session.class);
- session.lock(execution.getParent(), lockMode);
-
- execution.setState(Execution.STATE_INACTIVE_JOIN);
- execution.waitForSignal();
-
- return isComplete(execution);
-
- } else {
- throw new JbpmException("invalid execution state: " + execution.getState());
- }
- }
-
- /**
- * Joins all the incoming executions currently waiting at the gateway.
- *
- * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
- * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
- */
- protected ExecutionImpl join(ExecutionImpl execution) {
- Activity activity = execution.getActivity();
- ExecutionImpl concurrentRoot = execution.getParent();
- List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
-
- endJoinedExecutions(joinedExecutions);
-
- ExecutionImpl outgoingExecution = null;
- if (concurrentRoot.getExecutions().size() == 0) {
- outgoingExecution = concurrentRoot;
- outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
- } else {
- outgoingExecution = concurrentRoot.createExecution();
- outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
- }
-
- outgoingExecution.setActivity(activity);
- return outgoingExecution;
- }
-
- /**
* Section 14.3.2 of the BPMN 2.0 specification.
*
* The Inclusive Gateway is activated if
@@ -171,30 +90,5 @@
return true;
}
-
- protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
- List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
- List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
- for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
- if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
- && (concurrentExecution.getActivity()==activity)
- ) {
- joinedExecutions.add(concurrentExecution);
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
- }
-
- return joinedExecutions;
- }
- protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
- for (ExecutionImpl joinedExecution: joinedExecutions) {
- joinedExecution.end();
- }
- }
-
-
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java 2010-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java 2010-01-18 10:56:59 UTC (rev 6087)
@@ -21,16 +21,9 @@
*/
package org.jbpm.bpmn.flownodes;
-import java.util.ArrayList;
import java.util.List;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.jbpm.api.Execution;
-import org.jbpm.api.JbpmException;
-import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.internal.log.Log;
-import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.ExecutionImpl;
@@ -38,96 +31,16 @@
* @author Ronald van Kuijk (kukeltje)
* @author Joram Barrez
*/
-public class ParallelGatewayActivity extends AbstractGatewayActivity {
+public class ParallelGatewayActivity extends AbstractMergingGatewayActivity {
private static final Log LOG = Log.getLog(ParallelGatewayActivity.class.getName());
private static final long serialVersionUID = 1L;
- protected LockMode lockMode = LockMode.UPGRADE;
-
- public void execute(ActivityExecution execution) {
- execute((ExecutionImpl) execution);
- }
-
- public void execute(ExecutionImpl execution) {
- int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
-
- if (nrOfIncoming == 1) { // no join behaviour needed, save some time and do a fork immediately
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Only one incoming sequence flow found. Executing fork logic.");
- }
- fork(execution);
-
- } else {
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
- }
- boolean allExecutionsArrived = handleIncomingExecution(execution);
-
- // After executing the join functionality, it could be that all executions have arrived
- // at the gateway. In that case, the gateway can be left.
- if (allExecutionsArrived) {
- ExecutionImpl outgoingExecution = join(execution);
- fork(outgoingExecution);
- }
-
- }
- }
-
protected void fork(ExecutionImpl execution) {
proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_IGNORED));
}
- /**
- * Joins the incoming executions.
- * Returns true if all executions have reached the gateway.
- */
- protected boolean handleIncomingExecution(ExecutionImpl execution) {
- if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
-
- // force version increment in the parent execution
- Session session = EnvironmentImpl.getFromCurrent(Session.class);
- session.lock(execution.getParent(), lockMode);
-
- execution.setState(Execution.STATE_INACTIVE_JOIN);
- execution.waitForSignal();
-
- return isComplete(execution);
-
- } else {
- throw new JbpmException("invalid execution state: " + execution.getState());
- }
- }
-
- /**
- * Joins all the incoming executions currently waiting at the gateway.
- *
- * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
- * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
- */
- protected ExecutionImpl join(ExecutionImpl execution) {
- Activity activity = execution.getActivity();
- ExecutionImpl concurrentRoot = execution.getParent();
- List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
-
- endJoinedExecutions(joinedExecutions);
-
- ExecutionImpl outgoingExecution = null;
- if (concurrentRoot.getExecutions().size() == 0) {
- outgoingExecution = concurrentRoot;
- outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
- } else {
- outgoingExecution = concurrentRoot.createExecution();
- outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
- }
-
- outgoingExecution.setActivity(activity);
- return outgoingExecution;
- }
-
protected boolean isComplete(ExecutionImpl execution) {
Activity activity = execution.getActivity();
@@ -140,33 +53,10 @@
}
return result;
}
-
- protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
- List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
- List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
- for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
- if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
- && (concurrentExecution.getActivity()==activity)
- ) {
- joinedExecutions.add(concurrentExecution);
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
- }
-
- return joinedExecutions;
- }
-
- protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
- for (ExecutionImpl joinedExecution: joinedExecutions) {
- joinedExecution.end();
- }
- }
- public void setLockMode(LockMode lockMode) {
- this.lockMode = lockMode;
+ @Override
+ public boolean isDefaultEnabled() {
+ return false;
}
}
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-01-18 09:55:50 UTC (rev 6086)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-18 10:56:59 UTC (rev 6087)
@@ -32,6 +32,7 @@
import org.jbpm.api.activity.ActivityBehaviour;
import org.jbpm.bpmn.common.Resource;
import org.jbpm.bpmn.common.ResourceParameter;
+import org.jbpm.bpmn.flownodes.BpmnActivity;
import org.jbpm.bpmn.flownodes.BpmnBinding;
import org.jbpm.bpmn.flownodes.DatabasedGatewayActivity;
import org.jbpm.bpmn.model.BpmnProcessDefinition;
@@ -247,10 +248,10 @@
try {
// If something went wrong parsing the activity, there is no behaviour and an exception is thrown in .getBehaviour()
ActivityBehaviour behaviour = processDefinition.findActivity(sourceRef).getActivityBehaviour();
- if (behaviour instanceof DatabasedGatewayActivity) {
- DatabasedGatewayActivity databasedGatewayActivity = (DatabasedGatewayActivity) behaviour;
- String defaultSeqFlow = databasedGatewayActivity.getDefault();
- if (defaultSeqFlow != null) {
+ if (behaviour instanceof BpmnActivity) {
+ BpmnActivity bpmnActivity = (BpmnActivity) behaviour;
+ String defaultSeqFlow = bpmnActivity.getDefault();
+ if (bpmnActivity.isDefaultEnabled() && defaultSeqFlow != null) {
if (transitionId.equals(defaultSeqFlow)) {
processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(transition);
}
16 years, 3 months
JBoss JBPM SVN: r6086 - in jbpm4/trunk: qa and 1 other directory.
by do-not-reply@jboss.org
Author: tom.baeyens(a)jboss.com
Date: 2010-01-18 04:55:50 -0500 (Mon, 18 Jan 2010)
New Revision: 6086
Modified:
jbpm4/trunk/modules/test-upgrade/pom.xml
jbpm4/trunk/qa/build.xml
jbpm4/trunk/qa/hudson-jbpm4-upgrade.bat
jbpm4/trunk/qa/hudson-jbpm4-upgrade.sh
Log:
fixing upgrade ci
Modified: jbpm4/trunk/modules/test-upgrade/pom.xml
===================================================================
--- jbpm4/trunk/modules/test-upgrade/pom.xml 2010-01-16 03:29:46 UTC (rev 6085)
+++ jbpm4/trunk/modules/test-upgrade/pom.xml 2010-01-18 09:55:50 UTC (rev 6086)
@@ -34,6 +34,10 @@
<artifactId>jbpm-jpdl</artifactId>
</dependency>
<dependency>
+ <groupId>org.jbpm.jbpm4</groupId>
+ <artifactId>jbpm-bpmn</artifactId>
+ </dependency>
+ <dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
Modified: jbpm4/trunk/qa/build.xml
===================================================================
--- jbpm4/trunk/qa/build.xml 2010-01-16 03:29:46 UTC (rev 6085)
+++ jbpm4/trunk/qa/build.xml 2010-01-18 09:55:50 UTC (rev 6086)
@@ -258,6 +258,9 @@
<mkdir dir="upgrade/target/jbpm-test-upgrade" />
<unzip dest="upgrade/target/jbpm-test-upgrade" src="upgrade/target/jbpm-test-upgrade.jar" />
<delete file="upgrade/target/jbpm-test-upgrade/hibernate.properties" />
+
+ <ant antfile="${jbpm.home}/install/build.xml" target="install.hsqldb.server" />
+ <ant antfile="${jbpm.home}/install/build.xml" target="start.hsqldb.server" />
<!-- create jbpm schema using the old jbpm distro -->
<condition property="is.old.jbpm.40">
Modified: jbpm4/trunk/qa/hudson-jbpm4-upgrade.bat
===================================================================
--- jbpm4/trunk/qa/hudson-jbpm4-upgrade.bat 2010-01-16 03:29:46 UTC (rev 6085)
+++ jbpm4/trunk/qa/hudson-jbpm4-upgrade.bat 2010-01-18 09:55:50 UTC (rev 6086)
@@ -6,7 +6,6 @@
cd ..\..
cmd /C mvn -U -Pdistro,integration clean install
-start ant -f qa/build.xml %ANT_PROPERTIES% start.hsqldb
cmd /C ant -f qa/build.xml %ANT_PROPERTIES% testsuite.upgrade.setup
cd modules\test-upgrade
Modified: jbpm4/trunk/qa/hudson-jbpm4-upgrade.sh
===================================================================
--- jbpm4/trunk/qa/hudson-jbpm4-upgrade.sh 2010-01-16 03:29:46 UTC (rev 6085)
+++ jbpm4/trunk/qa/hudson-jbpm4-upgrade.sh 2010-01-18 09:55:50 UTC (rev 6086)
@@ -11,7 +11,6 @@
cd ../..
mvn -U -Pdistro,integration clean install
-ant -f qa/build.xml $ANT_PROPERTIES start.hsqldb &
ant -f qa/build.xml $ANT_PROPERTIES testsuite.upgrade.setup
cd modules/test-upgrade
16 years, 3 months
JBoss JBPM SVN: r6085 - in jbpm3/branches/jbpm-3.2-soa/modules/core/src: main/java/org/jbpm/command and 12 other directories.
by do-not-reply@jboss.org
Author: alex.guizar(a)jboss.com
Date: 2010-01-15 22:29:46 -0500 (Fri, 15 Jan 2010)
New Revision: 6085
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/bytes/ByteArray.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/UnlockTokenCommand.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Action.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Event.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Transition.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Comment.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/RuntimeAction.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/Delegation.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/def/ModuleDefinition.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/exe/ModuleInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/Swimlane.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/TaskController.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/PooledActor.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/SwimlaneInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskMgmtInstance.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ArrayUtil.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/EqualsUtil.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ProcessInstanceCommandTest.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/TokenCommandTest.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/db/GraphSessionDbTest.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/node/ProcessStateDbTest.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java
Log:
JBPM-2489: deprecate EqualsUtil.equals and replace all uses with correct equals() and hashCode() implementations
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/bytes/ByteArray.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/bytes/ByteArray.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/bytes/ByteArray.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -28,28 +28,31 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
+import org.jbpm.util.ArrayUtil;
import org.jbpm.util.StringUtil;
/**
- * is a persistable array of bytes. While there is no generic way of storing blobs
- * that is supported by many databases, all databases are able to handle small chunks
- * of bytes properly. It is the responsibility of this class to chop the large byte
- * array into small chunks of 1K (and combine the chunks again in the reverse way).
- * Hibernate will persist the list of byte-chunks in the database.
+ * is a persistable array of bytes. While there is no generic way of storing
+ * blobs that is supported by many databases, all databases are able to handle
+ * small chunks of bytes properly. It is the responsibility of this class to
+ * chop the large byte array into small chunks of 1K (and combine the chunks
+ * again in the reverse way). Hibernate will persist the list of byte-chunks in
+ * the database.
*
- * ByteArray is used in process variableInstances and in the file module (that stores the
- * non-parsed process archive files).
+ * ByteArray is used in process variableInstances and in the file module (that
+ * stores the non-parsed process archive files).
*/
public class ByteArray implements Serializable {
-
+
private static final long serialVersionUID = 1L;
-
+
long id;
protected String name;
protected List byteBlocks;
-
+
private static final Log log = LogFactory.getLog(ByteArray.class);
-
+
public ByteArray() {
}
@@ -63,15 +66,15 @@
}
void logBlocks(String msg) {
- for(int blockIndex=0; blockIndex<byteBlocks.size(); blockIndex++) {
+ for (int blockIndex = 0; blockIndex < byteBlocks.size(); blockIndex++) {
byte[] block = (byte[]) byteBlocks.get(blockIndex);
- log.debug(msg+"["+block.length+"] "+StringUtil.toHexString(block));
+ log.debug(msg + "[" + block.length + "] " + StringUtil.toHexString(block));
}
}
-
+
public ByteArray(ByteArray other) {
List otherByteBlocks = other.getByteBlocks();
- if (otherByteBlocks!=null) {
+ if (otherByteBlocks != null) {
this.byteBlocks = new ArrayList(otherByteBlocks);
}
this.name = other.name;
@@ -86,15 +89,34 @@
}
public boolean equals(Object o) {
- if (o==null) return false;
- if (! (o instanceof ByteArray)) return false;
+ if (o == this) return true;
+ if (!(o instanceof ByteArray)) return false;
+
ByteArray other = (ByteArray) o;
- return Arrays.equals(ByteBlockChopper.glueChopsBackTogether(byteBlocks), ByteBlockChopper.glueChopsBackTogether(other.byteBlocks));
+ if (id != 0 && id == other.getId()) return true;
+
+ List byteBlocks = this.byteBlocks;
+ List otherByteBlocks = other.getByteBlocks();
+ int n = byteBlocks.size();
+ if (n != otherByteBlocks.size()) return false;
+
+ for (int i = 0; i < n; i++) {
+ byte[] byteBlock = (byte[]) byteBlocks.get(i);
+ byte[] otherByteBlock = (byte[]) otherByteBlocks.get(i);
+ if (!Arrays.equals(byteBlock, otherByteBlock)) return false;
+ }
+ return true;
}
public int hashCode() {
- if (byteBlocks==null) return 0;
- return byteBlocks.hashCode();
+ if (byteBlocks == null) return 0;
+
+ int result = 1;
+ for (int i = 0, n = byteBlocks.size(); i < n; i++) {
+ byte[] byteBlock = (byte[]) byteBlocks.get(i);
+ result = 31 * result + ArrayUtil.hashCode(byteBlock);
+ }
+ return result;
}
public List getByteBlocks() {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/UnlockTokenCommand.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/UnlockTokenCommand.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/UnlockTokenCommand.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -26,7 +26,7 @@
}
else {
// requires newer jbpm version, see https://jira.jboss.org/jira/browse/JBPM-1888
- token.foreUnlock();
+ token.forceUnlock();
}
return token;
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Action.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Action.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Action.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -32,8 +32,6 @@
import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
import org.jbpm.jpdl.xml.JpdlXmlReader;
import org.jbpm.jpdl.xml.Parsable;
-import org.jbpm.util.ClassUtil;
-import org.jbpm.util.EqualsUtil;
public class Action implements ActionHandler, Parsable, Serializable {
@@ -58,46 +56,43 @@
}
public String toString() {
- String toString = null;
- if (actionExpression != null) {
- toString = "Action(" + actionExpression + ')';
+ StringBuffer result = new StringBuffer("Action(");
+ if (name != null) {
+ result.append(name);
}
- else {
- String className = ClassUtil.getSimpleName(getClass());
- if (name != null) {
- toString = className + '(' + name + ')';
- }
- else {
- toString = className + '@' + Integer.toHexString(hashCode());
- }
+ else if (actionDelegation != null) {
+ result.append(actionDelegation);
}
- return toString;
+ else if (actionExpression != null) {
+ result.append(actionExpression);
+ }
+ else if (referencedAction != null) {
+ result.append(referencedAction.getName());
+ }
+ return result.append(')').toString();
}
public void read(Element actionElement, JpdlXmlReader jpdlReader) {
String expression = actionElement.attributeValue("expression");
if (expression != null) {
actionExpression = expression;
-
}
else if (actionElement.attribute("ref-name") != null) {
jpdlReader.addUnresolvedActionReference(actionElement, this);
-
}
else if (actionElement.attribute("class") != null) {
actionDelegation = new Delegation();
actionDelegation.read(actionElement, jpdlReader);
-
}
else {
jpdlReader.addWarning("action does not have class nor ref-name attribute "
- + actionElement.asXML());
+ + actionElement.asXML());
}
String acceptPropagatedEvents = actionElement.attributeValue("accept-propagated-events");
if ("false".equalsIgnoreCase(acceptPropagatedEvents)
- || "no".equalsIgnoreCase(acceptPropagatedEvents)
- || "off".equalsIgnoreCase(acceptPropagatedEvents)) {
+ || "no".equalsIgnoreCase(acceptPropagatedEvents)
+ || "off".equalsIgnoreCase(acceptPropagatedEvents)) {
isPropagationAllowed = false;
}
@@ -118,19 +113,19 @@
}
public void execute(ExecutionContext executionContext) throws Exception {
- ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader surroundingClassLoader = Thread.currentThread()
+ .getContextClassLoader();
try {
- // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448)
- Thread.currentThread().setContextClassLoader(
- JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition()));
+ // set context class loader correctly for delegation class
+ // (https://jira.jboss.org/jira/browse/JBPM-1448)
+ ClassLoader classLoader = JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition());
+ Thread.currentThread().setContextClassLoader(classLoader);
if (referencedAction != null) {
referencedAction.execute(executionContext);
-
}
else if (actionExpression != null) {
JbpmExpressionEvaluator.evaluate(actionExpression, executionContext);
-
}
else if (actionDelegation != null) {
ActionHandler actionHandler = (ActionHandler) actionDelegation.getInstance();
@@ -147,8 +142,9 @@
if (processDefinition != null) {
// update the process definition action map
Map actionMap = processDefinition.getActions();
- // the != string comparison is to avoid null pointer checks. it is no problem if the body is executed a few times too much :-)
- if ((this.name != name) && (actionMap != null)) {
+ // the != string comparison is to avoid null pointer checks.
+ // no problem if the body is executed a few times too much :-)
+ if (this.name != name && actionMap != null) {
actionMap.remove(this.name);
actionMap.put(name, this);
}
@@ -159,12 +155,48 @@
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof Action)) return false;
+
+ Action other = (Action) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ if (name != null) {
+ // named actions are unique at the process definition level
+ return name.equals(other.getName())
+ && processDefinition.equals(other.getProcessDefinition());
+ }
+ return (actionDelegation != null ? actionDelegation.equals(other.getActionDelegation())
+ : actionExpression != null ? actionExpression.equals(other.getActionExpression())
+ : referencedAction != null ? referencedAction.equals(other.getActionExpression())
+ : false)
+ && event.equals(other.getEvent());
}
+ public int hashCode() {
+ int result = 1397928647;
+ if (name != null) {
+ // named actions are unique at the process definition level
+ result += name.hashCode();
+ result = 1290535769 * result + processDefinition.hashCode();
+ }
+ else {
+ if (actionDelegation != null) {
+ result += actionDelegation.hashCode();
+ }
+ else if (actionExpression != null) {
+ result += actionExpression.hashCode();
+ }
+ else if (referencedAction != null) {
+ result += referencedAction.hashCode();
+ }
+ result = 1290535769 * result + event.hashCode();
+ }
+ return result;
+ }
+
// getters and setters //////////////////////////////////////////////////////
public boolean acceptsPropagatedEvents() {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Event.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Event.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Event.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -25,10 +25,8 @@
import java.util.ArrayList;
import java.util.List;
-import org.jbpm.util.EqualsUtil;
+public class Event implements Serializable {
-public class Event implements Serializable {
-
private static final long serialVersionUID = 1L;
public static final String EVENTTYPE_TRANSITION = "transition";
@@ -49,16 +47,16 @@
public static final String EVENTTYPE_TIMER_CREATE = "timer-create";
public static final String EVENTTYPE_TIMER = "timer";
- long id = 0;
- protected String eventType = null;
- protected GraphElement graphElement = null;
- protected List actions = null;
-
+ long id;
+ protected String eventType;
+ protected GraphElement graphElement;
+ protected List actions;
+
// constructors /////////////////////////////////////////////////////////////
public Event() {
}
-
+
public Event(String eventType) {
this.eventType = eventType;
}
@@ -72,6 +70,7 @@
/**
* is the list of actions associated to this event.
+ *
* @return an empty list if no actions are associated.
*/
public List getActions() {
@@ -79,25 +78,26 @@
}
public boolean hasActions() {
- return ( (actions!=null)
- && (actions.size()>0) );
+ return actions != null && actions.size() > 0;
}
public Action addAction(Action action) {
- if (action==null) throw new IllegalArgumentException("can't add a null action to an event");
- if (actions==null) actions = new ArrayList();
+ if (action == null) {
+ throw new IllegalArgumentException("action is null");
+ }
+ if (actions == null) actions = new ArrayList();
actions.add(action);
action.event = this;
return action;
}
public void removeAction(Action action) {
- if (action==null) throw new IllegalArgumentException("can't remove a null action from an event");
- if (actions!=null) {
- if (actions.remove(action)) {
- action.event=null;
- }
+ if (action == null) {
+ throw new IllegalArgumentException("action is null");
}
+ if (actions != null && actions.remove(action)) {
+ action.event = null;
+ }
}
public String toString() {
@@ -105,23 +105,35 @@
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof Event)) return false;
+
+ Event other = (Event) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return eventType.equals(other.getEventType())
+ && graphElement.equals(other.getGraphElement());
}
+ public int hashCode() {
+ int result = 560044783 + eventType.hashCode();
+ result = 279308149 * result + graphElement.hashCode();
+ return result;
+ }
+
// getters and setters //////////////////////////////////////////////////////
public String getEventType() {
return eventType;
}
+
public GraphElement getGraphElement() {
return graphElement;
}
+
public long getId() {
return id;
}
-
- // private static final Log log = LogFactory.getLog(Event.class);
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/GraphElement.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -70,9 +70,10 @@
// events ///////////////////////////////////////////////////////////////////
/**
- * indicative set of event types supported by this graph element. this is currently only used
- * by the process designer to know which event types to show on a given graph element. in
- * process definitions and at runtime, there are no constraints on the event-types.
+ * indicative set of event types supported by this graph element. this is
+ * currently only used by the process designer to know which event types to
+ * show on a given graph element. in process definitions and at runtime, there
+ * are no constraints on the event-types.
*/
public abstract String[] getSupportedEventTypes();
@@ -97,10 +98,10 @@
public Event addEvent(Event event) {
if (event == null) {
- throw new IllegalArgumentException("can't add null event to graph element");
+ throw new IllegalArgumentException("event is null");
}
if (event.getEventType() == null) {
- throw new IllegalArgumentException("can't add an event without type to graph element");
+ throw new IllegalArgumentException("event type is null");
}
if (events == null) {
events = new HashMap();
@@ -113,11 +114,10 @@
public Event removeEvent(Event event) {
Event removedEvent = null;
if (event == null) {
- throw new IllegalArgumentException("can't remove null event from graph element");
+ throw new IllegalArgumentException("event is null");
}
if (event.getEventType() == null) {
- throw new IllegalArgumentException(
- "can't remove an event without type from graph element");
+ throw new IllegalArgumentException("event type is null");
}
if (events != null) {
removedEvent = (Event) events.remove(event.getEventType());
@@ -139,7 +139,7 @@
public ExceptionHandler addExceptionHandler(ExceptionHandler exceptionHandler) {
if (exceptionHandler == null) {
- throw new IllegalArgumentException("can't add null exceptionHandler to graph element");
+ throw new IllegalArgumentException("exception handler is null");
}
if (exceptionHandlers == null) {
exceptionHandlers = new ArrayList();
@@ -151,8 +151,7 @@
public void removeExceptionHandler(ExceptionHandler exceptionHandler) {
if (exceptionHandler == null) {
- throw new IllegalArgumentException(
- "can't remove null exceptionHandler from graph element");
+ throw new IllegalArgumentException("exception handler is null");
}
if (exceptionHandlers != null && exceptionHandlers.remove(exceptionHandler)) {
exceptionHandler.graphElement = null;
@@ -161,20 +160,21 @@
public void reorderExceptionHandler(int oldIndex, int newIndex) {
if (exceptionHandlers != null && Math.min(oldIndex, newIndex) >= 0
- && Math.max(oldIndex, newIndex) < exceptionHandlers.size()) {
+ && Math.max(oldIndex, newIndex) < exceptionHandlers.size()) {
Object o = exceptionHandlers.remove(oldIndex);
exceptionHandlers.add(newIndex, o);
}
else {
- throw new IndexOutOfBoundsException("couldn't reorder element from index '" + oldIndex
- + "' to index '" + newIndex + "' in " + exceptionHandlers);
+ throw new IndexOutOfBoundsException("could not move element from "
+ + oldIndex + " to " + newIndex);
}
}
// event handling ///////////////////////////////////////////////////////////
public void fireEvent(String eventType, ExecutionContext executionContext) {
- log.debug("event '" + eventType + "' on " + this + " for " + executionContext.getToken());
+ log.debug("event '" + eventType + "' on " + this + " for "
+ + executionContext.getToken());
try {
executionContext.setEventSource(this);
@@ -194,8 +194,10 @@
}
}
- public void fireAndPropagateEvent(String eventType, ExecutionContext executionContext) {
- // calculate if the event was fired on this element or if it was a propagated event
+ public void fireAndPropagateEvent(String eventType,
+ ExecutionContext executionContext) {
+ // check whether the event was fired on this element
+ // or propagated from another element
boolean isPropagated = !equals(executionContext.getEventSource());
// execute static actions
@@ -221,7 +223,8 @@
}
}
- void executeActions(List actions, ExecutionContext executionContext, boolean isPropagated) {
+ void executeActions(List actions, ExecutionContext executionContext,
+ boolean isPropagated) {
if (actions == null) return;
for (Iterator iter = actions.iterator(); iter.hasNext();) {
@@ -229,7 +232,8 @@
if (!action.acceptsPropagatedEvents() && isPropagated) continue;
if (action.isAsync()) {
- ExecuteActionJob job = createAsyncActionExecutionJob(executionContext.getToken(), action);
+ ExecuteActionJob job = createAsyncActionExecutionJob(
+ executionContext.getToken(), action);
MessageService messageService = (MessageService) Services.getCurrentService(Services.SERVICENAME_MESSAGE);
messageService.send(job);
}
@@ -239,7 +243,8 @@
}
}
- protected ExecuteActionJob createAsyncActionExecutionJob(Token token, Action action) {
+ protected ExecuteActionJob createAsyncActionExecutionJob(Token token,
+ Action action) {
ExecuteActionJob job = new ExecuteActionJob(token);
job.setAction(action);
job.setDueDate(new Date());
@@ -258,7 +263,8 @@
// the token needs to be locked. if this is an action
// being executed as the node behaviour or if the token
// is already locked, the token doesn't need to be locked.
- boolean actionMustBeLocked = executionContext.getEvent() != null && !token.isLocked();
+ boolean actionMustBeLocked = executionContext.getEvent() != null
+ && !token.isLocked();
try {
// update the execution context
@@ -285,8 +291,8 @@
}
}
catch (Exception exception) {
- // NOTE that Errors are not caught because that might halt the JVM and mask the original
- // Error
+ // NOTE that Errors are not caught because that might halt the JVM
+ // and mask the original Error
log.error("action threw exception: " + exception.getMessage(), exception);
// log the action exception
@@ -301,17 +307,21 @@
}
}
- List getRuntimeActionsForEvent(ExecutionContext executionContext, String eventType) {
+ List getRuntimeActionsForEvent(ExecutionContext executionContext,
+ String eventType) {
List runtimeActionsForEvent = null;
- List runtimeActions = executionContext.getProcessInstance().getRuntimeActions();
+ List runtimeActions = executionContext.getProcessInstance()
+ .getRuntimeActions();
if (runtimeActions != null) {
for (Iterator iter = runtimeActions.iterator(); iter.hasNext();) {
RuntimeAction runtimeAction = (RuntimeAction) iter.next();
- // if the runtime-action action is registered on this element and this eventType
+ // if the runtime action is registered on this element and eventType
if (equals(runtimeAction.getGraphElement())
- && eventType.equals(runtimeAction.getEventType())) {
+ && eventType.equals(runtimeAction.getEventType())) {
// ... add its action to the list of runtime actions
- if (runtimeActionsForEvent == null) runtimeActionsForEvent = new ArrayList();
+ if (runtimeActionsForEvent == null) {
+ runtimeActionsForEvent = new ArrayList();
+ }
runtimeActionsForEvent.add(runtimeAction.getAction());
}
}
@@ -320,14 +330,15 @@
}
/**
- * throws an ActionException if no applicable exception handler is found. An ExceptionHandler
- * is searched for in this graph element and then recursively up the parent hierarchy. If an
- * exception handler is found, it is applied. If the exception handler does not throw an
- * exception, the exception is considered handled. Otherwise the search for an applicable
- * exception handler continues where it left of with the newly thrown exception.
+ * throws an ActionException if no applicable exception handler is found. An
+ * ExceptionHandler is searched for in this graph element and then recursively
+ * up the parent hierarchy. If an exception handler is found, it is applied.
+ * If the exception handler does not throw an exception, the exception is
+ * considered handled. Otherwise the search for an applicable exception
+ * handler continues where it left of with the newly thrown exception.
*/
- public void raiseException(Throwable exception, ExecutionContext executionContext)
- throws DelegationException {
+ public void raiseException(Throwable exception,
+ ExecutionContext executionContext) throws DelegationException {
if (isAbleToHandleExceptions(executionContext)) {
try {
ExceptionHandler exceptionHandler = findExceptionHandler(exception);
@@ -355,30 +366,31 @@
// rollback the actions
// rollbackActions(executionContext);
- // if there is no parent we need to throw a delegation exception to the client
+ // if there is no parent, throw a delegation exception to the client
throw exception instanceof JbpmException ? (JbpmException) exception
: new DelegationException(exception, executionContext);
}
/**
- * Tells whether the given context is valid for exception handling by checking for:
+ * Tells whether the given context can handle exception by checking for:
* <ul>
* <li>the absence of a previous exception</li>
* <li>an active transaction, or no transaction at all</li>
* </ul>
*/
- private static boolean isAbleToHandleExceptions(ExecutionContext executionContext) {
+ private static boolean isAbleToHandleExceptions(
+ ExecutionContext executionContext) {
/*
- * if an exception is already set, we are already handling an exception; in this case don't
- * give the exception to the handlers but throw it to the client see
- * https://jira.jboss.org/jira/browse/JBPM-1887
+ * if an exception is already set, we are already handling an exception; in
+ * this case don't give the exception to the handlers but throw it to the
+ * client see https://jira.jboss.org/jira/browse/JBPM-1887
*/
if (executionContext.getException() != null) return false;
/*
- * check whether the transaction is still active before scanning the exception handlers.
- * that way we can load the exception handlers lazily see
- * https://jira.jboss.org/jira/browse/JBPM-1775
+ * check whether the transaction is still active before scanning the
+ * exception handlers. that way we can load the exception handlers lazily
+ * see https://jira.jboss.org/jira/browse/JBPM-1775
*/
JbpmContext jbpmContext = executionContext.getJbpmContext();
if (jbpmContext != null) {
@@ -386,7 +398,7 @@
if (service instanceof DbPersistenceService) {
DbPersistenceService persistenceService = (DbPersistenceService) service;
return persistenceService.isTransactionActive()
- || persistenceService.getTransaction() == null;
+ || persistenceService.getTransaction() == null;
}
}
@@ -448,16 +460,16 @@
if (!getClass().isInstance(o)) return false;
GraphElement other = (GraphElement) o;
- if (id != 0) return id == other.getId();
+ if (id != 0 && id == other.getId()) return true;
GraphElement parent = getParent();
- return (name != null ? name.equals(other.getName()) : other.getName() == null)
- && (parent != null ? parent.equals(other.getParent()) : other.getParent() == null);
+ return (name != null ? name.equals(other.getName())
+ : other.getName() == null)
+ && (parent != null ? parent.equals(other.getParent())
+ : other.getParent() == null);
}
public int hashCode() {
- if (id != 0) return (int) (id ^ (id >>> 32));
-
int result = 580399073 + (name != null ? name.hashCode() : 0);
GraphElement parent = getParent();
result = 345105097 * result + (parent != null ? parent.hashCode() : 0);
@@ -466,7 +478,8 @@
public String toString() {
return ClassUtil.getSimpleName(getClass())
- + (name != null ? '(' + name + ')' : '@' + Integer.toHexString(hashCode()));
+ + (name != null ? '(' + name + ')'
+ : '@' + Integer.toHexString(hashCode()));
}
// getters and setters //////////////////////////////////////////////////////
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/ProcessDefinition.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -65,13 +65,16 @@
// event types //////////////////////////////////////////////////////////////
- public static final String[] supportedEventTypes = new String[] {
- Event.EVENTTYPE_PROCESS_START, Event.EVENTTYPE_PROCESS_END, Event.EVENTTYPE_NODE_ENTER,
- Event.EVENTTYPE_NODE_LEAVE, Event.EVENTTYPE_TASK_CREATE, Event.EVENTTYPE_TASK_ASSIGN,
- Event.EVENTTYPE_TASK_START, Event.EVENTTYPE_TASK_END, Event.EVENTTYPE_TRANSITION,
- Event.EVENTTYPE_BEFORE_SIGNAL, Event.EVENTTYPE_AFTER_SIGNAL,
- Event.EVENTTYPE_SUPERSTATE_ENTER, Event.EVENTTYPE_SUPERSTATE_LEAVE,
- Event.EVENTTYPE_SUBPROCESS_CREATED, Event.EVENTTYPE_SUBPROCESS_END, Event.EVENTTYPE_TIMER };
+ public static final String[] supportedEventTypes = {
+ Event.EVENTTYPE_PROCESS_START, Event.EVENTTYPE_PROCESS_END,
+ Event.EVENTTYPE_NODE_ENTER, Event.EVENTTYPE_NODE_LEAVE,
+ Event.EVENTTYPE_TASK_CREATE, Event.EVENTTYPE_TASK_ASSIGN,
+ Event.EVENTTYPE_TASK_START, Event.EVENTTYPE_TASK_END,
+ Event.EVENTTYPE_TRANSITION, Event.EVENTTYPE_BEFORE_SIGNAL,
+ Event.EVENTTYPE_AFTER_SIGNAL, Event.EVENTTYPE_SUPERSTATE_ENTER,
+ Event.EVENTTYPE_SUPERSTATE_LEAVE, Event.EVENTTYPE_SUBPROCESS_CREATED,
+ Event.EVENTTYPE_SUBPROCESS_END, Event.EVENTTYPE_TIMER
+ };
public String[] getSupportedEventTypes() {
return supportedEventTypes;
@@ -86,20 +89,20 @@
public static ProcessDefinition createNewProcessDefinition() {
ProcessDefinition processDefinition = new ProcessDefinition();
- // now add all the default modules that are configured in the file jbpm.default.modules
+ // add all default modules from file jbpm.default.modules
String resource = JbpmConfiguration.Configs.getString("resource.default.modules");
Properties defaultModulesProperties = ClassLoaderUtil.getProperties(resource);
for (Iterator iter = defaultModulesProperties.keySet().iterator(); iter.hasNext();) {
String moduleClassName = (String) iter.next();
try {
- ModuleDefinition moduleDefinition = (ModuleDefinition) ClassLoaderUtil.classForName(moduleClassName)
+ ModuleDefinition moduleDefinition = (ModuleDefinition) ClassLoaderUtil.classForName(
+ moduleClassName)
.newInstance();
processDefinition.addDefinition(moduleDefinition);
-
}
catch (Exception e) {
- throw new JbpmException(
- "couldn't instantiate default module '" + moduleClassName + "'", e);
+ throw new JbpmException("could not instantiate module '"
+ + moduleClassName + '\'', e);
}
}
return processDefinition;
@@ -141,15 +144,16 @@
if (!(o instanceof ProcessDefinition)) return false;
ProcessDefinition other = (ProcessDefinition) o;
- return id != 0 ? id == other.getId() : (name != null ? name.equals(other.getName())
- : other.getName() == null)
- && version == other.getVersion();
+ if (id != 0 && id == other.getId()) return true;
+
+ return name != null && name.equals(other.getName())
+ && version == other.getVersion();
}
public int hashCode() {
- if (id != 0) return (int) (id ^ (id >>> 32));
+ if (name == null) return super.hashCode();
- int result = 224001527 + (name != null ? name.hashCode() : 0);
+ int result = 224001527 + name.hashCode();
result = 1568661329 * result + version;
return result;
}
@@ -177,7 +181,8 @@
if (resourceURL == null) {
throw new JpdlException("resource not found: " + xmlResource);
}
- JpdlXmlReader jpdlReader = new JpdlXmlReader(new InputSource(resourceURL.toString()));
+ JpdlXmlReader jpdlReader = new JpdlXmlReader(new InputSource(
+ resourceURL.toString()));
return jpdlReader.readProcessDefinition();
}
@@ -206,8 +211,8 @@
*
* @throws org.jbpm.jpdl.JpdlException if parsing reported an error.
*/
- public static ProcessDefinition parseParZipInputStream(ZipInputStream zipInputStream)
- throws IOException {
+ public static ProcessDefinition parseParZipInputStream(
+ ZipInputStream zipInputStream) throws IOException {
return new ProcessArchive(zipInputStream).parseProcessDefinition();
}
@@ -216,8 +221,10 @@
*
* @throws org.jbpm.jpdl.JpdlException if parsing reported an error.
*/
- public static ProcessDefinition parseParResource(String parResource) throws IOException {
- return parseParZipInputStream(new ZipInputStream(ClassLoaderUtil.getStream(parResource)));
+ public static ProcessDefinition parseParResource(String parResource)
+ throws IOException {
+ return parseParZipInputStream(new ZipInputStream(
+ ClassLoaderUtil.getStream(parResource)));
}
// nodes ////////////////////////////////////////////////////////////////////
@@ -255,8 +262,9 @@
// javadoc description in NodeCollection
public Node addNode(Node node) {
- if (node == null)
- throw new IllegalArgumentException("can't add a null node to a processdefinition");
+ if (node == null) {
+ throw new IllegalArgumentException("node is null");
+ }
if (nodes == null) nodes = new ArrayList();
nodes.add(node);
node.processDefinition = this;
@@ -271,8 +279,9 @@
// javadoc description in NodeCollection
public Node removeNode(Node node) {
Node removedNode = null;
- if (node == null)
- throw new IllegalArgumentException("can't remove a null node from a process definition");
+ if (node == null) {
+ throw new IllegalArgumentException("node is null");
+ }
if (nodes != null) {
if (nodes.remove(node)) {
removedNode = node;
@@ -290,13 +299,13 @@
// javadoc description in NodeCollection
public void reorderNode(int oldIndex, int newIndex) {
if (nodes != null && Math.min(oldIndex, newIndex) >= 0
- && Math.max(oldIndex, newIndex) < nodes.size()) {
+ && Math.max(oldIndex, newIndex) < nodes.size()) {
Object node = nodes.remove(oldIndex);
nodes.add(newIndex, node);
}
else {
- throw new IndexOutOfBoundsException("couldn't reorder element from index " + oldIndex
- + " to index " + newIndex);
+ throw new IndexOutOfBoundsException("could not move node from "
+ + oldIndex + " to " + newIndex);
}
}
@@ -311,7 +320,7 @@
}
public static String generateNodeName(List nodes) {
- String name = null;
+ String name;
if (nodes == null) {
name = "1";
}
@@ -327,18 +336,18 @@
static boolean containsName(List nodes, String name) {
for (Iterator iter = nodes.iterator(); iter.hasNext();) {
Node node = (Node) iter.next();
- if (name.equals(node.getName())) {
- return true;
- }
+ if (name.equals(node.getName())) return true;
}
return false;
}
- public static Node findNode(NodeCollection nodeCollection, String hierarchicalName) {
+ public static Node findNode(NodeCollection nodeCollection,
+ String hierarchicalName) {
Node node = null;
if (hierarchicalName != null && hierarchicalName.trim().length() > 0) {
- if (hierarchicalName.startsWith("/") && nodeCollection instanceof SuperState) {
+ if (hierarchicalName.charAt(0) == '/'
+ && nodeCollection instanceof SuperState) {
nodeCollection = ((SuperState) nodeCollection).getProcessDefinition();
}
@@ -348,7 +357,7 @@
if ("..".equals(namePart)) {
if (nodeCollection instanceof ProcessDefinition) {
throw new JbpmException("could not find node '" + hierarchicalName
- + "' because of a '..' on the process definition.");
+ + "' because of a '..' on the process definition.");
}
nodeCollection = (NodeCollection) ((GraphElement) nodeCollection).getParent();
}
@@ -380,15 +389,19 @@
// actions //////////////////////////////////////////////////////////////////
/**
- * creates a bidirectional relation between this process definition and the given action.
+ * creates a bidirectional relation between this process definition and the
+ * given action.
*
- * @throws IllegalArgumentException if action is null or if action.getName() is null.
+ * @throws IllegalArgumentException if action is null or if action.getName()
+ * is null.
*/
public Action addAction(Action action) {
- if (action == null)
- throw new IllegalArgumentException("can't add a null action to an process definition");
- if (action.getName() == null)
- throw new IllegalArgumentException("can't add an unnamed action to an process definition");
+ if (action == null) {
+ throw new IllegalArgumentException("action is null");
+ }
+ if (action.getName() == null) {
+ throw new IllegalArgumentException("action is unnamed");
+ }
if (actions == null) actions = new HashMap();
actions.put(action.getName(), action);
action.processDefinition = this;
@@ -396,20 +409,20 @@
}
/**
- * removes the bidirectional relation between this process definition and the given action.
+ * removes the bidirectional relation between this process definition and the
+ * given action.
*
- * @throws IllegalArgumentException if action is null or if the action was not present in the
- * actions of this process definition.
+ * @throws IllegalArgumentException if action is null or if the action was not
+ * present in the actions of this process definition.
*/
public void removeAction(Action action) {
if (action == null) {
- throw new IllegalArgumentException(
- "can't remove a null action from an process definition");
+ throw new IllegalArgumentException("action is null");
}
if (actions != null) {
if (!actions.containsValue(action)) {
throw new IllegalArgumentException(
- "can't remove an action that is not part of this process definition");
+ "action is not present in process definition");
}
actions.remove(action.getName());
action.processDefinition = null;
@@ -417,8 +430,7 @@
}
public Action getAction(String name) {
- if (actions == null) return null;
- return (Action) actions.get(name);
+ return actions != null ? (Action) actions.get(name) : null;
}
public Map getActions() {
@@ -437,9 +449,9 @@
public ModuleDefinition addDefinition(ModuleDefinition moduleDefinition) {
if (moduleDefinition == null) {
- throw new IllegalArgumentException(
- "can't add a null moduleDefinition to a process definition");
+ throw new IllegalArgumentException("module definition is null");
}
+
if (definitions == null) definitions = new HashMap();
definitions.put(moduleDefinition.getClass().getName(), moduleDefinition);
moduleDefinition.setProcessDefinition(this);
@@ -447,11 +459,11 @@
}
public ModuleDefinition removeDefinition(ModuleDefinition moduleDefinition) {
- ModuleDefinition removedDefinition = null;
if (moduleDefinition == null) {
- throw new IllegalArgumentException(
- "can't remove a null moduleDefinition from a process definition");
+ throw new IllegalArgumentException("module definition is null");
}
+
+ ModuleDefinition removedDefinition = null;
if (definitions != null) {
removedDefinition = (ModuleDefinition) definitions.remove(moduleDefinition.getClass()
.getName());
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Transition.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Transition.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Transition.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -44,7 +44,8 @@
// event types //////////////////////////////////////////////////////////////
- public static final String[] supportedEventTypes = new String[] { Event.EVENTTYPE_TRANSITION };
+ public static final String[] supportedEventTypes =
+ { Event.EVENTTYPE_TRANSITION };
public String[] getSupportedEventTypes() {
return supportedEventTypes;
@@ -66,8 +67,9 @@
}
/**
- * sets the from node unidirectionally. use {@link Node#addLeavingTransition(Transition)} to
- * get bidirectional relations mgmt.
+ * sets the from node unidirectionally. use
+ * {@link Node#addLeavingTransition(Transition)} to get bidirectional
+ * relations mgmt.
*/
public void setFrom(Node from) {
this.from = from;
@@ -76,8 +78,9 @@
// to ///////////////////////////////////////////////////////////////////////
/**
- * sets the to node unidirectionally. use {@link Node#addArrivingTransition(Transition)} to
- * get bidirectional relations mgmt.
+ * sets the to node unidirectionally. use
+ * {@link Node#addArrivingTransition(Transition)} to get bidirectional
+ * relations mgmt.
*/
public void setTo(Node to) {
this.to = to;
@@ -114,22 +117,25 @@
Token token = executionContext.getToken();
if (condition != null && isConditionEnforced) {
- Object result = JbpmExpressionEvaluator.evaluate(condition, executionContext);
+ Object result =
+ JbpmExpressionEvaluator.evaluate(condition, executionContext);
if (result == null) {
- throw new JbpmException("transition condition " + condition + " evaluated to null");
+ throw new JbpmException("transition condition " + condition
+ + " evaluated to null");
}
else if (!(result instanceof Boolean)) {
throw new JbpmException("transition condition " + condition
- + " evaluated to non-boolean: " + result.getClass().getName());
+ + " evaluated to non-boolean: " + result.getClass().getName());
}
- else if (!((Boolean) result).booleanValue()) {
- throw new JbpmException("transition condition " + condition + " evaluated to 'false'");
+ else if (((Boolean) result).booleanValue() == false) {
+ throw new JbpmException("transition condition " + condition
+ + " evaluated to 'false'");
}
}
// start the transition log
- TransitionLog transitionLog = new TransitionLog(this,
- executionContext.getTransitionSource());
+ TransitionLog transitionLog =
+ new TransitionLog(this, executionContext.getTransitionSource());
token.startCompositeLog(transitionLog);
try {
// fire leave events for superstates (if any)
@@ -156,23 +162,27 @@
Node destination = to;
while (destination != null && destination.isSuperStateNode()) {
List nodes = destination.getNodes();
- destination = nodes != null && !nodes.isEmpty() ? (Node) nodes.get(0) : null;
+ destination =
+ nodes != null && !nodes.isEmpty() ? (Node) nodes.get(0) : null;
}
if (destination == null) {
- String transitionName = (name != null ? "'" + name + "'" : "in node '" + from + "'");
+ String transitionName =
+ name != null ? '\'' + name + '\'' : "in node '" + from + '\'';
throw new JbpmException("transition " + transitionName
- + " doesn't have destination. check your processdefinition.xml");
+ + " has no destination");
}
// optimisation: check if there is a candidate superstate to be entered.
if (destination.getSuperState() != null) {
// collect all the superstates being left
List leavingSuperStates = collectAllSuperStates(destination, from);
- // reverse the order so that events are fired from outer to inner superstates
+ // reverse order so that events fire from outer to inner superstates
Collections.reverse(leavingSuperStates);
// fire a superstate-enter event for all superstates being left
- fireSuperStateEvents(leavingSuperStates, Event.EVENTTYPE_SUPERSTATE_ENTER, executionContext);
+ fireSuperStateEvents(leavingSuperStates,
+ Event.EVENTTYPE_SUPERSTATE_ENTER,
+ executionContext);
}
return destination;
@@ -182,9 +192,12 @@
// optimisation: check if there is a candidate superstate to be left.
if (executionContext.getTransitionSource().getSuperState() != null) {
// collect all the superstates being left
- List leavingSuperStates = collectAllSuperStates(executionContext.getTransitionSource(), to);
+ List leavingSuperStates =
+ collectAllSuperStates(executionContext.getTransitionSource(), to);
// fire a node-leave event for all superstates being left
- fireSuperStateEvents(leavingSuperStates, Event.EVENTTYPE_SUPERSTATE_LEAVE, executionContext);
+ fireSuperStateEvents(leavingSuperStates,
+ Event.EVENTTYPE_SUPERSTATE_LEAVE,
+ executionContext);
}
}
@@ -225,15 +238,15 @@
if (!(o instanceof Transition)) return false;
Transition other = (Transition) o;
- return id != 0 ? id == other.getId() : (name != null ? name.equals(other.getName())
+ if (id != 0 && id == other.getId()) return true;
+
+ return (name != null ? name.equals(other.getName())
: other.getName() == null)
- && (from != null ? from.equals(other.getFrom()) : other.getFrom() == null)
- && (to != null ? to.equals(other.getTo()) : other.getTo() == null);
+ && (from != null ? from.equals(other.getFrom()) : other.getFrom() == null)
+ && (to != null ? to.equals(other.getTo()) : other.getTo() == null);
}
public int hashCode() {
- if (id != 0) return (int) (id ^ (id >>> 32));
-
int result = 580399073 + (name != null ? name.hashCode() : 0);
result = 345105097 * result + (from != null ? from.hashCode() : 0);
result = 345105097 * result + (to != null ? to.hashCode() : 0);
@@ -248,10 +261,10 @@
if (from.hasLeavingTransition(name)) {
throw new IllegalArgumentException(
"couldn't set name '"
- + name
- + "' on transition '"
- + this
- + "'cause the from-node of this transition has already another leaving transition with the same name");
+ + name
+ + "' on transition '"
+ + this
+ + "'cause the from-node of this transition has already another leaving transition with the same name");
}
Map fromLeavingTransitions = from.getLeavingTransitionsMap();
fromLeavingTransitions.remove(this.name);
@@ -264,8 +277,10 @@
if (from != null && to != null) {
if (from.equals(to)) return from.getParent();
- for (GraphElement fromParent = from; fromParent != null; fromParent = fromParent.getParent()) {
- for (GraphElement toParent = to; toParent != null; toParent = toParent.getParent()) {
+ for (GraphElement fromParent = from; fromParent != null; fromParent =
+ fromParent.getParent()) {
+ for (GraphElement toParent = to; toParent != null; toParent =
+ toParent.getParent()) {
if (fromParent.equals(toParent)) return fromParent;
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Comment.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Comment.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Comment.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -26,78 +26,108 @@
import org.jbpm.security.SecurityHelper;
import org.jbpm.taskmgmt.exe.TaskInstance;
-import org.jbpm.util.EqualsUtil;
public class Comment implements Serializable {
private static final long serialVersionUID = 1L;
- long id = 0;
- int version = 0;
- protected String actorId = null;
- protected Date time = null;
- protected String message = null;
- protected Token token = null;
- protected TaskInstance taskInstance = null;
+ long id;
+ int version;
+ protected String actorId;
+ protected Date time;
+ protected String message;
+ protected Token token;
+ protected TaskInstance taskInstance;
public Comment() {
}
-
+
public Comment(String message) {
this.actorId = SecurityHelper.getAuthenticatedActorId();
this.time = new Date();
this.message = message;
}
-
+
public Comment(String actorId, String message) {
this.actorId = actorId;
this.time = new Date();
this.message = message;
}
-
+
public String toString() {
- return "comment("+(actorId!=null ? actorId+"|" : "")+message+")";
+ return "Comment(" + message + ')';
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof Comment)) return false;
+
+ Comment other = (Comment) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return message.equals(other.getMessage())
+ && (actorId != null ? actorId.equals(other.getActorId())
+ : other.getActorId() == null)
+ && (taskInstance != null ? taskInstance.equals(other.getTaskInstance())
+ : token != null ? token.equals(other.getToken()) : false);
}
+ public int hashCode() {
+ int result = 769046417 + message.hashCode();
+ result = 1770536419 * result + actorId != null ? actorId.hashCode() : 0;
+ if (taskInstance != null) {
+ result = 55354751 * result + taskInstance.hashCode();
+ }
+ else if (token != null) {
+ result = 55354751 * result + token.hashCode();
+ }
+ return result;
+ }
+
// getters and setters //////////////////////////////////////////////////////
-
+
public String getActorId() {
return actorId;
}
+
public long getId() {
return id;
}
+
public String getMessage() {
return message;
}
+
public Date getTime() {
return time;
}
+
public TaskInstance getTaskInstance() {
return taskInstance;
}
+
public Token getToken() {
return token;
}
+
public void setTaskInstance(TaskInstance taskInstance) {
this.taskInstance = taskInstance;
}
+
public void setToken(Token token) {
this.token = token;
}
+
public void setActorId(String actorId) {
this.actorId = actorId;
}
+
public void setMessage(String message) {
this.message = message;
}
+
public void setTime(Date time) {
this.time = time;
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/ProcessInstance.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -52,8 +52,9 @@
import org.jbpm.util.Clock;
/**
- * is one execution of a {@link org.jbpm.graph.def.ProcessDefinition}. To create a new process
- * execution of a process definition, just use the {@link #ProcessInstance(ProcessDefinition)}.
+ * is one execution of a {@link org.jbpm.graph.def.ProcessDefinition}. To create
+ * a new process execution of a process definition, just use the
+ * {@link #ProcessInstance(ProcessDefinition)}.
*/
public class ProcessInstance implements Identifiable, Serializable {
@@ -80,11 +81,12 @@
}
/**
- * creates a new process instance for the given process definition, puts the root-token (=main
- * path of execution) in the start state and executes the initial node. In case the initial
- * node is a start-state, it will behave as a wait state. For each of the optional module
- * definitions contained in the {@link ProcessDefinition}, the corresponding module instance
- * will be created.
+ * creates a new process instance for the given process definition, puts the
+ * root-token (=main path of execution) in the start state and executes the
+ * initial node. In case the initial node is a start-state, it will behave as
+ * a wait state. For each of the optional module definitions contained in the
+ * {@link ProcessDefinition}, the corresponding module instance will be
+ * created.
*
* @throws JbpmException if processDefinition is null.
*/
@@ -93,15 +95,16 @@
}
/**
- * creates a new process instance for the given process definition, puts the root-token (=main
- * path of execution) in the start state and executes the initial node. In case the initial
- * node is a start-state, it will behave as a wait state. For each of the optional module
- * definitions contained in the {@link ProcessDefinition}, the corresponding module instance
- * will be created.
+ * creates a new process instance for the given process definition, puts the
+ * root-token (=main path of execution) in the start state and executes the
+ * initial node. In case the initial node is a start-state, it will behave as
+ * a wait state. For each of the optional module definitions contained in the
+ * {@link ProcessDefinition}, the corresponding module instance will be
+ * created.
*
- * @param variables will be inserted into the context variables after the context submodule
- * has been created and before the process-start event is fired, which is also before
- * the execution of the initial node.
+ * @param variables will be inserted into the context variables after the
+ * context submodule has been created and before the process-start event is
+ * fired, which is also before the execution of the initial node.
* @throws JbpmException if processDefinition is null.
*/
public ProcessInstance(ProcessDefinition processDefinition, Map variables) {
@@ -109,27 +112,29 @@
}
/**
- * creates a new process instance for the given process definition, puts the root-token (=main
- * path of execution) in the start state and executes the initial node. In case the initial
- * node is a start-state, it will behave as a wait state. For each of the optional module
- * definitions contained in the {@link ProcessDefinition}, the corresponding module instance
- * will be created.
+ * creates a new process instance for the given process definition, puts the
+ * root-token (=main path of execution) in the start state and executes the
+ * initial node. In case the initial node is a start-state, it will behave as
+ * a wait state. For each of the optional module definitions contained in the
+ * {@link ProcessDefinition}, the corresponding module instance will be
+ * created.
*
- * @param variables will be inserted into the context variables after the context submodule
- * has been created and before the process-start event is fired, which is also before
- * the execution of the initial node.
+ * @param variables will be inserted into the context variables after the
+ * context submodule has been created and before the process-start event is
+ * fired, which is also before the execution of the initial node.
* @throws JbpmException if processDefinition is null.
*/
- public ProcessInstance(ProcessDefinition processDefinition, Map variables, String key) {
+ public ProcessInstance(ProcessDefinition processDefinition, Map variables,
+ String key) {
if (processDefinition == null) {
- throw new JbpmException("can't create a process instance when processDefinition is null");
+ throw new IllegalArgumentException("process definition is null");
}
// initialize the members
this.processDefinition = processDefinition;
this.rootToken = new Token(this);
this.key = key;
- // if this process instance is created in the context of a persistent operation
+ // if this is created in the context of a persistent operation
Services.assignId(this);
// create the optional definitions
@@ -175,7 +180,8 @@
// fire the process start event
if (initialNode != null) {
ExecutionContext executionContext = new ExecutionContext(rootToken);
- processDefinition.fireEvent(Event.EVENTTYPE_PROCESS_START, executionContext);
+ processDefinition.fireEvent(Event.EVENTTYPE_PROCESS_START,
+ executionContext);
// execute the start node
initialNode.execute(executionContext);
@@ -189,9 +195,9 @@
*/
public ModuleInstance addInstance(ModuleInstance moduleInstance) {
if (moduleInstance == null) {
- throw new IllegalArgumentException(
- "can't add a null moduleInstance to a process instance");
+ throw new IllegalArgumentException("module instance is null");
}
+
if (instances == null) instances = new HashMap();
instances.put(moduleInstance.getClass().getName(), moduleInstance);
moduleInstance.setProcessInstance(this);
@@ -202,11 +208,11 @@
* removes the given optional moduleinstance (bidirectional).
*/
public ModuleInstance removeInstance(ModuleInstance moduleInstance) {
- ModuleInstance removedModuleInstance = null;
if (moduleInstance == null) {
- throw new IllegalArgumentException(
- "can't remove a null moduleInstance from a process instance");
+ throw new IllegalArgumentException("module instance is null");
}
+
+ ModuleInstance removedModuleInstance = null;
if (instances != null) {
removedModuleInstance = (ModuleInstance) instances.remove(moduleInstance.getClass()
.getName());
@@ -222,8 +228,9 @@
*/
public ModuleInstance getInstance(Class clazz) {
ModuleInstance moduleInstance = null;
+ String className = clazz.getName();
if (instances != null) {
- moduleInstance = (ModuleInstance) instances.get(clazz.getName());
+ moduleInstance = (ModuleInstance) instances.get(className);
}
if (moduleInstance == null) {
@@ -231,18 +238,21 @@
// client requested an instance that is not in the map of instances.
// so we can safely assume that the client wants a transient instance
- moduleInstance = (ModuleInstance) transientInstances.get(clazz.getName());
+ moduleInstance = (ModuleInstance) transientInstances.get(className);
if (moduleInstance == null) {
try {
moduleInstance = (ModuleInstance) clazz.newInstance();
moduleInstance.setProcessInstance(this);
-
}
- catch (Exception e) {
- throw new JbpmException("couldn't instantiate transient module '" + clazz.getName()
- + "' with the default constructor");
+ catch (InstantiationException e) {
+ throw new JbpmException("could not instantiate transient module "
+ + className, e);
}
- transientInstances.put(clazz.getName(), moduleInstance);
+ catch (IllegalAccessException e) {
+ throw new JbpmException("could not access transient module "
+ + className, e);
+ }
+ transientInstances.put(className, moduleInstance);
}
}
@@ -264,9 +274,9 @@
}
/**
- * process instance extension for logging. Probably you don't need to access the logging
- * instance directly. Mostly, {@link Token#addLog(ProcessLog)} is sufficient and more
- * convenient.
+ * process instance extension for logging. Probably you don't need to access
+ * the logging instance directly. Mostly, {@link Token#addLog(ProcessLog)} is
+ * sufficient and more convenient.
*/
public LoggingInstance getLoggingInstance() {
return (LoggingInstance) getInstance(LoggingInstance.class);
@@ -275,40 +285,40 @@
// operations ///////////////////////////////////////////////////////////////
/**
- * instructs the main path of execution to continue by taking the default transition on the
- * current node.
+ * instructs the main path of execution to continue by taking the default
+ * transition on the current node.
*
* @throws IllegalStateException if the token is not active.
*/
public void signal() {
if (hasEnded()) {
- throw new IllegalStateException("couldn't signal token : token has ended");
+ throw new IllegalStateException("token has ended");
}
rootToken.signal();
}
/**
- * instructs the main path of execution to continue by taking the specified transition on the
- * current node.
+ * instructs the main path of execution to continue by taking the specified
+ * transition on the current node.
*
* @throws IllegalStateException if the token is not active.
*/
public void signal(String transitionName) {
if (hasEnded()) {
- throw new IllegalStateException("couldn't signal token : token has ended");
+ throw new IllegalStateException("token has ended");
}
rootToken.signal(transitionName);
}
/**
- * instructs the main path of execution to continue by taking the specified transition on the
- * current node.
+ * instructs the main path of execution to continue by taking the specified
+ * transition on the current node.
*
* @throws IllegalStateException if the token is not active.
*/
public void signal(Transition transition) {
if (hasEnded()) {
- throw new IllegalStateException("couldn't signal token : token has ended");
+ throw new IllegalStateException("token has ended");
}
rootToken.signal(transition);
}
@@ -335,7 +345,8 @@
if (superProcessToken != null && !superProcessToken.hasEnded()) {
addCascadeProcessInstance(superProcessToken.getProcessInstance());
- ExecutionContext superExecutionContext = new ExecutionContext(superProcessToken);
+ ExecutionContext superExecutionContext = new ExecutionContext(
+ superProcessToken);
superExecutionContext.setSubProcessInstance(this);
superProcessToken.signal(superExecutionContext);
}
@@ -348,8 +359,9 @@
MessageService messageService = services.getMessageService();
PersistenceService persistenceService = services.getPersistenceService();
if (messageService != null
- && persistenceService != null
- && persistenceService.getJobSession().countDeletableJobsForProcessInstance(this) > 0) {
+ && persistenceService != null
+ && persistenceService.getJobSession()
+ .countDeletableJobsForProcessInstance(this) > 0) {
CleanUpProcessJob job = new CleanUpProcessJob(rootToken);
job.setDueDate(new Date());
messageService.send(job);
@@ -359,8 +371,9 @@
}
/**
- * suspends this execution. This will make sure that tasks, timers and messages related to
- * this process instance will not show up in database queries.
+ * suspends this execution. This will make sure that tasks, timers and
+ * messages related to this process instance will not show up in database
+ * queries.
*
* @see #resume()
*/
@@ -370,10 +383,10 @@
}
/**
- * resumes a suspended execution. All timers that have been suspended might fire if the
- * duedate has been passed. If an admin resumes a process instance, the option should be
- * offered to update, remove and create the timers and messages related to this process
- * instance.
+ * resumes a suspended execution. All timers that have been suspended might
+ * fire if the duedate has been passed. If an admin resumes a process
+ * instance, the option should be offered to update, remove and create the
+ * timers and messages related to this process instance.
*
* @see #suspend()
*/
@@ -389,7 +402,7 @@
*/
public RuntimeAction addRuntimeAction(RuntimeAction runtimeAction) {
if (runtimeAction == null) {
- throw new IllegalArgumentException("can't add a null runtimeAction to a process instance");
+ throw new IllegalArgumentException("runtime action is null");
}
if (runtimeActions == null) runtimeActions = new ArrayList();
runtimeActions.add(runtimeAction);
@@ -403,8 +416,7 @@
public RuntimeAction removeRuntimeAction(RuntimeAction runtimeAction) {
RuntimeAction removedRuntimeAction = null;
if (runtimeAction == null) {
- throw new IllegalArgumentException(
- "can't remove a null runtimeAction from an process instance");
+ throw new IllegalArgumentException("runtime action is null");
}
if (runtimeActions != null) {
if (runtimeActions.remove(runtimeAction)) {
@@ -443,9 +455,11 @@
}
/**
- * looks up the token in the tree, specified by the slash-separated token path.
+ * looks up the token in the tree, specified by the slash-separated token
+ * path.
*
- * @param tokenPath is a slash-separated name that specifies a token in the tree.
+ * @param tokenPath is a slash-separated name that specifies a token in the
+ * tree.
* @return the specified token or null if the token is not found.
*/
public Token findToken(String tokenPath) {
@@ -482,23 +496,24 @@
if (!(o instanceof ProcessInstance)) return false;
ProcessInstance other = (ProcessInstance) o;
- return id != 0 ? id == other.getId() : (key != null ? key.equals(other.getKey())
- : other.getKey() == null)
- && processDefinition.equals(other.getProcessDefinition());
+ if (id != 0 && id == other.getId()) return true;
+
+ return key != null && key.equals(other.getKey())
+ && processDefinition.equals(other.getProcessDefinition());
}
public int hashCode() {
- if (id != 0) return (int) (id ^ (id >>> 32));
+ if (key == null) return super.hashCode();
- int result = 295436291 + (key != null ? key.hashCode() : 0);
+ int result = 295436291 + key.hashCode();
result = 1367411281 * result + processDefinition.hashCode();
return result;
}
public String toString() {
return "ProcessInstance"
- + (key != null ? '(' + key + ')' : id != 0 ? "(" + id + ')'
- : '@' + Integer.toHexString(hashCode()));
+ + (key != null ? '(' + key + ')' : id != 0 ? "(" + id + ')'
+ : '@' + Integer.toHexString(hashCode()));
}
// getters and setters //////////////////////////////////////////////////////
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/RuntimeAction.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/RuntimeAction.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/RuntimeAction.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -21,32 +21,35 @@
*/
package org.jbpm.graph.exe;
-import java.io.*;
+import java.io.Serializable;
-import org.jbpm.graph.def.*;
-import org.jbpm.util.EqualsUtil;
+import org.jbpm.graph.def.Action;
+import org.jbpm.graph.def.Event;
+import org.jbpm.graph.def.GraphElement;
+import org.jbpm.graph.def.ProcessDefinition;
/**
- * is an action that can be added at runtime to the execution of one process instance.
+ * is an action added at runtime to the execution of one process instance.
*/
public class RuntimeAction implements Serializable {
-
+
private static final long serialVersionUID = 1L;
-
- long id = 0;
- int version = 0;
- protected ProcessInstance processInstance = null;
- protected GraphElement graphElement = null;
- protected String eventType = null;
- protected Action action = null;
-
+
+ long id;
+ int version;
+ protected ProcessInstance processInstance;
+ protected GraphElement graphElement;
+ protected String eventType;
+ protected Action action;
+
public RuntimeAction() {
}
/**
- * creates a runtime action. Look up the event with {@link GraphElement#getEvent(String)}
- * and the action with {@link ProcessDefinition#getAction(String)}. You can only
- * lookup named actions easily.
+ * creates a runtime action. Look up the event with
+ * {@link GraphElement#getEvent(String)} and the action with
+ * {@link ProcessDefinition#getAction(String)}. You can only lookup named
+ * actions easily.
*/
public RuntimeAction(Event event, Action action) {
this.graphElement = event.getGraphElement();
@@ -54,33 +57,52 @@
this.action = action;
}
- public RuntimeAction(GraphElement graphElement, String eventType, Action action) {
+ public RuntimeAction(GraphElement graphElement, String eventType,
+ Action action) {
this.graphElement = graphElement;
this.eventType = eventType;
this.action = action;
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof Event)) return false;
+
+ RuntimeAction other = (RuntimeAction) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return eventType.equals(other.getEventType())
+ && graphElement.equals(other.getGraphElement())
+ && processInstance.equals(other.getProcessInstance());
}
-
+
+ public int hashCode() {
+ int result = 560044783 + eventType.hashCode();
+ result = 279308149 * result + graphElement.hashCode();
+ result = 106268467 * result + processInstance.hashCode();
+ return result;
+ }
+
// getters and setters //////////////////////////////////////////////////////
public long getId() {
return id;
}
+
public ProcessInstance getProcessInstance() {
return processInstance;
}
+
public Action getAction() {
return action;
}
+
public String getEventType() {
return eventType;
}
+
public GraphElement getGraphElement() {
return graphElement;
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/exe/Token.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -55,8 +55,8 @@
/**
* represents one path of execution and maintains a pointer to a node in the
- * {@link org.jbpm.graph.def.ProcessDefinition}. Most common way to get a hold of the token
- * objects is with {@link ProcessInstance#getRootToken()} or
+ * {@link org.jbpm.graph.def.ProcessDefinition}. Most common way to get a hold
+ * of the token objects is with {@link ProcessInstance#getRootToken()} or
* {@link org.jbpm.graph.exe.ProcessInstance#findToken(String)}.
*/
public class Token implements Identifiable, Serializable {
@@ -94,7 +94,8 @@
this.start = Clock.getCurrentTime();
this.processInstance = processInstance;
this.node = processInstance.getProcessDefinition().getStartState();
- this.isTerminationImplicit = processInstance.getProcessDefinition().isTerminationImplicit();
+ this.isTerminationImplicit = processInstance.getProcessDefinition()
+ .isTerminationImplicit();
// assign an id to this token before events get fired
Services.assignId(this);
@@ -128,29 +129,26 @@
}
/**
- * provides a signal to the token. this method activates this token and leaves the current
- * state over the default transition.
+ * provides a signal to the token. this method activates this token and leaves
+ * the current state over the default transition.
*/
public void signal() {
if (node == null) {
- throw new JbpmException("token '" + this
- + "' can't be signalled cause it is currently not positioned in a node");
+ throw new JbpmException(this + " is not positioned in a node");
}
if (node.getDefaultLeavingTransition() == null) {
- throw new JbpmException("couldn't signal " + this + " : node " + node
- + " has no default transition");
+ throw new JbpmException(node + " has no default transition");
}
signal(node.getDefaultLeavingTransition(), new ExecutionContext(this));
}
/**
- * Provides a signal to the token. This leave the current state over the given transition
- * name.
+ * Provides a signal to the token. This leave the current state over the given
+ * transition name.
*/
public void signal(String transitionName) {
if (node == null) {
- throw new JbpmException("token '" + this
- + "' can't be signalled cause it is currently not positioned in a node");
+ throw new JbpmException(this + "' is not positioned in a node");
}
Transition leavingTransition = node.getLeavingTransition(transitionName);
@@ -166,15 +164,17 @@
}
}
- if (leavingTransition == null)
- throw new JbpmException("transition '" + transitionName + "' does not exist on " + node);
+ if (leavingTransition == null) {
+ throw new JbpmException(node + " has no leaving transition named "
+ + transitionName);
+ }
signal(leavingTransition, new ExecutionContext(this));
}
/**
- * provides a signal to the token. this leave the current state over the given transition
- * name.
+ * provides a signal to the token. this leave the current state over the given
+ * transition name.
*/
public void signal(Transition transition) {
signal(transition, new ExecutionContext(this));
@@ -190,18 +190,16 @@
"couldn't signal without specifying a leaving transition : transition is null");
}
if (executionContext == null) {
- throw new JbpmException(
- "couldn't signal without an execution context: executionContext is null");
+ throw new JbpmException("execution context is null");
}
if (isSuspended) {
- throw new JbpmException("can't signal token '" + name + "' (" + id + "): it is suspended");
+ throw new JbpmException("token is suspended");
}
if (isLocked()) {
- throw new JbpmException("this token is locked by " + lock);
+ throw new JbpmException("token is locked by " + lock);
}
if (hasEnded()) {
- throw new JbpmException("Token '" + name + "' (" + id
- + ") is already ended and cannot be signaled");
+ throw new JbpmException("token has ended");
}
startCompositeLog(new SignalLog(transition));
@@ -226,8 +224,8 @@
}
/**
- * a set of all the leaving transitions on the current node for which the condition expression
- * resolves to true.
+ * a set of all the leaving transitions on the current node for which the
+ * condition expression resolves to true.
*/
public Set getAvailableTransitions() {
Set availableTransitions = new HashSet();
@@ -238,10 +236,11 @@
}
/**
- * adds available transitions of that node to the Set and after that calls itself recursivly
- * for the SuperSate of the Node if it has a super state
+ * adds available transitions of that node to the Set and after that calls
+ * itself recursivly for the SuperSate of the Node if it has a super state
*/
- private void addAvailableTransitionsOfNode(Node currentNode, Set availableTransitions) {
+ private void addAvailableTransitionsOfNode(Node currentNode,
+ Set availableTransitions) {
List leavingTransitions = currentNode.getLeavingTransitions();
if (leavingTransitions != null) {
Iterator iter = leavingTransitions.iterator();
@@ -249,9 +248,10 @@
Transition transition = (Transition) iter.next();
String conditionExpression = transition.getCondition();
if (conditionExpression != null) {
- Object result = JbpmExpressionEvaluator.evaluate(conditionExpression, new ExecutionContext(
- this));
- if ((result instanceof Boolean) && (((Boolean) result).booleanValue())) {
+ Object result = JbpmExpressionEvaluator.evaluate(conditionExpression,
+ new ExecutionContext(this));
+ if ((result instanceof Boolean)
+ && (((Boolean) result).booleanValue())) {
availableTransitions.add(transition);
}
}
@@ -261,14 +261,15 @@
}
}
if (currentNode.getSuperState() != null) {
- addAvailableTransitionsOfNode(currentNode.getSuperState(), availableTransitions);
+ addAvailableTransitionsOfNode(currentNode.getSuperState(),
+ availableTransitions);
}
}
/**
- * ends this token and all of its children (if any). this is the last active (=not-ended)
- * child of a parent token, the parent token will be ended as well and that verification will
- * continue to propagate.
+ * ends this token and all of its children (if any). this is the last active
+ * (=not-ended) child of a parent token, the parent token will be ended as
+ * well and that verification will continue to propagate.
*/
public void end() {
end(true);
@@ -277,10 +278,10 @@
/**
* ends this token with optional parent ending verification.
*
- * @param verifyParentTermination specifies if the parent token should be checked for
- * termination. if verifyParentTermination is set to true and this is the last
- * non-ended child of a parent token, the parent token will be ended as well and the
- * verification will continue to propagate.
+ * @param verifyParentTermination specifies if the parent token should be
+ * checked for termination. if verifyParentTermination is set to true and this
+ * is the last non-ended child of a parent token, the parent token will be
+ * ended as well and the verification will continue to propagate.
*/
public void end(boolean verifyParentTermination) {
// if not already ended
@@ -308,13 +309,15 @@
subProcessInstance.end();
}
- // only log child-token ends. process instance logs replace root token logs.
+ // only log child-token ends. process instance logs replace root token
+ // logs.
if (parent != null) {
// add a log
parent.addLog(new TokenEndLog(this));
}
- // if there are tasks associated to this token, remove signaling capabilities
+ // if there are tasks associated to this token, remove signaling
+ // capabilities
TaskMgmtInstance taskMgmtInstance = (processInstance != null ? processInstance.getTaskMgmtInstance()
: null);
if (taskMgmtInstance != null) {
@@ -354,11 +357,8 @@
if (isRoot()) {
processInstance.end();
}
- else {
-
- if (!parent.hasActiveChildren()) {
- parent.end();
- }
+ else if (!parent.hasActiveChildren()) {
+ parent.end();
}
}
@@ -395,8 +395,8 @@
}
/**
- * convenience method for starting a composite log. When you add composite logs, make sure you
- * put the {@link #endCompositeLog()} in a finally block.
+ * convenience method for starting a composite log. When you add composite
+ * logs, make sure you put the {@link #endCompositeLog()} in a finally block.
*/
public void startCompositeLog(CompositeLog compositeLog) {
LoggingInstance li = (LoggingInstance) processInstance.getInstance(LoggingInstance.class);
@@ -407,7 +407,8 @@
}
/**
- * convenience method for ending a composite log. Make sure you put this in a finally block.
+ * convenience method for ending a composite log. Make sure you put this in a
+ * finally block.
*/
public void endCompositeLog() {
LoggingInstance li = (LoggingInstance) processInstance.getInstance(LoggingInstance.class);
@@ -584,7 +585,8 @@
void suspendJobs() {
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
- JobSession jobSession = (jbpmContext != null ? jbpmContext.getJobSession() : null);
+ JobSession jobSession = jbpmContext != null ? jbpmContext.getJobSession()
+ : null;
if (jobSession != null) {
jobSession.suspendJobs(this);
}
@@ -619,7 +621,8 @@
void resumeJobs() {
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
- JobSession jobSession = (jbpmContext != null ? jbpmContext.getJobSession() : null);
+ JobSession jobSession = jbpmContext != null ? jbpmContext.getJobSession()
+ : null;
if (jobSession != null) {
jobSession.resumeJobs(this);
}
@@ -640,18 +643,18 @@
if (!(o instanceof Token)) return false;
Token other = (Token) o;
- return id != 0 ? id == other.getId() : (name != null ? name.equals(other.getName())
+ if (id != 0 && id == other.getId()) return true;
+
+ return (name != null ? name.equals(other.getName())
: other.getName() == null)
- && (parent != null ? parent.equals(other.getParent())
- : processInstance.equals(other.getProcessInstance()));
+ && (parent != null ? parent.equals(other.getParent())
+ : processInstance.equals(other.getProcessInstance()));
}
public int hashCode() {
- if (id != 0) return (int) (id ^ (id >>> 32));
-
int result = 2080763213 + (name != null ? name.hashCode() : 0);
result = 1076685199 * result
- + (parent != null ? parent.hashCode() : processInstance.hashCode());
+ + (parent != null ? parent.hashCode() : processInstance.hashCode());
return result;
}
@@ -659,7 +662,8 @@
return "Token(" + getFullName() + ')';
}
- public ProcessInstance createSubProcessInstance(ProcessDefinition subProcessDefinition) {
+ public ProcessInstance createSubProcessInstance(
+ ProcessDefinition subProcessDefinition) {
// create the new sub process instance
subProcessInstance = new ProcessInstance(subProcessDefinition);
// bind the subprocess to the super-process-token
@@ -671,56 +675,79 @@
}
/**
- * locks a process instance for further execution. A locked token cannot continue execution.
- * This is a non-persistent operation. This is used to prevent tokens being propagated during
- * the execution of actions.
+ * locks a process instance for further execution. A locked token cannot
+ * continue execution. This is a non-persistent operation. This is used to
+ * prevent tokens being propagated during the execution of actions.
*
* @see #unlock(String)
*/
public void lock(String lockOwnerId) {
if (lockOwnerId == null) {
- throw new JbpmException("can't lock with null value for the lockOwnerId");
+ throw new JbpmException("lock owner is null");
}
- if ((lock != null) && (!lock.equals(lockOwnerId))) {
- throw new JbpmException(this + " cannot be locked by '" + lockOwnerId
- + "' because it is already locked by '" + lock + "'");
+
+ if (lock == null) {
+ lock = lockOwnerId;
+ log.debug('\'' + lockOwnerId + "' locked " + this);
}
- log.debug("token[" + id + "] is locked by " + lockOwnerId);
- lock = lockOwnerId;
+ else if (!lock.equals(lockOwnerId)) {
+ throw new JbpmException('\'' + lockOwnerId + "' cannot lock " + this
+ + " because '" + lock + "' already locked it");
+ }
}
/**
* @see #lock(String)
*/
public void unlock(String lockOwnerId) {
- if (lock == null) {
- log.warn("lock owner '" + lockOwnerId + "' tries to unlock token '" + id
- + "' which is not locked");
+ if (lock != null) {
+ if (!lock.equals(lockOwnerId)) {
+ throw new JbpmException('\'' + lockOwnerId + "' cannot unlock " + this
+ + " because '" + lock + "' locked it");
+ }
+ lock = null;
+ log.debug('\'' + lockOwnerId + "' unlocked " + this);
}
- else if (!lock.equals(lockOwnerId)) {
- throw new JbpmException("'" + lockOwnerId + "' can't unlock token '" + id
- + "' because it was already locked by '" + lock + "'");
+ else {
+ log.warn(this + " was unlocked already");
}
- log.debug("token[" + id + "] is unlocked by " + lockOwnerId);
- lock = null;
}
/**
- * force unlocking the token, even if the owner is not known. In some use cases (e.g. in the
- * jbpm esb integration) the lock is persistent, so a state can be reached where the client
- * needs a possibility to force unlock of a token without knowing the owner. See
- * https://jira.jboss.org/jira/browse/JBPM-1888
+ * force unlocking the token, even if the owner is not known. In some use
+ * cases (e.g. in the jbpm esb integration) the lock is persistent, so a state
+ * can be reached where the client needs a possibility to force unlock of a
+ * token without knowing the owner.
+ *
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1888">JBPM-1888</a>
+ * @deprecated Use {@link #forceUnlock()} instead
*/
public void foreUnlock() {
- if (lock == null) {
- log.warn("Unlock of token '" + id + "' forced, but it is not locked");
+ forceUnlock();
+ }
+
+ /**
+ * force unlocking the token, even if the owner is not known. In some use
+ * cases (e.g. in the jbpm esb integration) the lock is persistent, so a state
+ * can be reached where the client needs a possibility to force unlock of a
+ * token without knowing the owner.
+ *
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1888">JBPM-1888</a>
+ */
+ public void forceUnlock() {
+ if (lock != null) {
+ lock = null;
+ log.debug("forcefully unlocked " + this);
}
- log.debug("Foce unlock of token[" + id + "] which was locked by " + lock);
- lock = null;
+ else {
+ log.warn(this + " was unlocked already");
+ }
}
/**
- * return the current lock owner of the token See https://jira.jboss.org/jira/browse/JBPM-1888
+ * return the current lock owner of the token
+ *
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1888">JBPM-1888</a>
*/
public String getLockOwner() {
return lock;
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/Delegation.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/Delegation.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/Delegation.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -41,7 +41,7 @@
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.jpdl.xml.JpdlXmlReader;
import org.jbpm.jpdl.xml.Parsable;
-import org.jbpm.util.EqualsUtil;
+import org.jbpm.jpdl.xml.Problem;
public class Delegation implements Parsable, Serializable {
@@ -55,7 +55,8 @@
instantiators.put("field", new FieldInstantiator());
instantiators.put("bean", new BeanInstantiator());
instantiators.put("constructor", new ConstructorInstantiator());
- instantiators.put("configuration-property", new ConfigurationPropertyInstantiator());
+ instantiators.put("configuration-property",
+ new ConfigurationPropertyInstantiator());
instantiators.put("xml", new XmlInstantiator());
return instantiators;
}
@@ -89,8 +90,10 @@
if (delegateElement.hasContent()) {
try {
StringWriter stringWriter = new StringWriter();
- // when parsing, it could be to store the config in the database, so we want to make the configuration compact
- XMLWriter xmlWriter = new XMLWriter(stringWriter, OutputFormat.createCompactFormat());
+ // when parsing, it could be to store the config in the database,
+ // so we want to make the configuration compact
+ XMLWriter xmlWriter = new XMLWriter(stringWriter,
+ OutputFormat.createCompactFormat());
for (Iterator iter = delegateElement.content().iterator(); iter.hasNext();) {
Object node = iter.next();
xmlWriter.write(node);
@@ -99,8 +102,8 @@
configuration = stringWriter.toString();
}
catch (IOException e) {
- jpdlReader.addWarning("io problem while parsing the configuration of "
- + delegateElement.asXML());
+ jpdlReader.addProblem(new Problem(Problem.LEVEL_WARNING,
+ "failed to write configuration xml", e));
}
}
}
@@ -111,12 +114,12 @@
String configuration = this.configuration;
if (configuration != null) {
try {
- Element actionElement = DocumentHelper.parseText("<action>" + configuration + "</action>")
- .getRootElement();
+ Element actionElement = DocumentHelper.parseText(
+ "<action>" + configuration + "</action>").getRootElement();
element.appendContent(actionElement);
}
catch (DocumentException e) {
- log.error("couldn't create dom-tree for action configuration '" + configuration + "'", e);
+ log.error("could not parse action configuration: " + configuration, e);
}
}
}
@@ -130,10 +133,10 @@
public Object instantiate() {
// The thread class loader was set before the instantiation correctly
- // to the ProcessClassLoader which can be directly used here
+ // to the ProcessClassLoader (PCL) which can be directly used here
// If we would construct a JbpmConfiguration.getProcessClassLoder here
- // we would have the hierarchy ProcessClassLoader -> ProcessClassLoader -> Context...
- // this is one ProcessClassLoader too much
+ // we would have the hierarchy PCL -> PCL -> Context...
+ // this is one PCL too much
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// find the instantiator
@@ -147,7 +150,8 @@
instantiatorCache.put(configType, instantiator);
}
catch (ClassNotFoundException e) {
- throw new JbpmException("could not load instantiator class '" + configType + "'", e);
+ throw new JbpmException("could not load instantiator class "
+ + configType, e);
}
catch (InstantiationException e) {
throw new JbpmException("could not instantiate " + configType, e);
@@ -164,17 +168,36 @@
return instantiator.instantiate(delegationClass, configuration);
}
catch (ClassNotFoundException e) {
- throw new DelegationException("could not load delegation class '" + className + "'", e);
+ throw new DelegationException("could not load delegation class "
+ + className, e);
}
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof Delegation)) return false;
+
+ Delegation other = (Delegation) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return className.equals(other.getClassName())
+ && (configuration != null ? configuration.equals(other.getConfiguration())
+ : other.getConfiguration() == null);
}
+ public int hashCode() {
+ int result = 2131399759 + className.hashCode();
+ result = 702058657 * result + configuration != null ? configuration.hashCode()
+ : 0;
+ return result;
+ }
+
+ public String toString() {
+ return "Delegation(" + className + ')';
+ }
+
// getters and setters //////////////////////////////////////////////////////
public String getClassName() {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/def/ModuleDefinition.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/def/ModuleDefinition.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/def/ModuleDefinition.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -25,12 +25,11 @@
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.module.exe.ModuleInstance;
-import org.jbpm.util.EqualsUtil;
public abstract class ModuleDefinition implements Serializable {
long id;
- protected String name;
+ protected String name; // name equals fully qualified class name
protected ProcessDefinition processDefinition;
private static final long serialVersionUID = 1L;
@@ -42,12 +41,24 @@
public abstract ModuleInstance createInstance();
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof ModuleDefinition)) return false;
+
+ ModuleDefinition other = (ModuleDefinition) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return name.equals(other.getName())
+ && processDefinition.equals(other.getProcessDefinition());
}
+ public int hashCode() {
+ int result = 2122701961 + name.hashCode();
+ result = 1574886923 * result + processDefinition.hashCode();
+ return result;
+ }
+
// getters and setters //////////////////////////////////////////////////////
public long getId() {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/exe/ModuleInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/exe/ModuleInstance.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/module/exe/ModuleInstance.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -26,43 +26,56 @@
import org.jbpm.JbpmContext;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.svc.Service;
-import org.jbpm.util.EqualsUtil;
public class ModuleInstance implements Serializable {
-
+
private static final long serialVersionUID = 1L;
-
- long id = 0;
- int version = 0;
- protected ProcessInstance processInstance = null;
-
+
+ long id;
+ int version;
+ protected ProcessInstance processInstance;
+
public ModuleInstance() {
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof ModuleInstance)) return false;
+
+ ModuleInstance other = (ModuleInstance) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return getClass().getName().equals(other.getClass().getName())
+ && processInstance.equals(other.getProcessInstance());
}
-
+
+ public int hashCode() {
+ int result = 1849786963 + getClass().getName().hashCode();
+ result = 1566965963 * result + processInstance.hashCode();
+ return result;
+ }
+
protected Service getService(String serviceName) {
Service service = null;
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
- if (jbpmContext!=null) {
+ if (jbpmContext != null) {
service = jbpmContext.getServices().getService(serviceName);
}
- return service;
+ return service;
}
-
+
// getters and setters //////////////////////////////////////////////////////
public long getId() {
return id;
}
+
public ProcessInstance getProcessInstance() {
return processInstance;
}
+
public void setProcessInstance(ProcessInstance processInstance) {
this.processInstance = processInstance;
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/Swimlane.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/Swimlane.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/Swimlane.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -21,27 +21,27 @@
*/
package org.jbpm.taskmgmt.def;
-import java.io.*;
-import java.util.*;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
-import org.jbpm.instantiation.*;
-import org.jbpm.util.EqualsUtil;
+import org.jbpm.instantiation.Delegation;
/**
* is a process role (aka participant).
*/
public class Swimlane implements Serializable {
-
+
private static final long serialVersionUID = 1L;
- long id = 0;
- protected String name = null;
- protected String actorIdExpression = null;
- protected String pooledActorsExpression = null;
- protected Delegation assignmentDelegation = null;
- protected TaskMgmtDefinition taskMgmtDefinition = null;
- protected Set tasks = null;
-
+ long id;
+ protected String name;
+ protected String actorIdExpression;
+ protected String pooledActorsExpression;
+ protected Delegation assignmentDelegation;
+ protected TaskMgmtDefinition taskMgmtDefinition;
+ protected Set tasks;
+
public Swimlane() {
}
@@ -50,8 +50,8 @@
}
/**
- * sets the taskMgmtDefinition unidirectionally. use TaskMgmtDefinition.addSwimlane to create
- * a bidirectional relation.
+ * sets the taskMgmtDefinition unidirectionally. use
+ * TaskMgmtDefinition.addSwimlane to create a bidirectional relation.
*/
public void setTaskMgmtDefinition(TaskMgmtDefinition taskMgmtDefinition) {
this.taskMgmtDefinition = taskMgmtDefinition;
@@ -59,8 +59,8 @@
// tasks ////////////////////////////////////////////////////////////////////
- public void addTask( Task task ) {
- if (tasks==null) tasks = new HashSet();
+ public void addTask(Task task) {
+ if (tasks == null) tasks = new HashSet();
tasks.add(task);
task.setSwimlane(this);
}
@@ -70,24 +70,38 @@
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof Swimlane)) return false;
+
+ Swimlane other = (Swimlane) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return name.equals(other.getName())
+ && taskMgmtDefinition.equals(other.getTaskMgmtDefinition());
}
+ public int hashCode() {
+ int result = 1154431951 + name.hashCode();
+ result = 1436943863 * result + taskMgmtDefinition.hashCode();
+ return result;
+ }
+
public void setActorIdExpression(String actorIdExpression) {
this.actorIdExpression = actorIdExpression;
- // Note: combination of actorIdExpression and pooledActorsExpression is allowed
+ // combination of actorIdExpression and pooledActorsExpression is allowed
// this.pooledActorsExpression = null;
this.assignmentDelegation = null;
}
+
public void setPooledActorsExpression(String pooledActorsExpression) {
- // Note: combination of actorIdExpression and pooledActorsExpression is allowed
+ // combination of actorIdExpression and pooledActorsExpression is allowed
// this.actorIdExpression = null;
this.pooledActorsExpression = pooledActorsExpression;
this.assignmentDelegation = null;
}
+
public void setAssignmentDelegation(Delegation assignmentDelegation) {
// assignment expressions and assignmentDelegation are mutually exclusive
this.actorIdExpression = null;
@@ -100,18 +114,23 @@
public TaskMgmtDefinition getTaskMgmtDefinition() {
return taskMgmtDefinition;
}
+
public String getActorIdExpression() {
return actorIdExpression;
}
+
public String getPooledActorsExpression() {
return pooledActorsExpression;
}
+
public Delegation getAssignmentDelegation() {
return assignmentDelegation;
}
+
public String getName() {
return name;
}
+
public long getId() {
return id;
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/TaskController.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/TaskController.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/def/TaskController.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -36,18 +36,17 @@
import org.jbpm.instantiation.UserCodeInterceptor;
import org.jbpm.instantiation.UserCodeInterceptorConfig;
import org.jbpm.taskmgmt.exe.TaskInstance;
-import org.jbpm.util.EqualsUtil;
/**
* is a controller for one task. this object either delegates to a custom
- * {@link org.jbpm.taskmgmt.def.TaskControllerHandler} or it is configured
- * with {@link org.jbpm.context.def.VariableAccess}s to perform the default
- * behaviour of the controller functionality for a task.
+ * {@link org.jbpm.taskmgmt.def.TaskControllerHandler} or it is configured with
+ * {@link org.jbpm.context.def.VariableAccess}s to perform the default behaviour
+ * of the controller functionality for a task.
*/
public class TaskController implements Serializable {
private static final long serialVersionUID = 1L;
-
+
long id = 0;
/**
@@ -62,35 +61,45 @@
* maps process variable names (java.lang.String) to VariableAccess objects.
*/
List variableAccesses = null;
-
+
public TaskController() {
}
-
+
/**
- * extract the list of information from the process variables and make them available locally.
- * Note that if no task instance variables are specified, the full process variables scope will be
- * visible (that means that the user did not specify a special task instance scope).
+ * extract the list of information from the process variables and make them
+ * available locally. Note that if no task instance variables are specified,
+ * the full process variables scope will be visible (that means that the user
+ * did not specify a special task instance scope).
*/
public void initializeVariables(TaskInstance taskInstance) {
- ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader surroundingClassLoader = Thread.currentThread()
+ .getContextClassLoader();
try {
- // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448)
- Thread.currentThread().setContextClassLoader(JbpmConfiguration.getProcessClassLoader(taskInstance.getTask().getProcessDefinition()));
+ // set context class loader correctly for delegation class
+ // https://jira.jboss.org/jira/browse/JBPM-1448
+ ClassLoader classLoader = JbpmConfiguration.getProcessClassLoader(taskInstance.getTask()
+ .getProcessDefinition());
+ Thread.currentThread().setContextClassLoader(classLoader);
if (taskControllerDelegation != null) {
TaskControllerHandler taskControllerHandler = (TaskControllerHandler) taskControllerDelegation.instantiate();
- ProcessInstance processInstance = taskInstance.getTaskMgmtInstance().getProcessInstance();
- ContextInstance contextInstance = (processInstance != null ? processInstance.getContextInstance() : null);
+ ProcessInstance processInstance = taskInstance.getTaskMgmtInstance()
+ .getProcessInstance();
+ ContextInstance contextInstance = (processInstance != null ? processInstance.getContextInstance()
+ : null);
Token token = taskInstance.getToken();
UserCodeInterceptor userCodeInterceptor = UserCodeInterceptorConfig.getUserCodeInterceptor();
if (userCodeInterceptor != null) {
- userCodeInterceptor.executeTaskControllerInitialization(taskControllerHandler, taskInstance, contextInstance, token);
- } else {
- taskControllerHandler.initializeTaskVariables(taskInstance, contextInstance, token);
+ userCodeInterceptor.executeTaskControllerInitialization(
+ taskControllerHandler, taskInstance, contextInstance, token);
}
-
- } else {
+ else {
+ taskControllerHandler.initializeTaskVariables(taskInstance,
+ contextInstance, token);
+ }
+ }
+ else {
Token token = taskInstance.getToken();
ProcessInstance processInstance = token.getProcessInstance();
ContextInstance contextInstance = processInstance.getContextInstance();
@@ -103,108 +112,131 @@
if (variableAccess.isReadable()) {
String variableName = variableAccess.getVariableName();
Object value = contextInstance.getVariable(variableName, token);
- log.debug("creating task instance variable '" + mappedName + "' from process variable '" + variableName + "', value '" + value + "'");
+ log.debug("creating task instance variable '" + mappedName
+ + "' from process variable '" + variableName + "', value '"
+ + value + "'");
taskInstance.setVariableLocally(mappedName, value);
- } else {
- log.debug("creating task instance local variable '" + mappedName + "'. initializing with null value.");
+ }
+ else {
+ log.debug("creating task instance local variable '" + mappedName
+ + "'. initializing with null value.");
taskInstance.setVariableLocally(mappedName, null);
}
}
}
}
- } finally {
+ }
+ finally {
Thread.currentThread().setContextClassLoader(surroundingClassLoader);
- }
+ }
}
/**
- * update the process variables from the the task-instance variables.
+ * update the process variables from the the task-instance variables.
*/
public void submitParameters(TaskInstance taskInstance) {
- ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader surroundingClassLoader = Thread.currentThread()
+ .getContextClassLoader();
try {
- // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448)
- Thread.currentThread().setContextClassLoader(JbpmConfiguration.getProcessClassLoader(taskInstance.getTask().getProcessDefinition()));
+ // set context class loader correctly for delegation class
+ // https://jira.jboss.org/jira/browse/JBPM-1448
+ ClassLoader classLoader = JbpmConfiguration.getProcessClassLoader(taskInstance.getTask()
+ .getProcessDefinition());
+ Thread.currentThread().setContextClassLoader(classLoader);
if (taskControllerDelegation != null) {
TaskControllerHandler taskControllerHandler = (TaskControllerHandler) taskControllerDelegation.instantiate();
- ProcessInstance processInstance = taskInstance.getTaskMgmtInstance().getProcessInstance();
- ContextInstance contextInstance = (processInstance != null ? processInstance.getContextInstance() : null);
+ ProcessInstance processInstance = taskInstance.getTaskMgmtInstance()
+ .getProcessInstance();
+ ContextInstance contextInstance = processInstance != null ? processInstance.getContextInstance()
+ : null;
Token token = taskInstance.getToken();
UserCodeInterceptor userCodeInterceptor = UserCodeInterceptorConfig.getUserCodeInterceptor();
if (userCodeInterceptor != null) {
- userCodeInterceptor.executeTaskControllerSubmission(taskControllerHandler, taskInstance, contextInstance, token);
- } else {
- taskControllerHandler.submitTaskVariables(taskInstance, contextInstance, token);
+ userCodeInterceptor.executeTaskControllerSubmission(
+ taskControllerHandler, taskInstance, contextInstance, token);
}
-
- } else {
-
+ else {
+ taskControllerHandler.submitTaskVariables(taskInstance,
+ contextInstance, token);
+ }
+ }
+ else {
Token token = taskInstance.getToken();
ProcessInstance processInstance = token.getProcessInstance();
ContextInstance contextInstance = processInstance.getContextInstance();
if (variableAccesses != null) {
String missingTaskVariables = null;
- Iterator iter = variableAccesses.iterator();
- while (iter.hasNext()) {
+ for (Iterator iter = variableAccesses.iterator(); iter.hasNext();) {
VariableAccess variableAccess = (VariableAccess) iter.next();
String mappedName = variableAccess.getMappedName();
// first check if the required variableInstances are present
- if ((variableAccess.isRequired()) && (!taskInstance.hasVariableLocally(mappedName))) {
+ if (variableAccess.isRequired()
+ && !taskInstance.hasVariableLocally(mappedName)) {
if (missingTaskVariables == null) {
missingTaskVariables = mappedName;
- } else {
+ }
+ else {
missingTaskVariables += ", " + mappedName;
}
}
}
- // if there are missing, required parameters, throw an
- // IllegalArgumentException
+ // if there are missing, required parameters, puke
if (missingTaskVariables != null) {
- throw new IllegalArgumentException("missing task variables: " + missingTaskVariables);
+ throw new IllegalArgumentException("missing task variables: "
+ + missingTaskVariables);
}
- iter = variableAccesses.iterator();
- while (iter.hasNext()) {
+ for (Iterator iter = variableAccesses.iterator(); iter.hasNext();) {
VariableAccess variableAccess = (VariableAccess) iter.next();
String mappedName = variableAccess.getMappedName();
String variableName = variableAccess.getVariableName();
if (variableAccess.isWritable()) {
Object value = taskInstance.getVariable(mappedName);
if (value != null) {
- log.debug("submitting task variable '" + mappedName + "' to process variable '" + variableName + "', value '" + value + "'");
+ log.debug("submitting task variable '" + mappedName
+ + "' to process variable '" + variableName + "', value '"
+ + value + "'");
contextInstance.setVariable(variableName, value, token);
}
}
}
}
}
- } finally {
+ }
+ finally {
Thread.currentThread().setContextClassLoader(surroundingClassLoader);
}
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof TaskController)) return false;
+
+ // task controller has no notion of equality beyond identity
+ TaskController other = (TaskController) o;
+ return id != 0 && id == other.getId();
}
-
+
// getters and setters //////////////////////////////////////////////////////
public List getVariableAccesses() {
return variableAccesses;
}
+
public Delegation getTaskControllerDelegation() {
return taskControllerDelegation;
}
+
public void setTaskControllerDelegation(Delegation taskControllerDelegation) {
this.taskControllerDelegation = taskControllerDelegation;
}
+
public long getId() {
return id;
}
@@ -212,6 +244,6 @@
public void setVariableAccesses(List variableAccesses) {
this.variableAccesses = variableAccesses;
}
-
+
private static Log log = LogFactory.getLog(TaskController.class);
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/PooledActor.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/PooledActor.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/PooledActor.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -26,8 +26,6 @@
import java.util.Iterator;
import java.util.Set;
-import org.jbpm.util.EqualsUtil;
-
public class PooledActor implements Serializable {
private static final long serialVersionUID = 1L;
@@ -38,8 +36,8 @@
protected Set taskInstances = null;
protected SwimlaneInstance swimlaneInstance = null;
- public static Set createPool(String[] actorIds, SwimlaneInstance swimlaneInstance,
- TaskInstance taskInstance) {
+ public static Set createPool(String[] actorIds,
+ SwimlaneInstance swimlaneInstance, TaskInstance taskInstance) {
Set pooledActors = new HashSet();
for (int i = 0; i < actorIds.length; i++) {
PooledActor pooledActor = new PooledActor(actorIds[i]);
@@ -90,14 +88,23 @@
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof PooledActor)) return false;
+
+ PooledActor other = (PooledActor) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return actorId.equals(other.getActorId());
}
+ public int hashCode() {
+ return actorId.hashCode();
+ }
+
public String toString() {
- return "PooledActor(" + actorId + ")";
+ return "PooledActor(" + actorId + ')';
}
// getters and setters //////////////////////////////////////////////////////
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/SwimlaneInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/SwimlaneInstance.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/SwimlaneInstance.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -25,7 +25,6 @@
import java.util.Set;
import org.jbpm.taskmgmt.def.Swimlane;
-import org.jbpm.util.EqualsUtil;
/**
* is a process role for a one process instance.
@@ -34,13 +33,13 @@
private static final long serialVersionUID = 1L;
- long id = 0;
- int version = 0;
- protected String name = null;
- protected String actorId = null;
- protected Set pooledActors = null;
- protected Swimlane swimlane = null;
- protected TaskMgmtInstance taskMgmtInstance = null;
+ long id;
+ int version;
+ protected String name;
+ protected String actorId;
+ protected Set pooledActors;
+ protected Swimlane swimlane;
+ protected TaskMgmtInstance taskMgmtInstance;
public SwimlaneInstance() {
}
@@ -55,12 +54,24 @@
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof SwimlaneInstance)) return false;
+
+ SwimlaneInstance other = (SwimlaneInstance) o;
+ if (id != 0 && id == other.getId()) return true;
+
+ return name.equals(other.getName())
+ && taskMgmtInstance.equals(other.getTaskMgmtInstance());
}
+ public int hashCode() {
+ int result = 1429026763 + name.hashCode();
+ result = 686197649 * result + taskMgmtInstance.hashCode();
+ return result;
+ }
+
// getters and setters //////////////////////////////////////////////////////
public long getId() {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskInstance.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskInstance.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -50,13 +50,14 @@
import org.jbpm.taskmgmt.log.TaskAssignLog;
import org.jbpm.taskmgmt.log.TaskEndLog;
import org.jbpm.util.Clock;
-import org.jbpm.util.EqualsUtil;
/**
- * is one task instance that can be assigned to an actor (read: put in someone's task list) and
- * that can trigger the continuation of execution of the token upon completion.
+ * is one task instance that can be assigned to an actor (read: put in someone's
+ * task list) and that can trigger the continuation of execution of the token
+ * upon completion.
*/
-public class TaskInstance extends VariableContainer implements Identifiable, Assignable {
+public class TaskInstance extends VariableContainer implements Identifiable,
+ Assignable {
private static final long serialVersionUID = 1L;
@@ -83,7 +84,7 @@
protected Set pooledActors;
protected List comments;
- // not persisted. just extra information for listeners of the task-assign event
+ // not persisted. extra information for task-assign event listeners
protected String previousActorId;
public TaskInstance() {
@@ -108,31 +109,34 @@
}
void submitVariables() {
- TaskController taskController = (task != null ? task.getTaskController() : null);
- // if there is a task controller,
+ TaskController taskController = task != null ? task.getTaskController()
+ : null;
+ // if a task controller is present,
if (taskController != null) {
- // the task controller is responsible for copying variables back into the process
+ // the task controller copies variables back into the process
taskController.submitParameters(this);
}
- // if there is no task controller
+ // in absence of a task controller,
else if (token != null && token.getProcessInstance() != null) {
- // the default behaviour is that all task-local variables are flushed to the process
+ // all task-local variables are flushed to the process
if (variableInstances != null) {
- ContextInstance contextInstance = token.getProcessInstance().getContextInstance();
- Iterator iter = variableInstances.values().iterator();
- while (iter.hasNext()) {
+ ContextInstance contextInstance = token.getProcessInstance()
+ .getContextInstance();
+ for (Iterator iter = variableInstances.values().iterator(); iter.hasNext();) {
VariableInstance variableInstance = (VariableInstance) iter.next();
- log.debug("flushing variable '" + variableInstance.getName() + "' from task '" + name
- + "' to process variables");
- // this was the simplest way to clone the variable instance; might be optimized
- contextInstance.setVariable(variableInstance.getName(), variableInstance.getValue(), token);
+ log.debug("flushing variable '" + variableInstance.getName()
+ + "' from task '" + name + "' to process variables");
+ // simple way to clone the variable instance; might be optimized
+ contextInstance.setVariable(variableInstance.getName(),
+ variableInstance.getValue(), token);
}
}
}
}
void initializeVariables() {
- TaskController taskController = (task != null ? task.getTaskController() : null);
+ TaskController taskController = task != null ? task.getTaskController()
+ : null;
if (taskController != null) {
taskController.initializeVariables(this);
}
@@ -144,12 +148,12 @@
public void create(ExecutionContext executionContext) {
if (create != null) {
- throw new IllegalStateException("task instance '" + id + "' was already created");
+ throw new IllegalStateException(this + " was already created");
}
create = Clock.getCurrentTime();
// if this task instance is associated with a task...
- if ((task != null) && (executionContext != null)) {
+ if (task != null && executionContext != null) {
// the TASK_CREATE event is fired
executionContext.setTaskInstance(this);
executionContext.setTask(task);
@@ -177,14 +181,17 @@
}
else { // lazily initialize the swimlane...
// get the swimlane instance (if there is any)
- swimlaneInstance = taskMgmtInstance.getInitializedSwimlaneInstance(executionContext, swimlane);
+ swimlaneInstance = taskMgmtInstance.getInitializedSwimlaneInstance(
+ executionContext, swimlane);
// copy the swimlaneInstance assignment into the taskInstance assignment
copySwimlaneInstanceAssignment(swimlaneInstance);
}
}
else { // this task is not in a swimlane
- taskMgmtInstance.performAssignment(task.getAssignmentDelegation(), task.getActorIdExpression(), task.getPooledActorsExpression(), this, executionContext);
+ taskMgmtInstance.performAssignment(task.getAssignmentDelegation(),
+ task.getActorIdExpression(), task.getPooledActorsExpression(), this,
+ executionContext);
}
updatePooledActorsReferences(swimlaneInstance);
@@ -192,17 +199,17 @@
public boolean isStartTaskInstance() {
boolean isStartTaskInstance = false;
- if (taskMgmtInstance != null && taskMgmtInstance.getTaskMgmtDefinition() != null) {
+ if (taskMgmtInstance != null
+ && taskMgmtInstance.getTaskMgmtDefinition() != null) {
isStartTaskInstance = task != null
- && task.equals(taskMgmtInstance.getTaskMgmtDefinition().getStartTask());
+ && task.equals(taskMgmtInstance.getTaskMgmtDefinition().getStartTask());
}
return isStartTaskInstance;
}
void updatePooledActorsReferences(SwimlaneInstance swimlaneInstance) {
if (pooledActors != null) {
- Iterator iter = pooledActors.iterator();
- while (iter.hasNext()) {
+ for (Iterator iter = pooledActors.iterator(); iter.hasNext();) {
PooledActor pooledActor = (PooledActor) iter.next();
pooledActor.setSwimlaneInstance(swimlaneInstance);
pooledActor.addTaskInstance(this);
@@ -211,8 +218,8 @@
}
/**
- * copies the assignment (that includes both the swimlaneActorId and the set of pooledActors)
- * of the given swimlane into this taskInstance.
+ * copies the assignment (that includes both the swimlaneActorId and the set
+ * of pooledActors) of the given swimlane into this taskInstance.
*/
public void copySwimlaneInstanceAssignment(SwimlaneInstance swimlaneInstance) {
setSwimlaneInstance(swimlaneInstance);
@@ -221,19 +228,21 @@
}
/**
- * gets the pool of actors for this task instance. If this task has a simlaneInstance and no
- * pooled actors, the pooled actors of the swimlane instance are returned.
+ * gets the pool of actors for this task instance. If this task has a
+ * simlaneInstance and no pooled actors, the pooled actors of the swimlane
+ * instance are returned.
*/
public Set getPooledActors() {
- if (swimlaneInstance != null && (pooledActors == null || pooledActors.isEmpty())) {
+ if (swimlaneInstance != null
+ && (pooledActors == null || pooledActors.isEmpty())) {
return swimlaneInstance.getPooledActors();
}
return pooledActors;
}
/**
- * (re)assign this task to the given actor. If this task is related to a swimlane instance,
- * that swimlane instance will be updated as well.
+ * (re)assign this task to the given actor. If this task is related to a
+ * swimlane instance, that swimlane instance will be updated as well.
*/
public void setActorId(String actorId) {
setActorId(actorId, true);
@@ -243,20 +252,20 @@
* (re)assign this task to the given actor.
*
* @param actorId is reference to the person that is assigned to this task.
- * @param overwriteSwimlane specifies if the related swimlane should be overwritten with the
- * given swimlaneActorId.
+ * @param overwriteSwimlane specifies if the related swimlane should be
+ * overwritten with the given swimlaneActorId.
*/
public void setActorId(String actorId, boolean overwriteSwimlane) {
// do the actual assignment
this.previousActorId = this.actorId;
this.actorId = actorId;
- if ((swimlaneInstance != null) && (overwriteSwimlane)) {
+ if (swimlaneInstance != null && overwriteSwimlane) {
log.debug("assigning task '" + name + "' to '" + actorId + "'");
swimlaneInstance.setActorId(actorId);
}
// fire the event
- if ((task != null) && (token != null)) {
+ if (task != null && token != null) {
ExecutionContext executionContext = new ExecutionContext(token);
executionContext.setTask(task);
executionContext.setTaskInstance(this);
@@ -280,12 +289,12 @@
}
/**
- * can optionally be used to indicate that the actor is starting to work on this task
- * instance.
+ * can optionally be used to indicate that the actor is starting to work on
+ * this task instance.
*/
public void start() {
if (start != null) {
- throw new IllegalStateException("task instance '" + id + "' is already started");
+ throw new IllegalStateException(this + " is already started");
}
start = Clock.getCurrentTime();
@@ -298,15 +307,16 @@
}
/**
- * convenience method that combines a {@link #setActorId(String)} and a {@link #start()}.
+ * convenience method that combines a {@link #setActorId(String)} and a
+ * {@link #start()}.
*/
public void start(String actorId) {
start(actorId, true);
}
/**
- * convenience method that combines a {@link #setActorId(String,boolean)} and a
- * {@link #start()}.
+ * convenience method that combines a {@link #setActorId(String,boolean)} and
+ * a {@link #start()}.
*/
public void start(String actorId, boolean overwriteSwimlane) {
setActorId(actorId, overwriteSwimlane);
@@ -326,8 +336,9 @@
}
/**
- * cancels this task. This task instance will be marked as cancelled and as ended. But
- * cancellation doesn't influence signalling and continuation of process execution.
+ * cancels this task. This task instance will be marked as cancelled and as
+ * ended. But cancellation doesn't influence signalling and continuation of
+ * process execution.
*/
public void cancel() {
markAsCancelled();
@@ -335,9 +346,9 @@
}
/**
- * cancels this task, takes the specified transition. This task intance will be marked as
- * cancelled and as ended. But cancellation doesn't influence singalling and continuation of
- * process execution.
+ * cancels this task, takes the specified transition. This task intance will
+ * be marked as cancelled and as ended. But cancellation doesn't influence
+ * singalling and continuation of process execution.
*/
public void cancel(Transition transition) {
markAsCancelled();
@@ -345,9 +356,9 @@
}
/**
- * cancels this task, takes the specified transition. This task intance will be marked as
- * cancelled and as ended. But cancellation doesn't influence singalling and continuation of
- * process execution.
+ * cancels this task, takes the specified transition. This task intance will
+ * be marked as cancelled and as ended. But cancellation doesn't influence
+ * singalling and continuation of process execution.
*/
public void cancel(String transitionName) {
markAsCancelled();
@@ -355,8 +366,8 @@
}
/**
- * marks this task as done. If this task is related to a task node this might trigger a signal
- * on the token.
+ * marks this task as done. If this task is related to a task node this might
+ * trigger a signal on the token.
*
* @see #end(Transition)
*/
@@ -365,43 +376,46 @@
}
/**
- * marks this task as done and specifies the name of a transition leaving the task-node for
- * the case that the completion of this task instances triggers a signal on the token. If this
- * task leads to a signal on the token, the given transition name will be used in the signal.
- * If this task completion does not trigger execution to move on, the transitionName is
- * ignored.
+ * marks this task as done and specifies the name of a transition leaving the
+ * task-node for the case that the completion of this task instances triggers
+ * a signal on the token. If this task leads to a signal on the token, the
+ * given transition name will be used in the signal. If this task completion
+ * does not trigger execution to move on, the transitionName is ignored.
*/
public void end(String transitionName) {
- Transition leavingTransition = null;
+ if (task == null) {
+ throw new JbpmException(this + " has no task definition");
+ }
- if (task != null) {
- Node node = task.getTaskNode();
+ Node node = task.getTaskNode();
+ if (node == null) {
+ node = (Node) task.getParent();
if (node == null) {
- node = (Node) task.getParent();
+ throw new JbpmException(this + " has no enclosing node");
}
+ }
- if (node != null) {
- leavingTransition = node.getLeavingTransition(transitionName);
- }
- }
+ Transition leavingTransition = node.getLeavingTransition(transitionName);
if (leavingTransition == null) {
- throw new JbpmException("task node does not have leaving transition: " + transitionName);
+ throw new JbpmException(node + " has no leaving transition named "
+ + transitionName);
}
end(leavingTransition);
}
/**
- * marks this task as done and specifies a transition leaving the task-node for the case that
- * the completion of this task instances triggers a signal on the token. If this task leads to
- * a signal on the token, the given transition name will be used in the signal. If this task
- * completion does not trigger execution to move on, the transition is ignored.
+ * marks this task as done and specifies a transition leaving the task-node
+ * for the case that the completion of this task instances triggers a signal
+ * on the token. If this task leads to a signal on the token, the given
+ * transition name will be used in the signal. If this task completion does
+ * not trigger execution to move on, the transition is ignored.
*/
public void end(Transition transition) {
if (this.end != null) {
- throw new IllegalStateException("task instance '" + id + "' is already ended");
+ throw new IllegalStateException(this + " has ended");
}
if (this.isSuspended) {
- throw new JbpmException("task instance '" + id + "' is suspended");
+ throw new JbpmException(this + " is suspended");
}
// mark the end of this task instance
@@ -424,22 +438,22 @@
// submit the variables
submitVariables();
- // verify if the end of this task triggers continuation of execution
+ // check whether completing this task causes execution to proceed
if (isSignalling) {
this.isSignalling = false;
- if (this.isStartTaskInstance() // ending start tasks always leads to a signal
- || (task != null && token != null && task.getTaskNode() != null && task.getTaskNode()
- .completionTriggersSignal(this))) {
+ if (this.isStartTaskInstance() // ending start task leads to signal
+ || (task != null && token != null && task.getTaskNode() != null && task.getTaskNode()
+ .completionTriggersSignal(this))) {
if (transition == null) {
- log.debug("completion of task '" + task.getName()
- + "' results in taking the default transition");
+ log.debug("completion of " + task
+ + " results in taking the default transition");
token.signal();
}
else {
- log.debug("completion of task '" + task.getName()
- + "' results in taking transition '" + transition + "'");
+ log.debug("completion of " + task.getName() + " results in taking "
+ + transition);
token.signal(transition);
}
}
@@ -455,7 +469,7 @@
*/
public void suspend() {
if (!isOpen) {
- throw new JbpmException("a task that is not open cannot be suspended: " + toString());
+ throw new JbpmException("task is not open");
}
isSuspended = true;
}
@@ -465,7 +479,7 @@
*/
public void resume() {
if (!isOpen) {
- throw new JbpmException("a task that is not open cannot be resumed: " + toString());
+ throw new JbpmException("task is not open");
}
isSuspended = false;
}
@@ -499,27 +513,33 @@
}
/**
- * is the list of transitions that can be used in the end method and it is null in case this
- * is not the last task instance.
+ * is the list of transitions that can be used in the end method and it is
+ * null in case this is not the last task instance.
*/
public List getAvailableTransitions() {
List transitions = null;
- if ((!isLast()) && (token != null)) {
+ if (!isLast() && token != null) {
transitions = new ArrayList(token.getAvailableTransitions());
}
return transitions;
}
// equals ///////////////////////////////////////////////////////////////////
- // hack to support comparing hibernate proxies against the real objects
- // since this always falls back to ==, we don't need to overwrite the hashcode
+
public boolean equals(Object o) {
- return EqualsUtil.equals(this, o);
+ if (this == o) return true;
+ if (!(o instanceof TaskInstance)) return false;
+
+ // task instance has no notion of equality other than identity
+ // see Wfp15MiWithAPrioriRuntimeKnowledgeTest
+ TaskInstance other = (TaskInstance) o;
+ return id != 0 && id == other.getId();
}
public String toString() {
return "TaskInstance"
- + (name != null ? "(" + name + ")" : "@" + Integer.toHexString(hashCode()));
+ + (name != null ? '(' + name + ')' : id != 0 ? "(" + id + ')'
+ : '@' + Integer.toHexString(hashCode()));
}
// private //////////////////////////////////////////////////////////////////
@@ -528,8 +548,7 @@
public void setPooledActors(Set pooledActors) {
if (pooledActors != null) {
this.pooledActors = new HashSet(pooledActors);
- Iterator iter = pooledActors.iterator();
- while (iter.hasNext()) {
+ for (Iterator iter = pooledActors.iterator(); iter.hasNext();) {
PooledActor pooledActor = (PooledActor) iter.next();
pooledActor.addTaskInstance(this);
}
@@ -543,7 +562,8 @@
protected VariableContainer getParentVariableContainer() {
ContextInstance contextInstance = getContextInstance();
- return (contextInstance != null ? contextInstance.getOrCreateTokenVariableMap(token) : null);
+ return contextInstance != null ? contextInstance.getOrCreateTokenVariableMap(token)
+ : null;
}
// getters and setters //////////////////////////////////////////////////////
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskMgmtInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskMgmtInstance.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/taskmgmt/exe/TaskMgmtInstance.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -63,14 +63,12 @@
private static final long serialVersionUID = 1L;
- TaskMgmtDefinition taskMgmtDefinition = null;
- Map swimlaneInstances = null;
- Set taskInstances = null;
+ TaskMgmtDefinition taskMgmtDefinition;
+ Map swimlaneInstances;
+ Set taskInstances;
- /**
- * non persistent collection that stores all the task instances that have variable updates
- */
- Collection taskInstanceVariableUpdates = null;
+ /** stores task instances having variable updates. not persisted. */
+ Collection taskInstanceVariableUpdates;
public TaskMgmtInstance() {
}
@@ -94,7 +92,7 @@
}
/**
- * creates a new task instance on the given token, for the given task.
+ * creates an instance of the given task, for the given token.
*/
public TaskInstance createTaskInstance(Task task, Token token) {
ExecutionContext executionContext = new ExecutionContext(token);
@@ -103,18 +101,19 @@
}
/**
- * creates a new task instance on the given task, in the given execution context.
+ * creates an instance of the given task, in the given execution context.
*/
- public TaskInstance createTaskInstance(Task task, ExecutionContext executionContext) {
+ public TaskInstance createTaskInstance(Task task,
+ ExecutionContext executionContext) {
// instantiate the new task instance
TaskInstance taskInstance = instantiateNewTaskInstance(executionContext);
- // bind the task instance to the TaskMgmtInstance
- addTaskInstance(taskInstance);
-
// initialize the task instance
if (task != null) taskInstance.setTask(task);
+ // bind the task instance to the TaskMgmtInstance
+ addTaskInstance(taskInstance);
+
// assign an id to the task instance
Services.assignId(taskInstance);
@@ -131,8 +130,10 @@
String durationString = null;
if (dueDateString.startsWith("#")) {
- String baseDateEL = dueDateString.substring(0, dueDateString.indexOf("}") + 1);
- Object result = JbpmExpressionEvaluator.evaluate(baseDateEL, executionContext);
+ String baseDateEL = dueDateString.substring(0,
+ dueDateString.indexOf("}") + 1);
+ Object result = JbpmExpressionEvaluator.evaluate(baseDateEL,
+ executionContext);
if (result instanceof Date) {
baseDate = (Date) result;
}
@@ -140,17 +141,15 @@
baseDate = ((Calendar) result).getTime();
}
else {
- throw new JbpmException("Invalid basedate type: "
- + baseDateEL
- + " is of type "
- + result.getClass().getName()
- + ". Only Date and Calendar are supported");
+ throw new JbpmException("base date is neither Date nor Calendar");
}
int endOfELIndex = dueDateString.indexOf("}");
if (endOfELIndex < (dueDateString.length() - 1)) {
- char durationSeparator = dueDateString.substring(endOfELIndex + 1).trim().charAt(0);
+ char durationSeparator = dueDateString.substring(endOfELIndex + 1)
+ .trim()
+ .charAt(0);
if (durationSeparator != '+' && durationSeparator != '-') {
- throw new JbpmException("Invalid duedate, + or - missing after EL");
+ throw new JbpmException("'+' or '-' missing after expression");
}
durationString = dueDateString.substring(endOfELIndex + 1).trim();
}
@@ -180,7 +179,8 @@
if (task != null) {
String description = task.getDescription();
if ((description != null) && (description.indexOf("#{") != -1)) {
- Object result = JbpmExpressionEvaluator.evaluate(description, executionContext);
+ Object result = JbpmExpressionEvaluator.evaluate(description,
+ executionContext);
if (result != null) {
taskInstance.setDescription(result.toString());
}
@@ -213,8 +213,8 @@
return taskInstance;
}
- public SwimlaneInstance getInitializedSwimlaneInstance(ExecutionContext executionContext,
- Swimlane swimlane) {
+ public SwimlaneInstance getInitializedSwimlaneInstance(
+ ExecutionContext executionContext, Swimlane swimlane) {
// initialize the swimlane
if (swimlaneInstances == null) swimlaneInstances = new HashMap();
SwimlaneInstance swimlaneInstance = (SwimlaneInstance) swimlaneInstances.get(swimlane.getName());
@@ -222,28 +222,33 @@
swimlaneInstance = new SwimlaneInstance(swimlane);
addSwimlaneInstance(swimlaneInstance);
// assign the swimlaneInstance
- performAssignment(swimlane.getAssignmentDelegation(), swimlane.getActorIdExpression(),
- swimlane.getPooledActorsExpression(), swimlaneInstance, executionContext);
+ performAssignment(swimlane.getAssignmentDelegation(),
+ swimlane.getActorIdExpression(),
+ swimlane.getPooledActorsExpression(), swimlaneInstance,
+ executionContext);
}
return swimlaneInstance;
}
- public void performAssignment(Delegation assignmentDelegation, String actorIdExpression,
- String pooledActorsExpression, Assignable assignable, ExecutionContext executionContext) {
+ public void performAssignment(Delegation assignmentDelegation,
+ String actorIdExpression, String pooledActorsExpression,
+ Assignable assignable, ExecutionContext executionContext) {
try {
if (assignmentDelegation != null) {
- performAssignmentDelegation(assignmentDelegation, assignable, executionContext);
+ performAssignmentDelegation(assignmentDelegation, assignable,
+ executionContext);
}
else {
if (actorIdExpression != null) {
- performAssignmentActorIdExpr(actorIdExpression, assignable, executionContext);
+ performAssignmentActorIdExpr(actorIdExpression, assignable,
+ executionContext);
}
if (pooledActorsExpression != null) {
- performAssignmentPooledActorsExpr(pooledActorsExpression, assignable, executionContext);
+ performAssignmentPooledActorsExpr(pooledActorsExpression, assignable,
+ executionContext);
}
}
-
}
catch (Exception exception) {
GraphElement graphElement = executionContext.getEventSource();
@@ -256,20 +261,24 @@
}
}
- void performAssignmentDelegation(Delegation assignmentDelegation, Assignable assignable,
- ExecutionContext executionContext) throws Exception {
- ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
+ void performAssignmentDelegation(Delegation assignmentDelegation,
+ Assignable assignable, ExecutionContext executionContext)
+ throws Exception {
+ ClassLoader surroundingClassLoader = Thread.currentThread()
+ .getContextClassLoader();
try {
- // set context class loader correctly for delegation class (https://jira.jboss.org/jira/browse/JBPM-1448)
- Thread.currentThread().setContextClassLoader(
- JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition()));
+ // set context class loader correctly for delegation class
+ // https://jira.jboss.org/jira/browse/JBPM-1448
+ ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(executionContext.getProcessDefinition());
+ Thread.currentThread().setContextClassLoader(processClassLoader);
// instantiate the assignment handler
AssignmentHandler assignmentHandler = (AssignmentHandler) assignmentDelegation.instantiate();
// invoke the assignment handler
UserCodeInterceptor userCodeInterceptor = UserCodeInterceptorConfig.getUserCodeInterceptor();
if (userCodeInterceptor != null) {
- userCodeInterceptor.executeAssignment(assignmentHandler, assignable, executionContext);
+ userCodeInterceptor.executeAssignment(assignmentHandler, assignable,
+ executionContext);
}
else {
assignmentHandler.assign(assignable, executionContext);
@@ -280,37 +289,31 @@
}
}
- void performAssignmentActorIdExpr(String actorIdExpression, Assignable assignable,
- ExecutionContext executionContext) {
- Object result = null;
- String actorId = null;
- try {
- result = JbpmExpressionEvaluator.evaluate(actorIdExpression, executionContext);
- if (result == null) {
- throw new JbpmException("actor-id expression '" + actorIdExpression + "' returned null");
- }
- actorId = (String) result;
+ void performAssignmentActorIdExpr(String actorIdExpression,
+ Assignable assignable, ExecutionContext executionContext) {
+ Object result = JbpmExpressionEvaluator.evaluate(actorIdExpression,
+ executionContext);
+ if (result == null) {
+ throw new JbpmException("actor-id expression '" + actorIdExpression
+ + "' returned null");
}
- catch (ClassCastException e) {
- throw new JbpmException("actor-id expression '"
- + actorIdExpression
- + "' didn't resolve to a java.lang.String: '"
- + result
- + "' ("
- + result.getClass().getName()
- + ")");
+ if (result instanceof String) {
+ assignable.setActorId((String) result);
}
- assignable.setActorId(actorId);
+ else {
+ throw new JbpmException("actor-id expression '" + actorIdExpression
+ + "' did not evaluate to string: '" + result);
+ }
}
- void performAssignmentPooledActorsExpr(String pooledActorsExpression, Assignable assignable,
- ExecutionContext executionContext) {
+ void performAssignmentPooledActorsExpr(String pooledActorsExpression,
+ Assignable assignable, ExecutionContext executionContext) {
String[] pooledActors = null;
- Object result = JbpmExpressionEvaluator.evaluate(pooledActorsExpression, executionContext);
+ Object result = JbpmExpressionEvaluator.evaluate(pooledActorsExpression,
+ executionContext);
if (result == null) {
throw new JbpmException("pooled-actors expression '"
- + pooledActorsExpression
- + "' returned null");
+ + pooledActorsExpression + "' returned null");
}
if (result instanceof String[]) {
@@ -329,20 +332,19 @@
pooledActors = (String[]) pooledActorList.toArray(new String[pooledActorList.size()]);
}
else {
- throw new JbpmException("pooled-actors expression '"
- + pooledActorsExpression
- + "' didn't resolve to a comma separated String, a Collection or a String[]: '"
- + result
- + "' ("
- + result.getClass().getName()
- + ")");
+ throw new JbpmException(
+ "pooled-actors expression '"
+ + pooledActorsExpression
+ + "' did not evaluate to comma-separated string, collection or string array: "
+ + result);
}
assignable.setPooledActors(pooledActors);
}
/**
- * creates a task instance on the rootToken, and assigns it to the currently authenticated user.
+ * creates a task instance on the rootToken, and assigns it to the currently
+ * authenticated user.
*/
public TaskInstance createStartTaskInstance() {
TaskInstance taskInstance = null;
@@ -358,24 +360,19 @@
TaskInstance instantiateNewTaskInstance(ExecutionContext executionContext) {
TaskInstanceFactory taskInstanceFactory = (TaskInstanceFactory) JbpmConfiguration.Configs.getObject("jbpm.task.instance.factory");
- if (taskInstanceFactory == null) {
- throw new JbpmException("jbpm.task.instance.factory was not configured in jbpm.cfg.xml");
- }
return taskInstanceFactory.createTaskInstance(executionContext);
}
/**
- * is true if the given token has task instances that keep the token from leaving the current
- * node.
+ * is true if the given token has task instances that keep the token from
+ * leaving the current node.
*/
public boolean hasBlockingTaskInstances(Token token) {
if (taskInstances != null) {
for (Iterator i = taskInstances.iterator(); i.hasNext();) {
TaskInstance taskInstance = (TaskInstance) i.next();
- if (!taskInstance.hasEnded()
- && taskInstance.isBlocking()
- && token != null
- && token.equals(taskInstance.getToken())) {
+ if (!taskInstance.hasEnded() && taskInstance.isBlocking()
+ && token != null && token.equals(taskInstance.getToken())) {
return true;
}
}
@@ -391,7 +388,8 @@
}
/**
- * is the collection of {@link TaskInstance}s on the given token that are not ended.
+ * is the collection of {@link TaskInstance}s on the given token that are not
+ * ended.
*/
public Collection getUnfinishedTasks(Token token) {
Collection unfinishedTasks = new ArrayList();
@@ -407,16 +405,16 @@
}
/**
- * is true if there are {@link TaskInstance}s on the given token that can trigger the token to
- * continue.
+ * is true if there are {@link TaskInstance}s on the given token that can
+ * trigger the token to continue.
*/
public boolean hasSignallingTasks(ExecutionContext executionContext) {
return (getSignallingTasks(executionContext).size() > 0);
}
/**
- * is the collection of {@link TaskInstance}s for the given token that can trigger the token to
- * continue.
+ * is the collection of {@link TaskInstance}s for the given token that can
+ * trigger the token to continue.
*/
public Collection getSignallingTasks(ExecutionContext executionContext) {
Collection signallingTasks = new ArrayList();
@@ -424,7 +422,7 @@
for (Iterator i = taskInstances.iterator(); i.hasNext();) {
TaskInstance taskInstance = (TaskInstance) i.next();
if (taskInstance.isSignalling()
- && (executionContext.getToken().equals(taskInstance.getToken()))) {
+ && (executionContext.getToken().equals(taskInstance.getToken()))) {
signallingTasks.add(taskInstance);
}
}
@@ -433,8 +431,8 @@
}
/**
- * returns all the taskInstances for the this process instance. This includes task instances that
- * have been completed previously.
+ * returns all the taskInstances for the this process instance. This includes
+ * task instances that have been completed previously.
*/
public Collection getTaskInstances() {
return taskInstances;
@@ -475,8 +473,7 @@
if (swimlane != null) {
return createSwimlaneInstance(swimlane);
}
- throw new JbpmException("couldn't create swimlane instance for non-existing swimlane "
- + swimlaneName);
+ throw new JbpmException("swimlane does not exist: " + swimlaneName);
}
public SwimlaneInstance createSwimlaneInstance(Swimlane swimlane) {
@@ -558,7 +555,8 @@
}
/**
- * removes signalling capabilities from all task instances related to the given token.
+ * removes signalling capabilities from all task instances related to the
+ * given token.
*/
public void removeSignalling(Token token) {
if (token != null && taskInstances != null) {
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ArrayUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ArrayUtil.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ArrayUtil.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -21,100 +21,132 @@
*/
package org.jbpm.util;
+import java.util.List;
+
/**
* Various methods for manipulating arrays.
*/
public class ArrayUtil {
- private ArrayUtil() {
- // hide default constructor to prevent instantiation
- }
+ private ArrayUtil() {
+ // hide default constructor to prevent instantiation
+ }
- /**
- * Returns a string representation of the contents of the specified array. If the array
- * contains other arrays as elements, they are converted to strings by the
- * {@link Object#toString} method inherited from <tt>Object</tt>, which describes their
- * <i>identities</i> rather than their contents.
- * <p>
- * The value returned by this method is equal to the value that would be returned by
- * <tt>Arrays.asList(a).toString()</tt>, unless the array is <tt>null</tt>, in which case
- * <tt>"null"</tt> is returned.
- *
- * @param a the array whose string representation to return
- * @return a string representation of <tt>a</tt>
- * @see <a
- * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#toString(Ob...">
- * java.util.Arrays.toString(Object[])</a>
- */
- public static String toString(Object[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
+ /**
+ * Returns a hash code based on the contents of the specified array. For any
+ * two <tt>byte</tt> arrays <tt>a</tt> and <tt>b</tt> such that
+ * <tt>Arrays.equals(a, b)</tt>, it is also the case that
+ * <tt>Arrays.hashCode(a) == Arrays.hashCode(b)</tt>.
+ *
+ * <p>
+ * The value returned by this method is the same value that would be obtained
+ * by invoking the {@link List#hashCode() <tt>hashCode</tt>} method on a
+ * {@link List} containing a sequence of {@link Byte} instances representing
+ * the elements of <tt>a</tt> in the same order. If <tt>a</tt> is
+ * <tt>null</tt>, this method returns 0.
+ *
+ * @param a the array whose hash value to compute
+ * @return a content-based hash code for <tt>a</tt>
+ */
+ public static int hashCode(byte a[]) {
+ if (a == null) {
+ return 0;
+ }
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(a[0]);
+ int result = 1;
+ for (int i = 0; i < a.length; i++) {
+ result = 31 * result + a[i];
+ }
- for (int i = 1; i < a.length; i++) {
- buf.append(", ").append(a[i]);
- }
+ return result;
+ }
- return buf.append(']').toString();
- }
+ /**
+ * Returns a string representation of the contents of the specified array. If
+ * the array contains other arrays as elements, they are converted to strings
+ * by the {@link Object#toString} method inherited from <tt>Object</tt>, which
+ * describes their <i>identities</i> rather than their contents.
+ * <p>
+ * The value returned by this method is equal to the value that would be
+ * returned by <tt>Arrays.asList(a).toString()</tt>, unless the array is
+ * <tt>null</tt>, in which case <tt>"null"</tt> is returned.
+ *
+ * @param a the array whose string representation to return
+ * @return a string representation of <tt>a</tt>
+ * @see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#toString(Ob...">
+ * java.util.Arrays.toString(Object[])</a>
+ */
+ public static String toString(Object[] a) {
+ if (a == null) return "null";
+ if (a.length == 0) return "[]";
- /**
- * Returns a string representation of the contents of the specified array. The string
- * representation consists of a list of the array's elements, enclosed in square brackets (
- * <tt>"[]"</tt>). Adjacent elements are separated by the characters <tt>", "</tt> (a comma
- * followed by a space). Elements are converted to strings by <tt>String.valueOf(long)</tt>.
- * Returns <tt>"null"</tt> if the array is <tt>null</tt>.
- *
- * @param a the array whose string representation to return
- * @return a string representation of <tt>a</tt>
- * @see <a
- * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#toString(lo...">
- * java.util.Arrays.toString(long[])</a>
- */
- public static String toString(long[] a) {
- if (a == null) return "null";
- if (a.length == 0) return "[]";
+ StringBuffer buf = new StringBuffer();
+ buf.append('[').append(a[0]);
- StringBuffer buf = new StringBuffer();
- buf.append('[');
- buf.append(a[0]);
+ for (int i = 1; i < a.length; i++) {
+ buf.append(", ").append(a[i]);
+ }
- for (int i = 1; i < a.length; i++) {
- buf.append(", ").append(a[i]);
- }
+ return buf.append(']').toString();
+ }
- return buf.append(']').toString();
- }
+ /**
+ * Returns a string representation of the contents of the specified array. The
+ * string representation consists of a list of the array's elements, enclosed
+ * in square brackets ( <tt>"[]"</tt>). Adjacent elements are separated by the
+ * characters <tt>", "</tt> (a comma followed by a space). Elements are
+ * converted to strings by <tt>String.valueOf(long)</tt>. Returns
+ * <tt>"null"</tt> if the array is <tt>null</tt>.
+ *
+ * @param a the array whose string representation to return
+ * @return a string representation of <tt>a</tt>
+ * @see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#toString(lo...">
+ * java.util.Arrays.toString(long[])</a>
+ */
+ public static String toString(long[] a) {
+ if (a == null) return "null";
+ if (a.length == 0) return "[]";
- /**
- * Returns the index in the given array of the first occurrence of the specified element, or
- * -1 if the array does not contain this element.
- *
- * @param o element to search for.
- * @return the index of the first occurrence of the specified element, or -1 if the array does
- * not contain this element.
- */
- public static int indexOf(Object[] a, Object o) {
- if (o == null) {
- for (int i = 0; i < a.length; i++)
- if (a[i] == null) return i;
- }
- else {
- for (int i = 0; i < a.length; i++)
- if (o.equals(a[i])) return i;
- }
- return -1;
- }
+ StringBuffer buf = new StringBuffer();
+ buf.append('[');
+ buf.append(a[0]);
- /**
- * Tells whether the given array contains the specified element.
- *
- * @param o element whose presence in the array is to be tested.
- * @return <tt>true</tt> if the array contains the specified element.
- */
- public static boolean contains(Object[] a, Object o) {
- return indexOf(a, o) != -1;
- }
+ for (int i = 1; i < a.length; i++) {
+ buf.append(", ").append(a[i]);
+ }
+
+ return buf.append(']').toString();
+ }
+
+ /**
+ * Returns the index in the given array of the first occurrence of the
+ * specified element, or -1 if the array does not contain this element.
+ *
+ * @param o element to search for.
+ * @return the index of the first occurrence of the specified element, or -1
+ * if the array does not contain this element.
+ */
+ public static int indexOf(Object[] a, Object o) {
+ if (o == null) {
+ for (int i = 0; i < a.length; i++)
+ if (a[i] == null) return i;
+ }
+ else {
+ for (int i = 0; i < a.length; i++)
+ if (o.equals(a[i])) return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Tells whether the given array contains the specified element.
+ *
+ * @param o element whose presence in the array is to be tested.
+ * @return <tt>true</tt> if the array contains the specified element.
+ */
+ public static boolean contains(Object[] a, Object o) {
+ return indexOf(a, o) != -1;
+ }
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/EqualsUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/EqualsUtil.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/EqualsUtil.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -29,6 +29,12 @@
// hide default constructor to prevent instantiation
}
+ /**
+ * hack to support comparing hibernate proxies against the real objects.
+ * since it falls back to ==, clients don't need to override hashcode.
+ * @deprecated hack does not work
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-2489f">JBPM-2489</a>
+ */
public static boolean equals(Object thisObject, Object otherObject) {
return thisObject == otherObject || otherObject instanceof HibernateProxy
&& otherObject.equals(thisObject);
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ProcessInstanceCommandTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ProcessInstanceCommandTest.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ProcessInstanceCommandTest.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -15,145 +15,146 @@
*/
public class ProcessInstanceCommandTest extends AbstractDbTestCase {
- private ProcessDefinition processDefinition;
-
- protected void tearDown() throws Exception {
- if (processDefinition != null) {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
- }
- processDefinition = null;
-
- super.tearDown();
- }
-
public void testCancelProcessInstanceCommand() throws Exception {
String xml = "<process-definition name='TestException'>"
- + " <start-state name='start'>"
- + " <transition to='fork' />"
- + " </start-state>"
- + " <fork name='fork'>"
- + " <transition name='path1' to='path1' />"
- + " <transition name='path2' to='path2' />"
- + " </fork>"
- + " <state name='path1'>"
- + " <transition to='join' />"
- + " </state>"
- + " <state name='path2'>"
- + " <transition to='join' />"
- + " </state>"
- + " <join name='join'>"
- + " <transition to='end' />"
- + " </join>"
- + " <end-state name='end' />"
- + "</process-definition>";
-
- processDefinition = ProcessDefinition.parseXmlString(xml);
+ + " <start-state name='start'>"
+ + " <transition to='fork' />"
+ + " </start-state>"
+ + " <fork name='fork'>"
+ + " <transition name='path1' to='path1' />"
+ + " <transition name='path2' to='path2' />"
+ + " </fork>"
+ + " <state name='path1'>"
+ + " <transition to='join' />"
+ + " </state>"
+ + " <state name='path2'>"
+ + " <transition to='join' />"
+ + " </state>"
+ + " <join name='join'>"
+ + " <transition to='end' />"
+ + " </join>"
+ + " <end-state name='end' />"
+ + "</process-definition>";
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(xml);
jbpmContext.deployProcessDefinition(processDefinition);
- ProcessInstance processInstance = processDefinition.createProcessInstance();
- processInstance.getRootToken().signal();
- processInstance = saveAndReload(processInstance);
- assertFalse(processInstance.getRootToken().hasEnded());
- assertEquals("fork", processInstance.getRootToken().getNode().getName());
- for (Iterator iterator = processInstance.getRootToken().getChildren().values().iterator(); iterator.hasNext();) {
- Token childToken = (Token) iterator.next();
- assertFalse(childToken.hasEnded());
- }
+ newTransaction();
+ try {
+ ProcessInstance processInstance = processDefinition.createProcessInstance();
+ processInstance.signal();
- // execute CancelProcessInstanceCommand
- new CancelProcessInstanceCommand(processInstance.getId()).execute(jbpmContext);
+ processInstance = saveAndReload(processInstance);
+ assert !processInstance.hasEnded() : processInstance;
- // and verify it is canceled
- assertTrue(processInstance.getRootToken().hasEnded());
- assertEquals("fork", processInstance.getRootToken().getNode().getName());
- for (Iterator iterator = processInstance.getRootToken().getChildren().values().iterator(); iterator.hasNext();) {
- Token childToken = (Token) iterator.next();
- assertTrue(childToken.hasEnded());
+ Token rootToken = processInstance.getRootToken();
+ assertEquals("fork", rootToken.getNode().getName());
+ for (Iterator iterator = rootToken.getChildren().values().iterator(); iterator.hasNext();) {
+ Token childToken = (Token) iterator.next();
+ assert !childToken.hasEnded() : childToken;
+ }
+
+ // execute CancelProcessInstanceCommand
+ new CancelProcessInstanceCommand(processInstance.getId()).execute(jbpmContext);
+
+ // and verify it is canceled
+ assert rootToken.hasEnded() : processInstance;
+ assertEquals("fork", rootToken.getNode().getName());
+ for (Iterator iterator = rootToken.getChildren().values().iterator(); iterator.hasNext();) {
+ Token childToken = (Token) iterator.next();
+ assert childToken.hasEnded() : childToken;
+ }
}
+ finally {
+ graphSession.deleteProcessDefinition(processDefinition.getId());
+ }
}
public void testSuspendResumeProcessInstanceCommand() throws Exception {
- String xml = //
- "<?xml version='1.0' encoding='UTF-8'?>" //
- + "<process-definition name='TestException'>" //
- + " <start-state name='start'>" //
- + " <transition to='fork' />" //
- + " </start-state>" //
- + " <fork name='fork'>" //
- + " <transition name='path1' to='path1' />" //
- + " <transition name='path2' to='path2' />" //
- + " </fork>" //
- + " <state name='path1'>" //
- + " <transition to='join' />" //
- + " </state>" //
- + " <state name='path2'>" //
- + " <transition to='join' />" //
- + " </state>" //
- + " <join name='join'>" //
- + " <transition to='end' />" //
- + " </join>" //
- + " <end-state name='end' />" //
- + "</process-definition>";
-
- processDefinition = ProcessDefinition.parseXmlString(xml);
+ String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<process-definition name='TestException'>"
+ + " <start-state name='start'>"
+ + " <transition to='fork' />"
+ + " </start-state>"
+ + " <fork name='fork'>"
+ + " <transition name='path1' to='path1' />"
+ + " <transition name='path2' to='path2' />"
+ + " </fork>"
+ + " <state name='path1'>"
+ + " <transition to='join' />"
+ + " </state>"
+ + " <state name='path2'>"
+ + " <transition to='join' />"
+ + " </state>"
+ + " <join name='join'>"
+ + " <transition to='end' />"
+ + " </join>"
+ + " <end-state name='end' />"
+ + "</process-definition>";
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(xml);
jbpmContext.deployProcessDefinition(processDefinition);
- ProcessInstance processInstance = processDefinition.createProcessInstance();
- processInstance.getRootToken().signal();
- processInstance = saveAndReload(processInstance);
- assertFalse(processInstance.isSuspended());
- assertFalse(processInstance.getRootToken().isSuspended());
- assertEquals("fork", processInstance.getRootToken().getNode().getName());
- for (Iterator iterator = processInstance.getRootToken().getChildren().values().iterator(); iterator.hasNext();) {
- Token childToken = (Token) iterator.next();
- assertFalse(childToken.isSuspended());
- }
+ newTransaction();
+ try {
+ ProcessInstance processInstance = processDefinition.createProcessInstance();
+ processInstance.signal();
- // execute SuspendProcessInstanceCommand
- new SuspendProcessInstanceCommand().processInstanceId(processInstance.getId()).execute(
- jbpmContext);
+ processInstance = saveAndReload(processInstance);
+ assert !processInstance.isSuspended() : processInstance;
- // and verify
- assertTrue(processInstance.isSuspended());
- assertTrue(processInstance.getRootToken().isSuspended());
- assertEquals("fork", processInstance.getRootToken().getNode().getName());
- for (Iterator iterator = processInstance.getRootToken().getChildren().values().iterator(); iterator.hasNext();) {
- Token childToken = (Token) iterator.next();
- assertTrue(childToken.isSuspended());
+ Token rootToken = processInstance.getRootToken();
+ assert !rootToken.isSuspended() : rootToken;
+ assertEquals("fork", rootToken.getNode().getName());
+ for (Iterator iterator = rootToken.getChildren().values().iterator(); iterator.hasNext();) {
+ Token childToken = (Token) iterator.next();
+ assert !childToken.isSuspended() : childToken;
+ }
- try {
+ // execute SuspendProcessInstanceCommand
+ new SuspendProcessInstanceCommand().processInstanceId(
+ processInstance.getId()).execute(jbpmContext);
+
+ // and verify
+ assert processInstance.isSuspended() : processInstance;
+ assert rootToken.isSuspended() : rootToken;
+ assertEquals("fork", rootToken.getNode().getName());
+ for (Iterator iterator = rootToken.getChildren().values().iterator(); iterator.hasNext();) {
+ Token childToken = (Token) iterator.next();
+ assert childToken.isSuspended() : childToken;
+
+ try {
+ childToken.signal();
+ fail("signal should not be accepted on suspended token");
+ }
+ catch (JbpmException ex) {
+ // token is suspended
+ assert ex.getMessage().indexOf("suspended") != 0 : ex.getMessage();
+ }
+ }
+
+ // execute ResumeProcessInstanceCommand
+ new ResumeProcessInstanceCommand().processInstanceId(
+ processInstance.getId()).execute(jbpmContext);
+
+ // and verify
+ assert !processInstance.isSuspended() : processInstance;
+ assert !rootToken.isSuspended() : rootToken;
+ for (Iterator iter = rootToken.getChildren().values().iterator(); iter.hasNext();) {
+ Token childToken = (Token) iter.next();
+ assert !childToken.isSuspended() : childToken;
childToken.signal();
- fail("signal should not be accepted on suspended token");
}
- catch (Exception ex) {
- assertEquals(JbpmException.class, ex.getClass());
- // can't signal token 'path1' (5): it is suspended
- assertTrue("exception should be, that token is suspended", ex.getMessage().indexOf(
- "it is suspended") > 0);
- }
- }
- // execute ResumeProcessInstanceCommand
- new ResumeProcessInstanceCommand().processInstanceId(processInstance.getId()).execute(
- jbpmContext);
+ assertEquals("end", rootToken.getNode().getName());
+ assert processInstance.hasEnded() : processInstance;
- // and verify
- assertFalse(processInstance.isSuspended());
- assertFalse(processInstance.getRootToken().isSuspended());
- for (Iterator iterator = processInstance.getRootToken().getChildren().values().iterator(); iterator.hasNext();) {
- Token childToken = (Token) iterator.next();
- assertFalse(childToken.isSuspended());
- childToken.signal();
+ // check db state
+ processInstance = saveAndReload(processInstance);
+ assertEquals("end", processInstance.getRootToken().getNode().getName());
+ assert processInstance.hasEnded() : processInstance;
}
-
- assertEquals("end", processInstance.getRootToken().getNode().getName());
- assertTrue(processInstance.hasEnded());
-
- // check db state
- processInstance = saveAndReload(processInstance);
-
- assertEquals("end", processInstance.getRootToken().getNode().getName());
- assertTrue(processInstance.hasEnded());
+ finally {
+ graphSession.deleteProcessDefinition(processDefinition.getId());
+ }
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/TokenCommandTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/TokenCommandTest.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/TokenCommandTest.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -11,68 +11,71 @@
*
* @author bernd.ruecker(a)camunda.com
*/
-public class TokenCommandTest extends AbstractDbTestCase
-{
-
+public class TokenCommandTest extends AbstractDbTestCase {
+
public void testUnlockTokenCommand() throws Exception {
- String xml = //
- "<process-definition name='TestException'>" //
- +" <start-state name='start'>" //
- +" <transition to='wait' />" //
- +" </start-state>" //
- +" <state name='wait'>" //
- +" <transition to='end' />" //
- +" </state>" //
- +" <end-state name='end' />" //
- +"</process-definition>";
-
+ String xml = "<process-definition name='TestException'>"
+ + " <start-state name='start'>"
+ + " <transition to='wait' />"
+ + " </start-state>"
+ + " <state name='wait'>"
+ + " <transition to='end' />"
+ + " </state>"
+ + " <end-state name='end' />"
+ + "</process-definition>";
+
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(xml);
jbpmContext.deployProcessDefinition(processDefinition);
+
+ newTransaction();
try {
- ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("TestException");//processDefinition.createProcessInstance();
+ ProcessInstance processInstance = jbpmContext.newProcessInstance("TestException");
+ long tokenId = processInstance.getRootToken().getId();
processInstance.getRootToken().signal();
processInstance.getRootToken().lock("TEST-OWNER");
- long tokenId = processInstance.getRootToken().getId();
-
- processInstance = saveAndReload(processInstance);
+
+ processInstance = saveAndReload(processInstance);
try {
processInstance.getRootToken().signal();
fail("TOKEN IS LOCKED exception expected");
}
catch (JbpmException ex) {
- // org.jbpm.JbpmException: this token is locked by TEST-OWNER
- assertEquals("this token is locked by TEST-OWNER", ex.getMessage());
+ // token is locked
+ assert ex.getMessage().indexOf("locked") != -1 : ex.getMessage();
}
-
+
// unlocking without owner is a force unlock -> works
new UnlockTokenCommand().tokenId(tokenId).execute(jbpmContext);
-// Token token = jbpmContext.loadTokenForUpdate(processInstance.getRootToken().getId());
-// token.foreUnlock();
-
+
// unlock with same owner
- processInstance = saveAndReload(processInstance);
+ processInstance = saveAndReload(processInstance);
processInstance.getRootToken().lock("TEST-OWNER");
- processInstance = saveAndReload(processInstance);
- new UnlockTokenCommand().lockOwner("TEST-OWNER").tokenId(tokenId).execute(jbpmContext);
-
+
+ processInstance = saveAndReload(processInstance);
+ new UnlockTokenCommand().lockOwner("TEST-OWNER")
+ .tokenId(tokenId)
+ .execute(jbpmContext);
+
// unlocking with wrong owner fails
- processInstance = saveAndReload(processInstance);
+ processInstance = saveAndReload(processInstance);
processInstance.getRootToken().lock("TEST-OWNER");
- processInstance = saveAndReload(processInstance);
+
+ processInstance = saveAndReload(processInstance);
try {
- new UnlockTokenCommand().lockOwner("OTHER-OWNER").tokenId(tokenId).execute(jbpmContext);
- fail("'OTHER-OWNER' can't unlock token exception expected");
+ new UnlockTokenCommand().lockOwner("OTHER-OWNER")
+ .tokenId(tokenId)
+ .execute(jbpmContext);
+ fail("CANNOT UNLOCK TOKEN exception expected");
}
catch (JbpmException ex) {
- // org.jbpm.JbpmException: 'OTHER-OWNER' can't unlock token '1' because it was already locked by 'TEST-OWNER'
- assertTrue("Wrong exception, wasn't 'OTHER-OWNER' can't unlock token", ex.getMessage().indexOf("'OTHER-OWNER' can't unlock token")>=0);
+ // token is locked
+ assert ex.getMessage().indexOf("cannot unlock") != -1 : ex.getMessage();
}
}
finally {
newTransaction();
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ graphSession.deleteProcessDefinition(processDefinition.getId());
}
}
-
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/db/GraphSessionDbTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/db/GraphSessionDbTest.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/db/GraphSessionDbTest.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -250,13 +250,15 @@
}
public void testSaveAndLoadProcessInstance() {
- ProcessInstance processInstance = new ProcessInstance();
- processInstance = saveAndReload(processInstance);
+ ProcessDefinition processDefinition = new ProcessDefinition();
+ graphSession.saveProcessDefinition(processDefinition);
try {
+ ProcessInstance processInstance = new ProcessInstance(processDefinition);
+ processInstance = saveAndReload(processInstance);
assertNotNull(processInstance);
}
finally {
- graphSession.deleteProcessInstance(processInstance);
+ graphSession.deleteProcessDefinition(processDefinition);
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/node/ProcessStateDbTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/node/ProcessStateDbTest.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/graph/node/ProcessStateDbTest.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -22,7 +22,7 @@
package org.jbpm.graph.node;
import org.hibernate.criterion.Order;
-import org.jbpm.JbpmException;
+
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.db.AbstractDbTestCase;
import org.jbpm.graph.def.ProcessDefinition;
@@ -30,50 +30,41 @@
import org.jbpm.graph.exe.Token;
import org.jbpm.graph.log.ProcessStateLog;
-public class ProcessStateDbTest extends AbstractDbTestCase
-{
+public class ProcessStateDbTest extends AbstractDbTestCase {
- public void testProcessStateName()
- {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition>" +
- " <process-state name='subprocess' />" +
- "</process-definition>");
+ public void testProcessStateName() {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition>"
+ + " <process-state name='subprocess' />"
+ + "</process-definition>");
processDefinition = saveAndReload(processDefinition);
- try
- {
+ try {
ProcessState processState = (ProcessState) processDefinition.getNode("subprocess");
assertEquals("subprocess", processState.getName());
}
- finally
- {
+ finally {
jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition);
}
}
- public void testRecursiveProcessDefinition()
- {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='recursive process'>" +
- " <start-state>" +
- " <transition to='first wait' />" +
- " </start-state>" +
- " <state name='first wait'>" +
- " <transition to='subprocessnode' />" +
- " <transition name='done' to='end' />" +
- " </state>" +
- " <process-state name='subprocessnode'>" +
- " <sub-process name='recursive process' />" +
- " <transition to='end' />" +
- " </process-state>" +
- " <end-state name='end' />" +
- "</process-definition>"
- );
-
+ public void testRecursiveProcessDefinition() {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='recursive process'>"
+ + " <start-state>"
+ + " <transition to='first wait' />"
+ + " </start-state>"
+ + " <state name='first wait'>"
+ + " <transition to='subprocessnode' />"
+ + " <transition name='done' to='end' />"
+ + " </state>"
+ + " <process-state name='subprocessnode'>"
+ + " <sub-process name='recursive process' />"
+ + " <transition to='end' />"
+ + " </process-state>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
+
processDefinition = saveAndReload(processDefinition);
- try
- {
+ try {
ProcessInstance superProcessInstance = processDefinition.createProcessInstance();
superProcessInstance.signal();
superProcessInstance.signal();
@@ -85,7 +76,8 @@
ProcessInstance subProcessInstance = superToken.getSubProcessInstance();
assertNotNull(subProcessInstance);
- assertEquals("recursive process", subProcessInstance.getProcessDefinition().getName());
+ assertEquals("recursive process",
+ subProcessInstance.getProcessDefinition().getName());
Token subToken = subProcessInstance.getRootToken();
assertEquals("first wait", subToken.getNode().getName());
@@ -98,177 +90,165 @@
assertTrue(subProcessInstance.hasEnded());
assertTrue(superProcessInstance.hasEnded());
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinition.getId());
}
}
- public void testMultipleRecursiveProcessDefinitions()
- {
- for (int i=0; i<30; i++) {
+ public void testMultipleRecursiveProcessDefinitions() {
+ for (int i = 0; i < 30; i++) {
testRecursiveProcessDefinition();
newTransaction();
}
}
- public void testProcessStateSubProcessDefinition()
- {
+ public void testProcessStateSubProcessDefinition() {
// create the subprocess
ProcessDefinition subProcessDefinition = new ProcessDefinition("sub");
// store the subprocess in the database
graphSession.saveProcessDefinition(subProcessDefinition);
- try
- {
+ try {
// create the super process
- ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='super'>" +
- " <process-state name='subprocess' />" +
- "</process-definition>");
+ ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString("<process-definition name='super'>"
+ + " <process-state name='subprocess' />"
+ + "</process-definition>");
// resolve the reference to the subprocess
ProcessState processState = (ProcessState) superProcessDefinition.getNode("subprocess");
processState.setSubProcessDefinition(subProcessDefinition);
-
+
// save and reload the superprocess
- superProcessDefinition = saveAndReload(superProcessDefinition);
- try
- {
+ superProcessDefinition = saveAndReload(superProcessDefinition);
+ try {
processState = (ProcessState) superProcessDefinition.getNode("subprocess");
assertNotNull("sub", processState.getSubProcessDefinition().getName());
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(superProcessDefinition);
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ superProcessDefinition);
}
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(subProcessDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ subProcessDefinition.getId());
}
}
public void testProcessStateStartVariableMappings() {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition>" +
- " <process-state name='subprocess'>" +
- " <variable name='startsuperone' access='read,write' mapped-name='startsubone' />" +
- " <variable name='startsupertwo' access='read,write' mapped-name='startsubtwo' />" +
- " <variable name='startsuperthree' access='read,write' mapped-name='startsubthree' />" +
- " </process-state>" +
- "</process-definition>");
-
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition>"
+ + " <process-state name='subprocess'>"
+ + " <variable name='startsuperone' access='read,write' mapped-name='startsubone' />"
+ + " <variable name='startsupertwo' access='read,write' mapped-name='startsubtwo' />"
+ + " <variable name='startsuperthree' access='read,write' mapped-name='startsubthree' />"
+ + " </process-state>"
+ + "</process-definition>");
+
processDefinition = saveAndReload(processDefinition);
- try
- {
+ try {
ProcessState processState = (ProcessState) processDefinition.getNode("subprocess");
- assertEquals(3, processState.variableAccesses.size() );
+ assertEquals(3, processState.variableAccesses.size());
}
- finally
- {
+ finally {
jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition);
}
}
- public void testSubProcessBindingWithLatestVersion()
- {
+ public void testSubProcessBindingWithLatestVersion() {
final int versionCount = 3;
- for (int i = 0; i < versionCount; i++)
- {
- jbpmContext.deployProcessDefinition(new ProcessDefinition("the multiversion subprocess"));
+ for (int i = 0; i < versionCount; i++) {
+ jbpmContext.deployProcessDefinition(new ProcessDefinition(
+ "the multiversion subprocess"));
}
newTransaction();
- try
- {
- ProcessDefinition processDefinitionTwo = ProcessDefinition.parseXmlString(
- "<process-definition>" +
- " <process-state name='the sub process state'>" +
- " <sub-process name='the multiversion subprocess'/>" +
- " </process-state>" +
- "</process-definition>"
- );
+ try {
+ ProcessDefinition processDefinitionTwo = ProcessDefinition.parseXmlString("<process-definition>"
+ + " <process-state name='the sub process state'>"
+ + " <sub-process name='the multiversion subprocess'/>"
+ + " </process-state>"
+ + "</process-definition>");
processDefinitionTwo = saveAndReload(processDefinitionTwo);
- try
- {
+ try {
ProcessState processState = (ProcessState) processDefinitionTwo.getNode("the sub process state");
- assertEquals("the multiversion subprocess", processState.getSubProcessDefinition().getName() );
- assertEquals(3, processState.getSubProcessDefinition().getVersion() );
+ assertEquals("the multiversion subprocess",
+ processState.getSubProcessDefinition().getName());
+ assertEquals(3, processState.getSubProcessDefinition().getVersion());
}
- finally
- {
+ finally {
graphSession.deleteProcessDefinition(processDefinitionTwo);
}
}
- finally
- {
- for (int i = 1; i <= versionCount; i++)
- {
- ProcessDefinition processDefinition = graphSession.findProcessDefinition("the multiversion subprocess", i);
+ finally {
+ for (int i = 1; i <= versionCount; i++) {
+ ProcessDefinition processDefinition = graphSession.findProcessDefinition(
+ "the multiversion subprocess", i);
graphSession.deleteProcessDefinition(processDefinition);
- }
- }
+ }
+ }
}
- public void testAverageSubProcess()
- {
- ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='subprocess'>" +
- " <start-state name='start'>" +
- " <transition to='wait' />" +
- " </start-state>" +
- " <state name='wait'>" +
- " <transition to='end' />" +
- " </state>" +
- " <end-state name='end' />" +
- "</process-definition>");
+ public void testAverageSubProcess() {
+ ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlString("<process-definition name='subprocess'>"
+ + " <start-state name='start'>"
+ + " <transition to='wait' />"
+ + " </start-state>"
+ + " <state name='wait'>"
+ + " <transition to='end' />"
+ + " </state>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(subProcessDefinition);
-
- ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='superprocess'>" +
- " <start-state name='start'>" +
- " <transition to='sub process state' />" +
- " </start-state>" +
- " <process-state name='sub process state'>" +
- " <sub-process name='subprocess' />" +
- " <variable name='a' access='read' mapped-name='A' />" +
- " <variable name='b' mapped-name='B' />" +
- " <variable name='c' access='write' mapped-name='C' />" +
- " <transition to='wait' />" +
- " </process-state>" +
- " <state name='wait' />" +
- "</process-definition>");
+
+ ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString("<process-definition name='superprocess'>"
+ + " <start-state name='start'>"
+ + " <transition to='sub process state' />"
+ + " </start-state>"
+ + " <process-state name='sub process state'>"
+ + " <sub-process name='subprocess' />"
+ + " <variable name='a' access='read' mapped-name='A' />"
+ + " <variable name='b' mapped-name='B' />"
+ + " <variable name='c' access='write' mapped-name='C' />"
+ + " <transition to='wait' />"
+ + " </process-state>"
+ + " <state name='wait' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(superProcessDefinition);
- try
- {
+ try {
newTransaction();
-
+
ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("superprocess");
ContextInstance contextInstance = processInstance.getContextInstance();
contextInstance.setVariable("a", "1");
contextInstance.setVariable("b", "1");
contextInstance.setVariable("c", "1");
processInstance.signal();
-
+
newTransaction();
long processInstanceId = processInstance.getId();
- long subProcessInstanceId = processInstance.getRootToken().getSubProcessInstance().getId();
+ long subProcessInstanceId = processInstance.getRootToken()
+ .getSubProcessInstance()
+ .getId();
processInstance = jbpmContext.loadProcessInstance(processInstanceId);
assertNotNull(processInstance.getRootToken().getSubProcessInstance());
- assertEquals("sub process state", processInstance.getRootToken().getNode().getName());
+ assertEquals("sub process state", processInstance.getRootToken()
+ .getNode()
+ .getName());
contextInstance = processInstance.getContextInstance();
- assertEquals("1", contextInstance.getVariable("a") );
- assertEquals("1", contextInstance.getVariable("b") );
- assertEquals("1", contextInstance.getVariable("c") );
+ assertEquals("1", contextInstance.getVariable("a"));
+ assertEquals("1", contextInstance.getVariable("b"));
+ assertEquals("1", contextInstance.getVariable("c"));
ProcessInstance subProcessInstance = jbpmContext.loadProcessInstance(subProcessInstanceId);
- assertEquals("wait", subProcessInstance.getRootToken().getNode().getName());
+ assertEquals("wait", subProcessInstance.getRootToken()
+ .getNode()
+ .getName());
ContextInstance subContextInstance = subProcessInstance.getContextInstance();
- assertEquals("1", subContextInstance.getVariable("A") );
- assertEquals("1", subContextInstance.getVariable("B") );
- assertNull(subContextInstance.getVariable("C") );
-
+ assertEquals("1", subContextInstance.getVariable("A"));
+ assertEquals("1", subContextInstance.getVariable("B"));
+ assertNull(subContextInstance.getVariable("C"));
+
subContextInstance.setVariable("A", "2");
subContextInstance.setVariable("B", "2");
subContextInstance.setVariable("C", "2");
@@ -278,257 +258,270 @@
newTransaction();
- assertTrue(jbpmContext.loadProcessInstance(subProcessInstanceId).hasEnded());
-
+ assertTrue(jbpmContext.loadProcessInstance(subProcessInstanceId)
+ .hasEnded());
+
processInstance = jbpmContext.loadProcessInstance(processInstanceId);
assertEquals("wait", processInstance.getRootToken().getNode().getName());
contextInstance = processInstance.getContextInstance();
- assertEquals("1", contextInstance.getVariable("a") );
- assertEquals("2", contextInstance.getVariable("b") );
- assertEquals("2", contextInstance.getVariable("c") );
+ assertEquals("1", contextInstance.getVariable("a"));
+ assertEquals("2", contextInstance.getVariable("b"));
+ assertEquals("2", contextInstance.getVariable("c"));
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(superProcessDefinition.getId());
- jbpmContext.getGraphSession().deleteProcessDefinition(subProcessDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ superProcessDefinition.getId());
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ subProcessDefinition.getId());
}
}
- public void testSubProcessBindingByVersion()
- {
- ProcessDefinition processDefinitionOne = new ProcessDefinition("the ultimate subprocess");
+ public void testSubProcessBindingByVersion() {
+ ProcessDefinition processDefinitionOne = new ProcessDefinition(
+ "the ultimate subprocess");
jbpmContext.deployProcessDefinition(processDefinitionOne);
newTransaction();
- ProcessDefinition processDefinitionTwo = ProcessDefinition.parseXmlString(
- "<process-definition>" +
- " <process-state name='the sub process state'>" +
- " <sub-process name='the ultimate subprocess' version='1' />" +
- " </process-state>" +
- "</process-definition>"
- );
+ ProcessDefinition processDefinitionTwo = ProcessDefinition.parseXmlString("<process-definition>"
+ + " <process-state name='the sub process state'>"
+ + " <sub-process name='the ultimate subprocess' version='1' />"
+ + " </process-state>"
+ + "</process-definition>");
processDefinitionTwo = saveAndReload(processDefinitionTwo);
- try
- {
+ try {
ProcessState processState = (ProcessState) processDefinitionTwo.getNode("the sub process state");
- assertEquals("the ultimate subprocess", processState.getSubProcessDefinition().getName() );
- assertEquals(1, processState.getSubProcessDefinition().getVersion() );
+ assertEquals("the ultimate subprocess",
+ processState.getSubProcessDefinition().getName());
+ assertEquals(1, processState.getSubProcessDefinition().getVersion());
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinitionOne.getId());
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinitionTwo);
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinitionOne.getId());
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinitionTwo);
}
}
public void testSubProcessLogs() {
- ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='subprocess'>" +
- " <start-state name='start'>" +
- " <transition to='wait' />" +
- " </start-state>" +
- " <state name='wait'>" +
- " <transition to='end' />" +
- " </state>" +
- " <end-state name='end' />" +
- "</process-definition>");
+ ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlString("<process-definition name='subprocess'>"
+ + " <start-state name='start'>"
+ + " <transition to='wait' />"
+ + " </start-state>"
+ + " <state name='wait'>"
+ + " <transition to='end' />"
+ + " </state>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(subProcessDefinition);
-
- ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='superprocess'>" +
- " <start-state name='start'>" +
- " <transition to='sub process state' />" +
- " </start-state>" +
- " <process-state name='sub process state'>" +
- " <sub-process name='subprocess' />" +
- " <transition to='wait' />" +
- " </process-state>" +
- " <state name='wait' />" +
- "</process-definition>");
+
+ ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString("<process-definition name='superprocess'>"
+ + " <start-state name='start'>"
+ + " <transition to='sub process state' />"
+ + " </start-state>"
+ + " <process-state name='sub process state'>"
+ + " <sub-process name='subprocess' />"
+ + " <transition to='wait' />"
+ + " </process-state>"
+ + " <state name='wait' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(superProcessDefinition);
-
- try
- {
+
+ try {
newTransaction();
-
+
ProcessInstance superProcessInstance = jbpmContext.newProcessInstanceForUpdate("superprocess");
superProcessInstance.signal();
-
+
newTransaction();
- long subProcessInstanceId = superProcessInstance.getRootToken().getSubProcessInstance().getId();
+ long subProcessInstanceId = superProcessInstance.getRootToken()
+ .getSubProcessInstance()
+ .getId();
ProcessInstance subProcessInstance = jbpmContext.loadProcessInstance(subProcessInstanceId);
subProcessInstance.signal();
jbpmContext.save(subProcessInstance);
newTransaction();
- ProcessStateLog processStateLog = (ProcessStateLog) session.createCriteria(ProcessStateLog.class)
+ ProcessStateLog processStateLog = (ProcessStateLog) session.createCriteria(
+ ProcessStateLog.class)
.addOrder(Order.desc("enter"))
.setMaxResults(1)
.uniqueResult();
- assertEquals(subProcessInstanceId, processStateLog.getSubProcessInstance().getId());
- assertEquals(superProcessInstance.getId(), processStateLog.getToken().getProcessInstance().getId());
+ assertEquals(subProcessInstanceId,
+ processStateLog.getSubProcessInstance().getId());
+ assertEquals(superProcessInstance.getId(), processStateLog.getToken()
+ .getProcessInstance()
+ .getId());
}
- finally
- {
+ finally {
graphSession.deleteProcessDefinition(subProcessDefinition.getId());
graphSession.deleteProcessDefinition(superProcessDefinition.getId());
}
}
- public void testDynamicProcessBinding()
- {
- ProcessDefinition processDefinitionOne = ProcessDefinition.parseXmlString(
- "<process-definition name='subprocess1'>" +
- " <start-state name='start'>" +
- " <transition to='wait subprocess 1' />" +
- " </start-state>" +
- " <state name='wait subprocess 1'>" +
- " <transition to='end' />" +
- " </state>" +
- " <end-state name='end' />" +
- "</process-definition>");
+ public void testDynamicProcessBinding() {
+ ProcessDefinition processDefinitionOne = ProcessDefinition.parseXmlString("<process-definition name='subprocess1'>"
+ + " <start-state name='start'>"
+ + " <transition to='wait subprocess 1' />"
+ + " </start-state>"
+ + " <state name='wait subprocess 1'>"
+ + " <transition to='end' />"
+ + " </state>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinitionOne);
-
- ProcessDefinition processDefinitionTwo = ProcessDefinition.parseXmlString(
- "<process-definition name='subprocess2'>" +
- " <start-state name='start'>" +
- " <transition to='wait subprocess 2' />" +
- " </start-state>" +
- " <state name='wait subprocess 2'>" +
- " <transition to='end' />" +
- " </state>" +
- " <end-state name='end' />" +
- "</process-definition>");
- jbpmContext.deployProcessDefinition(processDefinitionTwo);
-
- ProcessDefinition processDefinitionThree = ProcessDefinition.parseXmlString(
- "<process-definition name='superprocess'>" +
- " <start-state name='start'>" +
- " <transition to='sub process state' />" +
- " </start-state>" +
- " <process-state name='sub process state'>" +
- " <sub-process name='#{mySubProcess}' binding='late'/>" +
- " <transition to='wait' />" +
- " </process-state>" +
- " <state name='wait' />" +
- "</process-definition>");
+
+ ProcessDefinition processDefinitionTwo = ProcessDefinition.parseXmlString("<process-definition name='subprocess2'>"
+ + " <start-state name='start'>"
+ + " <transition to='wait subprocess 2' />"
+ + " </start-state>"
+ + " <state name='wait subprocess 2'>"
+ + " <transition to='end' />"
+ + " </state>"
+ + " <end-state name='end' />"
+ + "</process-definition>");
+ jbpmContext.deployProcessDefinition(processDefinitionTwo);
+
+ ProcessDefinition processDefinitionThree = ProcessDefinition.parseXmlString("<process-definition name='superprocess'>"
+ + " <start-state name='start'>"
+ + " <transition to='sub process state' />"
+ + " </start-state>"
+ + " <process-state name='sub process state'>"
+ + " <sub-process name='#{mySubProcess}' binding='late'/>"
+ + " <transition to='wait' />"
+ + " </process-state>"
+ + " <state name='wait' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinitionThree);
- try
- {
+ try {
newTransaction();
-
+
ProcessInstance processInstance1 = jbpmContext.newProcessInstanceForUpdate("superprocess");
ContextInstance contextInstance = processInstance1.getContextInstance();
contextInstance.setVariable("mySubProcess", "subprocess1");
processInstance1.signal();
-
+
newTransaction();
long processInstanceId = processInstance1.getId();
- long subProcessInstanceId = processInstance1.getRootToken().getSubProcessInstance().getId();
- // System.out.println("process ID: " + processInstanceId + " subprocess ID: " + subProcessInstanceId);
-
+ long subProcessInstanceId = processInstance1.getRootToken()
+ .getSubProcessInstance()
+ .getId();
+ // System.out.println("process ID: " + processInstanceId +
+ // " subprocess ID: " + subProcessInstanceId);
+
processInstance1 = jbpmContext.loadProcessInstance(processInstanceId);
assertNotNull(processInstance1.getRootToken().getSubProcessInstance());
- assertEquals("sub process state", processInstance1.getRootToken().getNode().getName());
+ assertEquals("sub process state", processInstance1.getRootToken()
+ .getNode()
+ .getName());
contextInstance = processInstance1.getContextInstance();
- assertEquals("subprocess1", contextInstance.getVariable("mySubProcess") );
+ assertEquals("subprocess1", contextInstance.getVariable("mySubProcess"));
ProcessInstance subProcessInstance1 = jbpmContext.loadProcessInstance(subProcessInstanceId);
- assertEquals("subprocess1", subProcessInstance1.getProcessDefinition().getName());
- assertEquals("wait subprocess 1", subProcessInstance1.getRootToken().getNode().getName());
+ assertEquals("subprocess1", subProcessInstance1.getProcessDefinition()
+ .getName());
+ assertEquals("wait subprocess 1", subProcessInstance1.getRootToken()
+ .getNode()
+ .getName());
subProcessInstance1.signal();
jbpmContext.save(subProcessInstance1);
newTransaction();
- assertTrue(jbpmContext.loadProcessInstance(subProcessInstanceId).hasEnded());
-
+ assertTrue(jbpmContext.loadProcessInstance(subProcessInstanceId)
+ .hasEnded());
+
processInstance1 = jbpmContext.loadProcessInstance(processInstanceId);
assertEquals("wait", processInstance1.getRootToken().getNode().getName());
-
+
newTransaction();
-
+
ProcessInstance processInstance2 = jbpmContext.newProcessInstanceForUpdate("superprocess");
ContextInstance contextInstance2 = processInstance2.getContextInstance();
contextInstance2.setVariable("mySubProcess", "subprocess2");
processInstance2.signal();
-
+
newTransaction();
long processInstanceId2 = processInstance2.getId();
- long subProcessInstanceId2 = processInstance2.getRootToken().getSubProcessInstance().getId();
- // System.out.println("process ID: " + processInstanceId2 + " subprocess ID: " + subProcessInstanceId2);
-
+ long subProcessInstanceId2 = processInstance2.getRootToken()
+ .getSubProcessInstance()
+ .getId();
+ // System.out.println("process ID: " + processInstanceId2 +
+ // " subprocess ID: " + subProcessInstanceId2);
+
processInstance2 = jbpmContext.loadProcessInstance(processInstanceId2);
assertNotNull(processInstance2.getRootToken().getSubProcessInstance());
- assertEquals("sub process state", processInstance2.getRootToken().getNode().getName());
+ assertEquals("sub process state", processInstance2.getRootToken()
+ .getNode()
+ .getName());
contextInstance2 = processInstance2.getContextInstance();
- assertEquals("subprocess2", contextInstance2.getVariable("mySubProcess") );
+ assertEquals("subprocess2", contextInstance2.getVariable("mySubProcess"));
ProcessInstance subProcessInstance2 = jbpmContext.loadProcessInstance(subProcessInstanceId2);
- assertEquals("subprocess2", subProcessInstance2.getProcessDefinition().getName());
- assertEquals("wait subprocess 2", subProcessInstance2.getRootToken().getNode().getName());
+ assertEquals("subprocess2", subProcessInstance2.getProcessDefinition()
+ .getName());
+ assertEquals("wait subprocess 2", subProcessInstance2.getRootToken()
+ .getNode()
+ .getName());
subProcessInstance2.signal();
jbpmContext.save(subProcessInstance2);
newTransaction();
- assertTrue(jbpmContext.loadProcessInstance(subProcessInstanceId2).hasEnded());
-
+ assertTrue(jbpmContext.loadProcessInstance(subProcessInstanceId2)
+ .hasEnded());
+
processInstance2 = jbpmContext.loadProcessInstance(processInstanceId2);
assertEquals("wait", processInstance2.getRootToken().getNode().getName());
}
- finally
- {
+ finally {
newTransaction();
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinitionOne.getId());
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinitionTwo.getId());
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinitionThree.getId());
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinitionOne.getId());
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinitionTwo.getId());
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinitionThree.getId());
}
- }
+ }
- public void testUnboundSubProcess()
- {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='superprocess'>" +
- " <start-state name='start'>" +
- " <transition to='sub process state' />" +
- " </start-state>" +
- " <process-state name='sub process state'>" +
- " <sub-process name='subprocess' binding='late' />" +
- " <transition to='wait' />" +
- " </process-state>" +
- " <state name='wait' />" +
- "</process-definition>");
-
+ public void testUnboundSubProcess() {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='superprocess'>"
+ + " <start-state name='start'>"
+ + " <transition to='sub process state' />"
+ + " </start-state>"
+ + " <process-state name='sub process state'>"
+ + " <sub-process name='subprocess' binding='late' />"
+ + " <transition to='wait' />"
+ + " </process-state>"
+ + " <state name='wait' />"
+ + "</process-definition>");
+
jbpmContext.deployProcessDefinition(processDefinition);
- try
- {
+ try {
newTransaction();
- ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("superprocess");
- try
- {
+ ProcessInstance processInstance = jbpmContext.newProcessInstance("superprocess");
+ try {
processInstance.signal();
fail("expected exception");
}
- catch (JbpmException e)
- {
+ catch (IllegalArgumentException e) {
// expected
jbpmContext.setRollbackOnly();
}
}
- finally
- {
+ finally {
newTransaction();
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinition.getId());
}
}
}
Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java 2010-01-16 00:21:04 UTC (rev 6084)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/taskmgmt/exe/EndTasksDbTest.java 2010-01-16 03:29:46 UTC (rev 6085)
@@ -1,7 +1,6 @@
package org.jbpm.taskmgmt.exe;
import java.util.Collection;
-import java.util.Iterator;
import org.jbpm.db.AbstractDbTestCase;
import org.jbpm.graph.def.ActionHandler;
@@ -9,172 +8,165 @@
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
-public class EndTasksDbTest extends AbstractDbTestCase
-{
-
- public static class Buzz implements ActionHandler
- {
+public class EndTasksDbTest extends AbstractDbTestCase {
+
+ public static class Buzz implements ActionHandler {
private static final long serialVersionUID = 1L;
- public void execute(ExecutionContext executionContext) throws Exception
- {
+ public void execute(ExecutionContext executionContext) throws Exception {
throw new RuntimeException("buzz");
}
}
- public void testCancel()
- {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='endtasksprocess'>" +
- " <start-state>" +
- " <transition to='approval' />" +
- " </start-state>" +
- " <task-node name='approval' end-tasks='true'>" +
- " <task name='approve' description='Review order'>" +
- " <assignment pooled-actors='reviewers' />" +
- " </task>" +
- " <transition name='approve' to='process'>" +
- " <action class='"+Buzz.class.getName()+"' />" +
- " </transition>" +
- " <transition name='cancel' to='cancelled'/>" +
- " </task-node>" +
- " <state name='process' />" +
- " <state name='cancelled' />" +
- "</process-definition>"
- );
-
+ public void testCancel() {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='endtasksprocess'>"
+ + " <start-state>"
+ + " <transition to='approval' />"
+ + " </start-state>"
+ + " <task-node name='approval' end-tasks='true'>"
+ + " <task name='approve' description='Review order'>"
+ + " <assignment pooled-actors='reviewers' />"
+ + " </task>"
+ + " <transition name='approve' to='process'>"
+ + " <action class='"
+ + Buzz.class.getName()
+ + "' />"
+ + " </transition>"
+ + " <transition name='cancel' to='cancelled'/>"
+ + " </task-node>"
+ + " <state name='process' />"
+ + " <state name='cancelled' />" + "</process-definition>");
+
jbpmContext.deployProcessDefinition(processDefinition);
- try
- {
- ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
+ newTransaction();
+
+ try {
+ ProcessInstance processInstance = jbpmContext.newProcessInstance("endtasksprocess");
processInstance.signal();
processInstance = saveAndReload(processInstance);
+ assertEquals("approval", processInstance.getRootToken()
+ .getNode()
+ .getName());
- assertEquals("approval", processInstance.getRootToken().getNode().getName());
processInstance = saveAndReload(processInstance);
processInstance.signal("cancel");
- assertEquals("cancelled", processInstance.getRootToken().getNode().getName());
+ assertEquals("cancelled", processInstance.getRootToken()
+ .getNode()
+ .getName());
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinition.getId());
}
}
- public void testApprove()
- {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='endtasksprocess'>" +
- " <start-state>" +
- " <transition to='approval' />" +
- " </start-state>" +
- " <task-node name='approval' end-tasks='true'>" +
- " <task name='approve' description='Review order'>" +
- " <assignment pooled-actors='reviewers' />" +
- " </task>" +
- " <transition name='approve' to='process'/>" +
- " <transition name='reject' to='cancelled'/>" +
- " <transition name='cancel' to='cancelled'/>" +
- " </task-node>" +
- " <state name='process' />" +
- " <state name='cancelled' />" +
- "</process-definition>"
- );
+ public void testApprove() {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='endtasksprocess'>"
+ + " <start-state>"
+ + " <transition to='approval' />"
+ + " </start-state>"
+ + " <task-node name='approval' end-tasks='true'>"
+ + " <task name='approve' description='Review order'>"
+ + " <assignment pooled-actors='reviewers' />"
+ + " </task>"
+ + " <transition name='approve' to='process'/>"
+ + " <transition name='reject' to='cancelled'/>"
+ + " <transition name='cancel' to='cancelled'/>"
+ + " </task-node>"
+ + " <state name='process' />"
+ + " <state name='cancelled' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinition);
- try
- {
- newTransaction();
+ newTransaction();
+ try {
ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
processInstance.signal();
processInstance = saveAndReload(processInstance);
+ assertEquals("approval", processInstance.getRootToken()
+ .getNode()
+ .getName());
- assertEquals("approval", processInstance.getRootToken().getNode().getName());
- TaskInstance taskInstance = (TaskInstance) processInstance
- .getTaskMgmtInstance()
+ TaskInstance taskInstance = (TaskInstance) processInstance.getTaskMgmtInstance()
.getTaskInstances()
.iterator()
.next();
-
taskInstance.end("approve");
- assertEquals("process", processInstance.getRootToken().getNode().getName());
+ assertEquals("process", processInstance.getRootToken()
+ .getNode()
+ .getName());
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinition.getId());
}
}
- public void testReject()
- {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='endtasksprocess'>" +
- " <start-state>" +
- " <transition to='approval' />" +
- " </start-state>" +
- " <task-node name='approval' end-tasks='true'>" +
- " <task name='approve' description='Review order'>" +
- " <assignment pooled-actors='reviewers' />" +
- " </task>" +
- " <transition name='approve' to='process'/>" +
- " <transition name='reject' to='cancelled'/>" +
- " <transition name='cancel' to='cancelled'/>" +
- " </task-node>" +
- " <state name='process' />" +
- " <state name='cancelled' />" +
- "</process-definition>"
- );
+ public void testReject() {
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='endtasksprocess'>"
+ + " <start-state>"
+ + " <transition to='approval' />"
+ + " </start-state>"
+ + " <task-node name='approval' end-tasks='true'>"
+ + " <task name='approve' description='Review order'>"
+ + " <assignment pooled-actors='reviewers' />"
+ + " </task>"
+ + " <transition name='approve' to='process'/>"
+ + " <transition name='reject' to='cancelled'/>"
+ + " <transition name='cancel' to='cancelled'/>"
+ + " </task-node>"
+ + " <state name='process' />"
+ + " <state name='cancelled' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinition);
- try
- {
- newTransaction();
+ newTransaction();
+ try {
ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
processInstance.signal();
processInstance = saveAndReload(processInstance);
+ assertEquals("approval", processInstance.getRootToken()
+ .getNode()
+ .getName());
- assertEquals("approval", processInstance.getRootToken().getNode().getName());
- TaskInstance taskInstance = (TaskInstance) processInstance
- .getTaskMgmtInstance()
+ TaskInstance taskInstance = (TaskInstance) processInstance.getTaskMgmtInstance()
.getTaskInstances()
.iterator()
.next();
-
taskInstance.end("reject");
- assertEquals("cancelled", processInstance.getRootToken().getNode().getName());
+ assertEquals("cancelled", processInstance.getRootToken()
+ .getNode()
+ .getName());
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinition.getId());
}
}
public void testTaskInstancesAfterCancellation() {
- ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
- "<process-definition name='endtasksprocess'>" +
- " <start-state>" +
- " <transition to='approval' />" +
- " </start-state>" +
- " <task-node name='approval' end-tasks='true'>" +
- " <task name='approve' description='Review order'>" +
- " <assignment pooled-actors='reviewers' />" +
- " </task>" +
- " <transition name='approve' to='process'/>" +
- " <transition name='reject' to='cancelled'/>" +
- " <transition name='cancel' to='cancelled'/>" +
- " </task-node>" +
- " <state name='process' />" +
- " <state name='cancelled' />" +
- "</process-definition>"
- );
+ ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition name='endtasksprocess'>"
+ + " <start-state>"
+ + " <transition to='approval' />"
+ + " </start-state>"
+ + " <task-node name='approval' end-tasks='true'>"
+ + " <task name='approve' description='Review order'>"
+ + " <assignment pooled-actors='reviewers' />"
+ + " </task>"
+ + " <transition name='approve' to='process'/>"
+ + " <transition name='reject' to='cancelled'/>"
+ + " <transition name='cancel' to='cancelled'/>"
+ + " </task-node>"
+ + " <state name='process' />"
+ + " <state name='cancelled' />"
+ + "</process-definition>");
jbpmContext.deployProcessDefinition(processDefinition);
- try
- {
- newTransaction();
+ newTransaction();
+ try {
ProcessInstance processInstance = jbpmContext.newProcessInstanceForUpdate("endtasksprocess");
processInstance.signal();
@@ -182,19 +174,20 @@
processInstance = saveAndReload(processInstance);
processInstance.signal("cancel");
- Collection taskInstances = processInstance.getTaskMgmtInstance().getTaskInstances();
- Iterator iter = taskInstances.iterator();
- while(iter.hasNext()) {
- TaskInstance taskInstance = (TaskInstance) iter.next();
- assertTrue(taskInstance.getName()+" ended", taskInstance.hasEnded());
- assertFalse(taskInstance.getName()+" not cancelled", taskInstance.isCancelled());
- assertFalse(taskInstance.getName()+" not blocking", taskInstance.isBlocking());
- assertFalse(taskInstance.getName()+" not signalling", taskInstance.isSignalling());
- }
+ Collection taskInstances = processInstance.getTaskMgmtInstance()
+ .getTaskInstances();
+ assertEquals(1, taskInstances.size());
+
+ TaskInstance taskInstance = (TaskInstance) taskInstances.iterator()
+ .next();
+ assert taskInstance.hasEnded() : taskInstance;
+ assert !taskInstance.isCancelled() : taskInstance;
+ assert !taskInstance.isBlocking() : taskInstance;
+ assert !taskInstance.isSignalling() : taskInstance;
}
- finally
- {
- jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
+ finally {
+ jbpmContext.getGraphSession().deleteProcessDefinition(
+ processDefinition.getId());
}
}
}
16 years, 3 months
JBoss JBPM SVN: r6084 - in jbpm4/trunk/modules: bpmn/src/main/java/org/jbpm/bpmn/model and 5 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-15 19:21:04 -0500 (Fri, 15 Jan 2010)
New Revision: 6084
Added:
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java
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/InclusiveGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/ParallelGatewayTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/ParallelGatewayMergeTest.java
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/forkjoin/MultipleForksTest.java
Log:
JBPM2738: working on the inclusive gateway. Covered basic split/merge behaviour with new logic and test cases.
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-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -107,14 +107,21 @@
}
}
+ /**
+ * Returns the list of outgoing sequence flow for this activity.
+ * If the boolean 'checkConditions' is true, conditions on the sequence flow will be evaluated.
+ *
+ * Note that for activities that have a default sequence flow (eg Exclusive gateway),
+ * the default sequence flow will NOT be included in the returned list.
+ */
protected List<Transition> findOutgoingSequenceFlow(ExecutionImpl execution, boolean checkConditions) {
Activity activity = execution.getActivity();
// evaluate the conditions and find the transitions that should be forked
List<Transition> forkingTransitions = new ArrayList<Transition>();
List<Transition> outgoingTransitions = activity.getOutgoingTransitions();
+
for (Transition transition : outgoingTransitions) {
Condition condition = transition.getCondition();
- // also ignore the default transition of the exclusive gateway
if ( ( (condition == null)
|| (!checkConditions)
|| (condition.evaluate(execution))
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -21,9 +21,21 @@
*/
package org.jbpm.bpmn.flownodes;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.jbpm.api.Execution;
+import org.jbpm.api.JbpmException;
import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.bpmn.model.BpmnProcessDefinition;
import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.env.EnvironmentImpl;
+import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.ExecutionImpl;
+import org.jbpm.pvm.internal.model.Transition;
/**
* @author Joram Barrez
@@ -33,6 +45,8 @@
private static final long serialVersionUID = 1L;
private static final Log LOG = Log.getLog(InclusiveGatewayActivity.class.getName());
+
+ protected LockMode lockMode = LockMode.UPGRADE;
public void execute(ActivityExecution execution) throws Exception {
execute((ExecutionImpl) execution);
@@ -40,14 +54,147 @@
public void execute(ExecutionImpl execution) {
int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
+
if (nrOfIncoming == 1) { // no merge behaviour needed, save some time and do a fork immediately
if (LOG.isDebugEnabled()) {
LOG.debug("Only one incoming sequence flow found. Executing fork logic only.");
}
- proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED));
- }
+ fork(execution);
+ } else {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
+ }
+ boolean allExecutionsArrived = handleIncomingExecution(execution);
+
+ if (allExecutionsArrived) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("All executions have reached the inclusive join. Executing fork logic.");
+ }
+ ExecutionImpl outgoingExecution = join(execution);
+ fork(outgoingExecution);
+ }
+
+ }
- // TODO finish
+
}
+
+ public void fork(ExecutionImpl execution) {
+ List<Transition> outgointSeqFlow = findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED);
+
+ if (outgointSeqFlow.isEmpty()) {
+ Transition defaultSeqFlow = execution.getActivity().getDefaultOutgoingTransition();
+ if (defaultSeqFlow != null) {
+ outgointSeqFlow.add(defaultSeqFlow);
+ } else {
+ throw new JbpmException("No sequenceFlow condition evaluated to true for " +
+ execution.getActivity() + " and no default sequenceFlow was speficied");
+ }
+ }
+
+ proceed(execution, outgointSeqFlow);
+ }
+
+ /**
+ * Joins the incoming executions.
+ * Returns true if all executions have reached the gateway.
+ */
+ protected boolean handleIncomingExecution(ExecutionImpl execution) {
+ if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
+
+ // force version increment in the parent execution
+ Session session = EnvironmentImpl.getFromCurrent(Session.class);
+ session.lock(execution.getParent(), lockMode);
+ execution.setState(Execution.STATE_INACTIVE_JOIN);
+ execution.waitForSignal();
+
+ return isComplete(execution);
+
+ } else {
+ throw new JbpmException("invalid execution state: " + execution.getState());
+ }
+ }
+
+ /**
+ * Joins all the incoming executions currently waiting at the gateway.
+ *
+ * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
+ * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
+ */
+ protected ExecutionImpl join(ExecutionImpl execution) {
+ Activity activity = execution.getActivity();
+ ExecutionImpl concurrentRoot = execution.getParent();
+ List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
+
+ endJoinedExecutions(joinedExecutions);
+
+ ExecutionImpl outgoingExecution = null;
+ if (concurrentRoot.getExecutions().size() == 0) {
+ outgoingExecution = concurrentRoot;
+ outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
+ } else {
+ outgoingExecution = concurrentRoot.createExecution();
+ outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
+ }
+
+ outgoingExecution.setActivity(activity);
+ return outgoingExecution;
+ }
+
+ /**
+ * Section 14.3.2 of the BPMN 2.0 specification.
+ *
+ * The Inclusive Gateway is activated if
+ * - At least one incoming sequence flow has at least one Token and
+ * - for each empty incoming sequence flow, there is no Token in the graph anywhere
+ * upstream of this sequence flow, i.e., there is no directed path (formed by Sequence Flow)
+ * from a Token to this sequence flow unless
+ * - the path visits the inclusive gateway or
+ * - the path visits a node that has a directed path to a non-empty incoming sequence
+ * flow of the inclusive gateway.
+ */
+ protected boolean isComplete(ExecutionImpl incomingExecution) {
+ String currentActivityId = incomingExecution.getActivityName(); // id is stored in the name attribute
+ Collection<ExecutionImpl> allExecutions = incomingExecution.getProcessInstance().getExecutions();
+ BpmnProcessDefinition processDefinition = (BpmnProcessDefinition) incomingExecution.getProcessDefinition();
+
+ for (ExecutionImpl execution : allExecutions) {
+ String activityId = execution.getActivityName(); // id is stored in the name attribute
+ if (activityId != null && !currentActivityId.equals(activityId)) {
+ if (processDefinition.isReachable(activityId, currentActivityId)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
+ List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
+ List<ExecutionImpl> concurrentExecutions = (List<ExecutionImpl>)concurrentRoot.getExecutions();
+ for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
+ if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
+ && (concurrentExecution.getActivity()==activity)
+ ) {
+ joinedExecutions.add(concurrentExecution);
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found " + joinedExecutions.size() + " executions currently waiting at the gateway");
+ }
+
+ return joinedExecutions;
+ }
+
+ protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
+ for (ExecutionImpl joinedExecution: joinedExecutions) {
+ joinedExecution.end();
+ }
+ }
+
+
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -44,7 +44,7 @@
private static final long serialVersionUID = 1L;
- LockMode lockMode = LockMode.UPGRADE;
+ protected LockMode lockMode = LockMode.UPGRADE;
public void execute(ActivityExecution execution) {
execute((ExecutionImpl) execution);
@@ -54,31 +54,38 @@
int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
if (nrOfIncoming == 1) { // no join behaviour needed, save some time and do a fork immediately
+
if (LOG.isDebugEnabled()) {
LOG.debug("Only one incoming sequence flow found. Executing fork logic.");
}
fork(execution);
- } else { // Join behaviour needed
+ } else {
+
if (LOG.isDebugEnabled()) {
LOG.debug("Multiple incoming sequence flow found. Executing join logic.");
}
- join(execution);
+ boolean allExecutionsArrived = handleIncomingExecution(execution);
// After executing the join functionality, it could be that all executions have arrived
- // at the gateway. In that case, the gateway can be left using the fork functionality.
- proceedIfPossible(execution);
+ // at the gateway. In that case, the gateway can be left.
+ if (allExecutionsArrived) {
+ ExecutionImpl outgoingExecution = join(execution);
+ fork(outgoingExecution);
+ }
}
-
-
}
protected void fork(ExecutionImpl execution) {
proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_IGNORED));
}
- protected void join(ExecutionImpl execution) {
+ /**
+ * Joins the incoming executions.
+ * Returns true if all executions have reached the gateway.
+ */
+ protected boolean handleIncomingExecution(ExecutionImpl execution) {
if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
// force version increment in the parent execution
@@ -87,36 +94,46 @@
execution.setState(Execution.STATE_INACTIVE_JOIN);
execution.waitForSignal();
+
+ return isComplete(execution);
} else {
throw new JbpmException("invalid execution state: " + execution.getState());
}
}
- protected void proceedIfPossible(ExecutionImpl execution) {
+ /**
+ * Joins all the incoming executions currently waiting at the gateway.
+ *
+ * @return An execution that can be used to leave the gateway (one outgoing sequence flow)
+ * or to create child executions on (fork behaviour when multiple outgoing sequence flow).
+ */
+ protected ExecutionImpl join(ExecutionImpl execution) {
Activity activity = execution.getActivity();
ExecutionImpl concurrentRoot = execution.getParent();
List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
- if (isComplete(joinedExecutions, activity)) {
+ endJoinedExecutions(joinedExecutions);
- endJoinedExecutions(joinedExecutions);
+ ExecutionImpl outgoingExecution = null;
+ if (concurrentRoot.getExecutions().size() == 0) {
+ outgoingExecution = concurrentRoot;
+ outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
+ } else {
+ outgoingExecution = concurrentRoot.createExecution();
+ outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
+ }
- ExecutionImpl outgoingExecution = null;
- if (concurrentRoot.getExecutions().size() == 0) {
- outgoingExecution = concurrentRoot;
- outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
- } else {
- outgoingExecution = concurrentRoot.createExecution();
- outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
- }
-
- outgoingExecution.setActivity(activity);
- fork(outgoingExecution);
- }
+ outgoingExecution.setActivity(activity);
+ return outgoingExecution;
}
- protected boolean isComplete(List<ExecutionImpl> joinedExecutions, Activity activity) {
+ protected boolean isComplete(ExecutionImpl execution) {
+
+ Activity activity = execution.getActivity();
+ ExecutionImpl concurrentRoot = execution.getParent();
+ List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
+
boolean result = joinedExecutions.size() == activity.getIncomingTransitions().size();
if (LOG.isDebugEnabled()) {
LOG.debug("All incoming executions have arrived at the gateway: " + result);
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/model/BpmnProcessDefinition.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -23,12 +23,15 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.jbpm.bpmn.common.Resource;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
+import org.jbpm.pvm.internal.model.Transition;
import org.jbpm.pvm.internal.model.VariableDefinitionImpl;
import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
import org.w3c.dom.Element;
@@ -37,13 +40,15 @@
private static final long serialVersionUID = 1L;
- Map<String, TaskDefinitionImpl> taskDefinitions = new HashMap<String, TaskDefinitionImpl>();
- List<VariableDefinitionImpl> processVariableDefinitions = new ArrayList<VariableDefinitionImpl>();
- Map<String, Element> messages = new HashMap<String, Element>();
- Map<String, Element> itemDefinitions = new HashMap<String, Element>();
- Map<String, Element> interfaces = new HashMap<String, Element>();
- Map<String, Element> operations = new HashMap<String, Element>();
- Map<String, Resource> resources = new HashMap<String, Resource>();
+ protected Map<String, TaskDefinitionImpl> taskDefinitions = new HashMap<String, TaskDefinitionImpl>();
+ protected List<VariableDefinitionImpl> processVariableDefinitions = new ArrayList<VariableDefinitionImpl>();
+ protected Map<String, Element> messages = new HashMap<String, Element>();
+ protected Map<String, Element> itemDefinitions = new HashMap<String, Element>();
+ protected Map<String, Element> interfaces = new HashMap<String, Element>();
+ protected Map<String, Element> operations = new HashMap<String, Element>();
+ protected Map<String, Resource> resources = new HashMap<String, Resource>();
+ protected Map<String, Transition> sequenceFlow = new HashMap<String, Transition>();
+ protected Map<String, Set<String>> sourceToTargetMapping = new HashMap<String, Set<String>>(); // convience mapping: sourceRefId to all targetRefs
protected ExecutionImpl newProcessInstance() {
return new ExecutionImpl();
@@ -112,4 +117,38 @@
this.itemDefinitions = itemDefinitions;
}
+ public void addSequenceFlow(String transitionId, Transition transition) {
+ this.sequenceFlow.put(transitionId, transition);
+
+ String source = transition.getSource().getName();
+ if (sourceToTargetMapping.get(source) == null) {
+ sourceToTargetMapping.put(source, new HashSet<String>());
+ }
+ sourceToTargetMapping.get(source).add(transition.getDestination().getName());
+ }
+
+ public Map<String, Set<String>> getSourceToTargetMapping() {
+ return sourceToTargetMapping;
+ }
+
+ public boolean isReachable(String srcActivityId , String dstActivityId) {
+ return isReachable(srcActivityId, dstActivityId, new HashSet<String>());
+ }
+
+ protected boolean isReachable(String srcActivityId , String dstActivityId, Set<String> alreadyVisited) {
+ if (srcActivityId.equals(dstActivityId)) {
+ return true;
+ } else {
+ alreadyVisited.add(srcActivityId);
+ for (String destinationId : sourceToTargetMapping.get(srcActivityId)) {
+ if (!alreadyVisited.contains(destinationId)) {
+ if (isReachable(destinationId, dstActivityId, alreadyVisited)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
}
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-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -32,11 +32,8 @@
import org.jbpm.api.activity.ActivityBehaviour;
import org.jbpm.bpmn.common.Resource;
import org.jbpm.bpmn.common.ResourceParameter;
-import org.jbpm.bpmn.flownodes.AbstractGatewayActivity;
import org.jbpm.bpmn.flownodes.BpmnBinding;
import org.jbpm.bpmn.flownodes.DatabasedGatewayActivity;
-import org.jbpm.bpmn.flownodes.ExclusiveGatewayActivity;
-import org.jbpm.bpmn.flownodes.InclusiveGatewayActivity;
import org.jbpm.bpmn.model.BpmnProcessDefinition;
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.model.ActivityImpl;
@@ -118,7 +115,6 @@
processDefinition.setDescription(description);
}
- // TODO: should be done in a different way? On a different level?
parseResources((Element)processElement.getParentNode(), parse, processDefinition);
parseInterfaces((Element)processElement.getParentNode(), parse, processDefinition);
@@ -135,7 +131,7 @@
parseActivities(processElement, parse, processDefinition);
// bind activities to their destinations
- parseSequenceFlows(processElement, parse, processDefinition);
+ parseSequenceFlow(processElement, parse, processDefinition);
} finally {
parse.contextStackPop();
@@ -233,7 +229,7 @@
}
}
- public void parseSequenceFlows(Element element, Parse parse, CompositeElementImpl compositeElement) {
+ public void parseSequenceFlow(Element element, Parse parse, BpmnProcessDefinition processDefinition) {
List<Element> transitionElements = XmlUtil.elements(element, "sequenceFlow");
for (Element transitionElement : transitionElements) {
String transitionName = XmlUtil.attribute(transitionElement, "name", false, parse);
@@ -246,19 +242,26 @@
}
Element conditionElement = XmlUtil.element(transitionElement, "conditionExpression");
- TransitionImpl transition = compositeElement.findActivity(sourceRef).createOutgoingTransition();
+ TransitionImpl transition = processDefinition.findActivity(sourceRef).createOutgoingTransition();
try {
// If something went wrong parsing the activity, there is no behaviour and an exception is thrown in .getBehaviour()
- ActivityBehaviour a = compositeElement.findActivity(sourceRef).getActivityBehaviour();
- if (a instanceof DatabasedGatewayActivity) {
- if (transitionId.equals(((DatabasedGatewayActivity) a).getDefault())) {
- compositeElement.findActivity(sourceRef).setDefaultOutgoingTransition(transition);
+ ActivityBehaviour behaviour = processDefinition.findActivity(sourceRef).getActivityBehaviour();
+ if (behaviour instanceof DatabasedGatewayActivity) {
+ DatabasedGatewayActivity databasedGatewayActivity = (DatabasedGatewayActivity) behaviour;
+ String defaultSeqFlow = databasedGatewayActivity.getDefault();
+ if (defaultSeqFlow != null) {
+ if (transitionId.equals(defaultSeqFlow)) {
+ processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(transition);
+ }
+ } else {
+ processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(null);
}
} else {
// Other flownodes do not have default sequenceFlows, so set it to null
- compositeElement.findActivity(sourceRef).setDefaultOutgoingTransition(null);
+ processDefinition.findActivity(sourceRef).setDefaultOutgoingTransition(null);
}
+
} catch (JbpmException je) {
// catch it and only re-throw if not this specific exception.
if (!je.getMessage().contains("no behaviour on")) {
@@ -280,15 +283,22 @@
transition.setCondition(expressionCondition);
} else {
- parse.addProblem("Type of the conditionExpression on sequenceFlow with id=" + transitionId + " is of onsupported type 'bpmn:tExpression'",
- transitionElement);
+ parse.addProblem("Type of the conditionExpression on sequenceFlow with id=" +
+ transitionId + " is of onsupported type 'bpmn:tExpression'", transitionElement);
}
}
- compositeElement.findActivity(targetRef).addIncomingTransition(transition);
+ ActivityImpl activity = processDefinition.findActivity(targetRef);
+ if (activity != null) {
+ activity.addIncomingTransition(transition);
+ } else {
+ parse.addProblem("TargetRef '" + targetRef + "' cannot be found");
+ }
transition.setName(transitionId);
transition.setDescription(transitionName);
+
+ processDefinition.addSequenceFlow(transitionId, transition);
}
}
public void parseDefinition(Element documentElement, Parse parse) {
Modified: jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java
===================================================================
--- jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/test-base/src/main/java/org/jbpm/test/assertion/CollectionAssertions.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -24,6 +24,7 @@
*/
package org.jbpm.test.assertion;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
@@ -40,7 +41,7 @@
* Compares the elements of the two given collections.
* The order of elements is not checked.
*/
- public static <T> void assertElementsEqual(Collection<T> collection1, Collection<T> collection2) {
+ public static <T> void assertContainsSameElements(Collection<T> collection1, Collection<T> collection2) {
Assert.assertTrue("One of the given collections is null, while the other collection is not null",
(collection1 == null && collection2 == null)
@@ -62,6 +63,14 @@
}
+ /**
+ * Compares the elements of the two given collections.
+ * The order of elements is not checked.
+ */
+ public static <T> void assertContainsSameElements(Collection<T> collection1, T ... elements) {
+ assertContainsSameElements(collection1, Arrays.asList(elements));
+ }
+
@SuppressWarnings("unchecked")
private static String debugCollections(Collection ... collections) {
StringBuilder strb = new StringBuilder();
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/ParallelGatewayTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/ParallelGatewayTest.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/ParallelGatewayTest.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -68,7 +68,7 @@
List<Task> allTasks = taskQuery.list();
assertEquals(2, allTasks.size());
- CollectionAssertions.assertElementsEqual(Arrays.asList("UserTaskLeg1", "UserTaskLeg2"),
+ CollectionAssertions.assertContainsSameElements(Arrays.asList("UserTaskLeg1", "UserTaskLeg2"),
Arrays.asList(allTasks.get(0).getActivityName(), allTasks.get(1).getActivityName()));
// specifying a transition is unnecessary, BPMN has outgoing AND semantic!
Added: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java (rev 0)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/InclusiveGatewayTest.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -0,0 +1,159 @@
+/*
+ * 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.gateway;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jbpm.api.ProcessInstance;
+import org.jbpm.test.JbpmTestCase;
+import org.jbpm.test.assertion.CollectionAssertions;
+
+/**
+ * @author Joram Barrez
+ */
+public class InclusiveGatewayTest extends JbpmTestCase {
+
+ private static final String SIMPLE_SPLIT =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='simpleInclusiveSplit' name='inclusiveSplit' >" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='inclusiveGateway' />" +
+ " <inclusiveGateway id='inclusiveGateway' />" +
+ " <sequenceFlow id='flow2' sourceRef='inclusiveGateway' targetRef='wait1' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 5}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow3' sourceRef='inclusiveGateway' targetRef='wait2' />" + // wait2 will always be reached since it has no condition
+ " <sequenceFlow id='flow4' sourceRef='inclusiveGateway' targetRef='wait3' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 10}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <receiveTask id='wait1' />" +
+ " <sequenceFlow id='flow5' sourceRef='wait1' targetRef='theEnd' />" +
+ " <receiveTask id='wait2' />" +
+ " <sequenceFlow id='flow6' sourceRef='wait2' targetRef='theEnd' />" +
+ " <receiveTask id='wait3' />" +
+ " <sequenceFlow id='flow7' sourceRef='wait3' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' >" +
+ " <terminateEventDefinition/>" +
+ " </endEvent>" +
+ " </process>" +
+ "</definitions>";
+
+ /*
+ * Copy of the SIMPLE_SPLIT_PROCESS, where the 'always' outgoing sequence flow is replaced
+ * by a default sequence flow.
+ */
+ private static final String SIMPLE_SPLIT_WITH_DEFAULT =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='simpleInclusiveSplitWithDefault' name='inclusiveSplitWithDefault' >" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='inclusiveGateway' />" +
+ " <inclusiveGateway id='inclusiveGateway' default='flow3' />" +
+ " <sequenceFlow id='flow2' sourceRef='inclusiveGateway' targetRef='wait1' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 5}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow3' sourceRef='inclusiveGateway' targetRef='wait2' />" +
+ " <sequenceFlow id='flow4' sourceRef='inclusiveGateway' targetRef='wait3' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 10}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <receiveTask id='wait1' />" +
+ " <sequenceFlow id='flow5' sourceRef='wait1' targetRef='theEnd' />" +
+ " <receiveTask id='wait2' />" +
+ " <sequenceFlow id='flow6' sourceRef='wait2' targetRef='theEnd' />" +
+ " <receiveTask id='wait3' />" +
+ " <sequenceFlow id='flow7' sourceRef='wait3' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' >" +
+ " <terminateEventDefinition/>" +
+ " </endEvent>" +
+ " </process>" +
+ "</definitions>";
+
+ private static final String SIMPLE_SPLIT_AND_MERGE =
+ "<definitions xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ " <process id='simpleSplitAndMerge' name='inclusiveSplitAndMerge' >" +
+ " <startEvent id='theStart' />" +
+ " <sequenceFlow id='flow1' sourceRef='theStart' targetRef='inclusiveSplit' />" +
+ " <inclusiveGateway id='inclusiveSplit' default='flow3' />" +
+ " <sequenceFlow id='flow2' sourceRef='inclusiveSplit' targetRef='wait1' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 5}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <sequenceFlow id='flow3' sourceRef='inclusiveSplit' targetRef='wait2' />" +
+ " <sequenceFlow id='flow4' sourceRef='inclusiveSplit' targetRef='wait3' >" +
+ " <conditionExpression xsi:type='tFormalExpression'>${var > 10}</conditionExpression>" +
+ " </sequenceFlow>" +
+ " <receiveTask id='wait1' />" +
+ " <sequenceFlow id='flow5' sourceRef='wait1' targetRef='inclusiveJoin' />" +
+ " <receiveTask id='wait2' />" +
+ " <sequenceFlow id='flow6' sourceRef='wait2' targetRef='inclusiveJoin' />" +
+ " <receiveTask id='wait3' />" +
+ " <sequenceFlow id='flow7' sourceRef='wait3' targetRef='inclusiveJoin' />" +
+ " <inclusiveGateway id='inclusiveJoin' />" +
+ " <sequenceFlow id='flow8' sourceRef='inclusiveJoin' targetRef='theEnd' />" +
+ " <endEvent id='theEnd' />" +
+ " </process>" +
+ "</definitions>";
+
+ public void testSimpleSplit() {
+ deployBpmn2XmlString(SIMPLE_SPLIT);
+
+ // A var value < 5 will trigger all outgoing sequence flow
+ startAndVerifySimpleSplitProcess("simpleInclusiveSplit", 15, "wait1", "wait2", "wait3");
+
+ // A var value 0 < x < 10 will trigger only two sequence flow
+ startAndVerifySimpleSplitProcess("simpleInclusiveSplit", 7, "wait1", "wait2");
+
+ // A var value < 5 trigger only one sequence flow (the one without a condition)
+ startAndVerifySimpleSplitProcess("simpleInclusiveSplit", 3, "wait2");
+ }
+
+ public void testSimpleSplitWithDefault() {
+ deployBpmn2XmlString(SIMPLE_SPLIT_WITH_DEFAULT);
+
+ // A var value < 5 will trigger all outgoing sequence flow, but not the default one
+ startAndVerifySimpleSplitProcess("simpleInclusiveSplitWithDefault", 15, "wait1", "wait3");
+
+ // A var value 0 < x < 10 will trigger only one sequence flow
+ startAndVerifySimpleSplitProcess("simpleInclusiveSplitWithDefault", 7, "wait1");
+
+ // A var value < 5 trigger only one sequence flow (the default one)
+ startAndVerifySimpleSplitProcess("simpleInclusiveSplitWithDefault", 3, "wait2");
+ }
+
+ public void testSimpleSplitAndMerge() {
+ deployBpmn2XmlString(SIMPLE_SPLIT_AND_MERGE);
+
+ ProcessInstance pi = startAndVerifySimpleSplitProcess("simpleSplitAndMerge", 17, "wait1", "wait3");
+ executionService.signalExecutionById(pi.findActiveExecutionIn("wait1").getId());
+ assertProcessInstanceActive(pi);
+ executionService.signalExecutionById(pi.findActiveExecutionIn("wait3").getId());
+ assertProcessInstanceEnded(pi);
+ }
+
+ private ProcessInstance startAndVerifySimpleSplitProcess(String processKey, Integer varValue, String ... expectedActivities) {
+ Map<String, Object> vars = new HashMap<String, Object>();
+ vars.put("var", varValue);
+ ProcessInstance pi = executionService.startProcessInstanceByKey(processKey, vars);
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), expectedActivities);
+ return pi;
+ }
+
+}
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/ParallelGatewayMergeTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/ParallelGatewayMergeTest.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/test/gateway/ParallelGatewayMergeTest.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -113,14 +113,14 @@
deployBpmn2XmlString(TEST_SIMPLE_MERGE_PROCESS);
ProcessInstance pi = executionService.startProcessInstanceByKey("simpleMerge");
pi.findActiveActivityNames();
- CollectionAssertions.assertElementsEqual(pi.findActiveActivityNames(), Arrays.asList("wait1", "wait2"));
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), Arrays.asList("wait1", "wait2"));
}
public void testNestedParallelMerge() {
deployBpmn2XmlString(TEST_NESTED_MERGE_PROCESS);
ProcessInstance pi = executionService.startProcessInstanceByKey("nestedMerge");
- CollectionAssertions.assertElementsEqual(pi.findActiveActivityNames(), Arrays.asList("wait1", "wait2"));
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), Arrays.asList("wait1", "wait2"));
executionService.signalExecutionById(pi.findActiveExecutionIn("wait1").getId());
executionService.signalExecutionById(pi.findActiveExecutionIn("wait2").getId());
@@ -131,7 +131,7 @@
deployBpmn2XmlString(TEST_NESTED_MERGE_PROCESS_2);
ProcessInstance pi = executionService.startProcessInstanceByKey("nestedMerge2");
- CollectionAssertions.assertElementsEqual(pi.findActiveActivityNames(), Arrays.asList("wait"));
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), Arrays.asList("wait"));
executionService.signalExecutionById(pi.findActiveExecutionIn("wait").getId());
assertProcessInstanceEnded(pi);
Modified: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/forkjoin/MultipleForksTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/forkjoin/MultipleForksTest.java 2010-01-15 14:04:04 UTC (rev 6083)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/test/activity/forkjoin/MultipleForksTest.java 2010-01-16 00:21:04 UTC (rev 6084)
@@ -162,7 +162,7 @@
"</process>");
ProcessInstance pi = executionService.startProcessInstanceByKey("nestedForks");
- CollectionAssertions.assertElementsEqual(pi.findActiveActivityNames(), Arrays.asList("wait"));
+ CollectionAssertions.assertContainsSameElements(pi.findActiveActivityNames(), Arrays.asList("wait"));
executionService.signalExecutionById(pi.findActiveExecutionIn("wait").getId());
assertProcessInstanceEnded(pi);
}
16 years, 3 months
JBoss JBPM SVN: r6083 - jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-15 09:04:04 -0500 (Fri, 15 Jan 2010)
New Revision: 6083
Removed:
jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/UserTaskTest.java
Log:
Removed test case since it tests an invalid bpmn2 process
Deleted: jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/UserTaskTest.java
===================================================================
--- jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/UserTaskTest.java 2010-01-14 23:09:03 UTC (rev 6082)
+++ jbpm4/trunk/modules/test-db/src/test/java/org/jbpm/bpmn/UserTaskTest.java 2010-01-15 14:04:04 UTC (rev 6083)
@@ -1,252 +0,0 @@
-/*
- * 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;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jbpm.api.ProcessInstance;
-import org.jbpm.api.TaskQuery;
-import org.jbpm.api.task.Task;
-//import org.jbpm.bpmn.model.BpmnProcessDefinition;
-//import org.jbpm.bpmn.parser.BpmnParser;
-import org.jbpm.pvm.internal.model.ExecutionImpl;
-import org.jbpm.pvm.internal.xml.Parse;
-import org.jbpm.test.JbpmTestCase;
-
-/**
- * @author Bernd Ruecker (bernd.ruecker(a)camunda.com)
- */
-public class UserTaskTest extends JbpmTestCase {
-
-// static BpmnParser bpmnParser = new BpmnParser();
-//
-// public void testParsing() {
-// Parse parse = bpmnParser.createParse().setResource("org/jbpm/bpmn/UserTaskSimple.bpmn.xml").execute();
-//
-// if (!parse.getProblems().isEmpty()) {
-// fail("No problems should have occured. Problems: " + parse.getProblems());
-// }
-//
-// List<BpmnProcessDefinition> processDefinitions = (List<BpmnProcessDefinition>) parse.getDocumentObject();
-//
-// assertEquals(1, processDefinitions.size());
-//
-// BpmnProcessDefinition pd = processDefinitions.get(0);
-// assertNotNull(pd);
-// assertEquals("UserTaskSimpleProcess", pd.getKey());
-// }
-
- public void testNormalUserAssignment() {
- String deploymentId = repositoryService.createDeployment().addResourceFromClasspath("org/jbpm/bpmn/UserTaskSimple.bpmn.xml").deploy();
-
- try {
- Map variables = new HashMap();
- variables.put("assignedUser", "User1");
- ProcessInstance pi = executionService.startProcessInstanceByKey("UserTaskSimpleProcess", variables);
- assertEquals("UserTask", ((ExecutionImpl) pi).getActivityName());
-
- TaskQuery taskQuery = taskService.createTaskQuery();
- List<Task> allTasks = taskQuery.list();
- assertEquals(1, allTasks.size());
- assertEquals("UserTask", allTasks.get(0).getActivityName());
- assertEquals("User1", allTasks.get(0).getAssignee());
- assertEquals("MyForm.ftl", allTasks.get(0).getFormResourceName());
-
- // speciifiing a transition is unnecessary, BPMN has outgoing AND
- // semantic!
- // TODO: fix
- taskService.completeTask(allTasks.get(0).getId(), "flow2");
-
- assertEquals(0, taskQuery.list().size());
-
- // process instance is ended
- pi = executionService.findProcessInstanceById(pi.getId());
- // One way or another I would also expect this to work... pi is gone from
- // database immediately when ended. Only in History DB
- // assertEquals(true, pi.isEnded());
- assertNull(pi);
- } finally {
- repositoryService.deleteDeploymentCascade(deploymentId);
- }
- }
-
- /*
- public void testNormalGroupAssignment() {
- String deploymentId = repositoryService.createDeployment().addResourceFromClasspath("org/jbpm/bpmn/UserTaskGroup.bpmn.xml").deploy();
-
- try {
- Map<String, Object> variables = new HashMap<String, Object>();
- variables.put("assignedGroup", "Group1");
- ProcessInstance pi = executionService.startProcessInstanceByKey("UserTaskGroupProcess", variables);
-
- assertEquals("UserTask", ((ExecutionImpl) pi).getActivityName());
-
- TaskQuery taskQuery = taskService.createTaskQuery();
- List<Task> allTasks = taskQuery.list();
- assertEquals(1, allTasks.size());
-
- List<Task> groupTasks = taskService.findGroupTasks("Group1");
- assertEquals(1, groupTasks.size());
- assertEquals("UserTask", groupTasks.get(0).getActivityName());
-
- assertEquals("UserTask", allTasks.get(0).getActivityName());
-
- assertNull(allTasks.get(0).getAssignee());
-
- taskService.takeTask(allTasks.get(0).getId(), "User1");
-
- groupTasks = taskService.findGroupTasks("Group1");
- assertEquals(0, groupTasks.size());
-
- List<Task> userTasks = taskService.findPersonalTasks("User1");
- assertEquals(1, userTasks.size());
- assertEquals("UserTask", userTasks.get(0).getActivityName());
-
- taskService.completeTask(userTasks.get(0).getId(), "flow2");
-
- assertEquals(0, taskQuery.list().size());
-
- // process instance is ended
- pi = executionService.findProcessInstanceById(pi.getId());
- assertNull(pi);
- } finally {
- repositoryService.deleteDeploymentCascade(deploymentId);
- }
- }*/
-
- public void testNormalSequenceFlowCondition() {
- String deploymentId = repositoryService.createDeployment().addResourceFromClasspath("org/jbpm/bpmn/UserTaskSequenceFlowCondition.bpmn.xml").deploy();
-
- try {
- Map variables = new HashMap();
- ProcessInstance pi = executionService.startProcessInstanceByKey("UserTaskSequenceFlowConditionProcess");
-
- assertEquals("UserTask", ((ExecutionImpl) pi).getActivityName());
-
- TaskQuery taskQuery = taskService.createTaskQuery();
- List<Task> allTasks = taskQuery.list();
- assertEquals(1, allTasks.size());
-
- // Flow does not exist so task should be ended hence process endded since it is the only execution
- taskService.completeTask(allTasks.get(0).getId(), "NoFlow");
-
- assertEquals(0, taskQuery.list().size());
-
- // process instance is ended
- pi = executionService.findProcessInstanceById(pi.getId());
- assertNull(pi);
- } finally {
- repositoryService.deleteDeploymentCascade(deploymentId);
- }
- }
-
-
-
- /**
- * check that multiple outgoing sequence flows will be handled as fork, like
- * specified in BPMN
- *
- * Check with user tasks, sicne the engine stops there for sure.
- */
- public void testUncontrolledSequenceFlowAsFork() {
- String deploymentId = repositoryService.createDeployment().addResourceFromClasspath("org/jbpm/bpmn/forkWithUncontrolledSequenceFlow.bpmn.xml")
- .deploy();
-
- try {
-
- ProcessInstance pi = executionService.startProcessInstanceByKey("ForkWithUncontrolledSequenceFlowProcess");
-
- String pid = pi.getId();
-
- TaskQuery taskQuery = taskService.createTaskQuery();
- List<Task> allTasks = taskQuery.list();
-
- // since the uncontrolled sequence flow OUT of the activity behaves as a
- // fork
- // we now have two tasks
- assertEquals(2, allTasks.size());
- assertEquals("UserTaskLeg1", allTasks.get(0).getActivityName());
- assertEquals("UserTaskLeg2", allTasks.get(1).getActivityName());
-
- // specifying a transition is unnecessary, BPMN has outgoing AND semantic!
- // TODO: fix
- // Currently not passing any 'outcome'
- taskService.completeTask(allTasks.get(0).getId()); // define output /
- // flow?
- taskService.completeTask(allTasks.get(1).getId());
-
- assertEquals(0, taskQuery.list().size());
-
- pi = executionService.findProcessInstanceById(pid);
- // process instance is ended
- assertNull(pi);
-
- } finally {
- repositoryService.deleteDeploymentCascade(deploymentId);
- }
-
- }
-
- /**
- * check that multiple outgoing sequence flows will be handled as fork, like
- * specified in BPMN
- *
- * Check with user tasks, sicne the engine stops there for sure.
- */
- public void testUncontrolledSequenceFlowConditionAsFork() {
- /* String deploymentId = repositoryService.createDeployment().addResourceFromClasspath("org/jbpm/bpmn/forkWithUncontrolledSequenceFlowCondition.bpmn.xml")
- .deploy();
-
- try {
-
- ProcessInstance pi = executionService.startProcessInstanceByKey("ForkWithUncontrolledSequenceFlowConditionProcess");
-
- String pid = pi.getId();
-
- TaskQuery taskQuery = taskService.createTaskQuery();
- List<Task> allTasks = taskQuery.list();
-
- assertEquals(1, allTasks.size());
- assertEquals("forkingTask", allTasks.get(0).getActivityName());
- taskService.completeTask(allTasks.get(0).getId(), "NoFlow");
-
- // Even though the 'uncontrolled sequence flow' OUT of the activity behaves as a
- // fork we now have one task since one sequenceflow has a condition that evaluates to false
-
- allTasks = taskQuery.list();
- assertEquals(1, allTasks.size());
- assertEquals("UserTaskLeg2", allTasks.get(0).getActivityName());
- taskService.completeTask(allTasks.get(0).getId());
-
- pi = executionService.findProcessInstanceById(pid);
- // process instance is ended
- assertNull(pi);
-
- } finally {
- repositoryService.deleteDeploymentCascade(deploymentId);
- }*/
-
- }
-
-}
16 years, 3 months
JBoss JBPM SVN: r6082 - in jbpm4/trunk/modules: bpmn/src/main/java/org/jbpm/bpmn/parser and 2 other directories.
by do-not-reply@jboss.org
Author: jbarrez
Date: 2010-01-14 18:09:03 -0500 (Thu, 14 Jan 2010)
New Revision: 6082
Added:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/DatabasedGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayBinding.java
Modified:
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayBinding.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayBinding.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/JavaServiceTaskActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TaskActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/UserTaskActivity.java
jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java
jbpm4/trunk/modules/bpmn/src/main/resources/jbpm.bpmn.flownodes.xml
jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/exclusive/exclusive_gateway_default_seq_flow.bpmn.xml
Log:
Refactoring of gateway hierarchy.
Initial commit for Inclusive Gateway.
Added: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayActivity.java (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -0,0 +1,41 @@
+/*
+ * 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.flownodes;
+
+/**
+ * Abstract superclass for all gateway types.
+ *
+ * @author Joram Barrez
+ */
+public abstract class AbstractGatewayActivity extends BpmnActivity {
+
+ protected String gatewayDirection;
+
+ public String getGatewayDirection() {
+ return gatewayDirection;
+ }
+
+ public void setGatewayDirection(String gatewayDirection) {
+ this.gatewayDirection = gatewayDirection;
+ }
+
+}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayBinding.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayBinding.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/AbstractGatewayBinding.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -52,8 +52,10 @@
protected String name;
protected String gatewayDirection;
- boolean valid = true;
+ protected boolean valid = true;
+ protected String default_;
+
static ObjectBinding objectBinding = new ObjectBinding();
static WireParser wireParser = WireParser.getInstance();
@@ -68,16 +70,22 @@
public void parse(Element element, Parse parse) {
resetMemberFields();
+
id = element.getAttribute("id");
name = element.getAttribute("name");
+ this.default_ = null;
+ if (element.hasAttribute("default")) {
+ default_ = element.getAttribute("default");
+ }
+
// 'gatewayDirection' is a constraint on any gateway type.
// Since this is an optional attribute, we can't rely on it at runtime.
// As such, it is only used at parsing time to check if the constraints are met.
if (element.hasAttribute("gatewayDirection")) {
gatewayDirection = element.getAttribute("gatewayDirection");
} else {
- gatewayDirection = "unspecified";
+ gatewayDirection = "unspecified"; // default
}
// Count in/out sequence flow to validate gatewaydirection
@@ -108,6 +116,7 @@
outgoing = 0;
outSequenceFlows = new ArrayList<Element>();
valid = true;
+ default_ = null;
}
protected boolean validGatewayDirection(Parse parse, String elementName, Element element) {
@@ -126,5 +135,45 @@
}
return valid;
}
+
+ /**
+ * For some gateway types (exclusive/inclusive), conditions are required on every outgoing
+ * sequence flow. This operation will check if all sequence flow (excluding the default
+ * sequence flow) have such a condition defined.
+ *
+ * Also the reference from the default attribute is verified if it points to an existing
+ * sequence flow defined in the process.
+ *
+ * The operation will add problems to the given {@link Parse} object if problems are found.
+ * Also the 'valid' boolean wil be changed if needed.
+ */
+ protected void validateConditionOnAllSequenceFlow(Parse parse, Element element) {
+ boolean defaultExists = false;
+ for (Element outSeqFlow : outSequenceFlows) {
+
+ String sourceRef = outSeqFlow.getAttribute("sourceRef");
+ Element conditionalExpression = XmlUtil.element(outSeqFlow, "conditionExpression");
+
+ if (id.equals(sourceRef)) {
+
+ if (outSeqFlow.getAttribute("id").equals(default_)) {
+ defaultExists = true;
+ } else if (default_ != null && conditionalExpression == null) { // All but the 'default' sequenceFlow need to have a condition
+ parse.addProblem("exclusiveGateway '" + name + "' has default sequenceFlow '" + default_
+ + "' but " + outSeqFlow.getAttribute("id")
+ + " does not have a required conditionExpression", element);
+ valid = false; // do not break. Parsing may find other issues;
+ }
+ }
+
+ }
+
+ if (default_ != null && !defaultExists) {
+ parse.addProblem("exclusiveGateway '" + name + "' default sequenceFlow '" + default_
+ + "' does not exist or is not related to this node", element);
+ valid = false;
+ }
+
+ }
}
\ No newline at end of file
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-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/BpmnActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -28,7 +28,6 @@
import org.jbpm.api.Execution;
import org.jbpm.api.activity.ActivityBehaviour;
-import org.jbpm.bpmn.parser.BindingsParser;
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.Condition;
@@ -40,6 +39,7 @@
*
* @author bernd.ruecker(a)camunda.com
* @author Ronald van Kuijk (kukeltje)
+ * @author Joram Barrez
*/
public abstract class BpmnActivity implements ActivityBehaviour {
@@ -47,8 +47,6 @@
private static final long serialVersionUID = 1L;
- protected static final boolean FORK_ALLOWED = true;
- protected static final boolean FORK_DISALLOWED = !FORK_ALLOWED;
protected static final boolean CONDITIONS_CHECKED = true;
protected static final boolean CONDITIONS_IGNORED = !CONDITIONS_CHECKED;
@@ -56,8 +54,7 @@
/**
* In BPMN multiple outgoing sequence flows behave like a fork.
- *
- * Code copied basically from jPDL fork.
+ * Code initially based on the JPDL fork logic.
*/
protected void proceed(ExecutionImpl execution, List<Transition> transitions) {
if (log.isDebugEnabled()) {
@@ -92,16 +89,14 @@
Map<Transition, ExecutionImpl> childExecutionsMap = new HashMap<Transition, ExecutionImpl>();
for (Transition transition : transitions) {
- // launch a concurrent path of execution
- String childExecutionName = transition.getName();
- ExecutionImpl concurrentExecution = concurrentRoot.createExecution(childExecutionName);
+ ExecutionImpl concurrentExecution = concurrentRoot.createExecution(transition.getName());
concurrentExecution.setActivity(activity);
concurrentExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
childExecutionsMap.put(transition, concurrentExecution);
}
- // For a correct functionality, the child executions must all exist before the actual
- // transitions are taken.
+ // For a correct functionality, the child executions must all exist before the actual transitions are taken.
+ // So we start following the outgoing transitions after child execution creation.
for (Transition transition : childExecutionsMap.keySet()) {
childExecutionsMap.get(transition).take(transition);
@@ -112,7 +107,7 @@
}
}
- protected List<Transition> findTransitions(ExecutionImpl execution, boolean checkConditions) {
+ protected List<Transition> findOutgoingSequenceFlow(ExecutionImpl execution, boolean checkConditions) {
Activity activity = execution.getActivity();
// evaluate the conditions and find the transitions that should be forked
List<Transition> forkingTransitions = new ArrayList<Transition>();
Added: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/DatabasedGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/DatabasedGatewayActivity.java (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/DatabasedGatewayActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -0,0 +1,43 @@
+/*
+ * 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.flownodes;
+
+/**
+ * Superclass for gateway activities which use process data to synchronize (ie merge or split)
+ * sequence flow. A common feature of those gateway types is the possibility to define
+ * a default outgoing sequence flow, that will be taken when no condition evaluates to true.
+ *
+ * @author Joram Barrez
+ */
+public abstract class DatabasedGatewayActivity extends AbstractGatewayActivity {
+
+ protected String default_;
+
+ public String getDefault() {
+ return default_;
+ }
+
+ public void setDefault(String default_) {
+ this.default_ = default_;
+ }
+
+}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayActivity.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -34,11 +34,8 @@
* @author Tom Baeyens
* @author Ronald van Kuijk (kukeltje)
*/
-public class ExclusiveGatewayActivity extends BpmnActivity {
+public class ExclusiveGatewayActivity extends DatabasedGatewayActivity {
- String gatewayDirection = "unspecified"; // is the default behaviour
- String default_;
-
private static final long serialVersionUID = 1L;
private static final Log log = Log.getLog(BindingsParser.class.getName());
@@ -54,7 +51,7 @@
*/
public void execute(ExecutionImpl execution) {
- List<Transition> transitions = findTransitions(execution, CONDITIONS_CHECKED);
+ List<Transition> transitions = findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED);
int numTransitions = transitions.size();
if (numTransitions == 0) {
@@ -62,7 +59,8 @@
if (defaultTransition != null) {
transitions.add(defaultTransition);
} else {
- throw new JbpmException("No sequenceFlow condition evaluated to true for " + execution.getActivity() + " and no default sequenceFlow was speficied");
+ throw new JbpmException("No sequenceFlow condition evaluated to true for " +
+ execution.getActivity() + " and no default sequenceFlow was speficied");
}
} else if (numTransitions > 2) {
transitions = transitions.subList(0, 0);
@@ -83,20 +81,4 @@
}
- public String getGatewayDirection() {
- return gatewayDirection;
- }
-
- public void setGatewayDirection(String gatewayDirection) {
- this.gatewayDirection = gatewayDirection;
- }
-
- public String getDefault() {
- return default_;
- }
-
- public void setDefault(String default_) {
- this.default_ = default_;
- }
-
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayBinding.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayBinding.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ExclusiveGatewayBinding.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -21,7 +21,6 @@
*/
package org.jbpm.bpmn.flownodes;
-import org.jbpm.pvm.internal.util.XmlUtil;
import org.jbpm.pvm.internal.xml.Parse;
import org.jbpm.pvm.internal.xml.Parser;
import org.w3c.dom.Element;
@@ -38,42 +37,9 @@
}
public Object parse(Element element, Parse parse, Parser parser) {
-
super.parse(element, parse);
+ validateConditionOnAllSequenceFlow(parse, element);
- String default_ = null;
- if (element.hasAttribute("default")) {
- default_ = element.getAttribute("default");
- }
-
- // Check if all outgoing sequence flow have a condition (default excluded)
- boolean defaultExists = false;
- for (Element outSeqFlow : outSequenceFlows) {
-
- String sourceRef = outSeqFlow.getAttribute("sourceRef");
- Element conditionalExpression = XmlUtil.element(outSeqFlow, "conditionExpression");
-
- if (id.equals(sourceRef)) {
-
- if (outSeqFlow.getAttribute("id").equals(default_)) {
- defaultExists = true;
- } else if (default_ != null && conditionalExpression == null) { // All but the 'default' sequenceFlow need to have a condition
- parse.addProblem("exclusiveGateway '" + name + "' has default sequenceFlow '" + default_
- + "' but " + outSeqFlow.getAttribute("id")
- + " does not have a required conditionExpression", element);
- valid = false; // do not break. Parsing may find other issues;
- }
-
- }
-
- }
-
- if (default_ != null && !defaultExists) {
- parse.addProblem("exclusiveGateway '" + name + "' default sequenceFlow '" + default_
- + "' does not exist or is not related to this node", element);
- valid = false;
- }
-
if (!valid) {
return null;
}
Added: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -0,0 +1,53 @@
+/*
+ * 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.flownodes;
+
+import org.jbpm.api.activity.ActivityExecution;
+import org.jbpm.internal.log.Log;
+import org.jbpm.pvm.internal.model.ExecutionImpl;
+
+/**
+ * @author Joram Barrez
+ */
+public class InclusiveGatewayActivity extends DatabasedGatewayActivity {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Log LOG = Log.getLog(InclusiveGatewayActivity.class.getName());
+
+ public void execute(ActivityExecution execution) throws Exception {
+ execute((ExecutionImpl) execution);
+ }
+
+ public void execute(ExecutionImpl execution) {
+ int nrOfIncoming = execution.getActivity().getIncomingTransitions().size();
+ if (nrOfIncoming == 1) { // no merge behaviour needed, save some time and do a fork immediately
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Only one incoming sequence flow found. Executing fork logic only.");
+ }
+ proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED));
+ }
+
+ // TODO finish
+ }
+
+}
Added: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayBinding.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayBinding.java (rev 0)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/InclusiveGatewayBinding.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -0,0 +1,51 @@
+/*
+ * 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.flownodes;
+
+import org.jbpm.pvm.internal.xml.Parse;
+import org.jbpm.pvm.internal.xml.Parser;
+import org.w3c.dom.Element;
+
+/**
+ * @author Joram Barrez
+ */
+public class InclusiveGatewayBinding extends AbstractGatewayBinding {
+
+ public InclusiveGatewayBinding() {
+ super("inclusiveGateway");
+ }
+
+ public Object parse(Element element, Parse parse, Parser parser) {
+ super.parse(element, parse);
+ validateConditionOnAllSequenceFlow(parse, element);
+
+ if (!valid) {
+ return null;
+ }
+
+ InclusiveGatewayActivity inclusiveGatewayActivity = new InclusiveGatewayActivity();
+ inclusiveGatewayActivity.setDefault(default_);
+ inclusiveGatewayActivity.setGatewayDirection(gatewayDirection);
+ return inclusiveGatewayActivity;
+ }
+
+}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/JavaServiceTaskActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/JavaServiceTaskActivity.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/JavaServiceTaskActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -93,7 +93,7 @@
} catch (Exception e) {
throw new WireException("couldn't invoke method "+methodName+": "+e.getMessage(), e);
}
- proceed((ExecutionImpl)execution, findTransitions((ExecutionImpl)execution, CONDITIONS_CHECKED));
+ proceed((ExecutionImpl)execution, findOutgoingSequenceFlow((ExecutionImpl)execution, CONDITIONS_CHECKED));
}
public void setTarget(Object target) {
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/ParallelGatewayActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -38,7 +38,7 @@
* @author Ronald van Kuijk (kukeltje)
* @author Joram Barrez
*/
-public class ParallelGatewayActivity extends BpmnActivity {
+public class ParallelGatewayActivity extends AbstractGatewayActivity {
private static final Log LOG = Log.getLog(ParallelGatewayActivity.class.getName());
@@ -46,9 +46,6 @@
LockMode lockMode = LockMode.UPGRADE;
- //GatewayDirection indicates fork (divergence) or join (convergence).
- private String gatewayDirection;
-
public void execute(ActivityExecution execution) {
execute((ExecutionImpl) execution);
}
@@ -78,7 +75,7 @@
}
protected void fork(ExecutionImpl execution) {
- proceed(execution, findTransitions(execution, CONDITIONS_IGNORED));
+ proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_IGNORED));
}
protected void join(ExecutionImpl execution) {
@@ -150,14 +147,6 @@
joinedExecution.end();
}
}
-
- public String getGatewayDirection() {
- return gatewayDirection;
- }
-
- public void setGatewayDirection(String gatewayDirection) {
- this.gatewayDirection = gatewayDirection;
- }
public void setLockMode(LockMode lockMode) {
this.lockMode = lockMode;
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartActivity.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/StartActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -34,6 +34,6 @@
}
public void execute(ExecutionImpl execution) {
- proceed(execution, findTransitions(execution, CONDITIONS_CHECKED));
+ proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED));
}
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TaskActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TaskActivity.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/TaskActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -45,7 +45,7 @@
public void execute(ExecutionImpl execution) {
- proceed(execution, findTransitions(execution, CONDITIONS_CHECKED));
+ proceed(execution, findOutgoingSequenceFlow(execution, CONDITIONS_CHECKED));
}
Modified: jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/UserTaskActivity.java
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/UserTaskActivity.java 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/flownodes/UserTaskActivity.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -105,7 +105,7 @@
task.setSignalling(false);
execution.setVariable("jbpm_outcome", signalName);
- proceed(execution, findTransitions(execution, CONDITIONS_CHECKED));
+ proceed(execution, findOutgoingSequenceFlow(execution, 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-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/java/org/jbpm/bpmn/parser/BpmnParser.java 2010-01-14 23:09:03 UTC (rev 6082)
@@ -32,8 +32,11 @@
import org.jbpm.api.activity.ActivityBehaviour;
import org.jbpm.bpmn.common.Resource;
import org.jbpm.bpmn.common.ResourceParameter;
+import org.jbpm.bpmn.flownodes.AbstractGatewayActivity;
import org.jbpm.bpmn.flownodes.BpmnBinding;
+import org.jbpm.bpmn.flownodes.DatabasedGatewayActivity;
import org.jbpm.bpmn.flownodes.ExclusiveGatewayActivity;
+import org.jbpm.bpmn.flownodes.InclusiveGatewayActivity;
import org.jbpm.bpmn.model.BpmnProcessDefinition;
import org.jbpm.internal.log.Log;
import org.jbpm.pvm.internal.model.ActivityImpl;
@@ -239,21 +242,17 @@
String targetRef = XmlUtil.attribute(transitionElement, "targetRef", true, parse);
if (log.isDebugEnabled()) {
- log.trace(transitionId + ": " + sourceRef + " -> " + targetRef);
+ log.debug(transitionId + ": " + sourceRef + " -> " + targetRef);
}
Element conditionElement = XmlUtil.element(transitionElement, "conditionExpression");
- if (log.isDebugEnabled()) {
- log.trace(" with " + ((conditionElement == null) ? "0" : "1") + " conditionExpression");
- }
TransitionImpl transition = compositeElement.findActivity(sourceRef).createOutgoingTransition();
-
try {
// If something went wrong parsing the activity, there is no behaviour and an exception is thrown in .getBehaviour()
ActivityBehaviour a = compositeElement.findActivity(sourceRef).getActivityBehaviour();
- if (a instanceof ExclusiveGatewayActivity) {
- if (transitionId.equals(((ExclusiveGatewayActivity) a).getDefault())) {
+ if (a instanceof DatabasedGatewayActivity) {
+ if (transitionId.equals(((DatabasedGatewayActivity) a).getDefault())) {
compositeElement.findActivity(sourceRef).setDefaultOutgoingTransition(transition);
}
} else {
Modified: jbpm4/trunk/modules/bpmn/src/main/resources/jbpm.bpmn.flownodes.xml
===================================================================
--- jbpm4/trunk/modules/bpmn/src/main/resources/jbpm.bpmn.flownodes.xml 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/bpmn/src/main/resources/jbpm.bpmn.flownodes.xml 2010-01-14 23:09:03 UTC (rev 6082)
@@ -1,20 +1,21 @@
<activities>
- <!-- -->
+ <!-- Start / end events -->
<activity binding="org.jbpm.bpmn.flownodes.StartBinding" />
<activity binding="org.jbpm.bpmn.flownodes.EndBinding" />
<!-- Gateway bindings -->
<activity binding="org.jbpm.bpmn.flownodes.ExclusiveGatewayBinding" />
<activity binding="org.jbpm.bpmn.flownodes.ParallelGatewayBinding" />
+ <activity binding="org.jbpm.bpmn.flownodes.InclusiveGatewayBinding" />
<!-- -->
<activity binding="org.jbpm.bpmn.flownodes.ReceiveBinding" />
<!-- Task bindings -->
<activity binding="org.jbpm.bpmn.flownodes.ManualTaskBinding" />
- <activity binding="org.jbpm.bpmn.flownodes.ScriptTaskBinding" />
- <activity binding="org.jbpm.bpmn.flownodes.ServiceTaskBinding" />
+ <activity binding="org.jbpm.bpmn.flownodes.ScriptTaskBinding" />
+ <activity binding="org.jbpm.bpmn.flownodes.ServiceTaskBinding" />
<activity binding="org.jbpm.bpmn.flownodes.TaskBinding" />
<activity binding="org.jbpm.bpmn.flownodes.UserTaskBinding" />
Modified: jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/exclusive/exclusive_gateway_default_seq_flow.bpmn.xml
===================================================================
--- jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/exclusive/exclusive_gateway_default_seq_flow.bpmn.xml 2010-01-14 15:27:31 UTC (rev 6081)
+++ jbpm4/trunk/modules/examples/src/test/resources/org/jbpm/examples/bpmn/gateway/exclusive/exclusive_gateway_default_seq_flow.bpmn.xml 2010-01-14 23:09:03 UTC (rev 6082)
@@ -15,16 +15,17 @@
<sequenceFlow id="flow1" name="fromStartToExclusiveGateway"
sourceRef="start" targetRef="decision" />
- <exclusiveGateway id="decision" name="decideBasedOnAmountAndBankType" default="flow2"/>
-
- <sequenceFlow id="flow2" name="fromGatewayToStandard"
- sourceRef="decision" targetRef="standard">
- </sequenceFlow>
+ <exclusiveGateway id="decision" name="decideBasedOnAmountAndBankType" default="flow3"/>
+
- <sequenceFlow id="flow3" name="fromGatewayToEnEnough"
+ <sequenceFlow id="flow2" name="fromGatewayToEnEnough"
sourceRef="decision" targetRef="largeDeposit">
<conditionExpression xsi:type="tFormalExpression">${amount >= 500 && bankType != 'foreign'}</conditionExpression>
</sequenceFlow>
+
+ <sequenceFlow id="flow3" name="fromGatewayToStandard"
+ sourceRef="decision" targetRef="standard">
+ </sequenceFlow>
<sequenceFlow id="flow4" name="fromGatewayToMoreThanEnough"
sourceRef="decision" targetRef="foreignBank">
16 years, 3 months