This is an automated email from the ASF dual-hosted git repository.
bamaer 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 2c16b5ed68 Fix Inconsistency when saving workflow name tag of the file
saved as new workflow (#8627)
2c16b5ed68 is described below
commit 2c16b5ed68e572eac45fe0ecb539e5f8dcbeecd2
Author: Lance <[email protected]>
AuthorDate: Sun Sep 27 16:34:50 2026 +0800
Fix Inconsistency when saving workflow name tag of the file saved as new
workflow (#8627)
Signed-off-by: leehaut <[email protected]>
---
.../java/org/apache/hop/base/AbstractMeta.java | 12 ++
.../java/org/apache/hop/pipeline/PipelineMeta.java | 1 +
.../java/org/apache/hop/workflow/WorkflowMeta.java | 1 +
.../org/apache/hop/pipeline/PipelineMetaTest.java | 135 +++++++++++++--------
.../org/apache/hop/workflow/WorkflowMetaTest.java | 73 +++++++----
5 files changed, 149 insertions(+), 73 deletions(-)
diff --git a/engine/src/main/java/org/apache/hop/base/AbstractMeta.java
b/engine/src/main/java/org/apache/hop/base/AbstractMeta.java
index ef59cc1030..46da7d0153 100644
--- a/engine/src/main/java/org/apache/hop/base/AbstractMeta.java
+++ b/engine/src/main/java/org/apache/hop/base/AbstractMeta.java
@@ -184,6 +184,18 @@ public abstract class AbstractMeta
}
}
+ /**
+ * When the name is synchronized with the filename, copy that name into the
field XML
+ * serialization writes. {@link #getName()} already returns the
filename-derived value, but the
+ * persisted {@code name} element is a separate field and otherwise keeps
the name assigned when
+ * the file was created.
+ */
+ protected void persistSynchronizedName() {
+ if (isNameSynchronizedWithFilename() && !Utils.isEmpty(filename)) {
+ setName(getName());
+ }
+ }
+
/**
* Gets the filename.
*
diff --git a/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
b/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
index 1d57779ed4..151b4fb515 100644
--- a/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
+++ b/engine/src/main/java/org/apache/hop/pipeline/PipelineMeta.java
@@ -1630,6 +1630,7 @@ public class PipelineMeta extends AbstractMeta
*/
@Override
public String getXml(IVariables variables) throws HopException {
+ persistSynchronizedName();
return XmlHandler.getLicenseHeader(variables)
+ XmlFormatter.format(
XmlHandler.aroundTag(XML_TAG,
XmlMetadataUtil.serializeObjectToXml(this)));
diff --git a/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
b/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
index 0623fff77e..64bf6fa266 100644
--- a/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
+++ b/engine/src/main/java/org/apache/hop/workflow/WorkflowMeta.java
@@ -383,6 +383,7 @@ public class WorkflowMeta extends AbstractMeta
*/
@Override
public String getXml(IVariables variables) throws HopException {
+ persistSynchronizedName();
return XmlHandler.getLicenseHeader(variables)
+ XmlFormatter.format(
XmlHandler.aroundTag(XML_TAG,
XmlMetadataUtil.serializeObjectToXml(this)));
diff --git a/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
b/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
index c152c4389a..3b27d2304f 100644
--- a/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
+++ b/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
@@ -487,6 +487,31 @@ class PipelineMetaTest {
vars.getVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER));
}
+ @Test
+ void testGetXmlPersistsNameSynchronizedWithFilename() throws Exception {
+ PipelineMeta meta = new PipelineMeta();
+ meta.setName("New pipeline");
+ meta.setNameSynchronizedWithFilename(true);
+ meta.setFilename("/tmp/parameters_and_variables/Test Pipeline.hpl");
+
+ String xml = meta.getXml(new Variables());
+
+ assertTrue(xml.contains("<name>Test Pipeline</name>"));
+ assertFalse(xml.contains("<name>New pipeline</name>"));
+ }
+
+ @Test
+ void testGetXmlKeepsExplicitNameWhenNotSynchronized() throws Exception {
+ PipelineMeta meta = new PipelineMeta();
+ meta.setName("Custom name");
+ meta.setNameSynchronizedWithFilename(false);
+ meta.setFilename("/tmp/Test Pipeline.hpl");
+
+ String xml = meta.getXml(new Variables());
+
+ assertTrue(xml.contains("<name>Custom name</name>"));
+ }
+
@Test
void testSetInternalHopVariablesWithoutFilename() {
PipelineMeta meta = new PipelineMeta();
@@ -839,20 +864,22 @@ class PipelineMetaTest {
@Test
void testIssue7338() throws Exception {
String xml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<pipeline>\n"
- + " <transform>\n"
- + " <type>RowGenerator</type>\n"
- + " <name>100</name>\n"
- + " </transform>\n"
- + " <transform_error_handling>\n"
- + " <error>\n"
- + " <source_transform>100</source_transform>\n"
- + "
<target_transform>NonExistentTransform</target_transform>\n"
- + " <is_enabled>Y</is_enabled>\n"
- + " </error>\n"
- + " </transform_error_handling>\n"
- + "</pipeline>";
+ """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <pipeline>
+ <transform>
+ <type>RowGenerator</type>
+ <name>100</name>
+ </transform>
+ <transform_error_handling>
+ <error>
+ <source_transform>100</source_transform>
+ <target_transform>NonExistentTransform</target_transform>
+ <is_enabled>Y</is_enabled>
+ </error>
+ </transform_error_handling>
+ </pipeline>
+ """;
Node node = XmlHandler.loadXmlString(xml, PipelineMeta.XML_TAG);
PipelineMeta copy =
XmlMetadataUtil.deSerializeFromXml(node, PipelineMeta.class,
metadataProvider);
@@ -898,15 +925,17 @@ class PipelineMetaTest {
@Test
void loadingDropsAHopThatNamesATransformNotInTheFile() throws Exception {
String xml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<pipeline>\n"
- + " <transform><type>Dummy</type><name>Gen</name></transform>\n"
- + " <transform><type>Dummy</type><name>Keep</name></transform>\n"
- + " <order>\n"
- + "
<hop><from>Gen</from><to>Keep</to><enabled>Y</enabled></hop>\n"
- + " <hop><from>Gen</from><to>Renamed
away</to><enabled>Y</enabled></hop>\n"
- + " </order>\n"
- + "</pipeline>";
+ """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <pipeline>
+ <transform><type>Dummy</type><name>Gen</name></transform>
+ <transform><type>Dummy</type><name>Keep</name></transform>
+ <order>
+ <hop><from>Gen</from><to>Keep</to><enabled>Y</enabled></hop>
+ <hop><from>Gen</from><to>Renamed
away</to><enabled>Y</enabled></hop>
+ </order>
+ </pipeline>
+ """;
PipelineMeta loaded = new PipelineMeta();
loaded.loadXml(
@@ -927,17 +956,19 @@ class PipelineMetaTest {
@Test
void loadingDropsErrorHandlingThatNamesATransformNotInTheFile() throws
Exception {
String xml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<pipeline>\n"
- + " <transform><type>Dummy</type><name>REST
client</name></transform>\n"
- + " <transform_error_handling>\n"
- + " <error>\n"
- + " <source_transform>REST client</source_transform>\n"
- + " <target_transform>Dummy (do nothing)</target_transform>\n"
- + " <is_enabled>Y</is_enabled>\n"
- + " </error>\n"
- + " </transform_error_handling>\n"
- + "</pipeline>";
+ """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <pipeline>
+ <transform><type>Dummy</type><name>REST client</name></transform>
+ <transform_error_handling>
+ <error>
+ <source_transform>REST client</source_transform>
+ <target_transform>Dummy (do nothing)</target_transform>
+ <is_enabled>Y</is_enabled>
+ </error>
+ </transform_error_handling>
+ </pipeline>
+ """;
PipelineMeta loaded = new PipelineMeta();
loaded.loadXml(
@@ -960,23 +991,25 @@ class PipelineMetaTest {
@Test
void loadingKeepsDisabledHopsAndTheirErrorHandling() throws Exception {
String xml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<pipeline>\n"
- + " <transform><type>Dummy</type><name>Gen</name></transform>\n"
- + " <transform><type>Dummy</type><name>Good</name></transform>\n"
- + "
<transform><type>Dummy</type><name>Errors</name></transform>\n"
- + " <order>\n"
- + "
<hop><from>Gen</from><to>Good</to><enabled>N</enabled></hop>\n"
- + "
<hop><from>Gen</from><to>Errors</to><enabled>N</enabled></hop>\n"
- + " </order>\n"
- + " <transform_error_handling>\n"
- + " <error>\n"
- + " <source_transform>Gen</source_transform>\n"
- + " <target_transform>Errors</target_transform>\n"
- + " <is_enabled>Y</is_enabled>\n"
- + " </error>\n"
- + " </transform_error_handling>\n"
- + "</pipeline>";
+ """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <pipeline>
+ <transform><type>Dummy</type><name>Gen</name></transform>
+ <transform><type>Dummy</type><name>Good</name></transform>
+ <transform><type>Dummy</type><name>Errors</name></transform>
+ <order>
+ <hop><from>Gen</from><to>Good</to><enabled>N</enabled></hop>
+ <hop><from>Gen</from><to>Errors</to><enabled>N</enabled></hop>
+ </order>
+ <transform_error_handling>
+ <error>
+ <source_transform>Gen</source_transform>
+ <target_transform>Errors</target_transform>
+ <is_enabled>Y</is_enabled>
+ </error>
+ </transform_error_handling>
+ </pipeline>
+ """;
PipelineMeta loaded = new PipelineMeta();
loaded.loadXml(
diff --git a/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
b/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
index c1f4009c20..b280e6470a 100644
--- a/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
+++ b/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
@@ -294,6 +294,31 @@ class WorkflowMetaTest {
vars.getVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER));
}
+ @Test
+ void testGetXmlPersistsNameSynchronizedWithFilename() throws Exception {
+ WorkflowMeta meta = new WorkflowMeta();
+ meta.setName("New workflow");
+ meta.setNameSynchronizedWithFilename(true);
+ meta.setFilename("/tmp/parameters_and_variables/Test Workflow.hwf");
+
+ String xml = meta.getXml(new Variables());
+
+ assertTrue(xml.contains("<name>Test Workflow</name>"));
+ assertFalse(xml.contains("<name>New workflow</name>"));
+ }
+
+ @Test
+ void testGetXmlKeepsExplicitNameWhenNotSynchronized() throws Exception {
+ WorkflowMeta meta = new WorkflowMeta();
+ meta.setName("Custom name");
+ meta.setNameSynchronizedWithFilename(false);
+ meta.setFilename("/tmp/Test Workflow.hwf");
+
+ String xml = meta.getXml(new Variables());
+
+ assertTrue(xml.contains("<name>Custom name</name>"));
+ }
+
@Test
void testSetInternalHopVariablesWithoutFilename() {
WorkflowMeta meta = new WorkflowMeta();
@@ -452,17 +477,19 @@ class WorkflowMetaTest {
@Test
void loadingDropsAHopThatNamesAnActionNotInTheFile() throws Exception {
String xml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<workflow>\n"
- + " <name>fuzzymatch</name>\n"
- + " <actions>\n"
- + "
<action><name>Start</name><type>ActionFake</type></action>\n"
- + " <action><name>Run Fuzzy match
tests</name><type>ActionFake</type></action>\n"
- + " </actions>\n"
- + " <hops>\n"
- + " <hop><from>Start</from><to>Run Group By
tests</to><enabled>Y</enabled></hop>\n"
- + " </hops>\n"
- + "</workflow>";
+ """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <workflow>
+ <name>fuzzymatch</name>
+ <actions>
+ <action><name>Start</name><type>ActionFake</type></action>
+ <action><name>Run Fuzzy match
tests</name><type>ActionFake</type></action>
+ </actions>
+ <hops>
+ <hop><from>Start</from><to>Run Group By
tests</to><enabled>Y</enabled></hop>
+ </hops>
+ </workflow>
+ """;
// Dropping the hop is logged, and logging needs a log store to write to.
HopLogStore.init();
@@ -508,17 +535,19 @@ class WorkflowMetaTest {
@Test
void loadingKeepsDisabledHops() throws Exception {
String xml =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<workflow>\n"
- + " <name>disabled</name>\n"
- + " <actions>\n"
- + "
<action><name>Start</name><type>ActionFake</type></action>\n"
- + "
<action><name>Second</name><type>ActionFake</type></action>\n"
- + " </actions>\n"
- + " <hops>\n"
- + "
<hop><from>Start</from><to>Second</to><enabled>N</enabled></hop>\n"
- + " </hops>\n"
- + "</workflow>";
+ """
+ <?xml version="1.0" encoding="UTF-8"?>
+ <workflow>
+ <name>disabled</name>
+ <actions>
+ <action><name>Start</name><type>ActionFake</type></action>
+ <action><name>Second</name><type>ActionFake</type></action>
+ </actions>
+ <hops>
+ <hop><from>Start</from><to>Second</to><enabled>N</enabled></hop>
+ </hops>
+ </workflow>
+ """;
WorkflowMeta loaded = new WorkflowMeta();
loaded.loadXml(