提交 4d0c628b 编写于 作者: F falko.menge

Continued implementation of ACT-1021 (Trigger BPMN Error Events from Java Delegate)

上级 f8a7396f
......@@ -39,6 +39,12 @@ public class BpmnError extends ActivitiException {
public BpmnError(String errorCode, String message) {
super(message);
if (errorCode == null) {
throw new ActivitiException("Error Code must not be null.");
}
if (errorCode.length() < 1) {
throw new ActivitiException("Error Code must not be empty.");
}
this.errorCode = errorCode;
}
......
......@@ -34,6 +34,7 @@ import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.delegate.ExecutionListenerInvocation;
import org.activiti.engine.impl.delegate.TaskListenerInvocation;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmScope;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.impl.pvm.delegate.SignallableActivityBehavior;
......@@ -120,25 +121,43 @@ public class ClassDelegate extends AbstractBpmnActivityBehavior implements TaskL
} catch (BpmnError error) {
// find error handler
PvmActivity errorEventHandler = null;
for (PvmActivity activity : execution.getActivity().getActivities()) {
if (((ActivityImpl) activity).getActivityBehavior() instanceof BoundaryEventActivityBehavior) {
// TODO check error code of error handler
errorEventHandler = activity;
break;
// search for error handler with same error code as thrown Error
PvmScope scope = execution.getActivity();
while (errorEventHandler == null && scope != null) {
for (PvmActivity activity : scope.getActivities()) {
if (((ActivityImpl) activity).getActivityBehavior() instanceof BoundaryEventActivityBehavior
&& error.getErrorCode().equals(activity.getProperty("errorCode"))) {
errorEventHandler = activity;
break;
}
}
// search for generic error handler if no error handler with that error code has been found
if (errorEventHandler == null) {
for (PvmActivity activity : scope.getActivities()) {
if (((ActivityImpl) activity).getActivityBehavior() instanceof BoundaryEventActivityBehavior
&& (activity.getProperty("errorCode") == null || "".equals(activity.getProperty("errorCode")))) {
errorEventHandler = activity;
break;
}
}
}
// search for error handlers in parent scopes
if (errorEventHandler == null) {
if (scope instanceof PvmActivity) {
scope = ((PvmActivity) scope).getParent();
} else {
scope = null; // stop search
}
}
}
// TODO search for error handlers in parent scopes
ErrorEndEventActivityBehavior errorEndEvent = new ErrorEndEventActivityBehavior(error.getErrorCode());
if (errorEventHandler != null) {
// continue execution
ErrorEndEventActivityBehavior errorEndEvent = new ErrorEndEventActivityBehavior(error.getErrorCode());
errorEndEvent.setBorderEventActivityId(errorEventHandler.getId());
errorEndEvent.execute(execution);
// execution.executeActivity(errorEventHandler);
} else {
// throw error up
throw error;
}
// continue execution
errorEndEvent.execute(execution);
}
}
......
......@@ -242,8 +242,50 @@ public class BoundaryErrorEventTest extends PluggableActivitiTestCase {
@Deployment
public void testCatchErrorThrownByJavaDelegateOnServiceTask() {
String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnServiceTask").getId();
// The service task will throw and error event,
assertThatErrorHasBeenCaught(procId);
}
@Deployment
public void testCatchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode() {
String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode").getId();
assertThatErrorHasBeenCaught(procId);
}
@Deployment
public void testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcess() {
String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnEmbeddedSubProcess").getId();
assertThatErrorHasBeenCaught(procId);
}
@Deployment
public void testCatchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction() {
String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction").getId();
assertThatErrorHasBeenCaught(procId);
}
@Deployment(resources = {
"org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml",
"org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml"
})
public void testCatchErrorThrownByJavaDelegateOnCallActivity() {
String procId = runtimeService.startProcessInstanceByKey("catchErrorThrownByJavaDelegateOnCallActivity-parent").getId();
assertThatErrorHasBeenCaught(procId);
}
@Deployment(resources = {
"org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testUncaughtErrorThrownByJavaDelegateOnCallActivity-parent.bpmn20.xml",
"org/activiti/engine/test/bpmn/event/error/BoundaryErrorEventTest.testCatchErrorThrownByJavaDelegateOnCallActivity-child.bpmn20.xml"
})
public void testUncaughtErrorThrownByJavaDelegateOnCallActivity() {
try {
runtimeService.startProcessInstanceByKey("uncaughtErrorThrownByJavaDelegateOnCallActivity-parent");
} catch (ActivitiException e) {
assertTextPresent("No catching boundary event found for error with errorCode '23', neither in same process nor in parent process", e.getMessage());
}
}
private void assertThatErrorHasBeenCaught(String procId) {
// The service task will throw an error event,
// which is caught on the service task boundary
assertEquals("No tasks found in task list.", 1, taskService.createTaskQuery().count());
Task task = taskService.createTaskQuery().singleResult();
......@@ -253,5 +295,5 @@ public class BoundaryErrorEventTest extends PluggableActivitiTestCase {
taskService.complete(task.getId());
assertProcessEnded(procId);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="catchErrorThrownByJavaDelegateOnCallActivity-child">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="serviceTask" />
<serviceTask id="serviceTask" activiti:class="org.activiti.engine.test.bpmn.event.error.ThrowBpmnErrorDelegate" />
<sequenceFlow id="flow4" sourceRef="serviceTask" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="catchErrorThrownByJavaDelegateOnCallActivity-parent">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="callSubProcess" />
<callActivity id="callSubProcess" calledElement="catchErrorThrownByJavaDelegateOnCallActivity-child" />
<boundaryEvent id="catchError" attachedToRef="callSubProcess">
<errorEventDefinition />
</boundaryEvent>
<sequenceFlow id="flow3" sourceRef="catchError" targetRef="escalatedTask" />
<userTask id="escalatedTask" name="Escalated Task" />
<sequenceFlow id="flow4" sourceRef="callSubProcess" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="catchErrorThrownByJavaDelegateOnEmbeddedSubProcess">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="subProcess" />
<subProcess id="subProcess">
<startEvent id="subProcessStart"/>
<sequenceFlow id="flow2" sourceRef="subProcessStart" targetRef="serviceTask" />
<serviceTask id="serviceTask" activiti:class="org.activiti.engine.test.bpmn.event.error.ThrowBpmnErrorDelegate" />
</subProcess>
<boundaryEvent id="catchError" attachedToRef="subProcess">
<errorEventDefinition />
</boundaryEvent>
<sequenceFlow id="flow3" sourceRef="catchError" targetRef="escalatedTask" />
<userTask id="escalatedTask" name="Escalated Task" />
<sequenceFlow id="flow4" sourceRef="subProcess" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="catchErrorThrownByJavaDelegateOnEmbeddedSubProcessInduction">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="subProcess" />
<subProcess id="subProcess">
<startEvent id="subProcessStart"/>
<sequenceFlow id="flow2" sourceRef="subProcessStart" targetRef="subProcess1" />
<subProcess id="subProcess1">
<startEvent id="subProcess1Start"/>
<sequenceFlow id="flow5" sourceRef="subProcess1Start" targetRef="serviceTask" />
<serviceTask id="serviceTask" activiti:class="org.activiti.engine.test.bpmn.event.error.ThrowBpmnErrorDelegate" />
</subProcess>
</subProcess>
<boundaryEvent id="catchError" attachedToRef="subProcess">
<errorEventDefinition />
</boundaryEvent>
<sequenceFlow id="flow3" sourceRef="catchError" targetRef="escalatedTask" />
<userTask id="escalatedTask" name="Escalated Task" />
<sequenceFlow id="flow4" sourceRef="subProcess" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
......@@ -12,7 +12,7 @@
<serviceTask id="serviceTask" activiti:class="org.activiti.engine.test.bpmn.event.error.ThrowBpmnErrorDelegate" />
<boundaryEvent id="catchError" attachedToRef="serviceTask">
<errorEventDefinition errorRef="myError" />
<errorEventDefinition />
</boundaryEvent>
<sequenceFlow id="flow3" sourceRef="catchError" targetRef="escalatedTask" />
......
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<error id="error42" errorCode="42" />
<error id="error23" errorCode="23" />
<process id="catchErrorThrownByJavaDelegateOnServiceTaskWithErrorCode">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="serviceTask" />
<serviceTask id="serviceTask" activiti:class="org.activiti.engine.test.bpmn.event.error.ThrowBpmnErrorDelegate" />
<boundaryEvent id="ignoreError42" attachedToRef="serviceTask">
<errorEventDefinition errorRef="error42" />
</boundaryEvent>
<boundaryEvent id="catchError" attachedToRef="serviceTask">
<errorEventDefinition errorRef="error23" />
</boundaryEvent>
<sequenceFlow id="flow3" sourceRef="catchError" targetRef="escalatedTask" />
<userTask id="escalatedTask" name="Escalated Task" />
<sequenceFlow id="flow4" sourceRef="serviceTask" targetRef="theEnd" />
<sequenceFlow id="flow5" sourceRef="ignoreError42" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="uncaughtErrorThrownByJavaDelegateOnCallActivity-parent">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="callSubProcess" />
<callActivity id="callSubProcess" calledElement="catchErrorThrownByJavaDelegateOnCallActivity-child" />
<sequenceFlow id="flow4" sourceRef="callSubProcess" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册