提交 b3248b73 编写于 作者: M martin.grofcik 提交者: fheremans

PROCESS_COMPLETED event

上级 75630e1d
......@@ -175,10 +175,16 @@ public enum ActivitiEventType {
* for the activity corresponding to the task.
*/
TASK_COMPLETED,
/**
* A new membership has been created.
*/
/**
* A process has been completed. Dispatched after the last activity is ACTIVITY_COMPLETED. Process is completed
* when it reaches state in which process instance does not have any transition to take.
*/
PROCESS_COMPLETED,
/**
* A new membership has been created.
*/
MEMBERSHIP_CREATED,
/**
......@@ -192,7 +198,7 @@ public enum ActivitiEventType {
* so they can still be accessed in the dispatch method of the listener.
*/
MEMBERSHIPS_DELETED;
public static final ActivitiEventType[] EMPTY_ARRAY = new ActivitiEventType[] {};
/**
......
......@@ -69,6 +69,12 @@ public class AtomicOperationActivityEnd extends AbstractEventAtomicOperation {
execution.performOperation(ACTIVITY_END);
} else if (execution.isProcessInstanceType()) {
// dispatch process completed event
if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.PROCESS_COMPLETED, execution));
}
execution.performOperation(PROCESS_END);
} else if (execution.isScope()) {
......@@ -101,6 +107,12 @@ public class AtomicOperationActivityEnd extends AbstractEventAtomicOperation {
// we call end() because it sets isEnded on the execution
parentScopeExecution.end();
} else {
// dispatch process completed event
if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.PROCESS_COMPLETED, execution));
}
parentScopeExecution.performOperation(PROCESS_END);
}
} else {
......
......@@ -22,6 +22,7 @@ import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.Deployment;
/**
......@@ -173,6 +174,58 @@ public class ProcessInstanceEventsTest extends PluggableActivitiTestCase {
listener.clearEventsReceived();
}
/**
* Test Start->End process on PROCESS_COMPLETED event
*/
@Deployment(resources = {"org/activiti/engine/test/api/event/ProcessInstanceEventsTest.noneTaskProcess.bpmn20.xml"})
public void testProcessCompleted_StartEnd() throws Exception {
this.runtimeService.startProcessInstanceByKey("noneTaskProcess");
listener.checkEventCount(1, ActivitiEventType.PROCESS_COMPLETED);
}
/**
* Test Start->User Task process on PROCESS_COMPLETED event
*/
@Deployment(resources = {"org/activiti/engine/test/api/event/ProcessInstanceEventsTest.noEndProcess.bpmn20.xml"})
public void testProcessCompleted_NoEnd() throws Exception {
ProcessInstance noEndProcess = this.runtimeService.startProcessInstanceByKey("noEndProcess");
Task task = taskService.createTaskQuery().processInstanceId(noEndProcess.getId()).singleResult();
taskService.complete(task.getId());
listener.checkEventCount(1, ActivitiEventType.PROCESS_COMPLETED);
}
/**
* Test
* +-->Task1
* Start-<>
* +-->Task1
*
* process on PROCESS_COMPLETED event
*/
@Deployment(resources = {"org/activiti/engine/test/api/event/ProcessInstanceEventsTest.parallelGatewayNoEndProcess.bpmn20.xml"})
public void testProcessCompleted_ParallelGatewayNoEnd() throws Exception {
this.runtimeService.startProcessInstanceByKey("noEndProcess");
listener.checkEventCount(1, ActivitiEventType.PROCESS_COMPLETED);
}
/**
* Test
* +-->End1
* Start-<>
* +-->End2
* <p/>
* process on PROCESS_COMPLETED event
*/
@Deployment(resources = {"org/activiti/engine/test/api/event/ProcessInstanceEventsTest.parallelGatewayTwoEndsProcess.bpmn20.xml"})
public void testProcessCompleted_ParallelGatewayTwoEnds() throws Exception {
this.runtimeService.startProcessInstanceByKey("noEndProcess");
listener.checkEventCount(1, ActivitiEventType.PROCESS_COMPLETED);
}
@Override
protected void initializeServices() {
super.initializeServices();
......@@ -221,6 +274,16 @@ public class ProcessInstanceEventsTest extends PluggableActivitiTestCase {
return true;
}
public void checkEventCount(int expectedCount, ActivitiEventType eventType) {// count timer cancelled events
int actualCount = 0;
List<ActivitiEvent> eventsReceived = listener.getEventsReceived();
for (ActivitiEvent eventReceived : eventsReceived) {
if (eventType.equals(eventReceived.getType())) {
actualCount++;
}
}
assertEquals(eventType.name() + " event was expected " + expectedCount + " times.", expectedCount, actualCount);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
targetNamespace="Examples">
<process id="noEndProcess" name="No End Process">
<documentation>This is a process for testing purposes</documentation>
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
<userTask id="theTask" name="my task" />
</process>
</definitions>
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
targetNamespace="Examples">
<process id="noneTaskProcess" name="None Task Process">
<documentation>This is a process for testing purposes</documentation>
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
targetNamespace="Examples">
<process id="noEndProcess" name="No End Process">
<documentation>This is a process for testing purposes</documentation>
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theGateway"/>
<parallelGateway id="theGateway"/>
<sequenceFlow id="flow2" sourceRef="theGateway" targetRef="noneEvent1" />
<intermediateThrowEvent id="noneEvent1"/>
<sequenceFlow id="flow3" sourceRef="theGateway" targetRef="noneEvent2"/>
<intermediateThrowEvent id="noneEvent2"/>
</process>
</definitions>
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
targetNamespace="Examples">
<process id="noEndProcess" name="No End Process">
<documentation>This is a process for testing purposes</documentation>
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theGateway"/>
<parallelGateway id="theGateway"/>
<sequenceFlow id="flow2" sourceRef="theGateway" targetRef="endEvent1" />
<endEvent id="endEvent1"/>
<sequenceFlow id="flow3" sourceRef="theGateway" targetRef="endEvent2"/>
<endEvent id="endEvent2"/>
</process>
</definitions>
......@@ -1171,6 +1171,16 @@ in your subclass, BPMN-event throwing can be prevented. The classes involved are
fired before the process has moved on and will be followed by a <literal>ACTIVITY_COMPLETE</literal> event, targeting the activity that represents the completed task.</entry>
<entry><literal>org.activiti...ActivitiEntityEvent</literal></entry>
</row>
<row>
<entry>PROCESS_COMPLETED</entry>
<entry> A process has been completed. Dispatched after the last activity <literal>ACTIVITY_COMPLETED
</literal> event. Process is completed when it reaches state in which process instance does not have
any transition to take.
</entry>
<entry>
<literal>org.activiti...ActivitiEntityEvent</literal>
</entry>
</row>
<row>
<entry>MEMBERSHIP_CREATED</entry>
<entry>A user has been added to a group. The event contains the id's of the user and group involved.</entry>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册