This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new d7c5170bc0 issue #1872 (UDJE XML cleanup, MDI integration test) (#6796)
d7c5170bc0 is described below
commit d7c5170bc0d104bff9a5b0c856f05b198aa7d732
Author: Matt Casters <[email protected]>
AuthorDate: Tue Mar 17 09:27:53 2026 +0100
issue #1872 (UDJE XML cleanup, MDI integration test) (#6796)
---
.../0042-user-defined-java-expression-template.hpl | 62 +++++
.../0042-user-defined-java-expression-validate.hpl | 210 ++++++++++++++++
.../mdi/0042-user-defined-java-expression.hpl | 264 +++++++++++++++++++++
.../golden-user-defined-java-expression.csv | 4 +
integration-tests/mdi/files/janino.xml | 43 ++++
.../mdi/main-0042-user-defined-java-expression.hwf | 58 +++++
.../golden-user-defined-java-expression.json | 56 +++++
...user-defined-java-expression-validate UNIT.json | 48 ++++
.../hop/pipeline/transforms/janino/Janino.java | 43 ++--
.../pipeline/transforms/janino/JaninoDialog.java | 51 ++--
.../hop/pipeline/transforms/janino/JaninoMeta.java | 90 ++-----
.../transforms/janino/JaninoMetaFunction.java | 194 ++++-----------
.../pipeline/transforms/janino/JaninoMetaTest.java | 131 +++++-----
.../janino/src/test/resources/janino.xml | 43 ++++
14 files changed, 965 insertions(+), 332 deletions(-)
diff --git
a/integration-tests/mdi/0042-user-defined-java-expression-template.hpl
b/integration-tests/mdi/0042-user-defined-java-expression-template.hpl
new file mode 100644
index 0000000000..e143089752
--- /dev/null
+++ b/integration-tests/mdi/0042-user-defined-java-expression-template.hpl
@@ -0,0 +1,62 @@
+<?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-user-defined-java-expression-template</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>2026/03/16 17:49:10.301</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2026/03/16 17:49:10.301</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ </order>
+ <transform>
+ <name>User defined Java expression</name>
+ <type>Janino</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ <GUI>
+ <xloc>160</xloc>
+ <yloc>80</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git
a/integration-tests/mdi/0042-user-defined-java-expression-validate.hpl
b/integration-tests/mdi/0042-user-defined-java-expression-validate.hpl
new file mode 100644
index 0000000000..68d1aeeed9
--- /dev/null
+++ b/integration-tests/mdi/0042-user-defined-java-expression-validate.hpl
@@ -0,0 +1,210 @@
+<?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-user-defined-java-expression-validate</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>2026/03/16 17:52:25.666</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2026/03/16 17:52:25.666</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ <hop>
+ <from>/tmp/janino.hpl</from>
+ <to>Validate</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <transform>
+ <name>/tmp/janino.hpl</name>
+ <type>getXMLData</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <IsAFile>N</IsAFile>
+ <IsIgnoreEmptyFile>N</IsIgnoreEmptyFile>
+ <IsInFields>N</IsInFields>
+ <XmlField/>
+ <addresultfile>N</addresultfile>
+ <doNotFailIfNoFile>Y</doNotFailIfNoFile>
+ <encoding>UTF-8</encoding>
+ <extensionFieldName/>
+ <fields>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>field_name</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>field_name</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>formula_string</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>formula_string</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>value_type</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>value_type</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>value_length</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>Integer</type>
+ <xPath>value_length</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>value_precision</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>Integer</type>
+ <xPath>value_precision</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>replace_field</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>replace_field</xPath>
+ </field>
+ </fields>
+ <file>
+ <exclude_filemask/>
+ <file_required>N</file_required>
+ <filemask/>
+ <include_subfolders>N</include_subfolders>
+ <name>${java.io.tmpdir}/janino.hpl</name>
+ </file>
+ <hiddenFieldName/>
+ <ignorecomments>N</ignorecomments>
+ <include>N</include>
+ <include_field/>
+ <lastModificationTimeFieldName/>
+ <limit>0</limit>
+ <loopxpath>/pipeline/transform/formula</loopxpath>
+ <namespaceaware>N</namespaceaware>
+ <pathFieldName/>
+ <prunePath/>
+ <readurl>N</readurl>
+ <rootUriNameFieldName/>
+ <rownum>N</rownum>
+ <rownum_field/>
+ <shortFileFieldName/>
+ <sizeFieldName/>
+ <uriNameFieldName/>
+ <usetoken>N</usetoken>
+ <validating>N</validating>
+ <attributes/>
+ <GUI>
+ <xloc>112</xloc>
+ <yloc>112</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Validate</name>
+ <type>Dummy</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ <GUI>
+ <xloc>288</xloc>
+ <yloc>112</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git a/integration-tests/mdi/0042-user-defined-java-expression.hpl
b/integration-tests/mdi/0042-user-defined-java-expression.hpl
new file mode 100644
index 0000000000..825d26273b
--- /dev/null
+++ b/integration-tests/mdi/0042-user-defined-java-expression.hpl
@@ -0,0 +1,264 @@
+<?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-user-defined-java-expression</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>2026/03/16 17:49:35.033</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2026/03/16 17:49:35.033</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ <hop>
+ <from>files/janino.xml fields</from>
+ <to>0042-user-defined-java-expression-template.hpl</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <transform>
+ <name>files/janino.xml fields</name>
+ <type>getXMLData</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <IsAFile>N</IsAFile>
+ <IsIgnoreEmptyFile>N</IsIgnoreEmptyFile>
+ <IsInFields>N</IsInFields>
+ <XmlField/>
+ <addresultfile>N</addresultfile>
+ <doNotFailIfNoFile>Y</doNotFailIfNoFile>
+ <encoding>UTF-8</encoding>
+ <extensionFieldName/>
+ <fields>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>field_name</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>field_name</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>formula_string</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>formula_string</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>value_type</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>value_type</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>value_length</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>Integer</type>
+ <xPath>value_length</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>value_precision</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>Integer</type>
+ <xPath>value_precision</xPath>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <element_type>Node</element_type>
+ <format/>
+ <group/>
+ <length>-1</length>
+ <name>replace_field</name>
+ <precision>-1</precision>
+ <repeat>N</repeat>
+ <result_type>valueof</result_type>
+ <trim_type>none</trim_type>
+ <type>String</type>
+ <xPath>replace_field</xPath>
+ </field>
+ </fields>
+ <file>
+ <exclude_filemask/>
+ <file_required>N</file_required>
+ <filemask/>
+ <include_subfolders>N</include_subfolders>
+ <name>${PROJECT_HOME}/files/janino.xml</name>
+ </file>
+ <hiddenFieldName/>
+ <ignorecomments>N</ignorecomments>
+ <include>N</include>
+ <include_field/>
+ <lastModificationTimeFieldName/>
+ <limit>0</limit>
+ <loopxpath>/transform/formula</loopxpath>
+ <namespaceaware>N</namespaceaware>
+ <pathFieldName/>
+ <prunePath/>
+ <readurl>N</readurl>
+ <rootUriNameFieldName/>
+ <rownum>N</rownum>
+ <rownum_field/>
+ <shortFileFieldName/>
+ <sizeFieldName/>
+ <uriNameFieldName/>
+ <usetoken>N</usetoken>
+ <validating>N</validating>
+ <attributes/>
+ <GUI>
+ <xloc>112</xloc>
+ <yloc>64</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>0042-user-defined-java-expression-template.hpl</name>
+ <type>MetaInject</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+
<filename>${PROJECT_HOME}/0042-user-defined-java-expression-template.hpl</filename>
+ <run_configuration>local</run_configuration>
+ <source_transform/>
+ <source_output_fields> </source_output_fields>
+ <target_file>${java.io.tmpdir}/janino.hpl</target_file>
+ <create_parent_folder>Y</create_parent_folder>
+ <no_execution>Y</no_execution>
+ <allow_empty_stream_on_execution>N</allow_empty_stream_on_execution>
+ <stream_source_transform/>
+ <stream_target_transform/>
+ <mappings>
+ <mapping>
+ <target_transform_name>User defined Java
expression</target_transform_name>
+ <target_attribute_key>REPLACE_FIELD</target_attribute_key>
+ <target_detail>Y</target_detail>
+ <source_transform>files/janino.xml fields</source_transform>
+ <source_field>replace_field</source_field>
+ </mapping>
+ <mapping>
+ <target_transform_name>User defined Java
expression</target_transform_name>
+ <target_attribute_key>FIELD_NAME</target_attribute_key>
+ <target_detail>Y</target_detail>
+ <source_transform>files/janino.xml fields</source_transform>
+ <source_field>field_name</source_field>
+ </mapping>
+ <mapping>
+ <target_transform_name>User defined Java
expression</target_transform_name>
+ <target_attribute_key>VALUE_LENGTH</target_attribute_key>
+ <target_detail>Y</target_detail>
+ <source_transform>files/janino.xml fields</source_transform>
+ <source_field>value_length</source_field>
+ </mapping>
+ <mapping>
+ <target_transform_name>User defined Java
expression</target_transform_name>
+ <target_attribute_key>VALUE_PRECISION</target_attribute_key>
+ <target_detail>Y</target_detail>
+ <source_transform>files/janino.xml fields</source_transform>
+ <source_field>value_precision</source_field>
+ </mapping>
+ <mapping>
+ <target_transform_name>User defined Java
expression</target_transform_name>
+ <target_attribute_key>VALUE_TYPE</target_attribute_key>
+ <target_detail>Y</target_detail>
+ <source_transform>files/janino.xml fields</source_transform>
+ <source_field>value_type</source_field>
+ </mapping>
+ <mapping>
+ <target_transform_name>User defined Java
expression</target_transform_name>
+ <target_attribute_key>FIELD_FORMULA</target_attribute_key>
+ <target_detail>Y</target_detail>
+ <source_transform>files/janino.xml fields</source_transform>
+ <source_field>formula_string</source_field>
+ </mapping>
+ </mappings>
+ <attributes/>
+ <GUI>
+ <xloc>320</xloc>
+ <yloc>64</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git
a/integration-tests/mdi/datasets/golden-user-defined-java-expression.csv
b/integration-tests/mdi/datasets/golden-user-defined-java-expression.csv
new file mode 100644
index 0000000000..f900d15c47
--- /dev/null
+++ b/integration-tests/mdi/datasets/golden-user-defined-java-expression.csv
@@ -0,0 +1,4 @@
+field_name,formula_string,value_type,value_length,value_precision,replace_field
+f1,expression1,String,100,-1,replace1
+f2,expression2,Integer,7,-1,replace2
+f3,expression3,Number,9,2,replace3
diff --git a/integration-tests/mdi/files/janino.xml
b/integration-tests/mdi/files/janino.xml
new file mode 100644
index 0000000000..6abc2f9d84
--- /dev/null
+++ b/integration-tests/mdi/files/janino.xml
@@ -0,0 +1,43 @@
+<?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.
+ -->
+<transform>
+ <formula>
+ <field_name>f1</field_name>
+ <formula_string>expression1</formula_string>
+ <value_type>String</value_type>
+ <value_length>100</value_length>
+ <value_precision>-1</value_precision>
+ <replace_field>replace1</replace_field>
+ </formula>
+ <formula>
+ <field_name>f2</field_name>
+ <formula_string>expression2</formula_string>
+ <value_type>Integer</value_type>
+ <value_length>7</value_length>
+ <value_precision>-1</value_precision>
+ <replace_field>replace2</replace_field>
+ </formula>
+ <formula>
+ <field_name>f3<Get rows from result XML cleanup/field_name>
+ <formula_string>expression3</formula_string>
+ <value_type>Number</value_type>
+ <value_length>9</value_length>
+ <value_precision>2</value_precision>
+ <replace_field>replace3</replace_field>
+ </formula>
+</transform>
diff --git a/integration-tests/mdi/main-0042-user-defined-java-expression.hwf
b/integration-tests/mdi/main-0042-user-defined-java-expression.hwf
new file mode 100644
index 0000000000..bbd6b91986
--- /dev/null
+++ b/integration-tests/mdi/main-0042-user-defined-java-expression.hwf
@@ -0,0 +1,58 @@
+<?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-user-defined-java-expression</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <workflow_version/>
+ <created_user>-</created_user>
+ <created_date>2026/03/16 17:48:47.066</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2026/03/16 17:48:47.066</modified_date>
+ <parameters>
+ </parameters>
+ <actions>
+ <action>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <DayOfMonth>1</DayOfMonth>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <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>80</xloc>
+ <yloc>64</yloc>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ </hops>
+ <notepads>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git
a/integration-tests/mdi/metadata/dataset/golden-user-defined-java-expression.json
b/integration-tests/mdi/metadata/dataset/golden-user-defined-java-expression.json
new file mode 100644
index 0000000000..2a93f28c5b
--- /dev/null
+++
b/integration-tests/mdi/metadata/dataset/golden-user-defined-java-expression.json
@@ -0,0 +1,56 @@
+{
+ "base_filename": "golden-user-defined-java-expression.csv",
+ "name": "golden-user-defined-java-expression",
+ "description": "",
+ "dataset_fields": [
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "field_name",
+ "field_format": ""
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "formula_string",
+ "field_format": ""
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "value_type",
+ "field_format": ""
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": 0,
+ "field_name": "value_length",
+ "field_format": "####0;-####0"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": 0,
+ "field_name": "value_precision",
+ "field_format": "####0;-####0"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "replace_field",
+ "field_format": ""
+ }
+ ],
+ "folder_name": ""
+}
\ No newline at end of file
diff --git
a/integration-tests/mdi/metadata/unit-test/0042-user-defined-java-expression-validate
UNIT.json
b/integration-tests/mdi/metadata/unit-test/0042-user-defined-java-expression-validate
UNIT.json
new file mode 100644
index 0000000000..c3d9d3ab04
--- /dev/null
+++
b/integration-tests/mdi/metadata/unit-test/0042-user-defined-java-expression-validate
UNIT.json
@@ -0,0 +1,48 @@
+{
+ "database_replacements": [],
+ "autoOpening": true,
+ "description": "",
+ "persist_filename": "",
+ "test_type": "UNIT_TEST",
+ "variableValues": [],
+ "basePath": "${HOP_UNIT_TESTS_FOLDER}",
+ "golden_data_sets": [
+ {
+ "field_mappings": [
+ {
+ "transform_field": "field_name",
+ "data_set_field": "field_name"
+ },
+ {
+ "transform_field": "formula_string",
+ "data_set_field": "formula_string"
+ },
+ {
+ "transform_field": "value_type",
+ "data_set_field": "value_type"
+ },
+ {
+ "transform_field": "value_length",
+ "data_set_field": "value_length"
+ },
+ {
+ "transform_field": "value_precision",
+ "data_set_field": "value_precision"
+ },
+ {
+ "transform_field": "replace_field",
+ "data_set_field": "replace_field"
+ }
+ ],
+ "field_order": [
+ "field_name"
+ ],
+ "data_set_name": "golden-user-defined-java-expression",
+ "transform_name": "Validate"
+ }
+ ],
+ "input_data_sets": [],
+ "name": "0042-user-defined-java-expression-validate UNIT",
+ "trans_test_tweaks": [],
+ "pipeline_filename": "./0042-user-defined-java-expression-validate.hpl"
+}
\ No newline at end of file
diff --git
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/Janino.java
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/Janino.java
index 38c607de35..00bff1e971 100644
---
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/Janino.java
+++
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/Janino.java
@@ -72,17 +72,17 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
// Calculate replace indexes...
//
- data.replaceIndex = new int[meta.getFormula().length];
- data.returnType = new IValueMeta[meta.getFormula().length];
- for (int i = 0; i < meta.getFormula().length; i++) {
- JaninoMetaFunction fn = meta.getFormula()[i];
- data.returnType[i] =
ValueMetaFactory.createValueMeta(fn.getValueType());
- if (!Utils.isEmpty(fn.getReplaceField())) {
- data.replaceIndex[i] =
getInputRowMeta().indexOfValue(fn.getReplaceField());
+ data.replaceIndex = new int[meta.getFunctions().size()];
+ data.returnType = new IValueMeta[meta.getFunctions().size()];
+ for (int i = 0; i < meta.getFunctions().size(); i++) {
+ JaninoMetaFunction function = meta.getFunctions().get(i);
+ data.returnType[i] =
ValueMetaFactory.createValueMeta(function.getValueType());
+ if (!Utils.isEmpty(function.getReplaceField())) {
+ data.replaceIndex[i] =
getInputRowMeta().indexOfValue(function.getReplaceField());
if (data.replaceIndex[i] < 0) {
throw new HopException(
"Unknown field specified to replace with a formula result: ["
- + fn.getReplaceField()
+ + function.getReplaceField()
+ "]");
}
} else {
@@ -128,15 +128,15 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
// Initialize evaluators etc. Only do it once.
//
if (data.expressionEvaluators == null) {
- data.expressionEvaluators = new
ExpressionEvaluator[meta.getFormula().length];
+ data.expressionEvaluators = new
ExpressionEvaluator[meta.getFunctions().size()];
data.argumentIndexes = new ArrayList<>();
- for (int i = 0; i < meta.getFormula().length; i++) {
+ for (int i = 0; i < meta.getFunctions().size(); i++) {
List<Integer> argIndexes = new ArrayList<>();
data.argumentIndexes.add(argIndexes);
}
- for (int m = 0; m < meta.getFormula().length; m++) {
+ for (int m = 0; m < meta.getFunctions().size(); m++) {
List<Integer> argIndexes = data.argumentIndexes.get(m);
List<String> parameterNames = new ArrayList<>();
List<Class<?>> parameterTypes = new ArrayList<>();
@@ -147,7 +147,7 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
// See if the value is being used in a formula...
//
- if
(meta.getFormula()[m].getFormula().contains(valueMeta.getName())) {
+ if
(meta.getFunctions().get(m).getFormula().contains(valueMeta.getName())) {
// If so, add it to the indexes...
argIndexes.add(i);
@@ -156,8 +156,8 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
}
}
- JaninoMetaFunction fn = meta.getFormula()[m];
- if (!Utils.isEmpty(fn.getFieldName())) {
+ JaninoMetaFunction function = meta.getFunctions().get(m);
+ if (!Utils.isEmpty(function.getFieldName())) {
// Create the expression evaluator: is relatively slow so we do it
only for the first
// row...
@@ -168,8 +168,7 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
FunctionLib functionLib = new FunctionLib();
data.expressionEvaluators[m] = new ExpressionEvaluator();
data.expressionEvaluators[m].setParameters(
- parameterNames.toArray(new String[parameterNames.size()]),
- parameterTypes.toArray(new Class<?>[parameterTypes.size()]));
+ parameterNames.toArray(new String[0]),
parameterTypes.toArray(new Class<?>[0]));
data.expressionEvaluators[m].setReturnType(Object.class);
data.expressionEvaluators[m].setThrownExceptions(new Class<?>[]
{Exception.class});
data.expressionEvaluators[m].setParentClassLoader(loader);
@@ -177,22 +176,22 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
// Validate Formula
JaninoCheckerUtil janinoCheckerUtil = new JaninoCheckerUtil();
- List<String> codeCheck =
janinoCheckerUtil.checkCode(fn.getFormula());
+ List<String> codeCheck =
janinoCheckerUtil.checkCode(function.getFormula());
if (!codeCheck.isEmpty()) {
throw new HopException("Script contains code that is not allowed
: " + codeCheck);
}
- data.expressionEvaluators[m].cook(fn.getFormula());
+ data.expressionEvaluators[m].cook(function.getFormula());
} else {
throw new HopException(
"Unable to find field name for formula ["
- + (!StringUtil.isEmpty(fn.getFormula()) ? fn.getFormula()
: "")
+ + (!StringUtil.isEmpty(function.getFormula()) ?
function.getFormula() : "")
+ "]");
}
}
}
- for (int i = 0; i < meta.getFormula().length; i++) {
+ for (int i = 0; i < meta.getFunctions().size(); i++) {
List<Integer> argumentIndexes = data.argumentIndexes.get(i);
// This method can only accept the specified number of values...
@@ -222,9 +221,9 @@ public class Janino extends BaseTransform<JaninoMeta,
JaninoData> {
PKG,
"Janino.Error.ValueTypeMismatch",
valueMeta.getTypeDesc(),
- meta.getFormula()[i].getFieldName(),
+ meta.getFunctions().get(i).getFieldName(),
formulaResult.getClass(),
- meta.getFormula()[i].getFormula()));
+ meta.getFunctions().get(i).getFormula()));
}
}
diff --git
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
index 2b6984d113..a340064cd4 100644
---
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
+++
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java
@@ -83,7 +83,7 @@ public class JaninoDialog extends BaseTransformDialog {
fdlFields.top = new FormAttachment(wSpacer, margin);
wlFields.setLayoutData(fdlFields);
- final int FieldsRows = currentMeta.getFormula() != null ?
currentMeta.getFormula().length : 1;
+ final int nrFields = currentMeta.getFunctions().size();
colinf =
new ColumnInfo[] {
@@ -119,7 +119,7 @@ public class JaninoDialog extends BaseTransformDialog {
shell,
SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI,
colinf,
- FieldsRows,
+ nrFields,
null,
props);
@@ -214,20 +214,20 @@ public class JaninoDialog extends BaseTransformDialog {
/** Copy information from the meta-data currentMeta to the dialog fields. */
public void getData() {
- if (currentMeta.getFormula() != null) {
- for (int i = 0; i < currentMeta.getFormula().length; i++) {
- JaninoMetaFunction fn = currentMeta.getFormula()[i];
+ if (currentMeta.getFunctions() != null) {
+ for (int i = 0; i < currentMeta.getFunctions().size(); i++) {
+ JaninoMetaFunction function = currentMeta.getFunctions().get(i);
TableItem item = wFields.table.getItem(i);
- item.setText(1, Const.NVL(fn.getFieldName(), ""));
- item.setText(2, Const.NVL(fn.getFormula(), ""));
- item.setText(3,
Const.NVL(ValueMetaFactory.getValueMetaName(fn.getValueType()), ""));
- if (fn.getValueLength() >= 0) {
- item.setText(4, "" + fn.getValueLength());
+ item.setText(1, Const.NVL(function.getFieldName(), ""));
+ item.setText(2, Const.NVL(function.getFormula(), ""));
+ item.setText(3,
Const.NVL(ValueMetaFactory.getValueMetaName(function.getValueType()), ""));
+ if (function.getValueLength() >= 0) {
+ item.setText(4, "" + function.getValueLength());
}
- if (fn.getValuePrecision() >= 0) {
- item.setText(5, "" + fn.getValuePrecision());
+ if (function.getValuePrecision() >= 0) {
+ item.setText(5, "" + function.getValuePrecision());
}
- item.setText(6, Const.NVL(fn.getReplaceField(), ""));
+ item.setText(6, Const.NVL(function.getReplaceField(), ""));
}
}
@@ -265,21 +265,16 @@ public class JaninoDialog extends BaseTransformDialog {
transformName = wTransformName.getText(); // return value
- currentMeta.allocate(wFields.nrNonEmpty());
-
- for (int i = 0; i < nrNonEmptyFields; i++) {
- TableItem item = wFields.getNonEmpty(i);
-
- String fieldName = item.getText(1);
- String formula = item.getText(2);
- int valueType = ValueMetaFactory.getIdForValueMeta(item.getText(3));
- int valueLength = Const.toInt(item.getText(4), -1);
- int valuePrecision = Const.toInt(item.getText(5), -1);
- String replaceField = item.getText(6);
-
- currentMeta.getFormula()[i] =
- new JaninoMetaFunction(
- fieldName, formula, valueType, valueLength, valuePrecision,
replaceField);
+ currentMeta.getFunctions().clear();
+ for (TableItem item : wFields.getNonEmptyItems()) {
+ JaninoMetaFunction function = new JaninoMetaFunction();
+ function.setFieldName(item.getText(1));
+ function.setFormula(item.getText(2));
+
function.setValueType(ValueMetaFactory.getIdForValueMeta(item.getText(3)));
+ function.setValueLength(Const.toInt(item.getText(4), -1));
+ function.setValuePrecision(Const.toInt(item.getText(5), -1));
+ function.setReplaceField(item.getText(6));
+ currentMeta.getFunctions().add(function);
}
if (!originalMeta.equals(currentMeta)) {
diff --git
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
index 9ea918f174..4e3060959f 100644
---
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
+++
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMeta.java
@@ -16,29 +16,26 @@
*/
package org.apache.hop.pipeline.transforms.janino;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
+import lombok.Getter;
+import lombok.Setter;
import org.apache.hop.core.CheckResult;
-import org.apache.hop.core.Const;
import org.apache.hop.core.ICheckResult;
import org.apache.hop.core.annotations.Transform;
import org.apache.hop.core.exception.HopTransformException;
-import org.apache.hop.core.exception.HopXmlException;
-import org.apache.hop.core.injection.InjectionDeep;
import org.apache.hop.core.injection.InjectionSupported;
import org.apache.hop.core.row.IRowMeta;
import org.apache.hop.core.row.IValueMeta;
import org.apache.hop.core.row.value.ValueMetaFactory;
import org.apache.hop.core.util.Utils;
import org.apache.hop.core.variables.IVariables;
-import org.apache.hop.core.xml.XmlHandler;
import org.apache.hop.i18n.BaseMessages;
+import org.apache.hop.metadata.api.HopMetadataProperty;
import org.apache.hop.metadata.api.IHopMetadataProvider;
import org.apache.hop.pipeline.PipelineMeta;
import org.apache.hop.pipeline.transform.BaseTransformMeta;
import org.apache.hop.pipeline.transform.TransformMeta;
-import org.w3c.dom.Node;
@InjectionSupported(
localizationPrefix = "Janino.Injection.",
@@ -53,82 +50,31 @@ import org.w3c.dom.Node;
categoryDescription =
"i18n:org.apache.hop.pipeline.transform:BaseTransform.Category.Scripting",
keywords = "i18n::JaninoMeta.keyword",
documentationUrl = "/pipeline/transforms/userdefinedjavaexpression.html")
+@Getter
+@Setter
public class JaninoMeta extends BaseTransformMeta<Janino, JaninoData> {
private static final Class<?> PKG = JaninoMeta.class;
/** The formula calculations to be performed */
- @InjectionDeep private JaninoMetaFunction[] formula;
+ @HopMetadataProperty(
+ key = "formula",
+ injectionGroupKey = "FORMULA",
+ injectionGroupDescription = "Janino.Injection.FORMULA")
+ private List<JaninoMetaFunction> functions;
public JaninoMeta() {
- super(); // allocate BaseTransformMeta
+ super();
+ this.functions = new ArrayList<>();
}
- public JaninoMetaFunction[] getFormula() {
- return formula;
- }
-
- public void setFormula(JaninoMetaFunction[] calcTypes) {
- this.formula = calcTypes;
- }
-
- public void allocate(int nrCalcs) {
- formula = new JaninoMetaFunction[nrCalcs];
- }
-
- @Override
- public void loadXml(Node transformNode, IHopMetadataProvider
metadataProvider)
- throws HopXmlException {
- int nrCalcs = XmlHandler.countNodes(transformNode,
JaninoMetaFunction.XML_TAG);
- allocate(nrCalcs);
- for (int i = 0; i < nrCalcs; i++) {
- Node calcnode = XmlHandler.getSubNodeByNr(transformNode,
JaninoMetaFunction.XML_TAG, i);
- formula[i] = new JaninoMetaFunction(calcnode);
- }
- }
-
- @Override
- public String getXml() {
- StringBuilder retval = new StringBuilder();
-
- if (formula != null) {
- for (JaninoMetaFunction janinoMetaFunction : formula) {
- retval.append(" " + janinoMetaFunction.getXml() + Const.CR);
- }
- }
-
- return retval.toString();
- }
-
- public boolean equals(Object obj) {
- if (obj != null && (obj.getClass().equals(this.getClass()))) {
- JaninoMeta m = (JaninoMeta) obj;
- return Objects.equals(getXml(), m.getXml());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(formula);
+ public JaninoMeta(JaninoMeta m) {
+ this();
+ m.functions.forEach(f -> this.functions.add(new JaninoMetaFunction(f)));
}
@Override
public Object clone() {
- JaninoMeta retval = (JaninoMeta) super.clone();
- if (formula != null) {
- retval.allocate(formula.length);
- for (int i = 0; i < formula.length; i++) {
- retval.getFormula()[i] = (JaninoMetaFunction) formula[i].clone();
- }
- } else {
- retval.allocate(0);
- }
- return retval;
- }
-
- @Override
- public void setDefault() {
- formula = new JaninoMetaFunction[0];
+ return new JaninoMeta(this);
}
@Override
@@ -140,7 +86,7 @@ public class JaninoMeta extends BaseTransformMeta<Janino,
JaninoData> {
IVariables variables,
IHopMetadataProvider metadataProvider)
throws HopTransformException {
- for (JaninoMetaFunction fn : formula) {
+ for (JaninoMetaFunction fn : functions) {
if (Utils.isEmpty(fn.getReplaceField())) {
// Not replacing a field.
if (!Utils.isEmpty(fn.getFieldName())) {
diff --git
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaFunction.java
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaFunction.java
index 632bb6cac3..6668882505 100644
---
a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaFunction.java
+++
b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaFunction.java
@@ -17,60 +17,67 @@
package org.apache.hop.pipeline.transforms.janino;
import java.util.Objects;
-import org.apache.hop.core.Const;
-import org.apache.hop.core.injection.Injection;
-import org.apache.hop.core.row.value.ValueMetaFactory;
-import org.apache.hop.core.xml.XmlHandler;
-import org.w3c.dom.Node;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.hop.core.row.value.ValueMetaBase;
+import org.apache.hop.metadata.api.HopMetadataProperty;
+@Getter
+@Setter
public class JaninoMetaFunction implements Cloneable {
- public static final String XML_TAG = "formula";
-
- @Injection(name = "FIELD_NAME", group = "FORMULA")
+ @HopMetadataProperty(
+ key = "field_name",
+ injectionKey = "FIELD_NAME",
+ injectionKeyDescription = "Janino.Injection.FIELD_NAME")
private String fieldName;
- @Injection(name = "FIELD_FORMULA", group = "FORMULA")
+ @HopMetadataProperty(
+ key = "formula_string",
+ injectionKey = "FIELD_FORMULA",
+ injectionKeyDescription = "Janino.Injection.FIELD_FORMULA")
private String formula;
+ @HopMetadataProperty(
+ key = "value_type",
+ intCodeConverter = ValueMetaBase.ValueTypeCodeConverter.class,
+ injectionKey = "VALUE_TYPE",
+ injectionKeyDescription = "Janino.Injection.VALUE_TYPE")
private int valueType;
- @Injection(name = "VALUE_LENGTH", group = "FORMULA")
+ @HopMetadataProperty(
+ key = "value_length",
+ injectionKey = "VALUE_LENGTH",
+ injectionKeyDescription = "Janino.Injection.VALUE_LENGTH")
private int valueLength;
- @Injection(name = "VALUE_PRECISION", group = "FORMULA")
+ @HopMetadataProperty(
+ key = "value_precision",
+ injectionKey = "VALUE_PRECISION",
+ injectionKeyDescription = "Janino.Injection.VALUE_PRECISION")
private int valuePrecision;
- @Injection(name = "REPLACE_FIELD", group = "FORMULA")
+ @HopMetadataProperty(
+ key = "replace_field",
+ injectionKey = "REPLACE_FIELD",
+ injectionKeyDescription = "Janino.Injection.REPLACE_FIELD")
private String replaceField;
public JaninoMetaFunction() {}
- /**
- * @param fieldName
- * @param formula
- * @param valueType
- * @param valueLength
- * @param valuePrecision
- */
- public JaninoMetaFunction(
- String fieldName,
- String formula,
- int valueType,
- int valueLength,
- int valuePrecision,
- String replaceField) {
- this.fieldName = fieldName;
- this.formula = formula;
- this.valueType = valueType;
- this.valueLength = valueLength;
- this.valuePrecision = valuePrecision;
- this.replaceField = replaceField;
+ public JaninoMetaFunction(JaninoMetaFunction f) {
+ this();
+ this.fieldName = f.fieldName;
+ this.formula = f.formula;
+ this.valueType = f.valueType;
+ this.valueLength = f.valueLength;
+ this.valuePrecision = f.valuePrecision;
+ this.replaceField = f.replaceField;
}
public boolean equals(Object obj) {
if (obj != null && (obj.getClass().equals(this.getClass()))) {
JaninoMetaFunction mf = (JaninoMetaFunction) obj;
- return (getXml().equals(mf.getXml()));
+ return fieldName.equals(mf.getFieldName());
}
return false;
@@ -83,125 +90,6 @@ public class JaninoMetaFunction implements Cloneable {
@Override
public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- return null;
- }
- }
-
- public String getXml() {
- StringBuilder xml = new StringBuilder();
-
- xml.append(XmlHandler.openTag(XML_TAG));
-
- xml.append(XmlHandler.addTagValue("field_name", fieldName));
- xml.append(XmlHandler.addTagValue("formula_string", formula));
- xml.append(XmlHandler.addTagValue("value_type",
ValueMetaFactory.getValueMetaName(valueType)));
- xml.append(XmlHandler.addTagValue("value_length", valueLength));
- xml.append(XmlHandler.addTagValue("value_precision", valuePrecision));
- xml.append(XmlHandler.addTagValue("replace_field", replaceField));
-
- xml.append(XmlHandler.closeTag(XML_TAG));
-
- return xml.toString();
- }
-
- public JaninoMetaFunction(Node calcnode) {
- fieldName = XmlHandler.getTagValue(calcnode, "field_name");
- formula = XmlHandler.getTagValue(calcnode, "formula_string");
- valueType =
ValueMetaFactory.getIdForValueMeta(XmlHandler.getTagValue(calcnode,
"value_type"));
- valueLength = Const.toInt(XmlHandler.getTagValue(calcnode,
"value_length"), -1);
- valuePrecision = Const.toInt(XmlHandler.getTagValue(calcnode,
"value_precision"), -1);
- replaceField = XmlHandler.getTagValue(calcnode, "replace_field");
- }
-
- /**
- * @return Returns the fieldName.
- */
- public String getFieldName() {
- return fieldName;
- }
-
- /**
- * @param fieldName The fieldName to set.
- */
- public void setFieldName(String fieldName) {
- this.fieldName = fieldName;
- }
-
- /**
- * @return Returns the valueLength.
- */
- public int getValueLength() {
- return valueLength;
- }
-
- /**
- * @param valueLength The valueLength to set.
- */
- public void setValueLength(int valueLength) {
- this.valueLength = valueLength;
- }
-
- /**
- * @return Returns the valuePrecision.
- */
- public int getValuePrecision() {
- return valuePrecision;
- }
-
- /**
- * @param valuePrecision The valuePrecision to set.
- */
- public void setValuePrecision(int valuePrecision) {
- this.valuePrecision = valuePrecision;
- }
-
- /**
- * @return Returns the valueType.
- */
- public int getValueType() {
- return valueType;
- }
-
- /**
- * @param valueType The valueType to set.
- */
- public void setValueType(int valueType) {
- this.valueType = valueType;
- }
-
- @Injection(name = "VALUE_TYPE", group = "FORMULA")
- public void setValueType(String typeDesc) {
- this.valueType = ValueMetaFactory.getIdForValueMeta(typeDesc);
- }
-
- /**
- * @return the formula
- */
- public String getFormula() {
- return formula;
- }
-
- /**
- * @param formula the formula to set
- */
- public void setFormula(String formula) {
- this.formula = formula;
- }
-
- /**
- * @return the replaceField
- */
- public String getReplaceField() {
- return replaceField;
- }
-
- /**
- * @param replaceField the replaceField to set
- */
- public void setReplaceField(String replaceField) {
- this.replaceField = replaceField;
+ return new JaninoMetaFunction(this);
}
}
diff --git
a/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaTest.java
b/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaTest.java
index d4eadb5718..9eee4ed8ee 100644
---
a/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaTest.java
+++
b/plugins/transforms/janino/src/test/java/org/apache/hop/pipeline/transforms/janino/JaninoMetaTest.java
@@ -17,75 +17,92 @@
package org.apache.hop.pipeline.transforms.janino;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-import org.apache.hop.core.exception.HopException;
-import org.apache.hop.core.exception.HopPluginException;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Objects;
import org.apache.hop.core.plugins.PluginRegistry;
-import org.apache.hop.core.row.value.ValueMetaFactory;
+import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.core.row.value.ValueMetaDate;
+import org.apache.hop.core.row.value.ValueMetaInteger;
+import org.apache.hop.core.row.value.ValueMetaNumber;
+import org.apache.hop.core.row.value.ValueMetaPlugin;
import org.apache.hop.core.row.value.ValueMetaPluginType;
-import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
-import org.apache.hop.pipeline.transforms.loadsave.LoadSaveTester;
-import
org.apache.hop.pipeline.transforms.loadsave.validator.ArrayLoadSaveValidator;
-import
org.apache.hop.pipeline.transforms.loadsave.validator.IFieldLoadSaveValidator;
-import org.junit.jupiter.api.BeforeAll;
+import org.apache.hop.core.row.value.ValueMetaString;
+import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
+import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.RegisterExtension;
class JaninoMetaTest {
- @RegisterExtension
- static RestoreHopEngineEnvironmentExtension env = new
RestoreHopEngineEnvironmentExtension();
-
- @BeforeAll
- static void setUpBeforeClass() throws HopPluginException {
- PluginRegistry.addPluginType(ValueMetaPluginType.getInstance());
- PluginRegistry.init();
+ @BeforeEach
+ void beforeEach() throws Exception {
+ PluginRegistry registry = PluginRegistry.getInstance();
+ String[] classNames = {
+ ValueMetaString.class.getName(), ValueMetaInteger.class.getName(),
+ ValueMetaDate.class.getName(), ValueMetaNumber.class.getName()
+ };
+ for (String className : classNames) {
+ registry.registerPluginClass(className, ValueMetaPluginType.class,
ValueMetaPlugin.class);
+ }
}
@Test
- void testRoundTrip() throws HopException {
- List<String> attributes = Arrays.asList("formula");
-
- Map<String, IFieldLoadSaveValidator<?>> fieldLoadSaveValidatorAttributeMap
= new HashMap<>();
-
- IFieldLoadSaveValidator<JaninoMetaFunction[]>
janinoMetaFunctionArrayLoadSaveValidator =
- new ArrayLoadSaveValidator<>(new
JaninoMetaFunctionFieldLoadSaveValidator(), 25);
+ void testLoadSave() throws Exception {
+ Path path =
Paths.get(Objects.requireNonNull(getClass().getResource("/janino.xml")).toURI());
+ String xml = Files.readString(path);
+ JaninoMeta meta = new JaninoMeta();
+ XmlMetadataUtil.deSerializeFromXml(
+ XmlHandler.loadXmlString(xml, TransformMeta.XML_TAG),
+ JaninoMeta.class,
+ meta,
+ new MemoryMetadataProvider());
- fieldLoadSaveValidatorAttributeMap.put("formula",
janinoMetaFunctionArrayLoadSaveValidator);
+ validate(meta);
- LoadSaveTester loadSaveTester =
- new LoadSaveTester(
- JaninoMeta.class,
- attributes,
- new HashMap<>(),
- new HashMap<>(),
- fieldLoadSaveValidatorAttributeMap,
- new HashMap<>());
-
- loadSaveTester.testSerialization();
+ // Do a round trip:
+ //
+ String xmlCopy =
+ XmlHandler.openTag(TransformMeta.XML_TAG)
+ + XmlMetadataUtil.serializeObjectToXml(meta)
+ + XmlHandler.closeTag(TransformMeta.XML_TAG);
+ JaninoMeta metaCopy = new JaninoMeta();
+ XmlMetadataUtil.deSerializeFromXml(
+ XmlHandler.loadXmlString(xmlCopy, TransformMeta.XML_TAG),
+ JaninoMeta.class,
+ metaCopy,
+ new MemoryMetadataProvider());
+ validate(metaCopy);
}
- public class JaninoMetaFunctionFieldLoadSaveValidator
- implements IFieldLoadSaveValidator<JaninoMetaFunction> {
- @Override
- public JaninoMetaFunction getTestObject() {
- Random random = new Random();
- return new JaninoMetaFunction(
- UUID.randomUUID().toString(),
- UUID.randomUUID().toString(),
- random.nextInt(ValueMetaFactory.getAllValueMetaNames().length),
- random.nextInt(Integer.MAX_VALUE),
- random.nextInt(Integer.MAX_VALUE),
- UUID.randomUUID().toString());
- }
+ private static void validate(JaninoMeta meta) {
+ assertEquals(3, meta.getFunctions().size());
+ JaninoMetaFunction f = meta.getFunctions().getFirst();
+ assertEquals("f1", f.getFieldName());
+ assertEquals("expression1", f.getFormula());
+ assertEquals(IValueMeta.TYPE_STRING, f.getValueType());
+ assertEquals(100, f.getValueLength());
+ assertEquals(-1, f.getValuePrecision());
+ assertEquals("replace1", f.getReplaceField());
- @Override
- public boolean validateTestObject(JaninoMetaFunction testObject, Object
actual) {
- return testObject.equals(actual);
- }
+ f = meta.getFunctions().get(1);
+ assertEquals("f2", f.getFieldName());
+ assertEquals("expression2", f.getFormula());
+ assertEquals(IValueMeta.TYPE_INTEGER, f.getValueType());
+ assertEquals(7, f.getValueLength());
+ assertEquals(-1, f.getValuePrecision());
+ assertEquals("replace2", f.getReplaceField());
+
+ f = meta.getFunctions().get(2);
+ assertEquals("f3", f.getFieldName());
+ assertEquals("expression3", f.getFormula());
+ assertEquals(IValueMeta.TYPE_NUMBER, f.getValueType());
+ assertEquals(9, f.getValueLength());
+ assertEquals(2, f.getValuePrecision());
+ assertEquals("replace3", f.getReplaceField());
}
}
diff --git a/plugins/transforms/janino/src/test/resources/janino.xml
b/plugins/transforms/janino/src/test/resources/janino.xml
new file mode 100644
index 0000000000..08509604ae
--- /dev/null
+++ b/plugins/transforms/janino/src/test/resources/janino.xml
@@ -0,0 +1,43 @@
+<?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.
+ -->
+<transform>
+ <formula>
+ <field_name>f1</field_name>
+ <formula_string>expression1</formula_string>
+ <value_type>String</value_type>
+ <value_length>100</value_length>
+ <value_precision>-1</value_precision>
+ <replace_field>replace1</replace_field>
+ </formula>
+ <formula>
+ <field_name>f2</field_name>
+ <formula_string>expression2</formula_string>
+ <value_type>Integer</value_type>
+ <value_length>7</value_length>
+ <value_precision>-1</value_precision>
+ <replace_field>replace2</replace_field>
+ </formula>
+ <formula>
+ <field_name>f3</field_name>
+ <formula_string>expression3</formula_string>
+ <value_type>Number</value_type>
+ <value_length>9</value_length>
+ <value_precision>2</value_precision>
+ <replace_field>replace3</replace_field>
+ </formula>
+</transform>