This is an automated email from the ASF dual-hosted git repository.

tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie.git


The following commit(s) were added to refs/heads/main by this push:
     new 0cd7286f0b2 [NO_ISSUE] Fix for failing tests after PR 7199 (#7232)
0cd7286f0b2 is described below

commit 0cd7286f0b2bd7477dae587b871aa8dd9ee0858c
Author: Martin Weiler <[email protected]>
AuthorDate: Sun Oct 25 20:32:23 2026 -0600

    [NO_ISSUE] Fix for failing tests after PR 7199 (#7232)
---
 .../core/impl/OutputExpressionAssignment.java      | 22 ++++--
 .../core/impl/OutputExpressionAssignmentTest.java  | 82 ++++++++++++++++++++++
 2 files changed, 100 insertions(+), 4 deletions(-)

diff --git 
a/kogito-jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/OutputExpressionAssignment.java
 
b/kogito-jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/OutputExpressionAssignment.java
index 29119a0c21e..9897023310a 100644
--- 
a/kogito-jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/OutputExpressionAssignment.java
+++ 
b/kogito-jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/OutputExpressionAssignment.java
@@ -21,6 +21,7 @@ package org.jbpm.workflow.core.impl;
 import java.io.Serializable;
 import java.util.function.Function;
 import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.jbpm.process.instance.impl.AssignmentAction;
 import org.jbpm.process.instance.impl.AssignmentProducer;
@@ -32,23 +33,37 @@ import org.mvel2.integration.impl.SimpleValueResolver;
 
 public class OutputExpressionAssignment implements AssignmentAction {
 
+    private static final Pattern IDENTIFIER = 
Pattern.compile("[A-Za-z_$][\\w$]*");
+
     private DataDefinition from;
     private Serializable toCompiled;
     private DataDefinition to;
+    // set only when the expression is a bare variable name, e.g. #{var}
+    private String targetVariable;
 
     public OutputExpressionAssignment(DataDefinition from, DataDefinition to) {
         this.from = from;
         this.to = to;
         Matcher matcher = 
PatternConstants.PARAMETER_MATCHER.matcher(this.to.getExpression());
         if (matcher.find()) {
-            toCompiled = MVELProcessHelper.compileExpression(matcher.group(1) 
+ " = _value");
+            String expression = matcher.group(1).trim();
+            if (IDENTIFIER.matcher(expression).matches()) {
+                targetVariable = expression;
+            }
+            toCompiled = MVELProcessHelper.compileExpression(expression + " = 
_value");
         }
     }
 
     @Override
     public void execute(Function<String, Object> sourceResolver, 
Function<String, Object> targetResolver, AssignmentProducer producer) throws 
Exception {
-        // producer in this case is void
-        Object value = 
MVELProcessHelper.evaluator().executeExpression(toCompiled, new 
ImmutableDefaultFactory() {
+        if (targetVariable != null) {
+            // assigning to a variable cannot be done through MVEL here, so 
hand it to the producer
+            producer.accept(targetVariable, 
sourceResolver.apply(from.getLabel()));
+            return;
+        }
+        // otherwise (e.g. #{account.person}) the MVEL expression writes the 
value into the target object itself;
+        // to.getId() is not a variable, so nothing is produced (it would leak 
an undeclared process variable)
+        MVELProcessHelper.evaluator().executeExpression(toCompiled, new 
ImmutableDefaultFactory() {
 
             @Override
             public boolean isResolveable(String name) {
@@ -65,7 +80,6 @@ public class OutputExpressionAssignment implements 
AssignmentAction {
             }
 
         });
-        producer.accept(to.getId(), value);
     }
 
 }
\ No newline at end of file
diff --git 
a/kogito-jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/impl/OutputExpressionAssignmentTest.java
 
b/kogito-jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/impl/OutputExpressionAssignmentTest.java
new file mode 100644
index 00000000000..1c8e7e4fc65
--- /dev/null
+++ 
b/kogito-jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/impl/OutputExpressionAssignmentTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.jbpm.workflow.core.impl;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class OutputExpressionAssignmentTest {
+
+    public static class Person {
+        private String name;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    // The output <to> carries a generated element id (e.g. 
FormalExpression_3) that is NOT a process variable.
+    private static final String TO_ID = "FormalExpression_3";
+
+    private Map<String, Object> run(String toExpression, Function<String, 
Object> sourceResolver, Function<String, Object> targetResolver) throws 
Exception {
+        DataDefinition from = new DataDefinition("DataOutput_1", "personOut", 
"java.lang.Object");
+        DataDefinition to = new DataDefinition(TO_ID, "EXPRESSION (" + 
toExpression + ")", (String) null, toExpression);
+        OutputExpressionAssignment assignment = new 
OutputExpressionAssignment(from, to);
+
+        Map<String, Object> produced = new LinkedHashMap<>();
+        assignment.execute(sourceResolver, targetResolver, produced::put);
+        return produced;
+    }
+
+    @Test
+    void bareVariable_isProducedUnderVariableName() throws Exception {
+        Map<String, Object> produced = run("#{y}", name -> 
"personOut".equals(name) ? "value" : null, name -> null);
+
+        assertThat(produced).containsOnly(Map.entry("y", "value"));
+    }
+
+    @Test
+    void bareVariable_withSurroundingWhitespace_isProducedUnderVariableName() 
throws Exception {
+        Map<String, Object> produced = run("#{ y }", name -> 
"personOut".equals(name) ? "value" : null, name -> null);
+
+        assertThat(produced).containsOnly(Map.entry("y", "value"));
+    }
+
+    @Test
+    void propertyPath_writesIntoTargetObjectAndProducesNothing() throws 
Exception {
+        Person person = new Person();
+
+        Map<String, Object> produced = run("#{person.name}",
+                name -> "personOut".equals(name) ? "john" : null,
+                name -> "person".equals(name) ? person : null);
+
+        assertThat(person.getName()).isEqualTo("john");
+        // must not leak the <to> element id (FormalExpression_N) as an 
undeclared process variable
+        assertThat(produced).isEmpty();
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to