提交 83c78dc2 编写于 作者: T Tijs Rademakers

Merge branch 'master' of https://github.com/dromie/Activiti

......@@ -91,6 +91,10 @@ public abstract class MultiInstanceActivityBehavior extends FlowNodeActivityBeha
} catch (BpmnError error) {
ErrorPropagation.propagateError(error, execution);
}
if (resolveNrOfInstances(execution) == 0) {
leave(execution);
}
} else {
innerActivityBehavior.execute(execution);
}
......@@ -226,7 +230,7 @@ public abstract class MultiInstanceActivityBehavior extends FlowNodeActivityBeha
value = parent.getVariableLocal(variableName);
parent = parent.getParent();
}
return (Integer) value;
return (Integer) (value != null ? value : 0);
}
protected Integer getLocalLoopVariable(ActivityExecution execution, String variableName) {
......
......@@ -37,8 +37,8 @@ public class ParallelMultiInstanceBehavior extends MultiInstanceActivityBehavior
*/
protected void createInstances(ActivityExecution execution) throws Exception {
int nrOfInstances = resolveNrOfInstances(execution);
if (nrOfInstances <= 0) {
throw new ActivitiIllegalArgumentException("Invalid number of instances: must be positive integer value"
if (nrOfInstances < 0) {
throw new ActivitiIllegalArgumentException("Invalid number of instances: must be non-negative integer value"
+ ", but was " + nrOfInstances);
}
......@@ -122,7 +122,7 @@ public class ParallelMultiInstanceBehavior extends MultiInstanceActivityBehavior
executionEntity.getParent().forceUpdate();
List<ActivityExecution> joinedExecutions = executionEntity.findInactiveConcurrentExecutions(execution.getActivity());
if (joinedExecutions.size() == nrOfInstances || completionConditionSatisfied(execution)) {
if (joinedExecutions.size() >= nrOfInstances || completionConditionSatisfied(execution)) {
// Removing all active child executions (ie because completionCondition is true)
List<ExecutionEntity> executionsToRemove = new ArrayList<ExecutionEntity>();
......
......@@ -36,8 +36,8 @@ public class SequentialMultiInstanceBehavior extends MultiInstanceActivityBehavi
*/
protected void createInstances(ActivityExecution execution) throws Exception {
int nrOfInstances = resolveNrOfInstances(execution);
if (nrOfInstances <= 0) {
throw new ActivitiIllegalArgumentException("Invalid number of instances: must be positive integer value"
if (nrOfInstances < 0) {
throw new ActivitiIllegalArgumentException("Invalid number of instances: must be a non-negative integer value"
+ ", but was " + nrOfInstances);
}
......@@ -47,7 +47,9 @@ public class SequentialMultiInstanceBehavior extends MultiInstanceActivityBehavi
setLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES, 1);
logLoopDetails(execution, "initialized", 0, 0, 1, nrOfInstances);
executeOriginalBehavior(execution, 0);
if (nrOfInstances>0) {
executeOriginalBehavior(execution, 0);
}
}
/**
......@@ -69,7 +71,7 @@ public class SequentialMultiInstanceBehavior extends MultiInstanceActivityBehavi
setLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
logLoopDetails(execution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances, nrOfInstances);
if (loopCounter == nrOfInstances || completionConditionSatisfied(execution)) {
if (loopCounter >= nrOfInstances || completionConditionSatisfied(execution)) {
super.leave(execution);
} else {
try {
......
......@@ -16,6 +16,7 @@ package org.activiti.engine.test.bpmn.multiinstance;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
......@@ -1105,6 +1106,55 @@ public class MultiInstanceTest extends PluggableActivitiTestCase {
assertEquals(0, processInstances.size());
assertProcessEnded(processInstance.getId());
}
@Deployment(resources = { "org/activiti/engine/test/bpmn/multiinstance/MultiInstanceTest.testSequentialEmptyCollection.bpmn20.xml" })
public void testSequentialEmptyCollection() {
Collection<String> collection = Collections.emptyList();
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("collection", collection);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testSequentialEmptyCollection", variableMap);
assertNotNull(processInstance);
Task task = taskService.createTaskQuery().singleResult();
assertNull(task);
assertProcessEnded(processInstance.getId());
}
@Deployment(resources = { "org/activiti/engine/test/bpmn/multiinstance/MultiInstanceTest.testSequentialEmptyCollection.bpmn20.xml" })
public void testSequentialEmptyCollectionWithNonEmptyCollection() {
Collection<String> collection = Collections.singleton("Test");
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("collection", collection);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testSequentialEmptyCollection", variableMap);
assertNotNull(processInstance);
Task task = taskService.createTaskQuery().singleResult();
assertNotNull(task);
taskService.complete(task.getId());
assertProcessEnded(processInstance.getId());
}
@Deployment(resources = { "org/activiti/engine/test/bpmn/multiinstance/MultiInstanceTest.testParallelEmptyCollection.bpmn20.xml" })
public void testParalellEmptyCollection() throws Exception {
Collection<String> collection = Collections.emptyList();
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("collection", collection);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testParalellEmptyCollection", variableMap);
assertNotNull(processInstance);
Task task = taskService.createTaskQuery().singleResult();
assertNull(task);
assertProcessEnded(processInstance.getId());
}
@Deployment(resources = { "org/activiti/engine/test/bpmn/multiinstance/MultiInstanceTest.testParallelEmptyCollection.bpmn20.xml" })
public void testParalellEmptyCollectionWithNonEmptyCollection() {
Collection<String> collection = Collections.singleton("Test");
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("collection", collection);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testParalellEmptyCollection", variableMap);
assertNotNull(processInstance);
Task task = taskService.createTaskQuery().singleResult();
assertNotNull(task);
taskService.complete(task.getId());
assertProcessEnded(processInstance.getId());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="testParalellEmptyCollection" isExecutable="true">
<startEvent id="start"></startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="end"></sequenceFlow>
<endEvent id="end"></endEvent>
<userTask id="usertask1" name="Multi">
<multiInstanceLoopCharacteristics isSequential="true" activiti:collection="collection"></multiInstanceLoopCharacteristics>
</userTask>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_testParalellEmptyCollection">
<bpmndi:BPMNPlane bpmnElement="testParalellEmptyCollection" id="BPMNPlane_testParalellEmptyCollection">
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="35.0" width="35.0" x="0.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="35.0" width="35.0" x="230.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="60.0" width="100.0" x="80.0" y="0.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="35.0" y="32.0"></omgdi:waypoint>
<omgdi:waypoint x="42.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="42.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="80.0" y="30.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="180.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="192.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="192.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="230.0" y="32.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="testSequentialEmptyCollection" isExecutable="true">
<startEvent id="start"></startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="end"></sequenceFlow>
<endEvent id="end"></endEvent>
<userTask id="usertask1" name="Multi">
<multiInstanceLoopCharacteristics isSequential="true" activiti:collection="collection"></multiInstanceLoopCharacteristics>
</userTask>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_testSequentialEmptyCollection">
<bpmndi:BPMNPlane bpmnElement="testSequentialEmptyCollection" id="BPMNPlane_testSequentialEmptyCollection">
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="35.0" width="35.0" x="0.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="35.0" width="35.0" x="230.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="60.0" width="100.0" x="80.0" y="0.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="35.0" y="32.0"></omgdi:waypoint>
<omgdi:waypoint x="42.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="42.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="80.0" y="30.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="180.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="192.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="192.0" y="30.0"></omgdi:waypoint>
<omgdi:waypoint x="230.0" y="32.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册