Skip to content

Commit ce05e65

Browse files
Add TriggerableJavaDelegate activity behavior to be able to control the leave from the delegate (#3949)
Co-authored-by: Christopher Welsch <christopher.welsch@flowable.com>
1 parent d10e822 commit ce05e65

File tree

25 files changed

+1212
-8
lines changed

25 files changed

+1212
-8
lines changed

modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ServiceTaskDelegateExpressionActivityBehavior.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.flowable.engine.impl.delegate.ActivityBehavior;
3737
import org.flowable.engine.impl.delegate.ActivityBehaviorInvocation;
3838
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
39+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
40+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
3941
import org.flowable.engine.impl.delegate.invocation.DelegateInvocation;
4042
import org.flowable.engine.impl.delegate.invocation.FutureJavaDelegateInvocation;
4143
import org.flowable.engine.impl.delegate.invocation.JavaDelegateInvocation;
@@ -79,6 +81,7 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
7981
Object delegate = DelegateExpressionUtil.resolveDelegateExpression(expression, execution, fieldDeclarations);
8082
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
8183
boolean loggingSessionEnabled = processEngineConfiguration.isLoggingSessionEnabled();
84+
TriggerableJavaDelegateContextImpl triggerableJavaDelegateContext = null;
8285
try {
8386
if (triggerable && delegate instanceof TriggerableActivityBehavior) {
8487
if (loggingSessionEnabled) {
@@ -92,7 +95,17 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
9295
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
9396
"Triggered service task with delegate " + delegate, execution);
9497
}
95-
98+
} else if (triggerable && delegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
99+
if (loggingSessionEnabled) {
100+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
101+
"Triggering service task with java delegate " + delegate, execution);
102+
}
103+
triggerableJavaDelegateContext = new TriggerableJavaDelegateContextImpl(execution, signalName, signalData);
104+
triggerableJavaDelegate.trigger(triggerableJavaDelegateContext);
105+
if (loggingSessionEnabled) {
106+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
107+
"Triggered service task with java delegate " + delegate, execution);
108+
}
96109
} else if (loggingSessionEnabled) {
97110
if (!triggerable) {
98111
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
@@ -103,7 +116,10 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
103116
}
104117

105118
}
106-
leave(execution);
119+
120+
if (triggerableJavaDelegateContext == null || triggerableJavaDelegateContext.shouldLeave()) {
121+
leave(execution);
122+
}
107123
} catch (Exception exc) {
108124
handleException(exc, execution, loggingSessionEnabled);
109125
}

modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ServiceTaskFutureJavaDelegateActivityBehavior.java

+57-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
3333
import org.flowable.engine.impl.delegate.ActivityBehavior;
3434
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
35+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
36+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
3537
import org.flowable.engine.impl.delegate.invocation.FutureJavaDelegateInvocation;
3638
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
3739
import org.flowable.engine.impl.util.BpmnLoggingSessionUtil;
@@ -40,7 +42,7 @@
4042
/**
4143
* @author Filip Hrisafov
4244
*/
43-
public class ServiceTaskFutureJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior {
45+
public class ServiceTaskFutureJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior, TriggerableJavaDelegate {
4446

4547
private static final long serialVersionUID = 1L;
4648

@@ -77,7 +79,18 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
7779
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), execution);
7880
}
7981

80-
leave(execution);
82+
} else if (triggerable && futureJavaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
83+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
84+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
85+
"Triggering service task with java class " + futureJavaDelegate.getClass().getName(), execution);
86+
}
87+
TriggerableJavaDelegateContextImpl context = new TriggerableJavaDelegateContextImpl(execution, null, null);
88+
triggerableJavaDelegate.trigger(context);
89+
90+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
91+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
92+
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), execution);
93+
}
8194

8295
} else {
8396
if (processEngineConfiguration.isLoggingSessionEnabled()) {
@@ -147,7 +160,49 @@ public void execute(DelegateExecution execution) {
147160
leave(execution);
148161
}
149162
}
163+
}
164+
165+
@Override
166+
public void trigger(Context context) {
167+
CommandContext commandContext = CommandContextUtil.getCommandContext();
168+
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
169+
if (triggerable && futureJavaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
170+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
171+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
172+
"Triggering service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
173+
}
174+
triggerableJavaDelegate.trigger(context);
175+
176+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
177+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
178+
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
179+
}
150180

181+
} else if (triggerable && futureJavaDelegate instanceof TriggerableActivityBehavior) {
182+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
183+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
184+
"Triggering service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
185+
}
186+
187+
((TriggerableActivityBehavior) futureJavaDelegate).trigger(context.getExecution(), context.getSignalName(), context.getSignalData());
188+
189+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
190+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
191+
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
192+
}
193+
194+
} else {
195+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
196+
if (!triggerable) {
197+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
198+
"Service task with java class triggered but not triggerable " + futureJavaDelegate.getClass().getName(), context.getExecution());
199+
} else {
200+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
201+
"Service task with java class triggered but not implementing TriggerableActivityBehavior " + futureJavaDelegate.getClass()
202+
.getName(), context.getExecution());
203+
}
204+
}
205+
}
151206
}
152207

153208
protected void handleException(Throwable throwable, DelegateExecution execution, boolean loggingSessionEnabled) {

modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ServiceTaskJavaDelegateActivityBehavior.java

+58-3
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@
2323
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
2424
import org.flowable.engine.impl.delegate.ActivityBehavior;
2525
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
26+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
27+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
2628
import org.flowable.engine.impl.delegate.invocation.JavaDelegateInvocation;
2729
import org.flowable.engine.impl.util.BpmnLoggingSessionUtil;
2830
import org.flowable.engine.impl.util.CommandContextUtil;
2931

3032
/**
3133
* @author Tom Baeyens
3234
*/
33-
public class ServiceTaskJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior, ExecutionListener {
35+
public class ServiceTaskJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior, ExecutionListener, TriggerableJavaDelegate {
3436

3537
private static final long serialVersionUID = 1L;
3638

@@ -65,8 +67,19 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
6567
"Triggered service task with java class " + javaDelegate.getClass().getName(), execution);
6668
}
6769

68-
leave(execution);
69-
70+
} else if (triggerable && javaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
71+
TriggerableJavaDelegateContextImpl triggerableJavaDelegateContext = null;
72+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
73+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
74+
"Triggering service task with java delegate " + triggerableJavaDelegate, execution);
75+
}
76+
triggerableJavaDelegateContext = new TriggerableJavaDelegateContextImpl(execution, signalName, signalData);
77+
triggerableJavaDelegate.trigger(triggerableJavaDelegateContext);
78+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
79+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
80+
"Triggered service task with delegate " + triggerableJavaDelegate, execution);
81+
}
82+
7083
} else {
7184
if (processEngineConfiguration.isLoggingSessionEnabled()) {
7285
if (!triggerable) {
@@ -132,4 +145,46 @@ public void execute(DelegateExecution execution) {
132145
public void notify(DelegateExecution execution) {
133146
execute(execution);
134147
}
148+
149+
@Override
150+
public void trigger(Context context) {
151+
CommandContext commandContext = CommandContextUtil.getCommandContext();
152+
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
153+
154+
if (triggerable && javaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
155+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
156+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
157+
"Triggering service task with java delegate " + triggerableJavaDelegate, context.getExecution());
158+
}
159+
triggerableJavaDelegate.trigger(context);
160+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
161+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
162+
"Triggered service task with delegate " + triggerableJavaDelegate, context.getExecution());
163+
}
164+
} else if (triggerable && javaDelegate instanceof TriggerableActivityBehavior) {
165+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
166+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
167+
"Triggering service task with java class " + javaDelegate.getClass().getName(), context.getExecution());
168+
}
169+
170+
((TriggerableActivityBehavior) javaDelegate).trigger(context.getExecution(), context.getSignalName(), context.getSignalData());
171+
172+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
173+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
174+
"Triggered service task with java class " + javaDelegate.getClass().getName(), context.getExecution());
175+
}
176+
} else {
177+
if (processEngineConfiguration.isLoggingSessionEnabled()) {
178+
if (!triggerable) {
179+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
180+
"Service task with java class triggered but not triggerable " + javaDelegate.getClass().getName(), context.getExecution());
181+
182+
} else {
183+
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
184+
"Service task with java class triggered but not implementing TriggerableActivityBehavior " + javaDelegate.getClass().getName(),
185+
context.getExecution());
186+
}
187+
}
188+
}
189+
}
135190
}

modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/ClassDelegate.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import org.flowable.engine.impl.delegate.ActivityBehavior;
4343
import org.flowable.engine.impl.delegate.SubProcessActivityBehavior;
4444
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
45+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
46+
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
4547
import org.flowable.engine.impl.delegate.invocation.TaskListenerInvocation;
4648
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
4749
import org.flowable.engine.impl.util.CommandContextUtil;
@@ -208,7 +210,21 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
208210
if (activityBehaviorInstance == null) {
209211
activityBehaviorInstance = getActivityBehaviorInstance();
210212
}
211-
if (activityBehaviorInstance instanceof TriggerableActivityBehavior) {
213+
if (activityBehaviorInstance instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
214+
try {
215+
TriggerableJavaDelegateContextImpl context = new TriggerableJavaDelegateContextImpl(execution, null, null);
216+
triggerableJavaDelegate.trigger(context);
217+
if (triggerable && context.shouldLeave()) {
218+
leave(execution);
219+
}
220+
} catch (BpmnError error) {
221+
ErrorPropagation.propagateError(error, execution);
222+
} catch (RuntimeException e) {
223+
if (!ErrorPropagation.mapException(e, (ExecutionEntity) execution, mapExceptions)) {
224+
throw e;
225+
}
226+
}
227+
} else if (activityBehaviorInstance instanceof TriggerableActivityBehavior) {
212228
try {
213229
((TriggerableActivityBehavior) activityBehaviorInstance).trigger(execution, signalName, signalData);
214230
if (triggerable) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.engine.impl.delegate;
14+
15+
import org.flowable.engine.delegate.DelegateExecution;
16+
17+
/**
18+
* Similar to the {@link TriggerableActivityBehavior} but with a context that allows the implementing class
19+
* to decide if the execution should be left after the trigger or not
20+
* @author Christopher Welsch
21+
*/
22+
public interface TriggerableJavaDelegate {
23+
24+
void trigger(TriggerableJavaDelegate.Context context);
25+
26+
interface Context {
27+
28+
void doNotLeave();
29+
30+
Object getSignalData();
31+
32+
DelegateExecution getExecution();
33+
34+
String getSignalName();
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.engine.impl.delegate;
14+
15+
import org.flowable.engine.delegate.DelegateExecution;
16+
17+
/**
18+
* @author Christopher Welsch
19+
*/
20+
public class TriggerableJavaDelegateContextImpl implements TriggerableJavaDelegate.Context {
21+
22+
protected DelegateExecution execution;
23+
protected String signalName;
24+
protected Object signalData;
25+
26+
protected boolean shouldLeave = true;
27+
28+
public TriggerableJavaDelegateContextImpl(DelegateExecution execution, String signalName, Object signalData) {
29+
this.execution = execution;
30+
this.signalName = signalName;
31+
this.signalData = signalData;
32+
}
33+
@Override
34+
public DelegateExecution getExecution() {
35+
return execution;
36+
}
37+
38+
public void setExecution(DelegateExecution execution) {
39+
this.execution = execution;
40+
}
41+
42+
@Override
43+
public String getSignalName() {
44+
return signalName;
45+
}
46+
47+
public void setSignalName(String signalName) {
48+
this.signalName = signalName;
49+
}
50+
@Override
51+
public Object getSignalData() {
52+
return signalData;
53+
}
54+
55+
public void setSignalData(Object signalData) {
56+
this.signalData = signalData;
57+
}
58+
59+
@Override
60+
public void doNotLeave() {
61+
shouldLeave = false;
62+
}
63+
64+
public boolean shouldLeave() {
65+
return shouldLeave;
66+
}
67+
}

0 commit comments

Comments
 (0)