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

hansva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/master by this push:
     new 5927fed368 fixes to allow nested formulas on previously replaced 
fields, with integration test. #3239
     new 23ce8e2b92 Merge pull request #3273 from bamaer/3239
5927fed368 is described below

commit 5927fed36849b8128283987c23a4a4d03bb6a02c
Author: Bart Maertens <[email protected]>
AuthorDate: Thu Sep 28 20:36:30 2023 +0200

    fixes to allow nested formulas on previously replaced fields, with 
integration test. #3239
---
 .../transforms/0042-formula-nested-replace.hpl     | 175 +++++++++++++++++++++
 .../datasets/golden-formula-nested-replace.csv     |   2 +
 .../main-0042-formula-nested-replace.hwf           |  79 ++++++++++
 .../dataset/golden-formula-nested-replace.json     |  56 +++++++
 .../0042-formula-nested-replace UNIT.json          |  53 +++++++
 .../hop/pipeline/transforms/formula/Formula.java   | 147 +++++++++--------
 .../transforms/formula/util/FormulaParser.java     |  39 ++++-
 7 files changed, 476 insertions(+), 75 deletions(-)

diff --git a/integration-tests/transforms/0042-formula-nested-replace.hpl 
b/integration-tests/transforms/0042-formula-nested-replace.hpl
new file mode 100644
index 0000000000..c9078ae2bf
--- /dev/null
+++ b/integration-tests/transforms/0042-formula-nested-replace.hpl
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+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.
+
+-->
+<pipeline>
+  <info>
+    <name>0042-formula-nested-replace</name>
+    <name_sync_with_filename>Y</name_sync_with_filename>
+    <description/>
+    <extended_description/>
+    <pipeline_version/>
+    <pipeline_type>Normal</pipeline_type>
+    <parameters>
+    </parameters>
+    <capture_transform_performance>N</capture_transform_performance>
+    
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+    
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+    <created_user>-</created_user>
+    <created_date>2023/09/28 19:57:01.124</created_date>
+    <modified_user>-</modified_user>
+    <modified_date>2023/09/28 19:57:01.124</modified_date>
+  </info>
+  <notepads>
+  </notepads>
+  <order>
+    <hop>
+      <from>foo, bar</from>
+      <to>formula - nested replace</to>
+      <enabled>Y</enabled>
+    </hop>
+    <hop>
+      <from>formula - nested replace</from>
+      <to>verify</to>
+      <enabled>Y</enabled>
+    </hop>
+  </order>
+  <transform>
+    <name>foo, bar</name>
+    <type>DataGrid</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <data>
+      <line>
+        <item>foo</item>
+        <item>bar</item>
+        <item>42</item>
+      </line>
+    </data>
+    <fields>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>foo</name>
+        <type>String</type>
+      </field>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>bar</name>
+        <type>String</type>
+      </field>
+      <field>
+        <length>-1</length>
+        <precision>-1</precision>
+        <set_empty_string>N</set_empty_string>
+        <name>foo_numeric</name>
+        <type>Integer</type>
+      </field>
+    </fields>
+    <attributes/>
+    <GUI>
+      <xloc>112</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>formula - nested replace</name>
+    <type>Formula</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <formulas>
+      <formula>
+        <field_name>foobar</field_name>
+        <formula>[foo] &amp; [bar]</formula>
+        <replace_field>bar</replace_field>
+        <value_length>-1</value_length>
+        <value_precision>-1</value_precision>
+        <value_type>2</value_type>
+      </formula>
+      <formula>
+        <field_name>foo_numeric2</field_name>
+        <formula>24</formula>
+        <replace_field>foo_numeric</replace_field>
+        <value_length>-1</value_length>
+        <value_precision>-1</value_precision>
+        <value_type>5</value_type>
+      </formula>
+      <formula>
+        <field_name>foobar2</field_name>
+        <formula>if( [bar] = "foobar", "REPLACED", "NOT YET 
REPLACED")</formula>
+        <value_length>-1</value_length>
+        <value_precision>-1</value_precision>
+        <value_type>2</value_type>
+      </formula>
+      <formula>
+        <field_name>foobar3</field_name>
+        <formula>if( [foobar2] = "sdsdf", "WFWEF", [foobar])</formula>
+        <value_length>-1</value_length>
+        <value_precision>-1</value_precision>
+        <value_type>2</value_type>
+      </formula>
+      <formula>
+        <field_name>foobar4</field_name>
+        <formula>if( [foobar2] = "sdsdf", "WFWEF", [foo_numeric2])</formula>
+        <value_length>-1</value_length>
+        <value_precision>-1</value_precision>
+        <value_type>5</value_type>
+      </formula>
+    </formulas>
+    <attributes/>
+    <GUI>
+      <xloc>256</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform>
+    <name>verify</name>
+    <type>Dummy</type>
+    <description/>
+    <distribute>Y</distribute>
+    <custom_distribution/>
+    <copies>1</copies>
+    <partitioning>
+      <method>none</method>
+      <schema_name/>
+    </partitioning>
+    <attributes/>
+    <GUI>
+      <xloc>400</xloc>
+      <yloc>144</yloc>
+    </GUI>
+  </transform>
+  <transform_error_handling>
+  </transform_error_handling>
+  <attributes/>
+</pipeline>
diff --git 
a/integration-tests/transforms/datasets/golden-formula-nested-replace.csv 
b/integration-tests/transforms/datasets/golden-formula-nested-replace.csv
new file mode 100644
index 0000000000..aad374c667
--- /dev/null
+++ b/integration-tests/transforms/datasets/golden-formula-nested-replace.csv
@@ -0,0 +1,2 @@
+foo,bar,foo_numeric,foobar2,foobar3,foobar4
+foo,foobar,24,REPLACED,foobar,24
diff --git a/integration-tests/transforms/main-0042-formula-nested-replace.hwf 
b/integration-tests/transforms/main-0042-formula-nested-replace.hwf
new file mode 100644
index 0000000000..e19b56a52d
--- /dev/null
+++ b/integration-tests/transforms/main-0042-formula-nested-replace.hwf
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+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.
+
+-->
+<workflow>
+  <name>main-0042-formula-nested-replace</name>
+  <name_sync_with_filename>Y</name_sync_with_filename>
+  <description/>
+  <extended_description/>
+  <workflow_version/>
+  <created_user>-</created_user>
+  <created_date>2022/04/29 10:44:00.266</created_date>
+  <modified_user>-</modified_user>
+  <modified_date>2022/04/29 10:44:00.266</modified_date>
+  <parameters>
+    </parameters>
+  <actions>
+    <action>
+      <name>Start</name>
+      <description/>
+      <type>SPECIAL</type>
+      <attributes/>
+      <DayOfMonth>1</DayOfMonth>
+      <hour>12</hour>
+      <intervalMinutes>60</intervalMinutes>
+      <intervalSeconds>0</intervalSeconds>
+      <minutes>0</minutes>
+      <repeat>N</repeat>
+      <schedulerType>0</schedulerType>
+      <weekDay>1</weekDay>
+      <parallel>N</parallel>
+      <xloc>50</xloc>
+      <yloc>50</yloc>
+      <attributes_hac/>
+    </action>
+    <action>
+      <name>Run Formula Nested Replace Unit Tests</name>
+      <description/>
+      <type>RunPipelineTests</type>
+      <attributes/>
+      <test_names>
+        <test_name>
+          <name>0042-formula-nested-replace UNIT</name>
+        </test_name>
+      </test_names>
+      <parallel>N</parallel>
+      <xloc>192</xloc>
+      <yloc>48</yloc>
+      <attributes_hac/>
+    </action>
+  </actions>
+  <hops>
+    <hop>
+      <from>Start</from>
+      <to>Run Formula Nested Replace Unit Tests</to>
+      <enabled>Y</enabled>
+      <evaluation>Y</evaluation>
+      <unconditional>Y</unconditional>
+    </hop>
+  </hops>
+  <notepads>
+  </notepads>
+  <attributes/>
+</workflow>
diff --git 
a/integration-tests/transforms/metadata/dataset/golden-formula-nested-replace.json
 
b/integration-tests/transforms/metadata/dataset/golden-formula-nested-replace.json
new file mode 100644
index 0000000000..70e6c9aedc
--- /dev/null
+++ 
b/integration-tests/transforms/metadata/dataset/golden-formula-nested-replace.json
@@ -0,0 +1,56 @@
+{
+  "base_filename": "golden-formula-nested-replace.csv",
+  "name": "golden-formula-nested-replace",
+  "description": "",
+  "dataset_fields": [
+    {
+      "field_comment": "",
+      "field_length": -1,
+      "field_type": 2,
+      "field_precision": -1,
+      "field_name": "foo",
+      "field_format": ""
+    },
+    {
+      "field_comment": "",
+      "field_length": -1,
+      "field_type": 2,
+      "field_precision": -1,
+      "field_name": "bar",
+      "field_format": ""
+    },
+    {
+      "field_comment": "",
+      "field_length": -1,
+      "field_type": 5,
+      "field_precision": 0,
+      "field_name": "foo_numeric",
+      "field_format": "####0;-####0"
+    },
+    {
+      "field_comment": "",
+      "field_length": -1,
+      "field_type": 2,
+      "field_precision": -1,
+      "field_name": "foobar2",
+      "field_format": ""
+    },
+    {
+      "field_comment": "",
+      "field_length": -1,
+      "field_type": 2,
+      "field_precision": -1,
+      "field_name": "foobar3",
+      "field_format": ""
+    },
+    {
+      "field_comment": "",
+      "field_length": -1,
+      "field_type": 5,
+      "field_precision": 0,
+      "field_name": "foobar4",
+      "field_format": "####0;-####0"
+    }
+  ],
+  "folder_name": ""
+}
\ No newline at end of file
diff --git 
a/integration-tests/transforms/metadata/unit-test/0042-formula-nested-replace 
UNIT.json 
b/integration-tests/transforms/metadata/unit-test/0042-formula-nested-replace 
UNIT.json
new file mode 100644
index 0000000000..605ea98c48
--- /dev/null
+++ 
b/integration-tests/transforms/metadata/unit-test/0042-formula-nested-replace 
UNIT.json     
@@ -0,0 +1,53 @@
+{
+  "variableValues": [],
+  "database_replacements": [],
+  "autoOpening": true,
+  "basePath": "",
+  "golden_data_sets": [
+    {
+      "field_mappings": [
+        {
+          "transform_field": "foo",
+          "data_set_field": "foo"
+        },
+        {
+          "transform_field": "bar",
+          "data_set_field": "bar"
+        },
+        {
+          "transform_field": "foo_numeric",
+          "data_set_field": "foo_numeric"
+        },
+        {
+          "transform_field": "foobar2",
+          "data_set_field": "foobar2"
+        },
+        {
+          "transform_field": "foobar3",
+          "data_set_field": "foobar3"
+        },
+        {
+          "transform_field": "foobar4",
+          "data_set_field": "foobar4"
+        }
+      ],
+      "field_order": [
+        "foo",
+        "bar",
+        "foo_numeric",
+        "foobar2",
+        "foobar3",
+        "foobar4"
+      ],
+      "data_set_name": "golden-formula-nested-replace",
+      "transform_name": "verify"
+    }
+  ],
+  "input_data_sets": [],
+  "name": "0042-formula-nested-replace UNIT",
+  "description": "",
+  "persist_filename": "",
+  "trans_test_tweaks": [],
+  "pipeline_filename": "./0042-formula-nested-replace.hpl",
+  "test_type": "UNIT_TEST"
+}
\ No newline at end of file
diff --git 
a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/Formula.java
 
b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/Formula.java
index 285cfd5665..067942b26d 100644
--- 
a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/Formula.java
+++ 
b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/Formula.java
@@ -19,6 +19,7 @@ package org.apache.hop.pipeline.transforms.formula;
 
 import java.sql.Timestamp;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.exception.HopTransformException;
 import org.apache.hop.core.row.IValueMeta;
 import org.apache.hop.core.row.RowDataUtil;
 import org.apache.hop.core.row.value.ValueMetaFactory;
@@ -37,12 +38,14 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.HashMap;
 
 public class Formula extends BaseTransform<FormulaMeta, FormulaData> {
 
   private XSSFWorkbook workBook;
   private XSSFSheet workSheet;
   private Row sheetRow;
+  private HashMap<String, String> replaceMap;
 
   @Override
   public boolean init() {
@@ -50,11 +53,7 @@ public class Formula extends BaseTransform<FormulaMeta, 
FormulaData> {
     workBook = new XSSFWorkbook();
     workSheet = workBook.createSheet();
     sheetRow = workSheet.createRow(0);
-
-    data.returnType = new int[meta.getFormulas().size()];
-    for (int i = 0; i < meta.getFormulas().size(); i++) {
-      data.returnType[i] = -1;
-    }
+    replaceMap = new HashMap<String, String>();
 
     return true;
   }
@@ -78,10 +77,20 @@ public class Formula extends BaseTransform<FormulaMeta, 
FormulaData> {
       return false;
     }
 
-
     if (first) {
       first = false;
-      data.outputRowMeta = getInputRowMeta().clone();
+
+      try {
+        data.outputRowMeta = getInputRowMeta().clone();
+        meta.getFields(data.outputRowMeta, getTransformName(), null, null, 
this, metadataProvider);
+      } catch (HopTransformException e) {
+        throw new RuntimeException(e);
+      }
+
+      data.returnType = new int[meta.getFormulas().size()];
+      for (int i = 0; i < meta.getFormulas().size(); i++) {
+        data.returnType[i] = -1;
+      }
 
       // Calculate replace indexes...
       //
@@ -90,6 +99,9 @@ public class Formula extends BaseTransform<FormulaMeta, 
FormulaData> {
         FormulaMetaFunction fn = meta.getFormulas().get(j);
         if (!Utils.isEmpty(fn.getReplaceField())) {
           data.replaceIndex[j] = 
data.outputRowMeta.indexOfValue(fn.getReplaceField());
+
+          // keep track of the formula fields and the fields they replace for 
formula parsing later on.
+          replaceMap.put(fn.getFieldName(), fn.getReplaceField());
           if (data.replaceIndex[j] < 0) {
             throw new HopException(
                     "Unknown field specified to replace with a formula result: 
["
@@ -101,7 +113,7 @@ public class Formula extends BaseTransform<FormulaMeta, 
FormulaData> {
         }
       }
     }
-    meta.getFields(data.outputRowMeta, getTransformName(), null, null, this, 
metadataProvider);
+
     int tempIndex = getInputRowMeta().size();
 
 
@@ -114,73 +126,72 @@ public class Formula extends BaseTransform<FormulaMeta, 
FormulaData> {
     }
     sheetRow = workSheet.createRow(0);
 
-    Object outputValue = null;
     Object[] outputRowData = RowDataUtil.resizeArray(r, 
data.outputRowMeta.size());
+    Object outputValue = null;
 
     for (int i = 0; i < meta.getFormulas().size(); i++) {
 
       FormulaMetaFunction formula = meta.getFormulas().get(i);
-      FormulaParser parser = new FormulaParser(formula, data.outputRowMeta, r, 
sheetRow, variables);
-      CellValue cellValue = parser.getFormulaValue();
-
-      CellType cellType = cellValue.getCellType();
-
-      switch (cellType) {
-        case BLANK:
-          // should never happen.
-          break;
-        case NUMERIC:
-          outputValue = cellValue.getNumberValue();
-          int outputValueType = formula.getValueType();
-
-          switch (outputValueType) {
-            case IValueMeta.TYPE_NUMBER:
-              data.returnType[i] = FormulaData.RETURN_TYPE_NUMBER;
-              formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_NUMBER);
-              break;
-            case IValueMeta.TYPE_INTEGER:
-              data.returnType[i] = FormulaData.RETURN_TYPE_INTEGER;
-              formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_NUMBER);
-              break;
-            case IValueMeta.TYPE_BIGNUMBER:
-              data.returnType[i] = FormulaData.RETURN_TYPE_BIGDECIMAL;
-              formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_NUMBER);
-              break;
-            case IValueMeta.TYPE_DATE:
-              outputValue = DateUtil.getJavaDate(cellValue.getNumberValue());
-              data.returnType[i] = FormulaData.RETURN_TYPE_DATE;
-              formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_NUMBER);
-              break;
-            case IValueMeta.TYPE_TIMESTAMP:
-              outputValue = 
Timestamp.from(DateUtil.getJavaDate(cellValue.getNumberValue()).toInstant());
-              data.returnType[i] = FormulaData.RETURN_TYPE_TIMESTAMP;
-              formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_NUMBER);
-              break;
-            default:
-              break;
-          }
-          // get cell value
-          break;
-        case BOOLEAN:
-          outputValue = cellValue.getBooleanValue();
-          data.returnType[i] = FormulaData.RETURN_TYPE_BOOLEAN;
-          formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_BOOLEAN);
-          break;
-        case STRING:
-          outputValue = cellValue.getStringValue();
-          data.returnType[i] = FormulaData.RETURN_TYPE_STRING;
-          formula.setNeedDataConversion(formula.getValueType() != 
IValueMeta.TYPE_STRING);
-          break;
-        default:
-          break;
-      }
-
-      int realIndex = (data.replaceIndex[i] < 0) ? tempIndex++ : 
data.replaceIndex[i];
-
+      FormulaParser parser = new FormulaParser(formula, data.outputRowMeta, 
outputRowData, sheetRow, variables, replaceMap);
+      try {
+        CellValue cellValue = parser.getFormulaValue();
+        CellType cellType = cellValue.getCellType();
+
+        int outputValueType = formula.getValueType();
+        switch (cellType) {
+          case BLANK:
+            // should never happen.
+            break;
+          case NUMERIC:
+            outputValue = cellValue.getNumberValue();
+            switch (outputValueType) {
+              case IValueMeta.TYPE_NUMBER:
+                data.returnType[i] = FormulaData.RETURN_TYPE_NUMBER;
+                formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_NUMBER);
+                break;
+              case IValueMeta.TYPE_INTEGER:
+                data.returnType[i] = FormulaData.RETURN_TYPE_INTEGER;
+                formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_NUMBER);
+                break;
+              case IValueMeta.TYPE_BIGNUMBER:
+                data.returnType[i] = FormulaData.RETURN_TYPE_BIGDECIMAL;
+                formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_NUMBER);
+                break;
+              case IValueMeta.TYPE_DATE:
+                outputValue = DateUtil.getJavaDate(cellValue.getNumberValue());
+                data.returnType[i] = FormulaData.RETURN_TYPE_DATE;
+                formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_NUMBER);
+                break;
+              case IValueMeta.TYPE_TIMESTAMP:
+                outputValue = 
Timestamp.from(DateUtil.getJavaDate(cellValue.getNumberValue()).toInstant());
+                data.returnType[i] = FormulaData.RETURN_TYPE_TIMESTAMP;
+                formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_NUMBER);
+                break;
+              default:
+                break;
+            }
+            // get cell value
+            break;
+          case BOOLEAN:
+            outputValue = cellValue.getBooleanValue();
+            data.returnType[i] = FormulaData.RETURN_TYPE_BOOLEAN;
+            formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_BOOLEAN);
+            break;
+          case STRING:
+            outputValue = cellValue.getStringValue();
+            data.returnType[i] = FormulaData.RETURN_TYPE_STRING;
+            formula.setNeedDataConversion(outputValueType != 
IValueMeta.TYPE_STRING);
+            break;
+          default:
+            break;
+        }
 
+        int realIndex = (data.replaceIndex[i] < 0) ? tempIndex++ : 
data.replaceIndex[i];
 
-      outputRowData[realIndex] =
-          getReturnValue(outputValue, data.returnType[i], realIndex, formula);
+        outputRowData[realIndex] = getReturnValue(outputValue, 
data.returnType[i], realIndex, formula);
+      }catch(Exception e){
+        throw new HopException("Formula '" + formula.getFormula() + "' could 
not not be parsed ", e);
+      }
     }
 
     putRow(data.outputRowMeta, outputRowData);
diff --git 
a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/util/FormulaParser.java
 
b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/util/FormulaParser.java
index 871c64f66c..b660c9c659 100644
--- 
a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/util/FormulaParser.java
+++ 
b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/util/FormulaParser.java
@@ -26,13 +26,12 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellValue;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
-import org.apache.poi.ss.usermodel.RichTextString;
 import org.apache.poi.ss.usermodel.Row;
 
-import java.sql.Timestamp;
 import java.util.ArrayList;
-import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -46,24 +45,46 @@ public class FormulaParser {
   private Object[] dataRow;
   private Row sheetRow;
   private FormulaEvaluator evaluator;
+  private HashMap<String, String> replaceMap;
 
   public FormulaParser(
-      FormulaMetaFunction formulaMetaFunction, IRowMeta rowMeta, Object[] 
dataRow, Row sheetRow, IVariables variables) {
+      FormulaMetaFunction formulaMetaFunction, IRowMeta rowMeta, Object[] 
dataRow, Row sheetRow, IVariables variables, HashMap<String, String> 
replaceMap) {
     this.formulaMetaFunction = formulaMetaFunction;
     this.rowMeta = rowMeta;
     this.dataRow = dataRow;
     this.sheetRow = sheetRow;
     fieldNames = rowMeta.getFieldNames();
+    this.replaceMap = replaceMap;
     formula = variables.resolve(formulaMetaFunction.getFormula());
     evaluator = 
sheetRow.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
 
-    formulaFieldList = new ArrayList<>();
+    formulaFieldList = getFormulaFieldList(formula);
+
+    boolean getNewList = false;
+    for(String formulaField : formulaFieldList){
+      // check if we are working with a field that was replaced earlier.
+      Set<String> replaceKeys = replaceMap.keySet();
+      if(replaceKeys.contains(formulaField)){
+        String realFieldName = replaceMap.get(formulaField);
+        formula = formula.replaceAll("\\[" + formulaField + "\\]", "\\[" + 
realFieldName + "\\]");
+        getNewList = true;
+      }
+    }
+
+    if(getNewList){
+      formulaFieldList = getFormulaFieldList(formula);
+    }
+  }
+
+  private List<String> getFormulaFieldList(String formula){
+    List<String> theFields = new ArrayList<>();
     Pattern regex = Pattern.compile("\\[(.*?)\\]");
     Matcher regexMatcher = regex.matcher(formula);
 
     while (regexMatcher.find()) {
-      formulaFieldList.add(regexMatcher.group(1));
+      theFields.add(regexMatcher.group(1));
     }
+    return theFields;
   }
 
   public CellValue getFormulaValue() throws HopValueException {
@@ -73,8 +94,11 @@ public class FormulaParser {
     for (String formulaField : formulaFieldList) {
       char s = (char) fieldIndex;
       Cell cell = sheetRow.createCell(colIndex);
+
       int fieldPosition = rowMeta.indexOfValue(formulaField);
 
+      parsedFormula = parsedFormula.replaceAll("\\[" + formulaField + "\\]", s 
+ "1");
+
       IValueMeta fieldMeta = rowMeta.getValueMeta(fieldPosition);
       if (dataRow[fieldPosition] != null) {
         if (fieldMeta.isBoolean()) {
@@ -92,9 +116,10 @@ public class FormulaParser {
         } else {
           cell.setCellValue(rowMeta.getString(dataRow, fieldPosition));
         }
+      }else{
+        cell.setBlank();
       }
 
-      parsedFormula = parsedFormula.replaceAll("\\[" + formulaField + "\\]", s 
+ "1");
       fieldIndex++;
       colIndex++;
     }

Reply via email to