You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hop.apache.org by mc...@apache.org on 2026/04/02 19:44:48 UTC

(hop) branch main updated: Issue 1959 (#6942)

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 4b1a4ce17a Issue 1959 (#6942)
4b1a4ce17a is described below

commit 4b1a4ce17afbec8c7559144f62e5d90412d9fe8c
Author: Matt Casters <ma...@gmail.com>
AuthorDate: Thu Apr 2 21:44:41 2026 +0200

    Issue 1959 (#6942)
    
    * issue #1959 (Process Result Files cleanup)
    
    * issue #1959 (Process Result Files cleanup)
    
    * issue #1959 (Process Result Files cleanup)
---
 .../ActionCopyMoveResultFilenames.java             | 552 +++++++--------------
 .../ActionCopyMoveResultFilenamesDialog.java       | 219 ++++----
 .../ActionCopyMoveResultFilenamesTest.java         |  52 ++
 .../WorkflowActionCopyMoveResultFilenamesTest.java | 101 ----
 .../action-copy-move-result-filenames.xml          |  39 ++
 5 files changed, 369 insertions(+), 594 deletions(-)

diff --git a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
index 4bfacb0f5a..d425336ca7 100644
--- a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
+++ b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenames.java
@@ -23,19 +23,22 @@ import java.util.Iterator;
 import java.util.List;
 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.FileUtil;
+import org.apache.commons.vfs2.util.FileObjectUtils;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.ICheckResult;
 import org.apache.hop.core.Result;
 import org.apache.hop.core.ResultFile;
 import org.apache.hop.core.annotations.Action;
-import org.apache.hop.core.exception.HopXmlException;
+import org.apache.hop.core.exception.HopException;
 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.IEnumHasCodeAndDescription;
 import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionBase;
@@ -45,7 +48,6 @@ 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.apache.hop.workflow.engine.IWorkflowEngine;
-import org.w3c.dom.Node;
 
 /**
  * This defines a 'copymoveresultfilenames' action. Its main use would be to copy or move files in
@@ -59,62 +61,101 @@ import org.w3c.dom.Node;
     categoryDescription = "i18n:org.apache.hop.workflow:ActionCategory.Category.FileManagement",
     keywords = "i18n::ActionCopyMoveResultFilenames.keyword",
     documentationUrl = "/workflow/actions/processresultfilenames.html")
+@Getter
+@Setter
 public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneable, IAction {
   private static final Class<?> PKG = ActionCopyMoveResultFilenames.class;
+  public static final String SUCCESS_IF_AT_LEAST_X_FILES = "success_when_at_least";
+  public static final String SUCCESS_IF_ERRORS_LESS = "success_if_errors_less";
+  public static final String SUCCESS_IF_NO_ERRORS = "success_if_no_errors";
+
+  @Getter
+  public enum ActionType implements IEnumHasCodeAndDescription {
+    COPY("copy", BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.Copy.Label")),
+    MOVE("move", BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.Move.Label")),
+    DELETE("delete", BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.Delete.Label")),
+    ;
+    final String code;
+    final String description;
+
+    ActionType(String code, String description) {
+      this.code = code;
+      this.description = description;
+    }
+
+    public static String[] getDescriptions() {
+      return IEnumHasCodeAndDescription.getDescriptions(ActionType.class);
+    }
+
+    public ActionType lookupDescription(String description) {
+      return IEnumHasCodeAndDescription.lookupDescription(ActionType.class, description, COPY);
+    }
+  }
 
+  @HopMetadataProperty(key = "foldername")
   private String folderName;
+
+  @HopMetadataProperty(key = "specify_wildcard")
   private boolean specifyWildcard;
+
+  @HopMetadataProperty(key = "wildcard")
   private String wildcard;
+
+  @HopMetadataProperty(key = "wildcardexclude")
   private String wildcardExclude;
+
+  @HopMetadataProperty(key = "destination_folder")
   private String destinationFolder;
+
+  @HopMetadataProperty(key = "nr_errors_less_than")
   private String nrErrorsLessThan;
 
-  public static final String SUCCESS_IF_AT_LEAST_X_FILES = "success_when_at_least";
-  public static final String SUCCESS_IF_ERRORS_LESS = "success_if_errors_less";
-  public static final String SUCCESS_IF_NO_ERRORS = "success_if_no_errors";
-  private static final String CONST_SPACE_SHORT = "      ";
+  @HopMetadataProperty(key = "success_condition")
   private String successCondition;
-  private Pattern wildcardPattern;
-  private Pattern wildcardExcludePattern;
 
+  @HopMetadataProperty(key = "add_date")
   private boolean addDate;
+
+  @HopMetadataProperty(key = "add_time")
   private boolean addTime;
+
+  @HopMetadataProperty(key = "SpecifyFormat")
   private boolean specifyFormat;
+
+  @HopMetadataProperty(key = "date_time_format")
   private String dateTimeFormat;
+
+  @HopMetadataProperty(key = "AddDateBeforeExtension")
   private boolean addDateBeforeExtension;
-  private String action;
 
+  @HopMetadataProperty(key = "action", storeWithCode = true)
+  private ActionType action;
+
+  @HopMetadataProperty(key = "OverwriteFile")
   private boolean overwriteFile;
+
+  @HopMetadataProperty(key = "CreateDestinationFolder")
   private boolean createDestinationFolder;
+
+  @HopMetadataProperty(key = "RemovedSourceFilename")
   boolean removedSourceFilename;
+
+  @HopMetadataProperty(key = "AddDestinationFilename")
   boolean addDestinationFilename;
 
-  int nrErrors = 0;
+  private int nrErrors = 0;
   private int nrSuccess = 0;
-  boolean successConditionBroken = false;
-  boolean successConditionBrokenExit = false;
-  int limitFiles = 0;
+  private boolean successConditionBroken = false;
+  private int limitFiles = 0;
+  private Pattern wildcardPattern;
+  private Pattern wildcardExcludePattern;
 
   public ActionCopyMoveResultFilenames(String n) {
     super(n, "");
     removedSourceFilename = true;
     addDestinationFilename = true;
-    createDestinationFolder = false;
-    folderName = null;
-    wildcardExclude = null;
-    wildcard = null;
-    specifyWildcard = false;
-
-    overwriteFile = false;
-    addDate = false;
-    addTime = false;
-    specifyFormat = false;
-    dateTimeFormat = null;
-    addDateBeforeExtension = false;
-    destinationFolder = null;
     nrErrorsLessThan = "10";
-
-    action = "copy";
+    action = ActionType.COPY;
     successCondition = SUCCESS_IF_NO_ERRORS;
   }
 
@@ -122,236 +163,45 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
     this("");
   }
 
-  @Override
-  public Object clone() {
-    ActionCopyMoveResultFilenames je = (ActionCopyMoveResultFilenames) super.clone();
-    return je;
+  public ActionCopyMoveResultFilenames(ActionCopyMoveResultFilenames a) {
+    super(a);
+    this.folderName = a.folderName;
+    this.specifyWildcard = a.specifyWildcard;
+    this.wildcard = a.wildcard;
+    this.wildcardExclude = a.wildcardExclude;
+    this.destinationFolder = a.destinationFolder;
+    this.nrErrorsLessThan = a.nrErrorsLessThan;
+    this.successCondition = a.successCondition;
+    this.addDate = a.addDate;
+    this.addTime = a.addTime;
+    this.specifyFormat = a.specifyFormat;
+    this.dateTimeFormat = a.dateTimeFormat;
+    this.addDateBeforeExtension = a.addDateBeforeExtension;
+    this.action = a.action;
+    this.overwriteFile = a.overwriteFile;
+    this.createDestinationFolder = a.createDestinationFolder;
+    this.removedSourceFilename = a.removedSourceFilename;
+    this.addDestinationFilename = a.addDestinationFilename;
+
+    this.nrErrors = 0;
+    this.nrSuccess = 0;
+    this.successConditionBroken = false;
+    this.limitFiles = 0;
+    this.wildcardPattern = null;
+    this.wildcardExcludePattern = null;
   }
 
   @Override
-  public String getXml() {
-
-    // 358 chars in just tags and spaces alone
-    return super.getXml()
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("foldername", folderName)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("specify_wildcard", specifyWildcard)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("wildcard", wildcard)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("wildcardexclude", wildcardExclude)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("destination_folder", destinationFolder)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("nr_errors_less_than", nrErrorsLessThan)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("success_condition", successCondition)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("add_date", addDate)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("add_time", addTime)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("SpecifyFormat", specifyFormat)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("date_time_format", dateTimeFormat)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("action", action)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("AddDateBeforeExtension", addDateBeforeExtension)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("OverwriteFile", overwriteFile)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("CreateDestinationFolder", createDestinationFolder)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("RemovedSourceFilename", removedSourceFilename)
-        + CONST_SPACE_SHORT
-        + XmlHandler.addTagValue("AddDestinationFilename", addDestinationFilename);
-  }
-
-  @Override
-  public void loadXml(Node entrynode, IHopMetadataProvider metadataProvider, IVariables variables)
-      throws HopXmlException {
-    try {
-      super.loadXml(entrynode);
-      folderName = XmlHandler.getTagValue(entrynode, "foldername");
-      specifyWildcard = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "specify_wildcard"));
-      wildcard = XmlHandler.getTagValue(entrynode, "wildcard");
-      wildcardExclude = XmlHandler.getTagValue(entrynode, "wildcardexclude");
-      destinationFolder = XmlHandler.getTagValue(entrynode, "destination_folder");
-      nrErrorsLessThan = XmlHandler.getTagValue(entrynode, "nr_errors_less_than");
-      successCondition = XmlHandler.getTagValue(entrynode, "success_condition");
-      addDate = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "add_date"));
-      addTime = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "add_time"));
-      specifyFormat = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "SpecifyFormat"));
-      addDateBeforeExtension =
-          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "AddDateBeforeExtension"));
-
-      dateTimeFormat = XmlHandler.getTagValue(entrynode, "date_time_format");
-      action = XmlHandler.getTagValue(entrynode, "action");
-
-      overwriteFile = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "OverwriteFile"));
-      createDestinationFolder =
-          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "CreateDestinationFolder"));
-      removedSourceFilename =
-          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "RemovedSourceFilename"));
-      addDestinationFilename =
-          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "AddDestinationFilename"));
-
-    } catch (HopXmlException xe) {
-      throw new HopXmlException(
-          BaseMessages.getString(
-              PKG, "ActionCopyMoveResultFilenames.CanNotLoadFromXML", xe.getMessage()));
-    }
-  }
-
-  public void setSpecifyWildcard(boolean specifyWildcard) {
-    this.specifyWildcard = specifyWildcard;
-  }
-
-  public boolean isSpecifyWildcard() {
-    return specifyWildcard;
-  }
-
-  public void setFoldername(String folderName) {
-    this.folderName = folderName;
-  }
-
-  public String getFoldername() {
-    return folderName;
-  }
-
-  public String getWildcard() {
-    return wildcard;
-  }
-
-  public String getWildcardExclude() {
-    return wildcardExclude;
-  }
-
-  public String getRealWildcard() {
-    return resolve(getWildcard());
-  }
-
-  public void setWildcard(String wildcard) {
-    this.wildcard = wildcard;
-  }
-
-  public void setWildcardExclude(String wildcardExclude) {
-    this.wildcardExclude = wildcardExclude;
-  }
-
-  public void setAddDate(boolean adddate) {
-    this.addDate = adddate;
-  }
-
-  public boolean isAddDate() {
-    return addDate;
-  }
-
-  public void setAddTime(boolean addtime) {
-    this.addTime = addtime;
-  }
-
-  public boolean isAddTime() {
-    return addTime;
-  }
-
-  public void setAddDateBeforeExtension(boolean addDateBeforeExtension) {
-    this.addDateBeforeExtension = addDateBeforeExtension;
-  }
-
-  public boolean isAddDateBeforeExtension() {
-    return addDateBeforeExtension;
-  }
-
-  public boolean isOverwriteFile() {
-    return overwriteFile;
-  }
-
-  public void setOverwriteFile(boolean overwriteFile) {
-    this.overwriteFile = overwriteFile;
-  }
-
-  public void setCreateDestinationFolder(boolean createDestinationFolder) {
-    this.createDestinationFolder = createDestinationFolder;
-  }
-
-  public boolean isCreateDestinationFolder() {
-    return createDestinationFolder;
-  }
-
-  public boolean isRemovedSourceFilename() {
-    return removedSourceFilename;
-  }
-
-  public void setRemovedSourceFilename(boolean removedSourceFilename) {
-    this.removedSourceFilename = removedSourceFilename;
-  }
-
-  public void setAddDestinationFilename(boolean addDestinationFilename) {
-    this.addDestinationFilename = addDestinationFilename;
-  }
-
-  public boolean isAddDestinationFilename() {
-    return addDestinationFilename;
-  }
-
-  public boolean isSpecifyFormat() {
-    return specifyFormat;
-  }
-
-  public void setSpecifyFormat(boolean specifyFormat) {
-    this.specifyFormat = specifyFormat;
-  }
-
-  public void setDestinationFolder(String destinationFolder) {
-    this.destinationFolder = destinationFolder;
-  }
-
-  public String getDestinationFolder() {
-    return destinationFolder;
-  }
-
-  public void setNrErrorsLessThan(String nrErrorsLessThan) {
-    this.nrErrorsLessThan = nrErrorsLessThan;
-  }
-
-  public String getNrErrorsLessThan() {
-    return nrErrorsLessThan;
-  }
-
-  public void setSuccessCondition(String successCondition) {
-    this.successCondition = successCondition;
-  }
-
-  public String getSuccessCondition() {
-    return successCondition;
-  }
-
-  public void setAction(String action) {
-    this.action = action;
-  }
-
-  public String getAction() {
-    return action;
-  }
-
-  public String getDateTimeFormat() {
-    return dateTimeFormat;
-  }
-
-  public void setDateTimeFormat(String dateTimeFormat) {
-    this.dateTimeFormat = dateTimeFormat;
+  public Object clone() {
+    return new ActionCopyMoveResultFilenames(this);
   }
 
   @Override
-  public Result execute(Result previousResult, int nr) {
-    Result result = previousResult;
+  public Result execute(Result result, int nr) {
     result.setNrErrors(1);
     result.setResult(false);
 
-    boolean deleteFile = getAction().equals("delete");
+    boolean deleteFile = getAction() == ActionType.DELETE;
 
     String realdestinationFolder = null;
     if (!deleteFile) {
@@ -368,77 +218,70 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
       wildcardExcludePattern = Pattern.compile(resolve(wildcardExclude));
     }
 
-    if (previousResult != null) {
-      nrErrors = 0;
-      limitFiles = Const.toInt(resolve(getNrErrorsLessThan()), 10);
-      nrErrors = 0;
-      nrSuccess = 0;
-      successConditionBroken = false;
-      successConditionBrokenExit = false;
+    nrErrors = 0;
+    limitFiles = Const.toInt(resolve(getNrErrorsLessThan()), 10);
+    nrErrors = 0;
+    nrSuccess = 0;
+    successConditionBroken = false;
 
-      FileObject file = null;
+    FileObject file = null;
 
-      try {
-        int size = result.getResultFiles().size();
-        if (isBasic()) {
-          logBasic(
-              BaseMessages.getString(
-                  PKG, "ActionCopyMoveResultFilenames.log.FilesFound", "" + size));
-        }
+    try {
+      int size = result.getResultFiles().size();
+      if (isBasic()) {
+        logBasic(
+            BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.log.FilesFound", "" + size));
+      }
 
-        List<ResultFile> resultFiles = result.getResultFilesList();
-        if (!Utils.isEmpty(resultFiles)) {
-          for (Iterator<ResultFile> it = resultFiles.iterator();
-              it.hasNext() && !parentWorkflow.isStopped(); ) {
-            if (successConditionBroken) {
-              logError(
-                  BaseMessages.getString(
-                      PKG,
-                      "ActionCopyMoveResultFilenames.Error.SuccessConditionbroken",
-                      "" + nrErrors));
-              throw new Exception(
-                  BaseMessages.getString(
-                      PKG,
-                      "ActionCopyMoveResultFilenames.Error.SuccessConditionbroken",
-                      "" + nrErrors));
-            }
+      List<ResultFile> resultFiles = result.getResultFilesList();
+      if (!Utils.isEmpty(resultFiles)) {
+        for (Iterator<ResultFile> it = resultFiles.iterator();
+            it.hasNext() && !parentWorkflow.isStopped(); ) {
+          if (successConditionBroken) {
+            logError(
+                BaseMessages.getString(
+                    PKG,
+                    "ActionCopyMoveResultFilenames.Error.SuccessConditionbroken",
+                    "" + nrErrors));
+            throw new HopException(
+                BaseMessages.getString(
+                    PKG,
+                    "ActionCopyMoveResultFilenames.Error.SuccessConditionbroken",
+                    "" + nrErrors));
+          }
 
-            ResultFile resultFile = it.next();
-            file = resultFile.getFile();
-            if (file != null && file.exists()) {
-              if (!specifyWildcard
-                  || (checkFileWildcard(file.getName().getBaseName(), wildcardPattern, true)
-                      && !checkFileWildcard(
-                          file.getName().getBaseName(), wildcardExcludePattern, false)
-                      && specifyWildcard)) {
-                // Copy or Move file
-                if (!processFile(file, realdestinationFolder, result, parentWorkflow, deleteFile)) {
-                  // Update Errors
-                  updateErrors();
-                }
-              }
-
-            } else {
-              logError(
-                  BaseMessages.getString(
-                      PKG,
-                      "ActionCopyMoveResultFilenames.log.ErrorCanNotFindFile",
-                      file.toString()));
+          ResultFile resultFile = it.next();
+          file = resultFile.getFile();
+          if (file != null && file.exists()) {
+            if ((!specifyWildcard
+                    || (checkFileWildcard(file.getName().getBaseName(), wildcardPattern, true)
+                        && !checkFileWildcard(
+                            file.getName().getBaseName(), wildcardExcludePattern, false)
+                        && specifyWildcard))
+                && !processFile(file, realdestinationFolder, result, parentWorkflow, deleteFile)) {
               // Update Errors
               updateErrors();
             }
-          } // end for
-        }
-      } catch (Exception e) {
-        logError(BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.Error", e.toString()));
-      } finally {
-        if (file != null) {
-          try {
-            file.close();
-            file = null;
-          } catch (Exception ex) {
-            /* Ignore */
+
+          } else {
+            logError(
+                BaseMessages.getString(
+                    PKG,
+                    "ActionCopyMoveResultFilenames.log.ErrorCanNotFindFile",
+                    file == null ? "" : file.toString()));
+            // Update Errors
+            updateErrors();
           }
+        } // end for
+      }
+    } catch (Exception e) {
+      logError(BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.Error", e.toString()));
+    } finally {
+      if (file != null) {
+        try {
+          file.close();
+        } catch (Exception ex) {
+          /* Ignore */
         }
       }
     }
@@ -472,10 +315,7 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
   }
 
   private boolean createDestinationFolder(String folderName) {
-    FileObject folder = null;
-    try {
-      folder = HopVfs.getFileObject(folderName);
-
+    try (FileObject folder = HopVfs.getFileObject(folderName)) {
       if (!folder.exists()) {
         logError(
             BaseMessages.getString(
@@ -505,22 +345,12 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
               "ActionCopyMoveResultFilenames.Log.CanNotCreatedFolder",
               folderName,
               e.toString()));
-
-    } finally {
-      if (folder != null) {
-        try {
-          folder.close();
-          folder = null;
-        } catch (Exception ex) {
-          /* Ignore */
-        }
-      }
     }
     return false;
   }
 
   private boolean processFile(
-      FileObject sourcefile,
+      FileObject sourceFile,
       String destinationFolder,
       Result result,
       IWorkflowEngine<WorkflowMeta> parentWorkflow,
@@ -530,76 +360,76 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
     try {
       if (deleteFile) {
         // delete file
-        if (sourcefile.delete()) {
+        if (sourceFile.delete()) {
           if (isDetailed()) {
             logDetailed(
                 BaseMessages.getString(
-                    PKG, "ActionCopyMoveResultFilenames.log.DeletedFile", sourcefile.toString()));
+                    PKG, "ActionCopyMoveResultFilenames.log.DeletedFile", sourceFile.toString()));
           }
 
           // Remove source file from result files list
-          result.getResultFiles().remove(sourcefile.toString());
+          result.getResultFiles().remove(sourceFile.toString());
           nrSuccess++;
           if (isDetailed()) {
             logDetailed(
                 BaseMessages.getString(
                     PKG,
                     "ActionCopyMoveResultFilenames.RemovedFileFromResult",
-                    sourcefile.toString()));
+                    sourceFile.toString()));
           }
 
         } else {
           logError(
               BaseMessages.getString(
-                  PKG, "ActionCopyMoveResultFilenames.CanNotDeletedFile", sourcefile.toString()));
+                  PKG, "ActionCopyMoveResultFilenames.CanNotDeletedFile", sourceFile.toString()));
         }
       } else {
         // return destination short filename
-        String shortfilename = getDestinationFilename(sourcefile.getName().getBaseName());
+        String shortFilename = getDestinationFilename(sourceFile.getName().getBaseName());
         // build full destination filename
-        String destinationFilename = destinationFolder + Const.FILE_SEPARATOR + shortfilename;
-        FileObject destinationfile = HopVfs.getFileObject(destinationFilename);
-        boolean filexists = destinationfile.exists();
-        if (filexists && isDetailed()) {
+        String destinationFilename = destinationFolder + Const.FILE_SEPARATOR + shortFilename;
+        FileObject destinationFile = HopVfs.getFileObject(destinationFilename);
+        boolean fileExists = destinationFile.exists();
+        if (fileExists && isDetailed()) {
           logDetailed(
               BaseMessages.getString(
                   PKG, "ActionCopyMoveResultFilenames.Log.FileExists", destinationFilename));
         }
-        if ((!filexists) || (filexists && isOverwriteFile())) {
-          if (getAction().equals("copy")) {
+        if (!fileExists || isOverwriteFile()) {
+          if (getAction() == ActionType.COPY) {
             // Copy file
-            FileUtil.copyContent(sourcefile, destinationfile);
+            FileObjectUtils.writeContent(sourceFile, destinationFile);
             nrSuccess++;
             if (isDetailed()) {
               logDetailed(
                   BaseMessages.getString(
                       PKG,
                       "ActionCopyMoveResultFilenames.log.CopiedFile",
-                      sourcefile.toString(),
+                      sourceFile.toString(),
                       destinationFolder));
             }
           } else {
             // Move file
-            sourcefile.moveTo(destinationfile);
+            sourceFile.moveTo(destinationFile);
             nrSuccess++;
             if (isDetailed()) {
               logDetailed(
                   BaseMessages.getString(
                       PKG,
                       "ActionCopyMoveResultFilenames.log.MovedFile",
-                      sourcefile.toString(),
+                      sourceFile.toString(),
                       destinationFolder));
             }
           }
           if (isRemovedSourceFilename()) {
             // Remove source file from result files list
-            result.getResultFiles().remove(sourcefile.toString());
+            result.getResultFiles().remove(sourceFile.toString());
             if (isDetailed()) {
               logDetailed(
                   BaseMessages.getString(
                       PKG,
                       "ActionCopyMoveResultFilenames.RemovedFileFromResult",
-                      sourcefile.toString()));
+                      sourceFile.toString()));
             }
           }
           if (isAddDestinationFilename()) {
@@ -607,7 +437,7 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
             ResultFile resultFile =
                 new ResultFile(
                     ResultFile.FILE_TYPE_GENERAL,
-                    HopVfs.getFileObject(destinationfile.toString()),
+                    HopVfs.getFileObject(destinationFile.toString()),
                     parentWorkflow.getWorkflowName(),
                     toString());
             result.getResultFiles().put(resultFile.getFile().toString(), resultFile);
@@ -616,7 +446,7 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
                   BaseMessages.getString(
                       PKG,
                       "ActionCopyMoveResultFilenames.AddedFileToResult",
-                      destinationfile.toString()));
+                      destinationFile.toString()));
             }
           }
         }
@@ -631,12 +461,12 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
     return retval;
   }
 
-  private String getDestinationFilename(String shortsourcefilename) {
-    String shortfilename = shortsourcefilename;
-    int lenstring = shortsourcefilename.length();
-    int lastindexOfDot = shortfilename.lastIndexOf('.');
+  private String getDestinationFilename(String shortSourceFilename) {
+    String shortfilename = shortSourceFilename;
+    int stringLength = shortSourceFilename.length();
+    int lastIndexOfDot = shortfilename.lastIndexOf('.');
     if (isAddDateBeforeExtension()) {
-      shortfilename = shortfilename.substring(0, lastindexOfDot);
+      shortfilename = shortfilename.substring(0, lastIndexOfDot);
     }
 
     SimpleDateFormat daf = new SimpleDateFormat();
@@ -659,22 +489,22 @@ public class ActionCopyMoveResultFilenames extends ActionBase implements Cloneab
       }
     }
     if (isAddDateBeforeExtension()) {
-      shortfilename += shortsourcefilename.substring(lastindexOfDot, lenstring);
+      shortfilename += shortSourceFilename.substring(lastIndexOfDot, stringLength);
     }
 
     return shortfilename;
   }
 
   /**
-   * @param selectedfile
-   * @param pattern
-   * @param include
-   * @return True if the selectedfile matches the wildcard
+   * @param selectedFile the selected file
+   * @param pattern The pattern
+   * @param include Include
+   * @return True if the selectedFile matches the wildcard
    */
-  private boolean checkFileWildcard(String selectedfile, Pattern pattern, boolean include) {
+  private boolean checkFileWildcard(String selectedFile, Pattern pattern, boolean include) {
     boolean getIt = include;
     if (pattern != null) {
-      Matcher matcher = pattern.matcher(selectedfile);
+      Matcher matcher = pattern.matcher(selectedFile);
       getIt = matcher.matches();
     }
     return getIt;
diff --git a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java
index e539bd6c8a..64112b2cd3 100644
--- a/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java
+++ b/plugins/actions/copymoveresultfilenames/src/main/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesDialog.java
@@ -28,6 +28,7 @@ import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.IAction;
+import org.apache.hop.workflow.actions.copymoveresultfilenames.ActionCopyMoveResultFilenames.ActionType;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.events.ModifyListener;
@@ -59,9 +60,9 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
 
   private boolean changed;
 
-  private Label wlFoldername;
-  private Button wbFoldername;
-  private TextVar wFoldername;
+  private Label wlFolderName;
+  private Button wbFolderName;
+  private TextVar wFolderName;
 
   private Label wlAddDate;
   private Button wAddDate;
@@ -148,40 +149,40 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
           }
         });
 
-    // Foldername line
-    wlFoldername = new Label(shell, SWT.RIGHT);
-    wlFoldername.setText(
+    // Folder name line
+    wlFolderName = new Label(shell, SWT.RIGHT);
+    wlFolderName.setText(
         BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.Foldername.Label"));
-    PropsUi.setLook(wlFoldername);
-    FormData fdlFoldername = new FormData();
-    fdlFoldername.left = new FormAttachment(0, 0);
-    fdlFoldername.top = new FormAttachment(wAction, margin);
-    fdlFoldername.right = new FormAttachment(middle, -margin);
-    wlFoldername.setLayoutData(fdlFoldername);
-
-    wbFoldername = new Button(shell, SWT.PUSH | SWT.CENTER);
-    PropsUi.setLook(wbFoldername);
-    wbFoldername.setText(BaseMessages.getString(PKG, "System.Button.Browse"));
-    FormData fdbFoldername = new FormData();
-    fdbFoldername.right = new FormAttachment(100, 0);
-    fdbFoldername.top = new FormAttachment(wAction, 0);
-    wbFoldername.setLayoutData(fdbFoldername);
-
-    wFoldername = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-    PropsUi.setLook(wFoldername);
-    wFoldername.addModifyListener(lsMod);
-    FormData fdFoldername = new FormData();
-    fdFoldername.left = new FormAttachment(middle, 0);
-    fdFoldername.top = new FormAttachment(wAction, margin);
-    fdFoldername.right = new FormAttachment(wbFoldername, -margin);
-    wFoldername.setLayoutData(fdFoldername);
+    PropsUi.setLook(wlFolderName);
+    FormData fdlFolderName = new FormData();
+    fdlFolderName.left = new FormAttachment(0, 0);
+    fdlFolderName.top = new FormAttachment(wAction, margin);
+    fdlFolderName.right = new FormAttachment(middle, -margin);
+    wlFolderName.setLayoutData(fdlFolderName);
+
+    wbFolderName = new Button(shell, SWT.PUSH | SWT.CENTER);
+    PropsUi.setLook(wbFolderName);
+    wbFolderName.setText(BaseMessages.getString(PKG, "System.Button.Browse"));
+    FormData fdbFolderName = new FormData();
+    fdbFolderName.right = new FormAttachment(100, 0);
+    fdbFolderName.top = new FormAttachment(wAction, 0);
+    wbFolderName.setLayoutData(fdbFolderName);
+
+    wFolderName = new TextVar(variables, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+    PropsUi.setLook(wFolderName);
+    wFolderName.addModifyListener(lsMod);
+    FormData fdFolderName = new FormData();
+    fdFolderName.left = new FormAttachment(middle, 0);
+    fdFolderName.top = new FormAttachment(wAction, margin);
+    fdFolderName.right = new FormAttachment(wbFolderName, -margin);
+    wFolderName.setLayoutData(fdFolderName);
 
     // Whenever something changes, set the tooltip to the expanded version:
-    wFoldername.addModifyListener(
-        e -> wFoldername.setToolTipText(variables.resolve(wFoldername.getText())));
+    wFolderName.addModifyListener(
+        e -> wFolderName.setToolTipText(variables.resolve(wFolderName.getText())));
 
-    wbFoldername.addListener(
-        SWT.Selection, e -> BaseDialog.presentDirectoryDialog(shell, wFoldername, variables));
+    wbFolderName.addListener(
+        SWT.Selection, e -> BaseDialog.presentDirectoryDialog(shell, wFolderName, variables));
 
     // Create destination folder
     wlCreateDestinationFolder = new Label(shell, SWT.RIGHT);
@@ -190,7 +191,7 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     PropsUi.setLook(wlCreateDestinationFolder);
     FormData fdlCreateDestinationFolder = new FormData();
     fdlCreateDestinationFolder.left = new FormAttachment(0, 0);
-    fdlCreateDestinationFolder.top = new FormAttachment(wFoldername, margin);
+    fdlCreateDestinationFolder.top = new FormAttachment(wFolderName, margin);
     fdlCreateDestinationFolder.right = new FormAttachment(middle, -margin);
     wlCreateDestinationFolder.setLayoutData(fdlCreateDestinationFolder);
     wCreateDestinationFolder = new Button(shell, SWT.CHECK);
@@ -203,13 +204,7 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdCreateDestinationFolder.top = new FormAttachment(wlCreateDestinationFolder, 0, SWT.CENTER);
     fdCreateDestinationFolder.right = new FormAttachment(100, 0);
     wCreateDestinationFolder.setLayoutData(fdCreateDestinationFolder);
-    wCreateDestinationFolder.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-          }
-        });
+    wCreateDestinationFolder.addListener(SWT.Selection, e -> action.setChanged());
 
     // Overwrite files
     wlOverwriteFile = new Label(shell, SWT.RIGHT);
@@ -230,13 +225,7 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdOverwriteFile.top = new FormAttachment(wlOverwriteFile, 0, SWT.CENTER);
     fdOverwriteFile.right = new FormAttachment(100, 0);
     wOverwriteFile.setLayoutData(fdOverwriteFile);
-    wOverwriteFile.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-          }
-        });
+    wOverwriteFile.addListener(SWT.Selection, e -> action.setChanged());
 
     // Remove source filename from result filenames
     wlRemovedSourceFilename = new Label(shell, SWT.RIGHT);
@@ -257,13 +246,7 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdRemovedSourceFilename.top = new FormAttachment(wlRemovedSourceFilename, 0, SWT.CENTER);
     fdRemovedSourceFilename.right = new FormAttachment(100, 0);
     wRemovedSourceFilename.setLayoutData(fdRemovedSourceFilename);
-    wRemovedSourceFilename.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-          }
-        });
+    wRemovedSourceFilename.addListener(SWT.Selection, e -> action.setChanged());
 
     // Add destination filename to result filenames
     wlAddDestinationFilename = new Label(shell, SWT.RIGHT);
@@ -285,15 +268,9 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdAddDestinationFilename.top = new FormAttachment(wlAddDestinationFilename, 0, SWT.CENTER);
     fdAddDestinationFilename.right = new FormAttachment(100, 0);
     wAddDestinationFilename.setLayoutData(fdAddDestinationFilename);
-    wAddDestinationFilename.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-          }
-        });
+    wAddDestinationFilename.addListener(SWT.Selection, e -> action.setChanged());
 
-    // Create multi-part file?
+    // Add date?
     wlAddDate = new Label(shell, SWT.RIGHT);
     wlAddDate.setText(BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.AddDate.Label"));
     PropsUi.setLook(wlAddDate);
@@ -311,15 +288,14 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdAddDate.top = new FormAttachment(wlAddDate, 0, SWT.CENTER);
     fdAddDate.right = new FormAttachment(100, 0);
     wAddDate.setLayoutData(fdAddDate);
-    wAddDate.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-            setAddDateBeforeExtension();
-          }
+    wAddDate.addListener(
+        SWT.Selection,
+        e -> {
+          action.setChanged();
+          setAddDateBeforeExtension();
         });
-    // Create multi-part file?
+
+    // Add time?
     wlAddTime = new Label(shell, SWT.RIGHT);
     wlAddTime.setText(BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.AddTime.Label"));
     PropsUi.setLook(wlAddTime);
@@ -337,13 +313,11 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdAddTime.top = new FormAttachment(wlAddTime, 0, SWT.CENTER);
     fdAddTime.right = new FormAttachment(100, 0);
     wAddTime.setLayoutData(fdAddTime);
-    wAddTime.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-            setAddDateBeforeExtension();
-          }
+    wAddTime.addListener(
+        SWT.Selection,
+        e -> {
+          action.setChanged();
+          setAddDateBeforeExtension();
         });
 
     // Specify date time format?
@@ -365,14 +339,12 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdSpecifyFormat.top = new FormAttachment(wlSpecifyFormat, 0, SWT.CENTER);
     fdSpecifyFormat.right = new FormAttachment(100, 0);
     wSpecifyFormat.setLayoutData(fdSpecifyFormat);
-    wSpecifyFormat.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-            setDateTimeFormat();
-            setAddDateBeforeExtension();
-          }
+    wSpecifyFormat.addListener(
+        SWT.Selection,
+        e -> {
+          action.setChanged();
+          setDateTimeFormat();
+          setAddDateBeforeExtension();
         });
 
     // Prepare a list of possible DateTimeFormats...
@@ -421,13 +393,11 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdAddDateBeforeExtension.top = new FormAttachment(wlAddDateBeforeExtension, 0, SWT.CENTER);
     fdAddDateBeforeExtension.right = new FormAttachment(100, 0);
     wAddDateBeforeExtension.setLayoutData(fdAddDateBeforeExtension);
-    wAddDateBeforeExtension.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-            checkLimit();
-          }
+    wAddDateBeforeExtension.addListener(
+        SWT.Selection,
+        e -> {
+          action.setChanged();
+          checkLimit();
         });
 
     // LimitTo grouping?
@@ -464,13 +434,11 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     fdSpecifyWildcard.top = new FormAttachment(wlSpecifyWildcard, 0, SWT.CENTER);
     fdSpecifyWildcard.right = new FormAttachment(100, 0);
     wSpecifyWildcard.setLayoutData(fdSpecifyWildcard);
-    wSpecifyWildcard.addSelectionListener(
-        new SelectionAdapter() {
-          @Override
-          public void widgetSelected(SelectionEvent e) {
-            action.setChanged();
-            checkLimit();
-          }
+    wSpecifyWildcard.addListener(
+        SWT.Selection,
+        e -> {
+          action.setChanged();
+          checkLimit();
         });
 
     // Wildcard line
@@ -532,7 +500,7 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     // / END OF LimitTo GROUP
     // ///////////////////////////////////////////////////////////
 
-    // SuccessOngrouping?
+    // SuccessOn grouping?
     // ////////////////////////
     // START OF SUCCESS ON GROUP///
     // /
@@ -541,11 +509,10 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     wSuccessOn.setText(
         BaseMessages.getString(PKG, "ActionCopyMoveResultFilenames.SuccessOn.Group.Label"));
 
-    FormLayout successongroupLayout = new FormLayout();
-    successongroupLayout.marginWidth = 10;
-    successongroupLayout.marginHeight = 10;
-
-    wSuccessOn.setLayout(successongroupLayout);
+    FormLayout successOnGroupLayout = new FormLayout();
+    successOnGroupLayout.marginWidth = 10;
+    successOnGroupLayout.marginHeight = 10;
+    wSuccessOn.setLayout(successOnGroupLayout);
 
     // Success Condition
     Label wlSuccessCondition = new Label(wSuccessOn, SWT.RIGHT);
@@ -665,26 +632,14 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     wlAddTime.setEnabled(!wSpecifyFormat.getSelection());
   }
 
-  /** Copy information from the meta-data input to the dialog fields. */
+  /** Copy information from the metadata input to the dialog fields. */
   public void getData() {
     wName.setText(Const.NVL(action.getName(), ""));
     wSpecifyWildcard.setSelection(action.isSpecifyWildcard());
-    if (action.getWildcard() != null) {
-      wWildcard.setText(action.getWildcard());
-    }
-    if (action.getWildcardExclude() != null) {
-      wWildcardExclude.setText(action.getWildcardExclude());
-    }
-
-    if (action.getDestinationFolder() != null) {
-      wFoldername.setText(action.getDestinationFolder());
-    }
-
-    if (action.getNrErrorsLessThan() != null) {
-      wNrErrorsLessThan.setText(action.getNrErrorsLessThan());
-    } else {
-      wNrErrorsLessThan.setText("10");
-    }
+    wWildcard.setText(Const.NVL(action.getWildcard(), ""));
+    wWildcardExclude.setText(Const.NVL(action.getWildcardExclude(), ""));
+    wFolderName.setText(Const.NVL(action.getDestinationFolder(), ""));
+    wNrErrorsLessThan.setText(Const.NVL(action.getNrErrorsLessThan(), "10"));
 
     if (action.getSuccessCondition() != null) {
       if (action
@@ -703,9 +658,9 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     }
 
     if (action.getAction() != null) {
-      if (action.getAction().equals("move")) {
+      if (action.getAction() == ActionType.MOVE) {
         wAction.select(1);
-      } else if (action.getAction().equals("delete")) {
+      } else if (action.getAction() == ActionType.DELETE) {
         wAction.select(2);
       } else {
         wAction.select(0);
@@ -752,7 +707,7 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     action.setWildcard(wWildcard.getText());
     action.setWildcardExclude(wWildcardExclude.getText());
 
-    action.setDestinationFolder(wFoldername.getText());
+    action.setDestinationFolder(wFolderName.getText());
     action.setNrErrorsLessThan(wNrErrorsLessThan.getText());
 
     if (wSuccessCondition.getSelectionIndex() == 1) {
@@ -764,11 +719,11 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     }
 
     if (wAction.getSelectionIndex() == 1) {
-      action.setAction("move");
+      action.setAction(ActionType.MOVE);
     } else if (wAction.getSelectionIndex() == 2) {
-      action.setAction("delete");
+      action.setAction(ActionType.DELETE);
     } else {
-      action.setAction("copy");
+      action.setAction(ActionType.COPY);
     }
 
     action.setAddDate(wAddDate.getSelection());
@@ -806,8 +761,8 @@ public class ActionCopyMoveResultFilenamesDialog extends ActionDialog {
     wDateTimeFormat.setEnabled(copyOrMove);
     wAddDateBeforeExtension.setEnabled(copyOrMove);
     wlAddDateBeforeExtension.setEnabled(copyOrMove);
-    wlFoldername.setEnabled(copyOrMove);
-    wFoldername.setEnabled(copyOrMove);
-    wbFoldername.setEnabled(copyOrMove);
+    wlFolderName.setEnabled(copyOrMove);
+    wFolderName.setEnabled(copyOrMove);
+    wbFolderName.setEnabled(copyOrMove);
   }
 }
diff --git a/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java b/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java
new file mode 100644
index 0000000000..c023653d8b
--- /dev/null
+++ b/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/ActionCopyMoveResultFilenamesTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.copymoveresultfilenames;
+
+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 ActionCopyMoveResultFilenamesTest {
+  @Test
+  void testSerializationRoundTrip() throws Exception {
+    ActionCopyMoveResultFilenames action =
+        ActionSerializationTestUtil.testSerialization(
+            "/action-copy-move-result-filenames.xml", ActionCopyMoveResultFilenames.class);
+
+    assertEquals("folder", action.getFolderName());
+    assertTrue(action.isSpecifyWildcard());
+    assertEquals("wildcard", action.getWildcard());
+    assertEquals("exclusionWildcard", action.getWildcardExclude());
+    assertEquals("destination", action.getDestinationFolder());
+    assertEquals("10", action.getNrErrorsLessThan());
+    assertEquals("success_when_at_least", action.getSuccessCondition());
+    assertTrue(action.isAddDate());
+    assertTrue(action.isAddTime());
+    assertTrue(action.isSpecifyFormat());
+    assertEquals("dt_format", action.getDateTimeFormat());
+    assertEquals(ActionCopyMoveResultFilenames.ActionType.MOVE, action.getAction());
+    assertTrue(action.isAddDateBeforeExtension());
+    assertTrue(action.isOverwriteFile());
+    assertTrue(action.isCreateDestinationFolder());
+    assertTrue(action.isRemovedSourceFilename());
+    assertTrue(action.isAddDestinationFilename());
+  }
+}
diff --git a/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/WorkflowActionCopyMoveResultFilenamesTest.java b/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/WorkflowActionCopyMoveResultFilenamesTest.java
deleted file mode 100644
index 4c54727ec0..0000000000
--- a/plugins/actions/copymoveresultfilenames/src/test/java/org/apache/hop/workflow/actions/copymoveresultfilenames/WorkflowActionCopyMoveResultFilenamesTest.java
+++ /dev/null
@@ -1,101 +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.copymoveresultfilenames;
-
-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 WorkflowActionCopyMoveResultFilenamesTest
-    extends WorkflowActionLoadSaveTestSupport<ActionCopyMoveResultFilenames> {
-  @RegisterExtension
-  static RestoreHopEngineEnvironmentExtension env = new RestoreHopEngineEnvironmentExtension();
-
-  @Override
-  protected Class<ActionCopyMoveResultFilenames> getActionClass() {
-    return ActionCopyMoveResultFilenames.class;
-  }
-
-  @Override
-  protected List<String> listAttributes() {
-    return Arrays.asList(
-        "foldername",
-        "specifywildcard",
-        "wildcard",
-        "wildcardexclude",
-        "destination_folder",
-        "nr_errors_less_than",
-        "success_condition",
-        "add_date",
-        "add_time",
-        "SpecifyFormat",
-        "date_time_format",
-        "action",
-        "AddDateBeforeExtension",
-        "OverwriteFile",
-        "CreateDestinationFolder",
-        "RemovedSourceFilename",
-        "AddDestinationFilename");
-  }
-
-  @Override
-  protected Map<String, String> createGettersMap() {
-    return toMap(
-        "foldername", "getFoldername",
-        "specifywildcard", "isSpecifyWildcard",
-        "wildcard", "getWildcard",
-        "wildcardexclude", "getWildcardExclude",
-        "destination_folder", "getDestinationFolder",
-        "nr_errors_less_than", "getNrErrorsLessThan",
-        "success_condition", "getSuccessCondition",
-        "add_date", "isAddDate",
-        "add_time", "isAddTime",
-        "SpecifyFormat", "isSpecifyFormat",
-        "date_time_format", "getDateTimeFormat",
-        "action", "getAction",
-        "AddDateBeforeExtension", "isAddDateBeforeExtension",
-        "OverwriteFile", "isOverwriteFile",
-        "CreateDestinationFolder", "isCreateDestinationFolder",
-        "RemovedSourceFilename", "isRemovedSourceFilename",
-        "AddDestinationFilename", "isAddDestinationFilename");
-  }
-
-  @Override
-  protected Map<String, String> createSettersMap() {
-    return toMap(
-        "foldername", "setFoldername",
-        "specifywildcard", "setSpecifyWildcard",
-        "wildcard", "setWildcard",
-        "wildcardexclude", "setWildcardExclude",
-        "destination_folder", "setDestinationFolder",
-        "nr_errors_less_than", "setNrErrorsLessThan",
-        "success_condition", "setSuccessCondition",
-        "add_date", "setAddDate",
-        "add_time", "setAddTime",
-        "SpecifyFormat", "setSpecifyFormat",
-        "date_time_format", "setDateTimeFormat",
-        "action", "setAction",
-        "AddDateBeforeExtension", "setAddDateBeforeExtension",
-        "OverwriteFile", "setOverwriteFile",
-        "CreateDestinationFolder", "setCreateDestinationFolder",
-        "RemovedSourceFilename", "setRemovedSourceFilename",
-        "AddDestinationFilename", "setAddDestinationFilename");
-  }
-}
diff --git a/plugins/actions/copymoveresultfilenames/src/test/resources/action-copy-move-result-filenames.xml b/plugins/actions/copymoveresultfilenames/src/test/resources/action-copy-move-result-filenames.xml
new file mode 100644
index 0000000000..f7d2294a72
--- /dev/null
+++ b/plugins/actions/copymoveresultfilenames/src/test/resources/action-copy-move-result-filenames.xml
@@ -0,0 +1,39 @@
+<?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>
+    <foldername>folder</foldername>
+    <specify_wildcard>Y</specify_wildcard>
+    <wildcard>wildcard</wildcard>
+    <wildcardexclude>exclusionWildcard</wildcardexclude>
+    <destination_folder>destination</destination_folder>
+    <nr_errors_less_than>10</nr_errors_less_than>
+    <success_condition>success_when_at_least</success_condition>
+    <add_date>Y</add_date>
+    <add_time>Y</add_time>
+    <SpecifyFormat>Y</SpecifyFormat>
+    <date_time_format>dt_format</date_time_format>
+    <action>move</action>
+    <AddDateBeforeExtension>Y</AddDateBeforeExtension>
+    <OverwriteFile>Y</OverwriteFile>
+    <CreateDestinationFolder>Y</CreateDestinationFolder>
+    <RemovedSourceFilename>Y</RemovedSourceFilename>
+    <AddDestinationFilename>Y</AddDestinationFilename>
+</action>
+