diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java index c95f68a580f..c2098f2e86f 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java @@ -193,6 +193,7 @@ import org.flowable.cmmn.engine.impl.scripting.CmmnEngineScriptTraceEnhancer; import org.flowable.cmmn.engine.impl.scripting.CmmnVariableScopeResolverFactory; import org.flowable.cmmn.engine.impl.task.DefaultCmmnTaskVariableScopeResolver; +import org.flowable.cmmn.engine.impl.util.CmmnEventInstanceOutParameterHandler; import org.flowable.cmmn.engine.impl.variable.CmmnAggregatedVariableType; import org.flowable.cmmn.engine.interceptor.CmmnIdentityLinkInterceptor; import org.flowable.cmmn.engine.interceptor.CreateCasePageTaskInterceptor; @@ -680,6 +681,8 @@ public class CmmnEngineConfiguration extends AbstractBuildableEngineConfiguratio protected boolean alwaysUseArraysForDmnMultiHitPolicies = true; + protected CmmnEventInstanceOutParameterHandler cmmnEventInstanceOutParameterHandler; + // Localization support protected CaseDefinitionLocalizationManager caseDefinitionLocalizationManager; protected CaseLocalizationManager caseLocalizationManager; @@ -809,6 +812,13 @@ protected void init() { afterInitEventRegistryEventBusConsumer(); initHistoryCleaningManager(); + initEventInstanceOutParameterHandler(); + } + + public void initEventInstanceOutParameterHandler() { + if (cmmnEventInstanceOutParameterHandler == null) { + cmmnEventInstanceOutParameterHandler = new CmmnEventInstanceOutParameterHandler(); + } } public void initCaseDiagramGenerator() { @@ -4473,4 +4483,12 @@ public CmmnEngineConfiguration setPlanItemLocalizationManager(PlanItemLocalizati this.planItemLocalizationManager = planItemLocalizationManager; return this; } + + public CmmnEventInstanceOutParameterHandler getCmmnEventInstanceOutParameterHandler() { + return cmmnEventInstanceOutParameterHandler; + } + + public void setCmmnEventInstanceOutParameterHandler(CmmnEventInstanceOutParameterHandler cmmnEventInstanceOutParameterHandler) { + this.cmmnEventInstanceOutParameterHandler = cmmnEventInstanceOutParameterHandler; + } } diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/EventRegistryEventListenerActivityBehaviour.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/EventRegistryEventListenerActivityBehaviour.java index 180e3904c0a..cf918de0009 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/EventRegistryEventListenerActivityBehaviour.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/EventRegistryEventListenerActivityBehaviour.java @@ -27,8 +27,8 @@ import org.flowable.cmmn.engine.impl.behavior.CoreCmmnTriggerableActivityBehavior; import org.flowable.cmmn.engine.impl.behavior.PlanItemActivityBehavior; import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity; +import org.flowable.cmmn.engine.impl.util.CmmnEventInstanceOutParameterHandler; import org.flowable.cmmn.engine.impl.util.CommandContextUtil; -import org.flowable.cmmn.engine.impl.util.EventInstanceCmmnUtil; import org.flowable.cmmn.engine.impl.util.ExpressionUtil; import org.flowable.cmmn.engine.impl.util.PlanItemInstanceUtil; import org.flowable.cmmn.model.ExtensionElement; @@ -81,7 +81,7 @@ protected String resolveEventDefinitionKey(PlanItemInstanceEntity planItemInstan public void trigger(CommandContext commandContext, PlanItemInstanceEntity planItemInstanceEntity) { EventInstance eventInstance = (EventInstance) planItemInstanceEntity.getTransientVariable(EventConstants.EVENT_INSTANCE); if (eventInstance != null) { - handleEventInstance(planItemInstanceEntity, eventInstance); + handleEventInstance(planItemInstanceEntity, eventInstance, commandContext); } RepetitionRule repetitionRule = ExpressionUtil.getRepetitionRule(planItemInstanceEntity); @@ -110,10 +110,12 @@ public void trigger(CommandContext commandContext, PlanItemInstanceEntity planIt } } - protected void handleEventInstance(PlanItemInstanceEntity planItemInstanceEntity, EventInstance eventInstance) { + protected void handleEventInstance(PlanItemInstanceEntity planItemInstanceEntity, EventInstance eventInstance, CommandContext commandContext) { PlanItemDefinition planItemDefinition = planItemInstanceEntity.getPlanItemDefinition(); if (planItemDefinition != null) { - EventInstanceCmmnUtil.handleEventInstanceOutParameters(planItemInstanceEntity, planItemDefinition, eventInstance); + CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext); + CmmnEventInstanceOutParameterHandler outParameterHandler = cmmnEngineConfiguration.getCmmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(planItemInstanceEntity, planItemDefinition, eventInstance); } } diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceHelperImpl.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceHelperImpl.java index 6a5a4f22bc0..c763480d733 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceHelperImpl.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceHelperImpl.java @@ -38,10 +38,10 @@ import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntityManager; import org.flowable.cmmn.engine.impl.repository.CaseDefinitionUtil; import org.flowable.cmmn.engine.impl.task.TaskHelper; +import org.flowable.cmmn.engine.impl.util.CmmnEventInstanceOutParameterHandler; import org.flowable.cmmn.engine.impl.util.CmmnLoggingSessionUtil; import org.flowable.cmmn.engine.impl.util.CommandContextUtil; import org.flowable.cmmn.engine.impl.util.EntityLinkUtil; -import org.flowable.cmmn.engine.impl.util.EventInstanceCmmnUtil; import org.flowable.cmmn.engine.impl.util.IdentityLinkUtil; import org.flowable.cmmn.engine.impl.util.JobUtil; import org.flowable.cmmn.engine.interceptor.StartCaseInstanceAfterContext; @@ -368,7 +368,8 @@ protected void applyCaseInstanceBuilder(CmmnEngineConfiguration cmmnEngineConfig Object eventInstance = caseInstanceEntity.getTransientVariable(EventConstants.EVENT_INSTANCE); if (eventInstance instanceof EventInstance) { - EventInstanceCmmnUtil.handleEventInstanceOutParameters(caseInstanceEntity, caseModel, (EventInstance) eventInstance); + CmmnEventInstanceOutParameterHandler outParameterHandler = cmmnEngineConfiguration.getCmmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(caseInstanceEntity, caseModel, (EventInstance) eventInstance); } } diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/CmmnEventInstanceOutParameterHandler.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/CmmnEventInstanceOutParameterHandler.java new file mode 100644 index 00000000000..24d7f79f44f --- /dev/null +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/CmmnEventInstanceOutParameterHandler.java @@ -0,0 +1,47 @@ +package org.flowable.cmmn.engine.impl.util; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.cmmn.converter.CmmnXmlConstants; +import org.flowable.cmmn.model.BaseElement; +import org.flowable.cmmn.model.ExtensionElement; +import org.flowable.eventregistry.api.runtime.EventInstance; +import org.flowable.eventregistry.api.runtime.EventPayloadInstance; +import org.flowable.variable.api.delegate.VariableScope; + +public class CmmnEventInstanceOutParameterHandler { + + /** + * Processes the 'out parameters' of an {@link EventInstance} and stores the corresponding variables on the {@link VariableScope}. + * Typically used when mapping incoming event payload into a runtime instance. + */ + public void handleOutParameters(VariableScope variableScope, BaseElement baseElement, EventInstance eventInstance) { + List outParameters = baseElement.getExtensionElements() + .getOrDefault(CmmnXmlConstants.ELEMENT_EVENT_OUT_PARAMETER, Collections.emptyList()); + if (!outParameters.isEmpty()) { + Map payloadInstances = eventInstance.getPayloadInstances() + .stream() + .collect(Collectors.toMap(EventPayloadInstance::getDefinitionName, Function.identity())); + + for (ExtensionElement outParameter : outParameters) { + String payloadSourceName = outParameter.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_IOPARAMETER_SOURCE); + EventPayloadInstance payloadInstance = payloadInstances.get(payloadSourceName); + String variableName = outParameter.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_IOPARAMETER_TARGET); + if (StringUtils.isNotEmpty(variableName)) { + boolean isTransient = Boolean.parseBoolean(outParameter.getAttributeValue(null, "transient")); + Object value = payloadInstance != null ? payloadInstance.getValue() : null; + if (isTransient) { + variableScope.setTransientVariable(variableName, value); + } else { + variableScope.setVariable(variableName, value); + } + } + } + } + } +} diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/EventInstanceCmmnUtil.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/EventInstanceCmmnUtil.java index 91295f59321..d06da61d7af 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/EventInstanceCmmnUtil.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/EventInstanceCmmnUtil.java @@ -16,11 +16,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.flowable.cmmn.converter.CmmnXmlConstants; import org.flowable.cmmn.model.BaseElement; import org.flowable.cmmn.model.ExtensionElement; @@ -38,36 +34,6 @@ */ public class EventInstanceCmmnUtil { - /** - * Processes the 'out parameters' of an {@link EventInstance} and stores the corresponding variables on the {@link VariableScope}. - * - * Typically used when mapping incoming event payload into a runtime instance. - */ - public static void handleEventInstanceOutParameters(VariableScope variableScope, BaseElement baseElement, EventInstance eventInstance) { - List outParameters = baseElement.getExtensionElements() - .getOrDefault(CmmnXmlConstants.ELEMENT_EVENT_OUT_PARAMETER, Collections.emptyList()); - if (!outParameters.isEmpty()) { - Map payloadInstances = eventInstance.getPayloadInstances() - .stream() - .collect(Collectors.toMap(EventPayloadInstance::getDefinitionName, Function.identity())); - - for (ExtensionElement outParameter : outParameters) { - String payloadSourceName = outParameter.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_IOPARAMETER_SOURCE); - EventPayloadInstance payloadInstance = payloadInstances.get(payloadSourceName); - String variableName = outParameter.getAttributeValue(null, CmmnXmlConstants.ATTRIBUTE_IOPARAMETER_TARGET); - if (StringUtils.isNotEmpty(variableName)) { - Boolean isTransient = Boolean.valueOf(outParameter.getAttributeValue(null, "transient")); - Object value = payloadInstance != null ? payloadInstance.getValue() : null; - if (Boolean.TRUE.equals(isTransient)) { - variableScope.setTransientVariable(variableName, value); - } else { - variableScope.setVariable(variableName, value); - } - } - } - } - } - /** * Reads the 'in parameters' and converts them to {@link EventPayloadInstance} instances. * diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/BoundaryEventRegistryEventActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/BoundaryEventRegistryEventActivityBehavior.java index 6845186d3c6..17ae91c638e 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/BoundaryEventRegistryEventActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/BoundaryEventRegistryEventActivityBehavior.java @@ -26,10 +26,10 @@ import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.BpmnEventInstanceOutParameterHandler; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.CorrelationUtil; import org.flowable.engine.impl.util.CountingEntityUtil; -import org.flowable.engine.impl.util.EventInstanceBpmnUtil; import org.flowable.eventregistry.api.runtime.EventInstance; import org.flowable.eventregistry.impl.constant.EventConstants; import org.flowable.eventsubscription.service.EventSubscriptionService; @@ -76,14 +76,15 @@ public void execute(DelegateExecution execution) { public void trigger(DelegateExecution execution, String triggerName, Object triggerData) { ExecutionEntity executionEntity = (ExecutionEntity) execution; BoundaryEvent boundaryEvent = (BoundaryEvent) execution.getCurrentFlowElement(); - + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); + Object eventInstance = execution.getTransientVariables().get(EventConstants.EVENT_INSTANCE); if (eventInstance instanceof EventInstance) { - EventInstanceBpmnUtil.handleEventInstanceOutParameters(execution, boundaryEvent, (EventInstance) eventInstance); + BpmnEventInstanceOutParameterHandler outParameterHandler = processEngineConfiguration.getBpmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(execution, boundaryEvent, (EventInstance) eventInstance); } if (boundaryEvent.isCancelActivity()) { - ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); EventSubscriptionService eventSubscriptionService = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService(); List eventSubscriptions = executionEntity.getEventSubscriptions(); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/EventSubProcessEventRegistryStartEventActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/EventSubProcessEventRegistryStartEventActivityBehavior.java index 296f9e7af45..a85104c015a 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/EventSubProcessEventRegistryStartEventActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/EventSubProcessEventRegistryStartEventActivityBehavior.java @@ -32,9 +32,9 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; +import org.flowable.engine.impl.util.BpmnEventInstanceOutParameterHandler; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.CountingEntityUtil; -import org.flowable.engine.impl.util.EventInstanceBpmnUtil; import org.flowable.eventregistry.api.runtime.EventInstance; import org.flowable.eventregistry.impl.constant.EventConstants; import org.flowable.eventsubscription.service.EventSubscriptionService; @@ -80,7 +80,8 @@ public void trigger(DelegateExecution execution, String triggerName, Object trig Object eventInstance = execution.getTransientVariable(EventConstants.EVENT_INSTANCE); if (eventInstance instanceof EventInstance) { - EventInstanceBpmnUtil.handleEventInstanceOutParameters(execution, startEvent, (EventInstance) eventInstance); + BpmnEventInstanceOutParameterHandler outParameterHandler = processEngineConfiguration.getBpmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(execution, startEvent, (EventInstance) eventInstance); } if (startEvent.isInterrupting()) { diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/IntermediateCatchEventRegistryEventActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/IntermediateCatchEventRegistryEventActivityBehavior.java index 90a2f2f6c89..0b4f05d47b3 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/IntermediateCatchEventRegistryEventActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/IntermediateCatchEventRegistryEventActivityBehavior.java @@ -26,10 +26,10 @@ import org.flowable.engine.history.DeleteReason; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.BpmnEventInstanceOutParameterHandler; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.CorrelationUtil; import org.flowable.engine.impl.util.CountingEntityUtil; -import org.flowable.engine.impl.util.EventInstanceBpmnUtil; import org.flowable.eventregistry.api.runtime.EventInstance; import org.flowable.eventregistry.impl.constant.EventConstants; import org.flowable.eventsubscription.service.EventSubscriptionService; @@ -103,14 +103,15 @@ public void eventCancelledByEventGateway(DelegateExecution execution) { protected ExecutionEntity deleteEventSubscription(DelegateExecution execution) { ExecutionEntity executionEntity = (ExecutionEntity) execution; + CommandContext commandContext = Context.getCommandContext(); + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); Object eventInstance = execution.getTransientVariables().get(EventConstants.EVENT_INSTANCE); if (eventInstance instanceof EventInstance) { - EventInstanceBpmnUtil.handleEventInstanceOutParameters(execution, execution.getCurrentFlowElement(), (EventInstance) eventInstance); + BpmnEventInstanceOutParameterHandler outParameterHandler = processEngineConfiguration.getBpmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(execution, execution.getCurrentFlowElement(), (EventInstance) eventInstance); } - CommandContext commandContext = Context.getCommandContext(); - ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); EventSubscriptionService eventSubscriptionService = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService(); List eventSubscriptions = executionEntity.getEventSubscriptions(); @@ -123,6 +124,4 @@ protected ExecutionEntity deleteEventSubscription(DelegateExecution execution) { } return executionEntity; } - - } diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ReceiveEventTaskActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ReceiveEventTaskActivityBehavior.java index 790ee0e21d1..ce1218cf74e 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ReceiveEventTaskActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ReceiveEventTaskActivityBehavior.java @@ -26,10 +26,10 @@ import org.flowable.engine.impl.bpmn.helper.SkipExpressionUtil; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.BpmnEventInstanceOutParameterHandler; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.CorrelationUtil; import org.flowable.engine.impl.util.CountingEntityUtil; -import org.flowable.engine.impl.util.EventInstanceBpmnUtil; import org.flowable.eventregistry.api.runtime.EventInstance; import org.flowable.eventregistry.impl.constant.EventConstants; import org.flowable.eventsubscription.service.EventSubscriptionService; @@ -84,13 +84,13 @@ public void execute(DelegateExecution execution) { @Override public void trigger(DelegateExecution execution, String signalName, Object signalData) { ExecutionEntity executionEntity = (ExecutionEntity) execution; + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); Object eventInstance = execution.getTransientVariables().get(EventConstants.EVENT_INSTANCE); if (eventInstance instanceof EventInstance) { - EventInstanceBpmnUtil.handleEventInstanceOutParameters(execution, execution.getCurrentFlowElement(), (EventInstance) eventInstance); + BpmnEventInstanceOutParameterHandler outParameterHandler = processEngineConfiguration.getBpmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(execution, execution.getCurrentFlowElement(), (EventInstance) eventInstance); } - - ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); EventSubscriptionService eventSubscriptionService = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService(); List eventSubscriptions = executionEntity.getEventSubscriptions(); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/SendEventTaskActivityBehavior.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/SendEventTaskActivityBehavior.java index 109edac5f42..6af6e9b3785 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/SendEventTaskActivityBehavior.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/SendEventTaskActivityBehavior.java @@ -37,6 +37,7 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.jobexecutor.AsyncSendEventJobHandler; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.util.BpmnEventInstanceOutParameterHandler; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.CorrelationUtil; import org.flowable.engine.impl.util.CountingEntityUtil; @@ -230,12 +231,13 @@ protected List getChannelModels(CommandContext commandContext, Del public void trigger(DelegateExecution execution, String signalName, Object signalData) { if (sendEventServiceTask.isTriggerable()) { Object eventInstance = execution.getTransientVariables().get(EventConstants.EVENT_INSTANCE); + CommandContext commandContext = CommandContextUtil.getCommandContext(); + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); if (eventInstance instanceof EventInstance) { - EventInstanceBpmnUtil.handleEventInstanceOutParameters(execution, sendEventServiceTask, (EventInstance) eventInstance); + BpmnEventInstanceOutParameterHandler outParameterHandler = processEngineConfiguration.getBpmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(execution, sendEventServiceTask, (EventInstance) eventInstance); } - CommandContext commandContext = CommandContextUtil.getCommandContext(); - ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); EventSubscriptionService eventSubscriptionService = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService(); ExecutionEntity executionEntity = (ExecutionEntity) execution; List eventSubscriptions = executionEntity.getEventSubscriptions(); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java index f35dd0bcbc5..736180ce1f6 100755 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cfg/ProcessEngineConfigurationImpl.java @@ -345,6 +345,7 @@ import org.flowable.engine.impl.repository.DeploymentProcessDefinitionDeletionManagerImpl; import org.flowable.engine.impl.scripting.ProcessEngineScriptTraceEnhancer; import org.flowable.engine.impl.scripting.VariableScopeResolverFactory; +import org.flowable.engine.impl.util.BpmnEventInstanceOutParameterHandler; import org.flowable.engine.impl.util.ProcessInstanceHelper; import org.flowable.engine.impl.variable.BpmnAggregatedVariableType; import org.flowable.engine.impl.variable.ParallelMultiInstanceLoopVariableType; @@ -850,6 +851,8 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig protected boolean handleProcessEngineExecutorsAfterEngineCreate = true; + protected BpmnEventInstanceOutParameterHandler bpmnEventInstanceOutParameterHandler; + // Backwards compatibility ////////////////////////////////////////////////////////////// protected boolean flowable5CompatibilityEnabled; // Default flowable 5 backwards compatibility is disabled! @@ -987,6 +990,13 @@ public void init() { initHistoryCleaningManager(); initLocalizationManagers(); + initEventInstanceOutParameterHandler(); + } + + public void initEventInstanceOutParameterHandler() { + if (bpmnEventInstanceOutParameterHandler == null) { + bpmnEventInstanceOutParameterHandler = new BpmnEventInstanceOutParameterHandler(); + } } // failedJobCommandFactory @@ -5474,4 +5484,11 @@ public void setBatchStatusTimeCycleConfig(String batchStatusTimeCycleConfig) { this.batchStatusTimeCycleConfig = batchStatusTimeCycleConfig; } + public BpmnEventInstanceOutParameterHandler getBpmnEventInstanceOutParameterHandler() { + return bpmnEventInstanceOutParameterHandler; + } + + public void setBpmnEventInstanceOutParameterHandler(BpmnEventInstanceOutParameterHandler bpmnEventInstanceOutParameterHandler) { + this.bpmnEventInstanceOutParameterHandler = bpmnEventInstanceOutParameterHandler; + } } diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/BpmnEventInstanceOutParameterHandler.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/BpmnEventInstanceOutParameterHandler.java new file mode 100644 index 00000000000..a67657dbf4f --- /dev/null +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/BpmnEventInstanceOutParameterHandler.java @@ -0,0 +1,65 @@ +package org.flowable.engine.impl.util; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.flowable.bpmn.constants.BpmnXMLConstants; +import org.flowable.bpmn.model.BaseElement; +import org.flowable.bpmn.model.ExtensionElement; +import org.flowable.bpmn.model.IOParameter; +import org.flowable.bpmn.model.SendEventServiceTask; +import org.flowable.eventregistry.api.runtime.EventInstance; +import org.flowable.eventregistry.api.runtime.EventPayloadInstance; +import org.flowable.variable.api.delegate.VariableScope; + +public class BpmnEventInstanceOutParameterHandler { + + /** + * Processes the 'out parameters' of an {@link EventInstance} and stores the corresponding variables on the {@link VariableScope}. + * Typically used when mapping incoming event payload into a runtime instance (the {@link VariableScope}). + */ + public void handleOutParameters(VariableScope variableScope, BaseElement baseElement, EventInstance eventInstance) { + Map payloadInstances = eventInstance.getPayloadInstances() + .stream() + .collect(Collectors.toMap(EventPayloadInstance::getDefinitionName, Function.identity())); + + if (baseElement instanceof SendEventServiceTask eventServiceTask) { + if (!eventServiceTask.getEventOutParameters().isEmpty()) { + for (IOParameter parameter : eventServiceTask.getEventOutParameters()) { + setEventParameterVariable(parameter.getSource(), parameter.getTarget(), + parameter.isTransient(), payloadInstances, variableScope); + } + } + + } else { + List outParameters = baseElement.getExtensionElements() + .getOrDefault(BpmnXMLConstants.ELEMENT_EVENT_OUT_PARAMETER, Collections.emptyList()); + if (!outParameters.isEmpty()) { + for (ExtensionElement outParameter : outParameters) { + String payloadSourceName = outParameter.getAttributeValue(null, BpmnXMLConstants.ATTRIBUTE_IOPARAMETER_SOURCE); + String variableName = outParameter.getAttributeValue(null, BpmnXMLConstants.ATTRIBUTE_IOPARAMETER_TARGET); + boolean isTransient = Boolean.parseBoolean(outParameter.getAttributeValue(null, "transient")); + setEventParameterVariable(payloadSourceName, variableName, isTransient, payloadInstances, variableScope); + } + } + } + } + + protected void setEventParameterVariable(String source, String target, boolean isTransient, + Map payloadInstances, VariableScope variableScope) { + + EventPayloadInstance payloadInstance = payloadInstances.get(source); + if (StringUtils.isNotEmpty(target)) { + Object value = payloadInstance != null ? payloadInstance.getValue() : null; + if (isTransient) { + variableScope.setTransientVariable(target, value); + } else { + variableScope.setVariable(target, value); + } + } + } +} diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/EventInstanceBpmnUtil.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/EventInstanceBpmnUtil.java index 65158d11820..4ced31c76e0 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/EventInstanceBpmnUtil.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/EventInstanceBpmnUtil.java @@ -16,9 +16,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.flowable.bpmn.constants.BpmnXMLConstants; @@ -37,41 +34,8 @@ public class EventInstanceBpmnUtil { - /** - * Processes the 'out parameters' of an {@link EventInstance} and stores the corresponding variables on the {@link VariableScope}. - * - * Typically used when mapping incoming event payload into a runtime instance (the {@link VariableScope}). - */ - public static void handleEventInstanceOutParameters(VariableScope variableScope, BaseElement baseElement, EventInstance eventInstance) { - Map payloadInstances = eventInstance.getPayloadInstances() - .stream() - .collect(Collectors.toMap(EventPayloadInstance::getDefinitionName, Function.identity())); - - if (baseElement instanceof SendEventServiceTask eventServiceTask) { - if (!eventServiceTask.getEventOutParameters().isEmpty()) { - for (IOParameter parameter : eventServiceTask.getEventOutParameters()) { - setEventParameterVariable(parameter.getSource(), parameter.getTarget(), - parameter.isTransient(), payloadInstances, variableScope); - } - } - - } else { - List outParameters = baseElement.getExtensionElements() - .getOrDefault(BpmnXMLConstants.ELEMENT_EVENT_OUT_PARAMETER, Collections.emptyList()); - if (!outParameters.isEmpty()) { - for (ExtensionElement outParameter : outParameters) { - String payloadSourceName = outParameter.getAttributeValue(null, BpmnXMLConstants.ATTRIBUTE_IOPARAMETER_SOURCE); - String variableName = outParameter.getAttributeValue(null, BpmnXMLConstants.ATTRIBUTE_IOPARAMETER_TARGET); - boolean isTransient = Boolean.parseBoolean(outParameter.getAttributeValue(null, "transient")); - setEventParameterVariable(payloadSourceName, variableName, isTransient, payloadInstances, variableScope); - } - } - } - } - /** * Reads the 'in parameters' and converts them to {@link EventPayloadInstance} instances. - * * Typically used when needing to create {@link EventInstance}'s and populate the payload. */ public static Collection createEventPayloadInstances(VariableScope variableScope, ExpressionManager expressionManager, @@ -118,22 +82,8 @@ public static Collection createEventPayloadInstances(Varia return eventPayloadInstances; } - - protected static void setEventParameterVariable(String source, String target, boolean isTransient, - Map payloadInstances, VariableScope variableScope) { - - EventPayloadInstance payloadInstance = payloadInstances.get(source); - if (StringUtils.isNotEmpty(target)) { - Object value = payloadInstance != null ? payloadInstance.getValue() : null; - if (Boolean.TRUE.equals(isTransient)) { - variableScope.setTransientVariable(target, value); - } else { - variableScope.setVariable(target, value); - } - } - } - - protected static void addEventPayloadInstance(List eventPayloadInstances, String source, String target, + + protected static void addEventPayloadInstance(List eventPayloadInstances, String source, String target, VariableScope variableScope, ExpressionManager expressionManager, EventModel eventDefinition) { EventPayload eventPayloadDefinition = eventDefinition.getPayload(target); diff --git a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessInstanceHelper.java b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessInstanceHelper.java index fbc1a5792aa..6c52bb99c9b 100644 --- a/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessInstanceHelper.java +++ b/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessInstanceHelper.java @@ -42,6 +42,7 @@ import org.flowable.common.engine.impl.callback.CallbackData; import org.flowable.common.engine.impl.callback.RuntimeInstanceStateChangeCallback; import org.flowable.common.engine.impl.context.Context; +import org.flowable.common.engine.impl.el.DefinitionVariableContainer; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.common.engine.impl.logging.LoggingSessionConstants; import org.flowable.common.engine.impl.util.CollectionUtil; @@ -64,7 +65,6 @@ import org.flowable.eventsubscription.service.impl.persistence.entity.SignalEventSubscriptionEntity; import org.flowable.identitylink.api.IdentityLinkType; import org.flowable.job.service.impl.persistence.entity.TimerJobEntity; -import org.flowable.common.engine.impl.el.DefinitionVariableContainer; import tools.jackson.databind.node.ObjectNode; @@ -258,8 +258,8 @@ public ProcessInstance createAndStartProcessInstanceWithInitialFlowElement(Proce Object eventInstance = startInstanceBeforeContext.getTransientVariables().get(EventConstants.EVENT_INSTANCE); if (eventInstance instanceof EventInstance) { - EventInstanceBpmnUtil.handleEventInstanceOutParameters(processInstance, startInstanceBeforeContext.getInitialFlowElement(), - (EventInstance) eventInstance); + BpmnEventInstanceOutParameterHandler outParameterHandler = processEngineConfiguration.getBpmnEventInstanceOutParameterHandler(); + outParameterHandler.handleOutParameters(processInstance, startInstanceBeforeContext.getInitialFlowElement(), (EventInstance) eventInstance); } for (String varName : startInstanceBeforeContext.getTransientVariables().keySet()) {