Skip to content

Commit

Permalink
Add TriggerableJavaDelegate activity behavior to be able to control t…
Browse files Browse the repository at this point in the history
…he leave from the delegate (#3949)

Co-authored-by: Christopher Welsch <[email protected]>
  • Loading branch information
WelschChristopher and Christopher Welsch committed Aug 26, 2024
1 parent d10e822 commit ce05e65
Show file tree
Hide file tree
Showing 25 changed files with 1,212 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import org.flowable.engine.impl.delegate.ActivityBehavior;
import org.flowable.engine.impl.delegate.ActivityBehaviorInvocation;
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
import org.flowable.engine.impl.delegate.invocation.DelegateInvocation;
import org.flowable.engine.impl.delegate.invocation.FutureJavaDelegateInvocation;
import org.flowable.engine.impl.delegate.invocation.JavaDelegateInvocation;
Expand Down Expand Up @@ -79,6 +81,7 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
Object delegate = DelegateExpressionUtil.resolveDelegateExpression(expression, execution, fieldDeclarations);
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
boolean loggingSessionEnabled = processEngineConfiguration.isLoggingSessionEnabled();
TriggerableJavaDelegateContextImpl triggerableJavaDelegateContext = null;
try {
if (triggerable && delegate instanceof TriggerableActivityBehavior) {
if (loggingSessionEnabled) {
Expand All @@ -92,7 +95,17 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with delegate " + delegate, execution);
}

} else if (triggerable && delegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
if (loggingSessionEnabled) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java delegate " + delegate, execution);
}
triggerableJavaDelegateContext = new TriggerableJavaDelegateContextImpl(execution, signalName, signalData);
triggerableJavaDelegate.trigger(triggerableJavaDelegateContext);
if (loggingSessionEnabled) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with java delegate " + delegate, execution);
}
} else if (loggingSessionEnabled) {
if (!triggerable) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
Expand All @@ -103,7 +116,10 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
}

}
leave(execution);

if (triggerableJavaDelegateContext == null || triggerableJavaDelegateContext.shouldLeave()) {
leave(execution);
}
} catch (Exception exc) {
handleException(exc, execution, loggingSessionEnabled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.delegate.ActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
import org.flowable.engine.impl.delegate.invocation.FutureJavaDelegateInvocation;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.BpmnLoggingSessionUtil;
Expand All @@ -40,7 +42,7 @@
/**
* @author Filip Hrisafov
*/
public class ServiceTaskFutureJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior {
public class ServiceTaskFutureJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior, TriggerableJavaDelegate {

private static final long serialVersionUID = 1L;

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

leave(execution);
} else if (triggerable && futureJavaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java class " + futureJavaDelegate.getClass().getName(), execution);
}
TriggerableJavaDelegateContextImpl context = new TriggerableJavaDelegateContextImpl(execution, null, null);
triggerableJavaDelegate.trigger(context);

if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), execution);
}

} else {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
Expand Down Expand Up @@ -147,7 +160,49 @@ public void execute(DelegateExecution execution) {
leave(execution);
}
}
}

@Override
public void trigger(Context context) {
CommandContext commandContext = CommandContextUtil.getCommandContext();
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
if (triggerable && futureJavaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
}
triggerableJavaDelegate.trigger(context);

if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
}

} else if (triggerable && futureJavaDelegate instanceof TriggerableActivityBehavior) {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
}

((TriggerableActivityBehavior) futureJavaDelegate).trigger(context.getExecution(), context.getSignalName(), context.getSignalData());

if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with java class " + futureJavaDelegate.getClass().getName(), context.getExecution());
}

} else {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
if (!triggerable) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
"Service task with java class triggered but not triggerable " + futureJavaDelegate.getClass().getName(), context.getExecution());
} else {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
"Service task with java class triggered but not implementing TriggerableActivityBehavior " + futureJavaDelegate.getClass()
.getName(), context.getExecution());
}
}
}
}

protected void handleException(Throwable throwable, DelegateExecution execution, boolean loggingSessionEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.delegate.ActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
import org.flowable.engine.impl.delegate.invocation.JavaDelegateInvocation;
import org.flowable.engine.impl.util.BpmnLoggingSessionUtil;
import org.flowable.engine.impl.util.CommandContextUtil;

/**
* @author Tom Baeyens
*/
public class ServiceTaskJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior, ExecutionListener {
public class ServiceTaskJavaDelegateActivityBehavior extends TaskActivityBehavior implements ActivityBehavior, ExecutionListener, TriggerableJavaDelegate {

private static final long serialVersionUID = 1L;

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

leave(execution);

} else if (triggerable && javaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
TriggerableJavaDelegateContextImpl triggerableJavaDelegateContext = null;
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java delegate " + triggerableJavaDelegate, execution);
}
triggerableJavaDelegateContext = new TriggerableJavaDelegateContextImpl(execution, signalName, signalData);
triggerableJavaDelegate.trigger(triggerableJavaDelegateContext);
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with delegate " + triggerableJavaDelegate, execution);
}

} else {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
if (!triggerable) {
Expand Down Expand Up @@ -132,4 +145,46 @@ public void execute(DelegateExecution execution) {
public void notify(DelegateExecution execution) {
execute(execution);
}

@Override
public void trigger(Context context) {
CommandContext commandContext = CommandContextUtil.getCommandContext();
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);

if (triggerable && javaDelegate instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java delegate " + triggerableJavaDelegate, context.getExecution());
}
triggerableJavaDelegate.trigger(context);
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with delegate " + triggerableJavaDelegate, context.getExecution());
}
} else if (triggerable && javaDelegate instanceof TriggerableActivityBehavior) {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_BEFORE_TRIGGER,
"Triggering service task with java class " + javaDelegate.getClass().getName(), context.getExecution());
}

((TriggerableActivityBehavior) javaDelegate).trigger(context.getExecution(), context.getSignalName(), context.getSignalData());

if (processEngineConfiguration.isLoggingSessionEnabled()) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_AFTER_TRIGGER,
"Triggered service task with java class " + javaDelegate.getClass().getName(), context.getExecution());
}
} else {
if (processEngineConfiguration.isLoggingSessionEnabled()) {
if (!triggerable) {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
"Service task with java class triggered but not triggerable " + javaDelegate.getClass().getName(), context.getExecution());

} else {
BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SERVICE_TASK_WRONG_TRIGGER,
"Service task with java class triggered but not implementing TriggerableActivityBehavior " + javaDelegate.getClass().getName(),
context.getExecution());
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import org.flowable.engine.impl.delegate.ActivityBehavior;
import org.flowable.engine.impl.delegate.SubProcessActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegate;
import org.flowable.engine.impl.delegate.TriggerableJavaDelegateContextImpl;
import org.flowable.engine.impl.delegate.invocation.TaskListenerInvocation;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
Expand Down Expand Up @@ -208,7 +210,21 @@ public void trigger(DelegateExecution execution, String signalName, Object signa
if (activityBehaviorInstance == null) {
activityBehaviorInstance = getActivityBehaviorInstance();
}
if (activityBehaviorInstance instanceof TriggerableActivityBehavior) {
if (activityBehaviorInstance instanceof TriggerableJavaDelegate triggerableJavaDelegate) {
try {
TriggerableJavaDelegateContextImpl context = new TriggerableJavaDelegateContextImpl(execution, null, null);
triggerableJavaDelegate.trigger(context);
if (triggerable && context.shouldLeave()) {
leave(execution);
}
} catch (BpmnError error) {
ErrorPropagation.propagateError(error, execution);
} catch (RuntimeException e) {
if (!ErrorPropagation.mapException(e, (ExecutionEntity) execution, mapExceptions)) {
throw e;
}
}
} else if (activityBehaviorInstance instanceof TriggerableActivityBehavior) {
try {
((TriggerableActivityBehavior) activityBehaviorInstance).trigger(execution, signalName, signalData);
if (triggerable) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.flowable.engine.impl.delegate;

import org.flowable.engine.delegate.DelegateExecution;

/**
* Similar to the {@link TriggerableActivityBehavior} but with a context that allows the implementing class
* to decide if the execution should be left after the trigger or not
* @author Christopher Welsch
*/
public interface TriggerableJavaDelegate {

void trigger(TriggerableJavaDelegate.Context context);

interface Context {

void doNotLeave();

Object getSignalData();

DelegateExecution getExecution();

String getSignalName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.flowable.engine.impl.delegate;

import org.flowable.engine.delegate.DelegateExecution;

/**
* @author Christopher Welsch
*/
public class TriggerableJavaDelegateContextImpl implements TriggerableJavaDelegate.Context {

protected DelegateExecution execution;
protected String signalName;
protected Object signalData;

protected boolean shouldLeave = true;

public TriggerableJavaDelegateContextImpl(DelegateExecution execution, String signalName, Object signalData) {
this.execution = execution;
this.signalName = signalName;
this.signalData = signalData;
}
@Override
public DelegateExecution getExecution() {
return execution;
}

public void setExecution(DelegateExecution execution) {
this.execution = execution;
}

@Override
public String getSignalName() {
return signalName;
}

public void setSignalName(String signalName) {
this.signalName = signalName;
}
@Override
public Object getSignalData() {
return signalData;
}

public void setSignalData(Object signalData) {
this.signalData = signalData;
}

@Override
public void doNotLeave() {
shouldLeave = false;
}

public boolean shouldLeave() {
return shouldLeave;
}
}
Loading

0 comments on commit ce05e65

Please sign in to comment.