From acb7a5def353d52f634dda59917c0e00b06244ec Mon Sep 17 00:00:00 2001 From: Arthur H <516104+arthware@users.noreply.github.com> Date: Wed, 14 Jun 2023 08:30:01 +0200 Subject: [PATCH] Fix VariableContainerELResolver to return a value for plain VariableContainers (#3662) * The VariableContainerElResolver missed an else branch to return a value for plain VariableContainers (Handled VariableScope only). --- .../impl/el/VariableContainerELResolver.java | 4 + .../JsonVariableContainerExpressionTest.java | 76 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 modules/flowable-engine/src/test/java/org/flowable/engine/test/el/JsonVariableContainerExpressionTest.java diff --git a/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/VariableContainerELResolver.java b/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/VariableContainerELResolver.java index 2de1515bba8..142182854f7 100644 --- a/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/VariableContainerELResolver.java +++ b/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/VariableContainerELResolver.java @@ -50,6 +50,10 @@ public Object getValue(ELContext context, Object base, Object property) { // reviews[0].score, reviews is an aggregated variable which is read only value = variableInstance.getValue(); } + } else { + // simple variable container can be written to by default. + // No further checks required. + value = variableContainer.getVariable(variable); } } else { value = variableContainer.getVariable(variable); diff --git a/modules/flowable-engine/src/test/java/org/flowable/engine/test/el/JsonVariableContainerExpressionTest.java b/modules/flowable-engine/src/test/java/org/flowable/engine/test/el/JsonVariableContainerExpressionTest.java new file mode 100644 index 00000000000..3bf01034b81 --- /dev/null +++ b/modules/flowable-engine/src/test/java/org/flowable/engine/test/el/JsonVariableContainerExpressionTest.java @@ -0,0 +1,76 @@ +/* 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.test.el; + +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; + +import java.util.HashMap; +import java.util.Map; + +import org.flowable.common.engine.api.variable.VariableContainer; +import org.flowable.common.engine.impl.el.VariableContainerWrapper; +import org.flowable.common.engine.impl.variable.MapDelegateVariableContainer; +import org.flowable.engine.impl.test.PluggableFlowableTestCase; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class JsonVariableContainerExpressionTest extends PluggableFlowableTestCase { + + @Test + public void setNestedJsonVariableValueWithVariableContainerWrapper() { + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode objectNode = objectMapper.createObjectNode(); + + Map variables = new HashMap<>(); + variables.put("muppetshow", objectNode); + + VariableContainerWrapper simpleVariableContainer = new VariableContainerWrapper(variables); + assertThatJson(executeSetValueExpression("${muppetshow.characters.frog.name}", "Kermit", simpleVariableContainer) + .getVariable("muppetshow")) + .isEqualTo("{characters:{frog:{'name':'Kermit'}}}"); + + assertThatJson(executeSetValueExpression("${muppetshow.startingYear}", 1976, simpleVariableContainer) + .getVariable("muppetshow")) + .isEqualTo("{characters:{frog:{name:'Kermit'}},startingYear:1976}"); + } + + @Test + public void setNestedJsonVariableValueWithMapDelegateVariableContainer() { + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode objectNode = objectMapper.createObjectNode(); + MapDelegateVariableContainer simpleVariableContainer = new MapDelegateVariableContainer().addTransientVariable("muppetshow", objectNode); + assertThatJson(executeSetValueExpression("${muppetshow.characters.frog.name}", "Kermit", simpleVariableContainer) + .getVariable("muppetshow")) + .isEqualTo("{characters:{frog:{'name':'Kermit'}}}"); + + assertThatJson(executeSetValueExpression("${muppetshow.startingYear}", 1976, simpleVariableContainer) + .getVariable("muppetshow")) + .isEqualTo("{characters:{frog:{name:'Kermit'}},startingYear:1976}"); + } + + protected VariableContainer executeSetValueExpression(String expression, Object value, VariableContainer variableContainer) { + processEngineConfiguration.getCommandExecutor() + .execute(commandContext -> { + processEngineConfiguration.getExpressionManager() + .createExpression(expression) + .setValue(value, variableContainer); + return null; + }); + return variableContainer; + } + +}