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

mcasters 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 47c69e16d1 issue #1974 (Folders Compare) (#6941)
47c69e16d1 is described below

commit 47c69e16d1f402899d11abde994bb81b1e8d629f
Author: Matt Casters <[email protected]>
AuthorDate: Thu Apr 2 23:49:17 2026 +0200

    issue #1974 (Folders Compare) (#6941)
    
    * issue #1974 (Folders Compare)
    
    * issue #1974 (Folders Compare import fix)
    
    * issue #1974 (Folders Compare old test delete)
---
 .../folderscompare/ActionFoldersCompare.java       | 231 +++++++--------------
 .../folderscompare/ActionFoldersCompareDialog.java |   4 +-
 .../folderscompare/ActionFoldersCompareTest.java   |  41 ++++
 .../WorkflowActionFoldersCompareTest.java          |  71 -------
 .../src/test/resources/action-folders-compare.xml  |  27 +++
 5 files changed, 144 insertions(+), 230 deletions(-)

diff --git 
a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
 
b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
index 61cf7d48a3..efd9489a96 100644
--- 
a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
+++ 
b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompare.java
@@ -20,12 +20,13 @@ package org.apache.hop.workflow.actions.folderscompare;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.commons.vfs2.FileSelectInfo;
 import org.apache.commons.vfs2.FileSelector;
@@ -34,13 +35,12 @@ import org.apache.hop.core.ICheckResult;
 import org.apache.hop.core.Result;
 import org.apache.hop.core.annotations.Action;
 import org.apache.hop.core.exception.HopFileException;
-import org.apache.hop.core.exception.HopXmlException;
 import org.apache.hop.core.io.CountingInputStream;
 import org.apache.hop.core.util.Utils;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.core.vfs.HopVfs;
-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.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionBase;
@@ -49,7 +49,6 @@ import 
org.apache.hop.workflow.action.validator.AbstractFileValidator;
 import org.apache.hop.workflow.action.validator.ActionValidatorUtils;
 import org.apache.hop.workflow.action.validator.AndValidator;
 import org.apache.hop.workflow.action.validator.ValidatorContext;
-import org.w3c.dom.Node;
 
 /**
  * This defines a 'folder compare' action. It will compare 2 folders, and will 
either follow the
@@ -63,6 +62,8 @@ import org.w3c.dom.Node;
     categoryDescription = 
"i18n:org.apache.hop.workflow:ActionCategory.Category.FileManagement",
     keywords = "i18n::ActionFoldersCompare.keyword",
     documentationUrl = "/workflow/actions/comparefolders.html")
+@Getter
+@Setter
 public class ActionFoldersCompare extends ActionBase implements Cloneable, 
IAction {
   private static final Class<?> PKG = ActionFoldersCompare.class;
   private static final String CONST_SPACE_SHORT = "      ";
@@ -73,108 +74,56 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
   private static final String CONST_FILENAME1 = "filename1";
   private static final String CONST_FILENAME2 = "filename2";
 
+  @HopMetadataProperty(key = "include_subfolders")
+  private boolean includeSubFolders;
+
+  @HopMetadataProperty(key = "compare_filecontent")
+  private boolean compareFileContent;
+
+  @HopMetadataProperty(key = "compare_filesize")
+  private boolean compareFileSize;
+
+  @HopMetadataProperty(key = "compareonly")
+  private String compareOnly;
+
+  @HopMetadataProperty(key = "wildcard")
+  private String wildcard;
+
+  @HopMetadataProperty(key = "filename1")
   private String filename1;
+
+  @HopMetadataProperty(key = "filename2")
   private String filename2;
-  private String wildcard;
-  private String compareonly;
-  private boolean includesubfolders;
-  private boolean comparefilecontent;
-  private boolean comparefilesize;
 
   public ActionFoldersCompare(String n) {
-
     super(n, "");
-    includesubfolders = false;
-    comparefilesize = false;
-    comparefilecontent = false;
-    compareonly = "all";
+    includeSubFolders = false;
+    compareFileSize = false;
+    compareFileContent = false;
+    compareOnly = "all";
     wildcard = null;
     filename1 = null;
     filename2 = null;
   }
 
-  public void setCompareOnly(String comparevalue) {
-    this.compareonly = comparevalue;
-  }
-
-  public String getCompareOnly() {
-    return compareonly;
-  }
-
   public ActionFoldersCompare() {
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionFoldersCompare je = (ActionFoldersCompare) super.clone();
-    return je;
-  }
-
-  @Override
-  public String getXml() {
-
-    // 133 chars in just spaces and tag names alone
-    return super.getXml()
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("include_subfolders", includesubfolders)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("compare_filecontent", comparefilecontent)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("compare_filesize", comparefilesize)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("compareonly", compareonly)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("wildcard", wildcard)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue(CONST_FILENAME1, filename1)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue(CONST_FILENAME2, filename2);
+  public ActionFoldersCompare(ActionFoldersCompare a) {
+    super(a);
+    this.includeSubFolders = a.includeSubFolders;
+    this.compareFileContent = a.compareFileContent;
+    this.compareFileSize = a.compareFileSize;
+    this.compareOnly = a.compareOnly;
+    this.wildcard = a.wildcard;
+    this.filename1 = a.filename1;
+    this.filename2 = a.filename2;
   }
 
   @Override
-  public void loadXml(Node entrynode, IHopMetadataProvider metadataProvider, 
IVariables variables)
-      throws HopXmlException {
-    try {
-      super.loadXml(entrynode);
-      includesubfolders =
-          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"include_subfolders"));
-      comparefilecontent =
-          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"compare_filecontent"));
-      comparefilesize = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"compare_filesize"));
-
-      compareonly = XmlHandler.getTagValue(entrynode, "compareonly");
-      wildcard = XmlHandler.getTagValue(entrynode, "wildcard");
-      filename1 = XmlHandler.getTagValue(entrynode, CONST_FILENAME1);
-      filename2 = XmlHandler.getTagValue(entrynode, CONST_FILENAME2);
-    } catch (HopXmlException xe) {
-      throw new HopXmlException(
-          BaseMessages.getString(PKG, 
"ActionFoldersCompare.Meta.UnableLoadXML", xe.getMessage()));
-    }
-  }
-
-  public void setIncludeSubfolders(boolean includeSubfolders) {
-    this.includesubfolders = includeSubfolders;
-  }
-
-  public boolean isIncludeSubfolders() {
-    return includesubfolders;
-  }
-
-  public void setCompareFileContent(boolean comparefilecontent) {
-    this.comparefilecontent = comparefilecontent;
-  }
-
-  public boolean isCompareFileContent() {
-    return comparefilecontent;
-  }
-
-  public void setCompareFileSize(boolean comparefilesize) {
-    this.comparefilesize = comparefilesize;
-  }
-
-  public boolean isCompareFileSize() {
-    return comparefilesize;
+  public Object clone() {
+    return new ActionFoldersCompare(this);
   }
 
   public String getRealWildcard() {
@@ -196,7 +145,7 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
    * @param file2 second file to compare
    * @param result result to add bytes read to (for data volume tracking)
    * @return true if files are equal, false if they are not
-   * @throws org.apache.hop.core.exception.HopFileException upon IO problems
+   * @throws HopFileException upon IO problems
    */
   protected boolean equalFileContents(FileObject file1, FileObject file2, 
Result result)
       throws HopFileException {
@@ -232,8 +181,7 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
   }
 
   @Override
-  public Result execute(Result previousResult, int nr) {
-    Result result = previousResult;
+  public Result execute(Result result, int nr) {
     result.setResult(false);
     boolean ok = true;
 
@@ -317,13 +265,11 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
 
                 // Let's now fetch Folder1
                 // and for each entry, we will search it in Folder2
-                // if the entry exists..we will compare file entry (file or 
folder?)
+                // if the entry exists... we will compare file entry (file or 
folder?)
                 // if the 2 entry are file (not folder), we will compare 
content
                 Set<Map.Entry<String, String>> entrees = 
collection1.entrySet();
-                Iterator<Map.Entry<String, String>> iterateur = 
entrees.iterator();
 
-                while (iterateur.hasNext()) {
-                  Map.Entry<String, String> entree = iterateur.next();
+                for (Map.Entry<String, String> entree : entrees) {
                   if (!collection2.containsKey(entree.getKey())) {
                     ok = false;
                     if (isDetailed()) {
@@ -388,7 +334,7 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
                       // Files are the same type ...
                       if (filefolder2.getType() == FileType.FILE) {
                         // Let's compare file size
-                        if (comparefilesize) {
+                        if (compareFileSize) {
                           long filefolder1Size = 
filefolder1.getContent().getSize();
                           long filefolder2Size = 
filefolder2.getContent().getSize();
                           if (filefolder1Size != filefolder2Size) {
@@ -417,7 +363,7 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
                         }
 
                         if (ok
-                            && comparefilecontent
+                            && compareFileContent
                             && !equalFileContents(filefolder1, filefolder2, 
result)) {
                           // Let's compare files content..
                           ok = false;
@@ -513,43 +459,40 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
 
     @Override
     public boolean includeFile(FileSelectInfo info) {
+      if (info.getFile().toString().equals(sourceFolder)) {
+        return false;
+      }
+
       boolean returncode = false;
       try {
-        if (!info.getFile().toString().equals(sourceFolder)) {
-          // Pass over the Base folder itself
-          String shortFilename = info.getFile().getName().getBaseName();
-
-          if (info.getFile().getParent().equals(info.getBaseFolder())) {
-            // In the Base Folder...
-            if ((info.getFile().getType() == FileType.FILE && 
compareonly.equals("only_files"))
-                || (info.getFile().getType() == FileType.FOLDER
-                    && compareonly.equals("only_folders"))
-                || (getFileWildcard(shortFilename) && 
compareonly.equals("specify"))
-                || (compareonly.equals("all"))) {
-              returncode = true;
-            }
-          } else {
-            // Not in the Base Folder...Only if include sub folders
-
-            if ((includesubfolders
-                    && (info.getFile().getType() == FileType.FILE
-                        && compareonly.equals("only_files"))
-                || (info.getFile().getType() == FileType.FOLDER
-                    && compareonly.equals("only_folders"))
-                || (getFileWildcard(shortFilename) && 
compareonly.equals("specify"))
-                || (compareonly.equals("all")))) {
-              returncode = true;
-            }
+        // Pass over the Base folder itself
+        String shortFilename = info.getFile().getName().getBaseName();
+
+        if (info.getFile().getParent().equals(info.getBaseFolder())) {
+          // In the Base Folder...
+          if ((info.getFile().getType() == FileType.FILE && 
compareOnly.equals("only_files"))
+              || (info.getFile().getType() == FileType.FOLDER && 
compareOnly.equals("only_folders"))
+              || (getFileWildcard(shortFilename) && 
compareOnly.equals("specify"))
+              || (compareOnly.equals("all"))) {
+            returncode = true;
+          }
+        } else {
+          // Not in the Base Folder... Only if include sub folders
+
+          if ((includeSubFolders
+                  && (info.getFile().getType() == FileType.FILE && 
compareOnly.equals("only_files"))
+              || (info.getFile().getType() == FileType.FOLDER && 
compareOnly.equals("only_folders"))
+              || (getFileWildcard(shortFilename) && 
compareOnly.equals("specify"))
+              || (compareOnly.equals("all")))) {
+            returncode = true;
           }
         }
       } catch (Exception e) {
-
         logError(
             "Error while finding files ... in ["
                 + info.getFile().toString()
                 + "]. Exception :"
                 + e.getMessage());
-        returncode = false;
       }
       return returncode;
     }
@@ -561,20 +504,18 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
   }
 
   /**
-   * @param selectedfile
-   * @return True if the selectedfile matches the wildcard
+   * @param selectedFile The selected file
+   * @return True if the selected file matches the wildcard
    */
-  private boolean getFileWildcard(String selectedfile) {
-    Pattern pattern = null;
+  private boolean getFileWildcard(String selectedFile) {
+    Pattern pattern;
     boolean getIt = true;
 
     if (!Utils.isEmpty(wildcard)) {
       pattern = Pattern.compile(wildcard);
       // First see if the file matches the regular expression!
-      if (pattern != null) {
-        Matcher matcher = pattern.matcher(selectedfile);
-        getIt = matcher.matches();
-      }
+      Matcher matcher = pattern.matcher(selectedFile);
+      getIt = matcher.matches();
     }
 
     return getIt;
@@ -585,30 +526,6 @@ public class ActionFoldersCompare extends ActionBase 
implements Cloneable, IActi
     return true;
   }
 
-  public void setWildcard(String wildcard) {
-    this.wildcard = wildcard;
-  }
-
-  public String getWildcard() {
-    return wildcard;
-  }
-
-  public void setFilename1(String filename) {
-    this.filename1 = filename;
-  }
-
-  public String getFilename1() {
-    return filename1;
-  }
-
-  public void setFilename2(String filename) {
-    this.filename2 = filename;
-  }
-
-  public String getFilename2() {
-    return filename2;
-  }
-
   @Override
   public void check(
       List<ICheckResult> remarks,
diff --git 
a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
 
b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
index 50c156d81c..6de1d50546 100644
--- 
a/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
+++ 
b/plugins/actions/folderscompare/src/main/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareDialog.java
@@ -411,7 +411,7 @@ public class ActionFoldersCompareDialog extends 
ActionDialog {
       wFilename2.setText(action.getFilename2());
     }
 
-    wIncludeSubfolders.setSelection(action.isIncludeSubfolders());
+    wIncludeSubfolders.setSelection(action.isIncludeSubFolders());
     wCompareFileContent.setSelection(action.isCompareFileContent());
     wCompareFileSize.setSelection(action.isCompareFileSize());
   }
@@ -435,7 +435,7 @@ public class ActionFoldersCompareDialog extends 
ActionDialog {
       mb.open();
       return;
     }
-    action.setIncludeSubfolders(wIncludeSubfolders.getSelection());
+    action.setIncludeSubFolders(wIncludeSubfolders.getSelection());
     action.setCompareFileContent(wCompareFileContent.getSelection());
     action.setCompareFileSize(wCompareFileSize.getSelection());
 
diff --git 
a/plugins/actions/folderscompare/src/test/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareTest.java
 
b/plugins/actions/folderscompare/src/test/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareTest.java
new file mode 100644
index 0000000000..0861fa7b74
--- /dev/null
+++ 
b/plugins/actions/folderscompare/src/test/java/org/apache/hop/workflow/actions/folderscompare/ActionFoldersCompareTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.hop.workflow.actions.folderscompare;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hop.workflow.action.ActionSerializationTestUtil;
+import org.junit.jupiter.api.Test;
+
+class ActionFoldersCompareTest {
+  @Test
+  void testSerializeRoundTrip() throws Exception {
+    ActionFoldersCompare action =
+        ActionSerializationTestUtil.testSerialization(
+            "/action-folders-compare.xml", ActionFoldersCompare.class);
+    assertEquals("all", action.getCompareOnly());
+    assertEquals("wildcard", action.getWildcard());
+    assertEquals("folder1", action.getFilename1());
+    assertEquals("folder2", action.getFilename2());
+    assertTrue(action.isIncludeSubFolders());
+    assertTrue(action.isCompareFileContent());
+    assertTrue(action.isCompareFileSize());
+  }
+}
diff --git 
a/plugins/actions/folderscompare/src/test/java/org/apache/hop/workflow/actions/folderscompare/WorkflowActionFoldersCompareTest.java
 
b/plugins/actions/folderscompare/src/test/java/org/apache/hop/workflow/actions/folderscompare/WorkflowActionFoldersCompareTest.java
deleted file mode 100644
index 16cc07f3ef..0000000000
--- 
a/plugins/actions/folderscompare/src/test/java/org/apache/hop/workflow/actions/folderscompare/WorkflowActionFoldersCompareTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hop.workflow.actions.folderscompare;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension;
-import 
org.apache.hop.workflow.action.loadsave.WorkflowActionLoadSaveTestSupport;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-class WorkflowActionFoldersCompareTest
-    extends WorkflowActionLoadSaveTestSupport<ActionFoldersCompare> {
-  @RegisterExtension
-  static RestoreHopEngineEnvironmentExtension env = new 
RestoreHopEngineEnvironmentExtension();
-
-  @Override
-  protected Class<ActionFoldersCompare> getActionClass() {
-    return ActionFoldersCompare.class;
-  }
-
-  @Override
-  protected List<String> listAttributes() {
-    return Arrays.asList(
-        "filename1",
-        "filename2",
-        "wildcard",
-        "compareonly",
-        "includesubfolders",
-        "comparefilecontent",
-        "comparefilesize");
-  }
-
-  @Override
-  protected Map<String, String> createGettersMap() {
-    return toMap(
-        "filename1", "getFilename1",
-        "filename2", "getFilename2",
-        "wildcard", "getWildcard",
-        "compareonly", "getCompareOnly",
-        "includesubfolders", "isIncludeSubfolders",
-        "comparefilecontent", "isCompareFileContent",
-        "comparefilesize", "isCompareFileSize");
-  }
-
-  @Override
-  protected Map<String, String> createSettersMap() {
-    return toMap(
-        "filename1", "setFilename1",
-        "filename2", "setFilename2",
-        "wildcard", "setWildcard",
-        "compareonly", "setCompareOnly",
-        "includesubfolders", "setIncludeSubfolders",
-        "comparefilecontent", "setCompareFileContent",
-        "comparefilesize", "setCompareFileSize");
-  }
-}
diff --git 
a/plugins/actions/folderscompare/src/test/resources/action-folders-compare.xml 
b/plugins/actions/folderscompare/src/test/resources/action-folders-compare.xml
new file mode 100644
index 0000000000..6458f71368
--- /dev/null
+++ 
b/plugins/actions/folderscompare/src/test/resources/action-folders-compare.xml
@@ -0,0 +1,27 @@
+<?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.
+  ~
+  -->
+<action>
+    <include_subfolders>Y</include_subfolders>
+    <compare_filecontent>Y</compare_filecontent>
+    <compare_filesize>Y</compare_filesize>
+    <compareonly>all</compareonly>
+    <wildcard>wildcard</wildcard>
+    <filename1>folder1</filename1>
+    <filename2>folder2</filename2>
+</action>

Reply via email to