From e9570f9a7127c771334ff641582ff294fe14a291 Mon Sep 17 00:00:00 2001
From: Abhiram Gundala <164050036+Abhitocode@users.noreply.github.com>
Date: Fri, 4 Oct 2024 09:40:18 -0400
Subject: [PATCH] dynamic variable

---
 .../bpmn2/xml/BusinessRuleTaskHandler.java    | 28 ++++++++++++++---
 .../codegen/rules/BusinessRuleTaskIT.java     | 31 +++++++++++++++++++
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BusinessRuleTaskHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BusinessRuleTaskHandler.java
index 6956bf551fc..1d69e68648a 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BusinessRuleTaskHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BusinessRuleTaskHandler.java
@@ -70,9 +70,21 @@ protected Node handleNode(final Node node, final Element element, final String u
                 }
             }
 
-            String namespace = parameters.get(NAMESPACE_PROP);
-            String model = parameters.get(MODEL_PROP);
-            String decision = parameters.get(DECISION_PROP);
+            String namespace = parameters.getOrDefault(NAMESPACE_PROP, "");
+            String model = parameters.getOrDefault(MODEL_PROP, "");//we have to actually get #{university}
+            //but we were not getting that. we were just getting null as label for this expression was empty
+            String decision = parameters.getOrDefault(DECISION_PROP, "");
+            String variableRegex = "#\\{[^}]+}";
+            if (namespace.matches(variableRegex)) {
+                namespace = resolveProcessVariable(namespace, parser, element);
+            }
+            if (model.matches(variableRegex)) {
+                model = resolveProcessVariable(model, parser, element);
+            }
+            if (decision.matches(variableRegex)) {
+                decision = resolveProcessVariable(decision, parser, element);
+            }
+
             ruleSetNode.setRuleType(RuleType.decision(
                     namespace,
                     model,
@@ -94,7 +106,6 @@ public void writeNode(Node node, StringBuilder xmlDump, int metaDataType) {
         RuleType ruleType = ruleSetNode.getRuleType();
         if (ruleType != null) {
             xmlDump.append("g:ruleFlowGroup=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(ruleType.getName()) + "\" " + EOL);
-            // else DMN
         }
 
         xmlDump.append(" implementation=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(ruleSetNode.getLanguage()) + "\" >" + EOL);
@@ -104,4 +115,13 @@ public void writeNode(Node node, StringBuilder xmlDump, int metaDataType) {
         endNode("businessRuleTask", xmlDump);
     }
 
+    private String resolveProcessVariable(String expression, Parser parser, Element element) {
+
+        String varName = expression.substring(expression.indexOf("#{") + 2, expression.indexOf("}"));
+
+        String variableValue = element.getAttribute(varName);//as we understand that the variable is university. But how to get the value since the variables are not in the attribute list?
+
+        return expression.replace("#{" + varName + "}", variableValue);
+    }
+
 }
diff --git a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/rules/BusinessRuleTaskIT.java b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/rules/BusinessRuleTaskIT.java
index 07aae3207c7..37b4b63cf0f 100644
--- a/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/rules/BusinessRuleTaskIT.java
+++ b/kogito-codegen-modules/kogito-codegen-processes-integration-tests/src/test/java/org/kie/kogito/codegen/rules/BusinessRuleTaskIT.java
@@ -208,6 +208,37 @@ public void testDecision() throws Exception {
         }
     }
 
+    @Test
+    public void testDynamicDecision() throws Exception {
+        Map<AbstractCodegenIT.TYPE, List<String>> resourcesTypeMap = new HashMap<>();
+        resourcesTypeMap.put(TYPE.PROCESS, Collections.singletonList("decision/dynamic/DynamicDmnProcess.bpmn2"));
+        resourcesTypeMap.put(TYPE.DECISION, Collections.singletonList("decision/dynamic/HarvardUniversity/HarvardUniversity.dmn"));
+        Application app = generateCode(resourcesTypeMap);
+        assertThat(app).isNotNull();
+        Process<? extends Model> p =
+                app.get(Processes.class)
+                        .processById("DynamicDmnProcess");
+
+        // first run 16, 1 and expected days is 27
+        {
+            Model m = p.createModel();
+            HashMap<String, Object> vars = new HashMap<>();
+            vars.put("marks", 43);
+            vars.put("university", "HarvardUniversity");
+            m.fromMap(vars);
+
+            ProcessInstance<? extends Model> processInstance = p.createInstance(m);
+            processInstance.start();
+
+            assertThat(processInstance.status()).isEqualTo(ProcessInstance.STATE_COMPLETED);
+            Model result = processInstance.variables();
+
+            assertThat(result.toMap().get("result"))
+                    .isNotNull()
+                    .isEqualTo("failed");
+        }
+    }
+
     @Test
     public void testBusinessRuleTaskWithIOExpression() throws Exception {
         Map<AbstractCodegenIT.TYPE, List<String>> resourcesTypeMap = new HashMap<>();