Skip to content

Commit c6d7dbb

Browse files
committed
Drive End and IntermediateThrow event validation through getSupportedLocations()
Align EndEventValidator and IntermediateThrowEventValidator with the four already-refactored placement validators so all six EventDefinitionLocation values are enforced. Built-ins keep their existing behavior; custom EventDefinitions declaring END_EVENT or INTERMEDIATE_THROW_EVENT support are now valid at those placements.
1 parent b5b39c7 commit c6d7dbb

4 files changed

Lines changed: 49 additions & 21 deletions

File tree

modules/flowable-engine/src/test/java/org/flowable/standalone/validation/DefaultProcessValidatorTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.flowable.bpmn.model.SequenceFlow;
3535
import org.flowable.bpmn.model.StartEvent;
3636
import org.flowable.bpmn.model.TerminateEventDefinition;
37+
import org.flowable.bpmn.model.TimerEventDefinition;
3738
import org.flowable.bpmn.model.UserTask;
3839
import org.flowable.common.engine.api.io.InputStreamProvider;
3940
import org.flowable.engine.test.util.TestProcessUtil;
@@ -415,6 +416,36 @@ void testBoundaryEventWithUnsupportedDefinition() {
415416
tuple(Problems.BOUNDARY_EVENT_INVALID_EVENT_DEFINITION, "Invalid or unsupported event definition", "invalidBoundaryEvent", false));
416417
}
417418

419+
@Test
420+
void testEndEventWithUnsupportedDefinition() {
421+
BpmnModel bpmnModel = new BpmnModel();
422+
Process process = new Process();
423+
process.setId("endEventWithUnsupportedDefinition");
424+
process.setExecutable(true);
425+
bpmnModel.addProcess(process);
426+
427+
StartEvent start = new StartEvent();
428+
start.setId("start");
429+
process.addFlowElement(start);
430+
431+
EndEvent end = new EndEvent();
432+
end.setId("invalidEndEvent");
433+
end.setName("Invalid End Event");
434+
TimerEventDefinition timerEventDefinition = new TimerEventDefinition();
435+
timerEventDefinition.setTimeDuration("PT5M");
436+
end.addEventDefinition(timerEventDefinition);
437+
process.addFlowElement(end);
438+
439+
process.addFlowElement(new SequenceFlow("start", "invalidEndEvent"));
440+
441+
List<ValidationError> errors = processValidator.validate(bpmnModel);
442+
443+
assertThat(errors)
444+
.extracting(ValidationError::getProblem, ValidationError::getDefaultDescription, ValidationError::getActivityId, ValidationError::isWarning)
445+
.containsExactly(
446+
tuple(Problems.END_EVENT_INVALID_EVENT_DEFINITION, "Invalid or unsupported event definition", "invalidEndEvent", false));
447+
}
448+
418449
@Test
419450
void testInvalidMultiInstanceActivity() {
420451
BpmnModel bpmnModel = readBpmnModelFromXml("org/flowable/standalone/validation/invalidMultiInstanceActivity.bpmn20.xml");

modules/flowable-process-validation/src/main/java/org/flowable/validation/validator/Problems.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ public interface Problems {
134134
String DATA_OBJECT_MISSING_NAME = "flowable-data-object-missing-name";
135135

136136
String END_EVENT_CANCEL_ONLY_INSIDE_TRANSACTION = "flowable-end-event-cancel-only-inside-transaction";
137+
String END_EVENT_INVALID_EVENT_DEFINITION = "flowable-end-event-invalid-event-definition";
137138

138139
String DI_INVALID_REFERENCE = "flowable-di-invalid-reference";
139140
String DI_DOES_NOT_REFERENCE_FLOWNODE = "flowable-di-does-not-reference-flownode";

modules/flowable-process-validation/src/main/java/org/flowable/validation/validator/impl/EndEventValidator.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.flowable.bpmn.model.CancelEventDefinition;
1919
import org.flowable.bpmn.model.EndEvent;
2020
import org.flowable.bpmn.model.EventDefinition;
21+
import org.flowable.bpmn.model.EventDefinitionLocation;
2122
import org.flowable.bpmn.model.FlowElementsContainer;
2223
import org.flowable.bpmn.model.Process;
2324
import org.flowable.bpmn.model.Transaction;
@@ -34,20 +35,20 @@ public class EndEventValidator extends ProcessLevelValidator {
3435
protected void executeValidation(BpmnModel bpmnModel, Process process, ProcessValidationContext validationContext) {
3536
List<EndEvent> endEvents = process.findFlowElementsOfType(EndEvent.class);
3637
for (EndEvent endEvent : endEvents) {
37-
if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) {
38-
39-
EventDefinition eventDefinition = endEvent.getEventDefinitions().get(0);
40-
41-
// Error end event
42-
if (eventDefinition instanceof CancelEventDefinition) {
38+
if (endEvent.getEventDefinitions() == null || endEvent.getEventDefinitions().isEmpty()) {
39+
continue;
40+
}
41+
EventDefinition eventDefinition = endEvent.getEventDefinitions().get(0);
4342

44-
FlowElementsContainer parent = process.findParent(endEvent);
45-
if (!(parent instanceof Transaction)) {
46-
validationContext.addError(Problems.END_EVENT_CANCEL_ONLY_INSIDE_TRANSACTION, process, endEvent, "end event with cancelEventDefinition only supported inside transaction subprocess");
47-
}
43+
if (!eventDefinition.getSupportedLocations().contains(EventDefinitionLocation.END_EVENT)) {
44+
validationContext.addError(Problems.END_EVENT_INVALID_EVENT_DEFINITION, process, endEvent, eventDefinition, "Invalid or unsupported event definition");
45+
}
4846

47+
if (eventDefinition instanceof CancelEventDefinition) {
48+
FlowElementsContainer parent = process.findParent(endEvent);
49+
if (!(parent instanceof Transaction)) {
50+
validationContext.addError(Problems.END_EVENT_CANCEL_ONLY_INSIDE_TRANSACTION, process, endEvent, "end event with cancelEventDefinition only supported inside transaction subprocess");
4951
}
50-
5152
}
5253
}
5354
}

modules/flowable-process-validation/src/main/java/org/flowable/validation/validator/impl/IntermediateThrowEventValidator.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
import java.util.List;
1616

1717
import org.flowable.bpmn.model.BpmnModel;
18-
import org.flowable.bpmn.model.CompensateEventDefinition;
19-
import org.flowable.bpmn.model.EscalationEventDefinition;
2018
import org.flowable.bpmn.model.EventDefinition;
19+
import org.flowable.bpmn.model.EventDefinitionLocation;
2120
import org.flowable.bpmn.model.Process;
22-
import org.flowable.bpmn.model.SignalEventDefinition;
2321
import org.flowable.bpmn.model.ThrowEvent;
2422
import org.flowable.validation.ProcessValidationContext;
2523
import org.flowable.validation.validator.Problems;
@@ -34,14 +32,11 @@ public class IntermediateThrowEventValidator extends ProcessLevelValidator {
3432
protected void executeValidation(BpmnModel bpmnModel, Process process, ProcessValidationContext validationContext) {
3533
List<ThrowEvent> throwEvents = process.findFlowElementsOfType(ThrowEvent.class);
3634
for (ThrowEvent throwEvent : throwEvents) {
37-
EventDefinition eventDefinition = null;
38-
if (!throwEvent.getEventDefinitions().isEmpty()) {
39-
eventDefinition = throwEvent.getEventDefinitions().get(0);
35+
if (throwEvent.getEventDefinitions().isEmpty()) {
36+
continue;
4037
}
41-
42-
if (eventDefinition != null && !(eventDefinition instanceof SignalEventDefinition) &&
43-
!(eventDefinition instanceof EscalationEventDefinition) && !(eventDefinition instanceof CompensateEventDefinition)) {
44-
38+
EventDefinition eventDefinition = throwEvent.getEventDefinitions().get(0);
39+
if (!eventDefinition.getSupportedLocations().contains(EventDefinitionLocation.INTERMEDIATE_THROW_EVENT)) {
4540
validationContext.addError(Problems.THROW_EVENT_INVALID_EVENTDEFINITION, process, throwEvent, eventDefinition, "Unsupported intermediate throw event type");
4641
}
4742
}

0 commit comments

Comments
 (0)