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

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


The following commit(s) were added to refs/heads/master by this push:
     new c67168bd4d Revert "Cleanup XML of action Workflow #2002 and Pipeline 
#1986"
     new 5ca9a18b00 Merge pull request #2179 from hansva/master
c67168bd4d is described below

commit c67168bd4d6514fd090e86ab702ea02dec6c5f91
Author: Nicolas Adment <[email protected]>
AuthorDate: Fri Jan 13 22:13:00 2023 +0100

    Revert "Cleanup XML of action Workflow #2002 and Pipeline #1986"
    
    This reverts commit 739b3706514a8a08a33203c342a8386eaa75352d.
---
 .../java/org/apache/hop/core/logging/LogLevel.java |  91 ++--
 .../workflow/actions/pipeline/ActionPipeline.java  | 510 ++++++++++-----------
 .../actions/pipeline/ActionPipelineDialog.java     | 185 ++++----
 .../workflow/actions/workflow/ActionWorkflow.java  | 427 ++++++++---------
 .../actions/workflow/ActionWorkflowDialog.java     | 208 +++++----
 .../actions/workflow/ActionWorkflowRunner.java     |   1 +
 .../hop/ui/core/widget/MetaSelectionLine.java      |  11 +-
 .../hop/ui/workflow/actions/ActionBaseDialog.java  |  64 ++-
 .../actions/messages/messages_en_US.properties     |   2 +-
 9 files changed, 763 insertions(+), 736 deletions(-)

diff --git a/core/src/main/java/org/apache/hop/core/logging/LogLevel.java 
b/core/src/main/java/org/apache/hop/core/logging/LogLevel.java
index 5d5218e535..5b3aaef223 100644
--- a/core/src/main/java/org/apache/hop/core/logging/LogLevel.java
+++ b/core/src/main/java/org/apache/hop/core/logging/LogLevel.java
@@ -18,71 +18,61 @@
 package org.apache.hop.core.logging;
 
 import org.apache.hop.i18n.BaseMessages;
-import org.apache.hop.metadata.api.IEnumHasCode;
-import org.apache.hop.metadata.api.IEnumHasCodeAndDescription;
-
-public enum LogLevel implements IEnumHasCodeAndDescription {
-  NOTHING(0, "Nothing", "LogWriter.Level.Nothing.LongDesc"),
-  ERROR(1, "Error", "LogWriter.Level.Error.LongDesc"),
-  MINIMAL(2, "Minimal", "LogWriter.Level.Minimal.LongDesc"),
-  BASIC(3, "Basic", "LogWriter.Level.Basic.LongDesc"),
-  DETAILED(4, "Detailed", "LogWriter.Level.Detailed.LongDesc"),
-  DEBUG(5, "Debug", "LogWriter.Level.Debug.LongDesc"),
-  ROWLEVEL(6, "Rowlevel", "LogWriter.Level.Rowlevel.LongDesc");
-
-  private final int level;
-  private final String code;
-  private final String description;
-
-  private LogLevel(int level, String code, String description) {
+
+public enum LogLevel {
+  NOTHING(0, "Nothing"),
+  ERROR(1, "Error"),
+  MINIMAL(2, "Minimal"),
+  BASIC(3, "Basic"),
+  DETAILED(4, "Detailed"),
+  DEBUG(5, "Debug"),
+  ROWLEVEL(6, "Rowlevel");
+
+  private static final Class<?> PKG = LogLevel.class; // For Translator
+
+  public static final String[] logLevelDescriptions = {
+    BaseMessages.getString(PKG, "LogWriter.Level.Nothing.LongDesc"),
+    BaseMessages.getString(PKG, "LogWriter.Level.Error.LongDesc"),
+    BaseMessages.getString(PKG, "LogWriter.Level.Minimal.LongDesc"),
+    BaseMessages.getString(PKG, "LogWriter.Level.Basic.LongDesc"),
+    BaseMessages.getString(PKG, "LogWriter.Level.Detailed.LongDesc"),
+    BaseMessages.getString(PKG, "LogWriter.Level.Debug.LongDesc"),
+    BaseMessages.getString(PKG, "LogWriter.Level.Rowlevel.LongDesc"),
+  };
+
+  private int level;
+  private String code;
+
+  private LogLevel(int level, String code) {
     this.level = level;
     this.code = code;
-    this.description = BaseMessages.getString(LogLevel.class, description);
   }
 
   public int getLevel() {
     return level;
   }
 
-  @Override
   public String getCode() {
     return code;
   }
 
-  @Override
   public String getDescription() {
-    return description;
+    return logLevelDescriptions[level];
   }
-  
+
   /**
    * Return the log level for a certain log level code
    *
    * @param code the code to look for
    * @return the log level or BASIC if nothing matches.
    */
-  @Deprecated
   public static LogLevel getLogLevelForCode(String code) {
-    return IEnumHasCode.lookupCode(LogLevel.class, code, LogLevel.BASIC);
-  }
-  
-  /**
-   * Return the log level for a certain log level code
-   *
-   * @param code the code to look for
-   * @return the log level or BASIC if nothing matches.
-   */  
-  public static LogLevel lookupCode(final String code) {
-    return IEnumHasCode.lookupCode(LogLevel.class, code, LogLevel.BASIC);
-  }
-  
-  /**
-   * Return the log level for a certain log level description
-   *
-   * @param description the description to look for
-   * @return the log level or BASIC if nothing matches.
-   */  
-  public static LogLevel lookupDescription(final String description) {
-    return IEnumHasCodeAndDescription.lookupDescription(LogLevel.class, 
description, LogLevel.BASIC);
+    for (LogLevel logLevel : values()) {
+      if (logLevel.getCode().equalsIgnoreCase(code)) {
+        return logLevel;
+      }
+    }
+    return BASIC;
   }
 
   /**
@@ -128,16 +118,17 @@ public enum LogLevel implements 
IEnumHasCodeAndDescription {
     return this.level >= ROWLEVEL.level;
   }
 
-  /** 
-   * Return an array of log level descriptions, sorted by level (0==Nothing, 
6=Row Level)
-   * @return An array of log level descriptions
-   */
+  /** @return An array of log level descriptions, sorted by level (0==Nothing, 
6=Row Level) */
   public static String[] getLogLevelDescriptions() {
-    return IEnumHasCodeAndDescription.getDescriptions(LogLevel.class);
+    return logLevelDescriptions;
   }
 
   /** @return An array of log level codes, sorted by level (0==Nothing, 6=Row 
Level) */
   public static String[] logLogLevelCodes() {
-    return IEnumHasCode.getCodes(LogLevel.class);
+    String[] codes = new String[values().length];
+    for (int i = 0; i < codes.length; i++) {
+      codes[i] = values()[i].getCode();
+    }
+    return codes;
   }
 }
diff --git 
a/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipeline.java
 
b/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipeline.java
index cb16636561..98164e0446 100644
--- 
a/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipeline.java
+++ 
b/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipeline.java
@@ -26,6 +26,7 @@ import org.apache.hop.core.RowMetaAndData;
 import org.apache.hop.core.SqlStatement;
 import org.apache.hop.core.annotations.Action;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.exception.HopXmlException;
 import org.apache.hop.core.file.IHasFilename;
 import org.apache.hop.core.logging.LogChannelFileWriter;
 import org.apache.hop.core.logging.LogLevel;
@@ -37,8 +38,8 @@ import org.apache.hop.core.util.FileUtil;
 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.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.TransformWithMappingMeta;
@@ -55,6 +56,7 @@ import org.apache.hop.workflow.action.IAction;
 import org.apache.hop.workflow.action.validator.ActionValidatorUtils;
 import org.apache.hop.workflow.action.validator.AndValidator;
 import org.apache.hop.workflow.engine.IWorkflowEngine;
+import org.w3c.dom.Node;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -74,144 +76,80 @@ import java.util.Map;
 public class ActionPipeline extends ActionBase implements Cloneable, IAction {
   private static final Class<?> PKG = ActionPipeline.class; // For Translator
 
-  public static final class ParameterDefinition {
-    @HopMetadataProperty(key = "pass_all_parameters")
-    private boolean passingAllParameters = true;
-    
-    @HopMetadataProperty(groupKey = "parameters", key = "parameter")
-    private List<Parameter> parameters;
-
-    public ParameterDefinition() {
-      this.parameters = new ArrayList<>();
-    }
+  private String filename;
 
-    public boolean isPassingAllParameters() {
-      return passingAllParameters;
-    }
+  public String[] arguments;
 
-    public void setPassingAllParameters(boolean passingAllParameters) {
-      this.passingAllParameters = passingAllParameters;
-    }
-    
-    public List<Parameter> getParameters() {
-      return parameters;
-    }
+  public boolean paramsFromPrevious;
 
-    public void setParameters(List<Parameter> parameters) {
-      this.parameters = parameters;
-    }
-    
-    public String[] getNames() {
-      List<String> list = new ArrayList<>();
-      for (Parameter parameter:parameters) {
-        list.add(parameter.getName());
-      }
-      return list.toArray(new String[0]);
-    }
-    
-    public String[] getValues() {
-      List<String> list = new ArrayList<>();
-      for (Parameter parameter:parameters) {
-        list.add(parameter.getValue());
-      }
-      return list.toArray(new String[0]);
-    }
-  }
-  
-  public static final class Parameter {
-    @HopMetadataProperty
-    public String name;
-    @HopMetadataProperty
-    public String value;
-    @HopMetadataProperty(key="stream_name")
-    public String field;   
-    
-    public String getName() {
-      return name;
-    }
-    public String getValue() {
-      return value;
-    }
-    public String getField() {
-      return field;
-    }
-    public void setName(String name) {
-      this.name = name;
-    }
-    public void setValue(String value) {
-      this.value = value;
-    }
-    public void setField(String field) {
-      this.field = field;
-    }
-  }
-  
-  @HopMetadataProperty(key = "filename")
-  private String filename;
+  public boolean execPerRow;
 
-  @HopMetadataProperty(key = "params_from_previous")
-  private boolean paramsFromPrevious;
+  public String[] parameters;
 
-  @HopMetadataProperty(key = "exec_per_row")
-  private boolean execPerRow;
+  public String[] parameterFieldNames;
 
-  @HopMetadataProperty(key = "clear_rows")
-  private boolean clearResultRows;
+  public String[] parameterValues;
 
-  @HopMetadataProperty(key = "clear_files")
-  private boolean clearResultFiles;
+  public boolean clearResultRows;
 
-  @HopMetadataProperty(key = "create_parent_folder")
-  private boolean createParentFolder;
+  public boolean clearResultFiles;
 
-  @HopMetadataProperty(key = "set_logfile")
-  private boolean setLogfile;
+  public boolean createParentFolder;
 
-  @HopMetadataProperty(key = "set_append_logfile")
-  private boolean setAppendLogfile;
+  public boolean setLogfile;
 
-  @HopMetadataProperty(key = "logfile")
-  private String logfile;
+  public boolean setAppendLogfile;
 
-  @HopMetadataProperty(key = "logext")  
-  private String logext;
+  public String logfile;
+  public String logext;
+  public boolean addDate;
+  public boolean addTime;
 
-  @HopMetadataProperty(key = "add_date")
-  private boolean addDate;
+  public LogLevel logFileLevel;
 
-  @HopMetadataProperty(key = "add_time")
-  private boolean addTime;
- 
-  @HopMetadataProperty(key = "loglevel", storeWithCode = true)
-  private LogLevel logFileLevel;
+  public boolean waitingToFinish = true;
 
-  @HopMetadataProperty(key = "wait_until_finished")
-  private boolean waitingToFinish = true;
+  private boolean passingAllParameters = true;
 
-  @HopMetadataProperty(key = "parameters")
-  private ParameterDefinition parameterDefinition;
-  
-  @HopMetadataProperty(key = "run_configuration")
   private String runConfiguration;
 
   private IPipelineEngine<PipelineMeta> pipeline;
 
   public ActionPipeline(String name) {
     super(name, "");
-    this.parameterDefinition = new ParameterDefinition();
   }
 
   public ActionPipeline() {
     this("");
     clear();
   }
-  
-  public ParameterDefinition getParameterDefinition() {
-    return parameterDefinition;
+
+  private void allocateArgs(int nrArgs) {
+    arguments = new String[nrArgs];
   }
 
-  public void setParameterDefinition(ParameterDefinition parameterDefinition) {
-    this.parameterDefinition = parameterDefinition;
+  private void allocateParams(int nrParameters) {
+    parameters = new String[nrParameters];
+    parameterFieldNames = new String[nrParameters];
+    parameterValues = new String[nrParameters];
+  }
+
+  @Override
+  public Object clone() {
+    ActionPipeline je = (ActionPipeline) super.clone();
+    if (arguments != null) {
+      int nrArgs = arguments.length;
+      je.allocateArgs(nrArgs);
+      System.arraycopy(arguments, 0, je.arguments, 0, nrArgs);
+    }
+    if (parameters != null) {
+      int nrParameters = parameters.length;
+      je.allocateParams(nrParameters);
+      System.arraycopy(parameters, 0, je.parameters, 0, nrParameters);
+      System.arraycopy(parameterFieldNames, 0, je.parameterFieldNames, 0, 
nrParameters);
+      System.arraycopy(parameterValues, 0, je.parameterValues, 0, 
nrParameters);
+    }
+    return je;
   }
 
   public void setFileName(String n) {
@@ -248,11 +186,139 @@ public class ActionPipeline extends ActionBase 
implements Cloneable, IAction {
     return retval;
   }
 
+  @Override
+  public String getXml() {
+    StringBuilder retval = new StringBuilder(300);
+
+    retval.append(super.getXml());
+
+    retval.append("      ").append(XmlHandler.addTagValue("filename", 
filename));
+    retval
+        .append("      ")
+        .append(XmlHandler.addTagValue("params_from_previous", 
paramsFromPrevious));
+    retval.append("      ").append(XmlHandler.addTagValue("exec_per_row", 
execPerRow));
+    retval.append("      ").append(XmlHandler.addTagValue("clear_rows", 
clearResultRows));
+    retval.append("      ").append(XmlHandler.addTagValue("clear_files", 
clearResultFiles));
+    retval.append("      ").append(XmlHandler.addTagValue("set_logfile", 
setLogfile));
+    retval.append("      ").append(XmlHandler.addTagValue("logfile", logfile));
+    retval.append("      ").append(XmlHandler.addTagValue("logext", logext));
+    retval.append("      ").append(XmlHandler.addTagValue("add_date", 
addDate));
+    retval.append("      ").append(XmlHandler.addTagValue("add_time", 
addTime));
+    retval
+        .append("      ")
+        .append(
+            XmlHandler.addTagValue(
+                "loglevel", logFileLevel != null ? logFileLevel.getCode() : 
null));
+    retval.append("      
").append(XmlHandler.addTagValue("set_append_logfile", setAppendLogfile));
+    retval.append("      
").append(XmlHandler.addTagValue("wait_until_finished", waitingToFinish));
+    retval
+        .append("      ")
+        .append(XmlHandler.addTagValue("create_parent_folder", 
createParentFolder));
+    retval.append("      ").append(XmlHandler.addTagValue("run_configuration", 
runConfiguration));
+
+    if (arguments != null) {
+      for (int i = 0; i < arguments.length; i++) {
+        // This is a very very bad way of making an XML file, don't use it (or
+        // copy it). Sven Boden
+        retval.append("      ").append(XmlHandler.addTagValue("argument" + i, 
arguments[i]));
+      }
+    }
+
+    if (parameters != null) {
+      retval.append("      
").append(XmlHandler.openTag("parameters")).append(Const.CR);
+
+      retval
+          .append("        ")
+          .append(XmlHandler.addTagValue("pass_all_parameters", 
passingAllParameters));
+
+      for (int i = 0; i < parameters.length; i++) {
+        // This is a better way of making the XML file than the arguments.
+        retval.append("        
").append(XmlHandler.openTag("parameter")).append(Const.CR);
+
+        retval.append("          ").append(XmlHandler.addTagValue("name", 
parameters[i]));
+        retval
+            .append("          ")
+            .append(XmlHandler.addTagValue("stream_name", 
parameterFieldNames[i]));
+        retval.append("          ").append(XmlHandler.addTagValue("value", 
parameterValues[i]));
+
+        retval.append("        
").append(XmlHandler.closeTag("parameter")).append(Const.CR);
+      }
+      retval.append("      
").append(XmlHandler.closeTag("parameters")).append(Const.CR);
+    }
+
+    return retval.toString();
+  }
+
+  @Override
+  public void loadXml(Node entrynode, IHopMetadataProvider metadataProvider, 
IVariables variables)
+      throws HopXmlException {
+    try {
+      super.loadXml(entrynode);
+
+      filename = XmlHandler.getTagValue(entrynode, "filename");
+
+      paramsFromPrevious =
+          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"params_from_previous"));
+      execPerRow = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"exec_per_row"));
+      clearResultRows = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"clear_rows"));
+      clearResultFiles = 
"Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, "clear_files"));
+      setLogfile = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"set_logfile"));
+      addDate = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"add_date"));
+      addTime = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"add_time"));
+      logfile = XmlHandler.getTagValue(entrynode, "logfile");
+      logext = XmlHandler.getTagValue(entrynode, "logext");
+      logFileLevel = 
LogLevel.getLogLevelForCode(XmlHandler.getTagValue(entrynode, "loglevel"));
+      createParentFolder =
+          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"create_parent_folder"));
+      runConfiguration = XmlHandler.getTagValue(entrynode, 
"run_configuration");
+
+      setAppendLogfile =
+          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"set_append_logfile"));
+      String wait = XmlHandler.getTagValue(entrynode, "wait_until_finished");
+      if (Utils.isEmpty(wait)) {
+        waitingToFinish = true;
+      } else {
+        waitingToFinish = "Y".equalsIgnoreCase(wait);
+      }
+
+      // How many arguments?
+      int argnr = 0;
+      while (XmlHandler.getTagValue(entrynode, "argument" + argnr) != null) {
+        argnr++;
+      }
+      allocateArgs(argnr);
+
+      // Read them all...
+      for (int a = 0; a < argnr; a++) {
+        arguments[a] = XmlHandler.getTagValue(entrynode, "argument" + a);
+      }
+
+      Node parametersNode = XmlHandler.getSubNode(entrynode, "parameters");
+
+      String passAll = XmlHandler.getTagValue(parametersNode, 
"pass_all_parameters");
+      passingAllParameters = Utils.isEmpty(passAll) || 
"Y".equalsIgnoreCase(passAll);
+
+      int nrParameters = XmlHandler.countNodes(parametersNode, "parameter");
+      allocateParams(nrParameters);
+
+      for (int i = 0; i < nrParameters; i++) {
+        Node knode = XmlHandler.getSubNodeByNr(parametersNode, "parameter", i);
+
+        parameters[i] = XmlHandler.getTagValue(knode, "name");
+        parameterFieldNames[i] = XmlHandler.getTagValue(knode, "stream_name");
+        parameterValues[i] = XmlHandler.getTagValue(knode, "value");
+      }
+    } catch (HopException e) {
+      throw new HopXmlException("Unable to load action of type 'pipeline' from 
XML node", e);
+    }
+  }
+
   @Override
   public void clear() {
     super.clear();
 
     filename = null;
+    arguments = null;
     execPerRow = false;
     addDate = false;
     addTime = false;
@@ -368,24 +434,26 @@ public class ActionPipeline extends ActionBase implements 
Cloneable, IAction {
       }
 
       INamedParameters namedParam = new NamedParameters();
-      for (Parameter parameter : parameterDefinition.getParameters()) {
-        if (!Utils.isEmpty(parameter.getName())) {
-          // We have a parameter
-          //
-          namedParam.addParameterDefinition(parameter.getName(), "", "Action 
runtime");
-          if (Utils.isEmpty(Const.trim(parameter.getField()))) {
-            // There is no field name specified.
-            //
-            String value = Const.NVL(resolve(parameter.getValue()), "");
-            namedParam.setParameterValue(parameter.getName(), value);
-          } else {
-            // something filled in, in the field column...
+      if (parameters != null) {
+        for (int idx = 0; idx < parameters.length; idx++) {
+          if (!Utils.isEmpty(parameters[idx])) {
+            // We have a parameter
             //
-            String value = "";
-            if (resultRow != null) {
-              value = resultRow.getString(parameter.getField(), "");
+            namedParam.addParameterDefinition(parameters[idx], "", "Action 
runtime");
+            if (Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
+              // There is no field name specified.
+              //
+              String value = Const.NVL(resolve(parameterValues[idx]), "");
+              namedParam.setParameterValue(parameters[idx], value);
+            } else {
+              // something filled in, in the field column...
+              //
+              String value = "";
+              if (resultRow != null) {
+                value = resultRow.getString(parameterFieldNames[idx], "");
+              }
+              namedParam.setParameterValue(parameters[idx], value);
             }
-            namedParam.setParameterValue(parameter.getName(), value);
           }
         }
       }
@@ -433,55 +501,58 @@ public class ActionPipeline extends ActionBase implements 
Cloneable, IAction {
 
           if (paramsFromPrevious) { // Copy the input the parameters
 
-              for (Parameter parameter : parameterDefinition.getParameters()) {
-                if (!Utils.isEmpty(parameter.getName())) {
+            if (parameters != null) {
+              for (int idx = 0; idx < parameters.length; idx++) {
+                if (!Utils.isEmpty(parameters[idx])) {
                   // We have a parameter
-                  if (Utils.isEmpty(Const.trim(parameter.getField()))) {
+                  if (Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
                     namedParam.setParameterValue(
-                        parameter.getName(), 
Const.NVL(resolve(parameter.getValue()), ""));
+                        parameters[idx], 
Const.NVL(resolve(parameterValues[idx]), ""));
                   } else {
                     String fieldValue = "";
 
                     if (resultRow != null) {
-                      fieldValue = resultRow.getString(parameter.getField(), 
"");
+                      fieldValue = 
resultRow.getString(parameterFieldNames[idx], "");
                     }
                     // Get the value from the input stream
-                    namedParam.setParameterValue(parameter.getName(), 
Const.NVL(fieldValue, ""));
+                    namedParam.setParameterValue(parameters[idx], 
Const.NVL(fieldValue, ""));
                   }
                 }
               }
-
+            }
           }
         } else {
 
           if (paramsFromPrevious) {
             // Copy the input the parameters
-            for (Parameter parameter : parameterDefinition.getParameters()) {
-                if (!Utils.isEmpty(parameter.getName())) {
+            if (parameters != null) {
+              for (int idx = 0; idx < parameters.length; idx++) {
+                if (!Utils.isEmpty(parameters[idx])) {
                   // We have a parameter
-                  if (Utils.isEmpty(Const.trim(parameter.getField()))) {
+                  if (Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
                     namedParam.setParameterValue(
-                        parameter.getName(), 
Const.NVL(resolve(parameter.getValue()), ""));
+                        parameters[idx], 
Const.NVL(resolve(parameterValues[idx]), ""));
                   } else {
                     String fieldValue = "";
 
                     if (resultRow != null) {
-                      fieldValue = resultRow.getString(parameter.getField(), 
"");
+                      fieldValue = 
resultRow.getString(parameterFieldNames[idx], "");
                     }
                     // Get the value from the input stream
-                    namedParam.setParameterValue(parameter.getName(), 
Const.NVL(fieldValue, ""));
+                    namedParam.setParameterValue(parameters[idx], 
Const.NVL(fieldValue, ""));
                   }
                 }
               }
             }
-
+          }
         }
 
         // Handle the parameters...
         //
         String[] parameterNames = pipelineMeta.listParameters();
 
-        prepareFieldNamesParameters(parameterDefinition.getParameters(), 
namedParam, this);
+        prepareFieldNamesParameters(
+            parameters, parameterFieldNames, parameterValues, namedParam, 
this);
 
         if (StringUtils.isEmpty(runConfiguration)) {
           throw new HopException(
@@ -521,9 +592,9 @@ public class ActionPipeline extends ActionBase implements 
Cloneable, IAction {
             pipeline,
             this,
             parameterNames,
-            parameterDefinition.getNames(),
-            parameterDefinition.getValues(),
-            parameterDefinition.isPassingAllParameters());
+            parameters,
+            parameterValues,
+            isPassingAllParameters());
 
         // First get the root workflow
         //
@@ -770,7 +841,7 @@ public class ActionPipeline extends ActionBase implements 
Cloneable, IAction {
     return proposedNewFilename;
   }
 
-  public String getLogfile() {
+  protected String getLogfile() {
     return logfile;
   }
 
@@ -784,6 +855,16 @@ public class ActionPipeline extends ActionBase implements 
Cloneable, IAction {
     this.waitingToFinish = waitingToFinish;
   }
 
+  /** @return the passingAllParameters */
+  public boolean isPassingAllParameters() {
+    return passingAllParameters;
+  }
+
+  /** @param passingAllParameters the passingAllParameters to set */
+  public void setPassingAllParameters(boolean passingAllParameters) {
+    this.passingAllParameters = passingAllParameters;
+  }
+
   public String getRunConfiguration() {
     return runConfiguration;
   }
@@ -838,123 +919,38 @@ public class ActionPipeline extends ActionBase 
implements Cloneable, IAction {
     super.setParentWorkflowMeta(parentWorkflowMeta);
   }
 
-  public void prepareFieldNamesParameters(List<Parameter> parameters, 
INamedParameters namedParam,
-      ActionPipeline actionPipeline) throws UnknownParamException {
-    for (Parameter parameter : parameters) {
+  public void prepareFieldNamesParameters(
+      String[] parameters,
+      String[] parameterFieldNames,
+      String[] parameterValues,
+      INamedParameters namedParam,
+      ActionPipeline actionPipeline)
+      throws UnknownParamException {
+    for (int idx = 0; idx < parameters.length; idx++) {
       // Grab the parameter value set in the Pipeline action
-      // Set parameter.getField() only if exists and if it is not declared any 
static parameter.getValue()
+      // Set fieldNameParameter only if exists and if it is not declared any 
staticValue(
+      // parameterValues array )
       //
-      String thisValue = namedParam.getParameterValue(parameter.getName());
-      // Set value only if is not empty at namedParam and exists in 
parameter.getField
-      if (!Utils.isEmpty(Const.trim(parameter.getField()))) {
-        // If is not empty then we have to ask if it exists too in 
parameter.getValue(), since
-        // the values in parameter.getValue() prevail over parameterFieldNames
-        // If is empty at parameter.getValue(), then we can finally add that 
variable with that
-        // value
-        if (Utils.isEmpty(Const.trim(parameter.getValue()))) {
-          actionPipeline.setVariable(parameter.getName(), Const.NVL(thisValue, 
""));
+      String thisValue = namedParam.getParameterValue(parameters[idx]);
+      // Set value only if is not empty at namedParam and exists in 
parameterFieldNames
+      if (idx < parameterFieldNames.length) {
+        // If exists then ask if is not empty
+        if (!Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
+          // If is not empty then we have to ask if it exists too in 
parameterValues array, since
+          // the values in
+          // parameterValues prevail over parameterFieldNames
+          if (idx < parameterValues.length) {
+            // If is empty at parameterValues array, then we can finally add 
that variable with that
+            // value
+            if (Utils.isEmpty(Const.trim(parameterValues[idx]))) {
+              actionPipeline.setVariable(parameters[idx], Const.NVL(thisValue, 
""));
+            }
+          } else {
+            // Or if not in parameterValues then we can add that variable with 
that value too
+            actionPipeline.setVariable(parameters[idx], Const.NVL(thisValue, 
""));
+          }
         }
-      } else {
-        // Or if not in parameter.getValue() then we can add that variable 
with that value too
-        actionPipeline.setVariable(parameter.getName(), Const.NVL(thisValue, 
""));
       }
-
     }
   }
- 
-  public boolean isExecPerRow() {
-    return execPerRow;
-  }
-  
-  public void setExecPerRow(boolean runEveryResultRow) {
-    this.execPerRow = runEveryResultRow;
-  }
-  
-  public boolean isAddDate() {
-    return addDate;
-  }
-
-  public boolean isAddTime() {
-    return addTime;
-  }
-
-  public void setAddDate(boolean addDate) {
-    this.addDate = addDate;
-  }
-
-  public void setAddTime(boolean addTime) {
-    this.addTime = addTime;
-  }
-
-  public String getLogext() {
-    return logext;
-  }
-
-  public void setFilename(String filename) {
-    this.filename = filename;
-  }
-
-  public void setLogfile(String logfile) {
-    this.logfile = logfile;
-  }
-
-  public void setLogext(String logext) {
-    this.logext = logext;
-  }
-
-  public boolean isSetLogfile() {
-    return setLogfile;
-  }
-
-  public LogLevel getLogFileLevel() {
-    return logFileLevel;
-  }
-
-  public boolean isCreateParentFolder() {
-    return createParentFolder;
-  }
-
-  public void setSetLogfile(boolean setLogfile) {
-    this.setLogfile = setLogfile;
-  }
-
-  public void setLogFileLevel(LogLevel logFileLevel) {
-    this.logFileLevel = logFileLevel;
-  }
-
-  public void setCreateParentFolder(boolean createParentFolder) {
-    this.createParentFolder = createParentFolder;
-  }
-
-  public boolean isParamsFromPrevious() {
-    return paramsFromPrevious;
-  }
-
-  public boolean isSetAppendLogfile() {
-    return setAppendLogfile;
-  }
-
-  public void setParamsFromPrevious(boolean paramsFromPrevious) {
-    this.paramsFromPrevious = paramsFromPrevious;
-  }
-
-  public void setSetAppendLogfile(boolean setAppendLogfile) {
-    this.setAppendLogfile = setAppendLogfile;
-  }
-
-  public boolean isClearResultRows() {
-    return clearResultRows;
-  }
-
-  public boolean isClearResultFiles() {
-    return clearResultFiles;
-  }
-
-  public void setClearResultRows(boolean clearResultRows) {
-    this.clearResultRows = clearResultRows;
-  }
-
-  public void setClearResultFiles(boolean clearResultFiles) {
-    this.clearResultFiles = clearResultFiles;
-  }  
 }
diff --git 
a/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipelineDialog.java
 
b/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipelineDialog.java
index 2166418cb2..37bc9259f7 100644
--- 
a/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipelineDialog.java
+++ 
b/plugins/actions/pipeline/src/main/java/org/apache/hop/workflow/actions/pipeline/ActionPipelineDialog.java
@@ -33,7 +33,6 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
-import org.apache.hop.ui.core.widget.MetaSelectionLine;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.pipeline.HopPipelineFileType;
 import org.apache.hop.ui.util.SwtSvgImageUtil;
@@ -43,14 +42,13 @@ import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionBase;
 import org.apache.hop.workflow.action.IAction;
 import org.apache.hop.workflow.action.IActionDialog;
-import org.apache.hop.workflow.actions.pipeline.ActionPipeline.Parameter;
-import 
org.apache.hop.workflow.actions.pipeline.ActionPipeline.ParameterDefinition;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TableItem;
 
@@ -60,8 +58,7 @@ import java.util.List;
 public class ActionPipelineDialog extends ActionBaseDialog implements 
IActionDialog {
   private static final Class<?> PKG = ActionPipeline.class; // For Translator
 
-  private ActionPipeline action;
-  private MetaSelectionLine<PipelineRunConfiguration> wRunConfiguration;
+  protected ActionPipeline action;
 
   private static final String[] FILE_FILTERLOGNAMES =
       new String[] {
@@ -128,13 +125,30 @@ public class ActionPipelineDialog extends 
ActionBaseDialog implements IActionDia
     fdWait.top = new FormAttachment(wClearFiles, 10);
     fdWait.left = new FormAttachment(0, 0);
     wWaitingToFinish.setLayoutData(fdWait);
-    
-    // force reload from file specification
-    wbGetParams.addListener(SWT.Selection, e -> getParameters(null));
 
-    wbBrowse.addListener(SWT.Selection, e -> pickFileVFS());
-
-    wbLogFilename.addListener(SWT.Selection, e -> 
selectLogFile(FILE_FILTERLOGNAMES));
+    wbGetParams.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent arg0) {
+            getParameters(null); // force reload from file specification
+          }
+        });
+
+    wbBrowse.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent e) {
+            pickFileVFS();
+          }
+        });
+
+    wbLogFilename.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent e) {
+            selectLogFile(FILE_FILTERLOGNAMES);
+          }
+        });
   }
 
   @Override
@@ -153,8 +167,8 @@ public class ActionPipelineDialog extends ActionBaseDialog 
implements IActionDia
   }
 
   @Override
-  protected int getParameterCount() {
-    return action.getParameterDefinition().getParameters().size();
+  protected String[] getParameters() {
+    return action.parameters;
   }
 
   private void getParameters(PipelineMeta inputPipelineMeta) {
@@ -187,22 +201,6 @@ public class ActionPipelineDialog extends ActionBaseDialog 
implements IActionDia
     }
   }
 
-  @Override
-  protected Control createRunConfigurationControl() {
-    wRunConfiguration =
-        new MetaSelectionLine<>(
-            variables,            
-            metadataProvider,
-            PipelineRunConfiguration.class,
-            shell,
-            SWT.BORDER,
-            null,
-            null,
-            true);
-    
-    return wRunConfiguration;
-  }
-
   protected void pickFileVFS() {
     HopPipelineFileType<PipelineMeta> pipelineFileType = new 
HopPipelineFileType<>();
     String filename =
@@ -227,42 +225,43 @@ public class ActionPipelineDialog extends 
ActionBaseDialog implements IActionDia
     wPath.setText(Const.NVL(action.getFilename(), ""));
 
     // Parameters
-    ParameterDefinition parameterDefinition = action.getParameterDefinition();
-    if (action.getParameterDefinition() != null) {
-      for (int i = 0; i < parameterDefinition.getParameters().size(); i++) {
-        Parameter parameter = parameterDefinition.getParameters().get(i);
-        TableItem item = wParameters.getTable().getItem(i);
-        if (!Utils.isEmpty(parameter.getName())) {
-          item.setText(1, Const.NVL(parameter.getName(), ""));
-          item.setText(2, Const.NVL(parameter.getField(), ""));
-          item.setText(3, Const.NVL(parameter.getValue(), ""));
+    if (action.parameters != null) {
+      for (int i = 0; i < action.parameters.length; i++) {
+        TableItem ti = wParameters.table.getItem(i);
+        if (!Utils.isEmpty(action.parameters[i])) {
+          ti.setText(1, Const.NVL(action.parameters[i], ""));
+          ti.setText(2, Const.NVL(action.parameterFieldNames[i], ""));
+          ti.setText(3, Const.NVL(action.parameterValues[i], ""));
         }
       }
       wParameters.setRowNums();
       wParameters.optWidth(true);
     }
 
-    wPassParams.setSelection(parameterDefinition.isPassingAllParameters());
+    wPassParams.setSelection(action.isPassingAllParameters());
 
-    if (action.getLogfile() != null) {
-      wLogfile.setText(action.getLogfile());
+    if (action.logfile != null) {
+      wLogfile.setText(action.logfile);
     }
-    if (action.getLogext() != null) {
-      wLogext.setText(action.getLogext());
+    if (action.logext != null) {
+      wLogext.setText(action.logext);
     }
 
-    wPrevToParams.setSelection(action.isParamsFromPrevious());
-    wEveryRow.setSelection(action.isExecPerRow());
-    wSetLogfile.setSelection(action.isSetLogfile());
-    wAddDate.setSelection(action.isAddDate());
-    wAddTime.setSelection(action.isAddTime());
-    wClearRows.setSelection(action.isClearResultRows());
-    wClearFiles.setSelection(action.isClearResultFiles());
+    wPrevToParams.setSelection(action.paramsFromPrevious);
+    wEveryRow.setSelection(action.execPerRow);
+    wSetLogfile.setSelection(action.setLogfile);
+    wAddDate.setSelection(action.addDate);
+    wAddTime.setSelection(action.addTime);
+    wClearRows.setSelection(action.clearResultRows);
+    wClearFiles.setSelection(action.clearResultFiles);
     wWaitingToFinish.setSelection(action.isWaitingToFinish());
-    wAppendLogfile.setSelection(action.isSetAppendLogfile());
-    wCreateParentFolder.setSelection(action.isCreateParentFolder());
-    if (action.getLogFileLevel() != null) {
-      wLoglevel.select(action.getLogFileLevel().getLevel());
+    wAppendLogfile.setSelection(action.setAppendLogfile);
+
+    wbLogFilename.setSelection(action.setAppendLogfile);
+
+    wCreateParentFolder.setSelection(action.createParentFolder);
+    if (action.logFileLevel != null) {
+      wLoglevel.select(action.logFileLevel.getLevel());
     }
 
     try {
@@ -293,8 +292,6 @@ public class ActionPipelineDialog extends ActionBaseDialog 
implements IActionDia
       LogChannel.UI.logError("Error getting pipeline run configurations", e);
     }
 
-    setLogFileEnabled();
-
     wName.selectAll();
     wName.setFocus();
   }
@@ -317,48 +314,62 @@ public class ActionPipelineDialog extends 
ActionBaseDialog implements IActionDia
               PKG, 
"ActionPipeline.Dialog.Exception.NoValidMappingDetailsFound"));
     }
 
-    ParameterDefinition parameterDefinition = action.getParameterDefinition();
-    parameterDefinition.getParameters().clear();
-    
     // Do the parameters
     int nrItems = wParameters.nrNonEmpty();
+    int nr = 0;
     for (int i = 0; i < nrItems; i++) {
-      TableItem item = wParameters.getNonEmpty(i);
+      String param = wParameters.getNonEmpty(i).getText(1);
+      if (param != null && param.length() != 0) {
+        nr++;
+      }
+    }
+    actionPipeline.parameters = new String[nrItems];
+    actionPipeline.parameterFieldNames = new String[nrItems];
+    actionPipeline.parameterValues = new String[nrItems];
+    nr = 0;
+    for (int i = 0; i < nrItems; i++) {
+      String param = wParameters.getNonEmpty(i).getText(1);
+      String fieldName = wParameters.getNonEmpty(i).getText(2);
+      String value = wParameters.getNonEmpty(i).getText(3);
 
-      Parameter parameter = new Parameter();
-      parameter.setName(item.getText(1));
+      actionPipeline.parameters[nr] = param;
 
-      String fieldName = Const.trim(item.getText(2));
-      if (!Utils.isEmpty(fieldName)) {
-        parameter.setField(fieldName);
+      if (!Utils.isEmpty(Const.trim(fieldName))) {
+        actionPipeline.parameterFieldNames[nr] = fieldName;
       } else {
-        parameter.setField("");
+        actionPipeline.parameterFieldNames[nr] = "";
       }
 
-      String value = Const.trim(item.getText(3));
-      if (!Utils.isEmpty(value)) {
-        parameter.setValue(value);
+      if (!Utils.isEmpty(Const.trim(value))) {
+        actionPipeline.parameterValues[nr] = value;
       } else {
-        parameter.setValue("");
+        actionPipeline.parameterValues[nr] = "";
       }
-      
-      parameterDefinition.getParameters().add(parameter);
+
+      nr++;
     }
-    parameterDefinition.setPassingAllParameters(wPassParams.getSelection());
-
-    actionPipeline.setLogfile(wLogfile.getText());
-    actionPipeline.setLogext(wLogext.getText());
-    
actionPipeline.setLogFileLevel(LogLevel.lookupDescription(wLoglevel.getText()));
-    actionPipeline.setParamsFromPrevious(wPrevToParams.getSelection());
-    actionPipeline.setExecPerRow(wEveryRow.getSelection());
-    actionPipeline.setSetLogfile(wSetLogfile.getSelection());
-    actionPipeline.setAddDate(wAddDate.getSelection());
-    actionPipeline.setAddTime(wAddTime.getSelection());
-    actionPipeline.setClearResultRows(wClearRows.getSelection());
-    actionPipeline.setClearResultFiles(wClearFiles.getSelection());
-    actionPipeline.setCreateParentFolder(wCreateParentFolder.getSelection());
+
+    actionPipeline.setPassingAllParameters(wPassParams.getSelection());
+
+    actionPipeline.logfile = wLogfile.getText();
+    actionPipeline.logext = wLogext.getText();
+
+    if (wLoglevel.getSelectionIndex() >= 0) {
+      actionPipeline.logFileLevel = 
LogLevel.values()[wLoglevel.getSelectionIndex()];
+    } else {
+      actionPipeline.logFileLevel = LogLevel.BASIC;
+    }
+
+    actionPipeline.paramsFromPrevious = wPrevToParams.getSelection();
+    actionPipeline.execPerRow = wEveryRow.getSelection();
+    actionPipeline.setLogfile = wSetLogfile.getSelection();
+    actionPipeline.addDate = wAddDate.getSelection();
+    actionPipeline.addTime = wAddTime.getSelection();
+    actionPipeline.clearResultRows = wClearRows.getSelection();
+    actionPipeline.clearResultFiles = wClearFiles.getSelection();
+    actionPipeline.createParentFolder = wCreateParentFolder.getSelection();
     actionPipeline.setRunConfiguration(wRunConfiguration.getText());
-    actionPipeline.setSetAppendLogfile(wAppendLogfile.getSelection());
+    actionPipeline.setAppendLogfile = wAppendLogfile.getSelection();
     actionPipeline.setWaitingToFinish(wWaitingToFinish.getSelection());
   }
 
diff --git 
a/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflow.java
 
b/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflow.java
index 10bf07a9a3..07be3351fb 100644
--- 
a/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflow.java
+++ 
b/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflow.java
@@ -26,6 +26,7 @@ import org.apache.hop.core.RowMetaAndData;
 import org.apache.hop.core.SqlStatement;
 import org.apache.hop.core.annotations.Action;
 import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.exception.HopXmlException;
 import org.apache.hop.core.file.IHasFilename;
 import org.apache.hop.core.logging.LogChannelFileWriter;
 import org.apache.hop.core.logging.LogLevel;
@@ -36,8 +37,8 @@ import org.apache.hop.core.util.CurrentDirectoryResolver;
 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.resource.IResourceNaming;
 import org.apache.hop.resource.ResourceDefinition;
@@ -51,6 +52,7 @@ import 
org.apache.hop.workflow.action.validator.ActionValidatorUtils;
 import org.apache.hop.workflow.action.validator.AndValidator;
 import org.apache.hop.workflow.engine.IWorkflowEngine;
 import org.apache.hop.workflow.engine.WorkflowEngineFactory;
+import org.w3c.dom.Node;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -75,102 +77,30 @@ import java.util.UUID;
 public class ActionWorkflow extends ActionBase implements Cloneable, IAction {
   private static final Class<?> PKG = ActionWorkflow.class; // For Translator
 
-  public static final class ParameterDefinition {
-    @HopMetadataProperty(key = "pass_all_parameters")
-    private boolean passingAllParameters = true;
-    
-    @HopMetadataProperty(groupKey = "parameters", key = "parameter")
-    private List<Parameter> parameters;
+  private String filename;
 
-    public ParameterDefinition() {
-      this.parameters = new ArrayList<>();
-    }
+  public boolean paramsFromPrevious;
+  public boolean execPerRow;
 
-    public boolean isPassingAllParameters() {
-      return passingAllParameters;
-    }
+  public String[] parameters;
+  public String[] parameterFieldNames;
+  public String[] parameterValues;
 
-    public void setPassingAllParameters(boolean passingAllParameters) {
-      this.passingAllParameters = passingAllParameters;
-    }
-    
-    public List<Parameter> getParameters() {
-      return parameters;
-    }
+  public boolean setLogfile;
+  public String logfile;
+  public String logext;
+  public boolean addDate;
+  public boolean addTime;
+  public LogLevel logFileLevel;
+
+  public boolean parallel;
+  public boolean setAppendLogfile;
+  public boolean createParentFolder;
+
+  public boolean waitingToFinish = true;
+
+  public boolean passingAllParameters = true;
 
-    public void setParameters(List<Parameter> parameters) {
-      this.parameters = parameters;
-    }
-  }
-  
-  public static final class Parameter {
-    @HopMetadataProperty
-    public String name;
-    @HopMetadataProperty
-    public String value;
-    @HopMetadataProperty(key="stream_name")
-    public String field;   
-    
-    public String getName() {
-      return name;
-    }
-    public String getValue() {
-      return value;
-    }
-    public String getField() {
-      return field;
-    }
-    public void setName(String name) {
-      this.name = name;
-    }
-    public void setValue(String value) {
-      this.value = value;
-    }
-    public void setField(String field) {
-      this.field = field;
-    }
-  }
-  
-  @HopMetadataProperty(key = "filename")
-  private String filename;
-  
-  @HopMetadataProperty(key = "params_from_previous")
-  private boolean paramsFromPrevious;
-  
-  @HopMetadataProperty(key = "exec_per_row")
-  private boolean execPerRow;
-  
-  @HopMetadataProperty(key = "set_logfile")
-  private boolean setLogfile;
-  
-  @HopMetadataProperty(key = "logfile")
-  private String logfile;
-  
-  @HopMetadataProperty(key = "logext")
-  private String logext; 
-  
-  @HopMetadataProperty(key = "add_date")
-  private boolean addDate;
-  
-  @HopMetadataProperty(key = "add_time")
-  private boolean addTime;
-  
-  @HopMetadataProperty(key = "loglevel", storeWithCode = true)
-  private LogLevel logFileLevel;
-  
-  @HopMetadataProperty(key = "set_append_logfile")
-  private boolean setAppendLogfile;
-  
-  @HopMetadataProperty(key = "create_parent_folder")
-  private boolean createParentFolder;
-  
-  @HopMetadataProperty(key = "wait_until_finished")
-  private boolean waitingToFinish = true;
-  
-  @HopMetadataProperty(key = "parameters")
-  private ParameterDefinition parameterDefinition;
-  
-  @HopMetadataProperty(key = "run_configuration")
   private String runConfiguration;
 
   public static final LogLevel DEFAULT_LOG_LEVEL = LogLevel.NOTHING;
@@ -179,7 +109,6 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
 
   public ActionWorkflow(String name) {
     super(name, "");
-    this.parameterDefinition = new ParameterDefinition();
   }
 
   public ActionWorkflow() {
@@ -187,8 +116,29 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
     clear();
   }
 
-  public void setFileName(String name) {
-    this.filename = name;
+  private void allocateArgs(int nrArgs) {}
+
+  private void allocateParams(int nrParameters) {
+    parameters = new String[nrParameters];
+    parameterFieldNames = new String[nrParameters];
+    parameterValues = new String[nrParameters];
+  }
+
+  @Override
+  public Object clone() {
+    ActionWorkflow je = (ActionWorkflow) super.clone();
+    if (parameters != null) {
+      int nrParameters = parameters.length;
+      je.allocateParams(nrParameters);
+      System.arraycopy(parameters, 0, je.parameters, 0, nrParameters);
+      System.arraycopy(parameterFieldNames, 0, je.parameterFieldNames, 0, 
nrParameters);
+      System.arraycopy(parameterValues, 0, je.parameterValues, 0, 
nrParameters);
+    }
+    return je;
+  }
+
+  public void setFileName(String n) {
+    filename = n;
   }
 
   @Override
@@ -229,12 +179,119 @@ public class ActionWorkflow extends ActionBase 
implements Cloneable, IAction {
     return retval;
   }
 
-  public ParameterDefinition getParameterDefinition() {
-    return parameterDefinition;
+  @Override
+  public String getXml() {
+    StringBuilder retval = new StringBuilder(400);
+
+    retval.append(super.getXml());
+
+    retval.append("      ").append(XmlHandler.addTagValue("run_configuration", 
runConfiguration));
+
+    retval.append("      ").append(XmlHandler.addTagValue("filename", 
filename));
+
+    retval
+        .append("      ")
+        .append(XmlHandler.addTagValue("params_from_previous", 
paramsFromPrevious));
+    retval.append("      ").append(XmlHandler.addTagValue("exec_per_row", 
execPerRow));
+    retval.append("      ").append(XmlHandler.addTagValue("set_logfile", 
setLogfile));
+    retval.append("      ").append(XmlHandler.addTagValue("logfile", logfile));
+    retval.append("      ").append(XmlHandler.addTagValue("logext", logext));
+    retval.append("      ").append(XmlHandler.addTagValue("add_date", 
addDate));
+    retval.append("      ").append(XmlHandler.addTagValue("add_time", 
addTime));
+    retval
+        .append("      ")
+        .append(
+            XmlHandler.addTagValue(
+                "loglevel",
+                logFileLevel != null ? logFileLevel.getCode() : 
DEFAULT_LOG_LEVEL.getCode()));
+    retval.append("      
").append(XmlHandler.addTagValue("wait_until_finished", waitingToFinish));
+    retval
+        .append("      ")
+        .append(XmlHandler.addTagValue("create_parent_folder", 
createParentFolder));
+    retval.append("      ").append(XmlHandler.addTagValue("run_configuration", 
runConfiguration));
+
+    if (parameters != null) {
+      retval.append("      ").append(XmlHandler.openTag("parameters"));
+
+      retval
+          .append("        ")
+          .append(XmlHandler.addTagValue("pass_all_parameters", 
passingAllParameters));
+
+      for (int i = 0; i < parameters.length; i++) {
+        // This is a better way of making the XML file than the arguments.
+        retval.append("            ").append(XmlHandler.openTag("parameter"));
+
+        retval.append("            ").append(XmlHandler.addTagValue("name", 
parameters[i]));
+        retval
+            .append("            ")
+            .append(XmlHandler.addTagValue("stream_name", 
parameterFieldNames[i]));
+        retval.append("            ").append(XmlHandler.addTagValue("value", 
parameterValues[i]));
+
+        retval.append("            ").append(XmlHandler.closeTag("parameter"));
+      }
+      retval.append("      ").append(XmlHandler.closeTag("parameters"));
+    }
+    retval.append("      
").append(XmlHandler.addTagValue("set_append_logfile", setAppendLogfile));
+
+    return retval.toString();
   }
 
-  public void setParameterDefinition(ParameterDefinition parameterDefinition) {
-    this.parameterDefinition = parameterDefinition;
+  @Override
+  public void loadXml(Node entrynode, IHopMetadataProvider metadataProvider, 
IVariables variables)
+      throws HopXmlException {
+    try {
+      super.loadXml(entrynode);
+
+      runConfiguration = XmlHandler.getTagValue(entrynode, 
"run_configuration");
+      filename = XmlHandler.getTagValue(entrynode, "filename");
+
+      paramsFromPrevious =
+          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"params_from_previous"));
+      execPerRow = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"exec_per_row"));
+      setLogfile = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"set_logfile"));
+      addDate = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"add_date"));
+      addTime = "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"add_time"));
+      logfile = XmlHandler.getTagValue(entrynode, "logfile");
+      logext = XmlHandler.getTagValue(entrynode, "logext");
+      logFileLevel = 
LogLevel.getLogLevelForCode(XmlHandler.getTagValue(entrynode, "loglevel"));
+      setAppendLogfile =
+          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"set_append_logfile"));
+      createParentFolder =
+          "Y".equalsIgnoreCase(XmlHandler.getTagValue(entrynode, 
"create_parent_folder"));
+      runConfiguration = XmlHandler.getTagValue(entrynode, 
"run_configuration");
+
+      String wait = XmlHandler.getTagValue(entrynode, "wait_until_finished");
+      if (Utils.isEmpty(wait)) {
+        waitingToFinish = true;
+      } else {
+        waitingToFinish = "Y".equalsIgnoreCase(wait);
+      }
+
+      // How many arguments?
+      int argnr = 0;
+      while (XmlHandler.getTagValue(entrynode, "argument" + argnr) != null) {
+        argnr++;
+      }
+      allocateArgs(argnr);
+
+      Node parametersNode = XmlHandler.getSubNode(entrynode, "parameters");
+
+      String passAll = XmlHandler.getTagValue(parametersNode, 
"pass_all_parameters");
+      passingAllParameters = Utils.isEmpty(passAll) || 
"Y".equalsIgnoreCase(passAll);
+
+      int nrParameters = XmlHandler.countNodes(parametersNode, "parameter");
+      allocateParams(nrParameters);
+
+      for (int i = 0; i < nrParameters; i++) {
+        Node knode = XmlHandler.getSubNodeByNr(parametersNode, "parameter", i);
+
+        parameters[i] = XmlHandler.getTagValue(knode, "name");
+        parameterFieldNames[i] = XmlHandler.getTagValue(knode, "stream_name");
+        parameterValues[i] = XmlHandler.getTagValue(knode, "value");
+      }
+    } catch (HopXmlException xe) {
+      throw new HopXmlException("Unable to load 'workflow' action from XML 
node", xe);
+    }
   }
 
   @Override
@@ -242,7 +299,7 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
     result.setEntryNr(nr);
 
     LogChannelFileWriter logChannelFileWriter = null;
-    LogLevel workflowLogLevel = parentWorkflow.getLogLevel();
+    LogLevel jobLogLevel = parentWorkflow.getLogLevel();
 
     if (setLogfile) {
       String realLogFilename = resolve(getLogFilename());
@@ -274,7 +331,7 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
         result.setResult(false);
         return result;
       }
-      workflowLogLevel = logFileLevel;
+      jobLogLevel = logFileLevel;
     }
 
     try {
@@ -346,36 +403,37 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
 
         // Now add those parameter values specified by the user in the action
         //
-        for (Parameter parameter : parameterDefinition.getParameters()) {
-            if (!Utils.isEmpty(parameter.getName())) {
+        if (parameters != null) {
+          for (int idx = 0; idx < parameters.length; idx++) {
+            if (!Utils.isEmpty(parameters[idx])) {
 
               // If it's not yet present in the parent workflow, add it...
               //
-              if (Const.indexOfString(parameter.getName(), 
namedParam.listParameters()) < 0) {
+              if (Const.indexOfString(parameters[idx], 
namedParam.listParameters()) < 0) {
                 // We have a parameter
                 try {
-                  namedParam.addParameterDefinition(parameter.getName(), "", 
"Action runtime");
+                  namedParam.addParameterDefinition(parameters[idx], "", 
"Action runtime");
                 } catch (DuplicateParamException e) {
                   // Should never happen
                   //
-                  logError("Duplicate parameter definition for " + 
parameter.getName());
+                  logError("Duplicate parameter definition for " + 
parameters[idx]);
                 }
               }
 
-              if (Utils.isEmpty(Const.trim(parameter.getField()))) {
+              if (Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
                 namedParam.setParameterValue(
-                    parameter.getName(), 
Const.NVL(resolve(parameter.getValue()), ""));
+                    parameters[idx], Const.NVL(resolve(parameterValues[idx]), 
""));
               } else {
                 // something filled in, in the field column...
                 //
                 String value = "";
                 if (resultRow != null) {
-                  value = resultRow.getString(parameter.getField(), "");
+                  value = resultRow.getString(parameterFieldNames[idx], "");
                 }
-                namedParam.setParameterValue(parameter.getName(), value);
+                namedParam.setParameterValue(parameters[idx], value);
               }
             }
-
+          }
         }
 
         Result oneResult = new Result();
@@ -392,20 +450,22 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
 
           if (paramsFromPrevious) { // Copy the input the parameters
 
-            for (Parameter parameter : parameterDefinition.getParameters()) {
-              if (!Utils.isEmpty(parameter.getName())) {
-                // We have a parameter
-                if (Utils.isEmpty(Const.trim(parameter.getField()))) {
-                  namedParam.setParameterValue(parameter.getName(),
-                      Const.NVL(resolve(parameter.getValue()), ""));
-                } else {
-                  String fieldValue = "";
-
-                  if (resultRow != null) {
-                    fieldValue = resultRow.getString(parameter.getField(), "");
+            if (parameters != null) {
+              for (int idx = 0; idx < parameters.length; idx++) {
+                if (!Utils.isEmpty(parameters[idx])) {
+                  // We have a parameter
+                  if (Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
+                    namedParam.setParameterValue(
+                        parameters[idx], 
Const.NVL(resolve(parameterValues[idx]), ""));
+                  } else {
+                    String fieldValue = "";
+
+                    if (resultRow != null) {
+                      fieldValue = 
resultRow.getString(parameterFieldNames[idx], "");
+                    }
+                    // Get the value from the input stream
+                    namedParam.setParameterValue(parameters[idx], 
Const.NVL(fieldValue, ""));
                   }
-                  // Get the value from the input stream
-                  namedParam.setParameterValue(parameter.getName(), 
Const.NVL(fieldValue, ""));
                 }
               }
             }
@@ -417,20 +477,23 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
           sourceRows = result.getRows();
 
           if (paramsFromPrevious) { // Copy the input the parameters
-            for (Parameter parameter : parameterDefinition.getParameters()) {
-              if (!Utils.isEmpty(parameter.getName())) {
-                // We have a parameter
-                if (Utils.isEmpty(Const.trim(parameter.getField()))) {
-                  namedParam.setParameterValue(parameter.getName(),
-                      Const.NVL(resolve(parameter.getValue()), ""));
-                } else {
-                  String fieldValue = "";
-
-                  if (resultRow != null) {
-                    fieldValue = resultRow.getString(parameter.getField(), "");
+
+            if (parameters != null) {
+              for (int idx = 0; idx < parameters.length; idx++) {
+                if (!Utils.isEmpty(parameters[idx])) {
+                  // We have a parameter
+                  if (Utils.isEmpty(Const.trim(parameterFieldNames[idx]))) {
+                    namedParam.setParameterValue(
+                        parameters[idx], 
Const.NVL(resolve(parameterValues[idx]), ""));
+                  } else {
+                    String fieldValue = "";
+
+                    if (resultRow != null) {
+                      fieldValue = 
resultRow.getString(parameterFieldNames[idx], "");
+                    }
+                    // Get the value from the input stream
+                    namedParam.setParameterValue(parameters[idx], 
Const.NVL(fieldValue, ""));
                   }
-                  // Get the value from the input stream
-                  namedParam.setParameterValue(parameter.getName(), 
Const.NVL(fieldValue, ""));
                 }
               }
             }
@@ -443,7 +506,7 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
             WorkflowEngineFactory.createWorkflowEngine(
                 this, resolve(runConfiguration), getMetadataProvider(), 
workflowMeta, this);
         workflow.setParentWorkflow(parentWorkflow);
-        workflow.setLogLevel(workflowLogLevel);
+        workflow.setLogLevel(jobLogLevel);
         workflow.shareWith(this);
         workflow.setResult(result);
         workflow.setInternalHopVariables();
@@ -470,7 +533,7 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
             // This value should pass down to the sub-workflow if that's what 
we
             // opted to do.
             //
-            if (parameterDefinition.isPassingAllParameters()) {
+            if (isPassingAllParameters()) {
               String parentValue = 
parentWorkflow.getParameterValue(parameterNames[idx]);
               if (!Utils.isEmpty(parentValue)) {
                 workflow.setParameterValue(parameterNames[idx], parentValue);
@@ -821,7 +884,7 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
     }
   }
 
-  public String getLogfile() {
+  protected String getLogfile() {
     return logfile;
   }
 
@@ -835,6 +898,16 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
     this.waitingToFinish = waitingToFinish;
   }
 
+  /** @return the passingAllParameters */
+  public boolean isPassingAllParameters() {
+    return passingAllParameters;
+  }
+
+  /** @param passingAllParameters the passingAllParameters to set */
+  public void setPassingAllParameters(boolean passingAllParameters) {
+    this.passingAllParameters = passingAllParameters;
+  }
+
   public IWorkflowEngine<WorkflowMeta> getWorkflow() {
     return workflow;
   }
@@ -875,76 +948,4 @@ public class ActionWorkflow extends ActionBase implements 
Cloneable, IAction {
       int index, IHopMetadataProvider metadataProvider, IVariables variables) 
throws HopException {
     return getWorkflowMeta(metadataProvider, variables);
   }
-  
-  public boolean isAddDate() {
-    return addDate;
-  }
-
-  public boolean isAddTime() {
-    return addTime;
-  }
-
-  public void setAddDate(boolean addDate) {
-    this.addDate = addDate;
-  }
-
-  public void setAddTime(boolean addTime) {
-    this.addTime = addTime;
-  }
-
-  public String getLogext() {
-    return logext;
-  }
-
-  public void setFilename(String filename) {
-    this.filename = filename;
-  }
-
-  public void setLogfile(String logfile) {
-    this.logfile = logfile;
-  }
-
-  public void setLogext(String logext) {
-    this.logext = logext;
-  }
-
-  public boolean isSetLogfile() {
-    return setLogfile;
-  }
-
-  public LogLevel getLogFileLevel() {
-    return logFileLevel;
-  }
-
-  public boolean isCreateParentFolder() {
-    return createParentFolder;
-  }
-
-  public void setSetLogfile(boolean setLogfile) {
-    this.setLogfile = setLogfile;
-  }
-
-  public void setLogFileLevel(LogLevel logFileLevel) {
-    this.logFileLevel = logFileLevel;
-  }
-
-  public void setCreateParentFolder(boolean createParentFolder) {
-    this.createParentFolder = createParentFolder;
-  }
-
-  public boolean isParamsFromPrevious() {
-    return paramsFromPrevious;
-  }
-
-  public boolean isSetAppendLogfile() {
-    return setAppendLogfile;
-  }
-
-  public void setParamsFromPrevious(boolean paramsFromPrevious) {
-    this.paramsFromPrevious = paramsFromPrevious;
-  }
-
-  public void setSetAppendLogfile(boolean setAppendLogfile) {
-    this.setAppendLogfile = setAppendLogfile;
-  }
 }
diff --git 
a/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowDialog.java
 
b/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowDialog.java
index 1245b80bca..5b585398b9 100644
--- 
a/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowDialog.java
+++ 
b/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowDialog.java
@@ -32,7 +32,6 @@ import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
-import org.apache.hop.ui.core.widget.MetaSelectionLine;
 import org.apache.hop.ui.hopgui.HopGui;
 import org.apache.hop.ui.hopgui.file.workflow.HopWorkflowFileType;
 import org.apache.hop.ui.util.SwtSvgImageUtil;
@@ -42,15 +41,16 @@ import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.ActionBase;
 import org.apache.hop.workflow.action.IAction;
 import org.apache.hop.workflow.action.IActionDialog;
-import org.apache.hop.workflow.actions.workflow.ActionWorkflow.Parameter;
-import 
org.apache.hop.workflow.actions.workflow.ActionWorkflow.ParameterDefinition;
 import org.apache.hop.workflow.config.WorkflowRunConfiguration;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TableItem;
 
@@ -60,9 +60,8 @@ import java.util.List;
 public class ActionWorkflowDialog extends ActionBaseDialog implements 
IActionDialog {
   private static final Class<?> PKG = ActionWorkflow.class; // For Translator
 
-  private ActionWorkflow action;
-  private MetaSelectionLine<WorkflowRunConfiguration> wRunConfiguration;
-  
+  protected ActionWorkflow action;
+
   private static final String[] FILE_FILTERLOGNAMES =
       new String[] {
         BaseMessages.getString(PKG, "ActionWorkflow.Fileformat.TXT"),
@@ -113,12 +112,39 @@ public class ActionWorkflowDialog extends 
ActionBaseDialog implements IActionDia
     fdWait.left = new FormAttachment(0, 0);
     wWaitingToFinish.setLayoutData(fdWait);
 
-    // force reload from file specification
-    wbGetParams.addListener(SWT.Selection, e -> getParameters(null));
-
-    wbBrowse.addListener(SWT.Selection, e -> pickFileVFS());
-
-    wbLogFilename.addListener(SWT.Selection, e -> 
selectLogFile(FILE_FILTERLOGNAMES));
+    // End Server Section
+
+    Composite cRunConfiguration = new Composite(wOptions, SWT.NONE);
+    cRunConfiguration.setLayout(new FormLayout());
+    PropsUi.setLook(cRunConfiguration);
+    FormData fdLocal = new FormData();
+    fdLocal.top = new FormAttachment(0);
+    fdLocal.right = new FormAttachment(100);
+    fdLocal.left = new FormAttachment(0);
+
+    wbGetParams.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent arg0) {
+            getParameters(null); // force reload from file specification
+          }
+        });
+
+    wbBrowse.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent e) {
+            pickFileVFS();
+          }
+        });
+
+    wbLogFilename.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent e) {
+            selectLogFile(FILE_FILTERLOGNAMES);
+          }
+        });
   }
 
   @Override
@@ -137,8 +163,8 @@ public class ActionWorkflowDialog extends ActionBaseDialog 
implements IActionDia
   }
 
   @Override
-  protected int getParameterCount() {
-    return action.getParameterDefinition().getParameters().size();
+  protected String[] getParameters() {
+    return action.parameters;
   }
 
   protected void getParameters(WorkflowMeta inputWorkflowMeta) {
@@ -169,22 +195,6 @@ public class ActionWorkflowDialog extends ActionBaseDialog 
implements IActionDia
           e);
     }
   }
-  
-  @Override
-  protected Control createRunConfigurationControl() {
-  wRunConfiguration =
-        new MetaSelectionLine<>(
-            variables,            
-            metadataProvider,
-            WorkflowRunConfiguration.class,
-            shell,
-            SWT.BORDER,
-            null,
-            null,
-            true);
-
-    return wRunConfiguration;
-  }
 
   protected void pickFileVFS() {
     HopWorkflowFileType<WorkflowMeta> workflowFileType = new 
HopWorkflowFileType<>();
@@ -211,43 +221,41 @@ public class ActionWorkflowDialog extends 
ActionBaseDialog implements IActionDia
     wPath.setText(Const.NVL(action.getFilename(), ""));
 
     // Parameters
-    ParameterDefinition parameterDefinition = action.getParameterDefinition();
-    if (action.getParameterDefinition() != null) {
-      for (int i = 0; i < parameterDefinition.getParameters().size(); i++) {
-        Parameter parameter = parameterDefinition.getParameters().get(i);
-        TableItem item = wParameters.getTable().getItem(i);
-        if (!Utils.isEmpty(parameter.getName())) {
-          item.setText(1, Const.NVL(parameter.getName(), ""));
-          item.setText(2, Const.NVL(parameter.getField(), ""));
-          item.setText(3, Const.NVL(parameter.getValue(), ""));
+    if (action.parameters != null) {
+      for (int i = 0; i < action.parameters.length; i++) {
+        TableItem ti = wParameters.table.getItem(i);
+        if (!Utils.isEmpty(action.parameters[i])) {
+          ti.setText(1, Const.NVL(action.parameters[i], ""));
+          ti.setText(2, Const.NVL(action.parameterFieldNames[i], ""));
+          ti.setText(3, Const.NVL(action.parameterValues[i], ""));
         }
       }
       wParameters.setRowNums();
       wParameters.optWidth(true);
     }
 
-    wPassParams.setSelection(parameterDefinition.isPassingAllParameters());
+    wPassParams.setSelection(action.isPassingAllParameters());
 
-    wPrevToParams.setSelection(action.isParamsFromPrevious());
-    wEveryRow.setSelection(action.isExecPerRow());
-    wSetLogfile.setSelection(action.isSetLogfile());
-    if (action.getLogfile() != null) {
-      wLogfile.setText(action.getLogfile());
+    wPrevToParams.setSelection(action.paramsFromPrevious);
+    wEveryRow.setSelection(action.execPerRow);
+    wSetLogfile.setSelection(action.setLogfile);
+    if (action.logfile != null) {
+      wLogfile.setText(action.logfile);
     }
-    if (action.getLogext() != null) {
-      wLogext.setText(action.getLogext());
+    if (action.logext != null) {
+      wLogext.setText(action.logext);
     }
-    wAddDate.setSelection(action.isAddDate());
-    wAddTime.setSelection(action.isAddTime());
+    wAddDate.setSelection(action.addDate);
+    wAddTime.setSelection(action.addTime);
 
-    if (action.getLogFileLevel() != null) {
-      wLoglevel.select(action.getLogFileLevel().getLevel());
+    if (action.logFileLevel != null) {
+      wLoglevel.select(action.logFileLevel.getLevel());
     } else {
       // Set the default log level
       wLoglevel.select(ActionWorkflow.DEFAULT_LOG_LEVEL.getLevel());
     }
-    wAppendLogfile.setSelection(action.isSetAppendLogfile());
-    wCreateParentFolder.setSelection(action.isCreateParentFolder());
+    wAppendLogfile.setSelection(action.setAppendLogfile);
+    wCreateParentFolder.setSelection(action.createParentFolder);
     wWaitingToFinish.setSelection(action.isWaitingToFinish());
 
     try {
@@ -265,8 +273,10 @@ public class ActionWorkflowDialog extends ActionBaseDialog 
implements IActionDia
       } catch (HopException e) {
         // Ignore errors
       }
-     
+
       wRunConfiguration.setItems(runConfigurations.toArray(new String[0]));
+      wRunConfiguration.setText(Const.NVL(action.getRunConfiguration(), ""));
+
       if (Utils.isEmpty(action.getRunConfiguration())) {
         wRunConfiguration.select(0);
       } else {
@@ -276,8 +286,6 @@ public class ActionWorkflowDialog extends ActionBaseDialog 
implements IActionDia
       LogChannel.UI.logError("Error getting workflow run configurations", e);
     }
 
-    setLogFileEnabled();
-    
     wName.selectAll();
     wName.setFocus();
   }
@@ -291,52 +299,64 @@ public class ActionWorkflowDialog extends 
ActionBaseDialog implements IActionDia
   }
 
   @VisibleForTesting
-  protected void getInfo(ActionWorkflow action) {
-    action.setName(wName.getText());
-    action.setFileName(wPath.getText());
-    action.setRunConfiguration(wRunConfiguration.getText());
-
-    ParameterDefinition parameterDefinition = action.getParameterDefinition();
-    parameterDefinition.getParameters().clear();
-    
+  protected void getInfo(ActionWorkflow aw) {
+    String jobPath = getPath();
+    aw.setName(getName());
+    aw.setFileName(jobPath);
+    aw.setRunConfiguration(wRunConfiguration.getText());
+
     // Do the parameters
     int nrItems = wParameters.nrNonEmpty();
+    int nr = 0;
     for (int i = 0; i < nrItems; i++) {
-      TableItem item = wParameters.getNonEmpty(i);
-      
-      Parameter parameter = new Parameter();
-      parameter.setName(item.getText(1));
-
-      String fieldName = Const.trim(item.getText(2));
-      if (!Utils.isEmpty(fieldName)) {
-        parameter.setField(fieldName);
+      String param = wParameters.getNonEmpty(i).getText(1);
+      if (param != null && param.length() != 0) {
+        nr++;
+      }
+    }
+    aw.parameters = new String[nr];
+    aw.parameterFieldNames = new String[nr];
+    aw.parameterValues = new String[nr];
+    nr = 0;
+    for (int i = 0; i < nrItems; i++) {
+      String param = wParameters.getNonEmpty(i).getText(1);
+      String fieldName = wParameters.getNonEmpty(i).getText(2);
+      String value = wParameters.getNonEmpty(i).getText(3);
+
+      aw.parameters[nr] = param;
+
+      if (!Utils.isEmpty(Const.trim(fieldName))) {
+        aw.parameterFieldNames[nr] = fieldName;
       } else {
-        parameter.setField("");
+        aw.parameterFieldNames[nr] = "";
       }
 
-      String value = Const.trim(item.getText(3));
-      if (!Utils.isEmpty(value)) {
-        parameter.setValue(value);
+      if (!Utils.isEmpty(Const.trim(value))) {
+        aw.parameterValues[nr] = value;
       } else {
-        parameter.setValue("");
+        aw.parameterValues[nr] = "";
       }
-      
-      parameterDefinition.getParameters().add(parameter);
+
+      nr++;
+    }
+    aw.setPassingAllParameters(wPassParams.getSelection());
+
+    aw.setLogfile = wSetLogfile.getSelection();
+    aw.addDate = wAddDate.getSelection();
+    aw.addTime = wAddTime.getSelection();
+    aw.logfile = wLogfile.getText();
+    aw.logext = wLogext.getText();
+    if (wLoglevel.getSelectionIndex() >= 0) {
+      aw.logFileLevel = LogLevel.values()[wLoglevel.getSelectionIndex()];
+    } else {
+      aw.logFileLevel = LogLevel.BASIC;
     }
-    parameterDefinition.setPassingAllParameters(wPassParams.getSelection());
-
-    action.setSetLogfile(wSetLogfile.getSelection());
-    action.setAddDate(wAddDate.getSelection());
-    action.setAddTime(wAddTime.getSelection());
-    action.setLogfile(wLogfile.getText());
-    action.setLogext(wLogext.getText());
-    action.setLogFileLevel(LogLevel.lookupDescription(wLoglevel.getText()));
-    action.setParamsFromPrevious(wPrevToParams.getSelection());
-    action.setExecPerRow(wEveryRow.getSelection());
-    action.setSetAppendLogfile(wAppendLogfile.getSelection());
-    action.setWaitingToFinish(wWaitingToFinish.getSelection());
-    action.setCreateParentFolder(wCreateParentFolder.getSelection());
-    action.setRunConfiguration(wRunConfiguration.getText());
+    aw.paramsFromPrevious = wPrevToParams.getSelection();
+    aw.execPerRow = wEveryRow.getSelection();
+    aw.setAppendLogfile = wAppendLogfile.getSelection();
+    aw.setWaitingToFinish(wWaitingToFinish.getSelection());
+    aw.createParentFolder = wCreateParentFolder.getSelection();
+    aw.setRunConfiguration(wRunConfiguration.getText());
   }
 
   @Override
diff --git 
a/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowRunner.java
 
b/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowRunner.java
index 8949304338..9857195078 100644
--- 
a/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowRunner.java
+++ 
b/plugins/actions/workflow/src/main/java/org/apache/hop/workflow/actions/workflow/ActionWorkflowRunner.java
@@ -25,6 +25,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.workflow.Workflow;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.engine.IWorkflowEngine;
+import org.apache.hop.workflow.engines.local.LocalWorkflowEngine;
 
 public class ActionWorkflowRunner implements Runnable {
   private static final Class<?> PKG = Workflow.class; // For Translator
diff --git 
a/ui/src/main/java/org/apache/hop/ui/core/widget/MetaSelectionLine.java 
b/ui/src/main/java/org/apache/hop/ui/core/widget/MetaSelectionLine.java
index 91346b229f..6603fea160 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/widget/MetaSelectionLine.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/widget/MetaSelectionLine.java
@@ -171,9 +171,7 @@ public class MetaSelectionLine<T extends IHopMetadata> 
extends Composite {
     }
     fdLabel.top = new FormAttachment(0, margin + 
(EnvironmentUtils.getInstance().isWeb() ? 3 : 0));
     wLabel.setLayoutData(fdLabel);
-    if ( labelText!=null ) {
-      wLabel.setText(labelText);
-    }
+    wLabel.setText(labelText);
     wLabel.setToolTipText(toolTipText);
     wLabel.requestLayout(); // Avoid GTK error in log
 
@@ -212,12 +210,7 @@ public class MetaSelectionLine<T extends IHopMetadata> 
extends Composite {
     wCombo = new ComboVar(this.variables, this, textFlags, toolTipText);
     FormData fdCombo = new FormData();
     if (leftAlignedLabel) {
-      if ( labelText==null ) {
-        fdCombo.left = new FormAttachment(0, 0);
-      } 
-      else {
-        fdCombo.left = new FormAttachment(wLabel, margin, SWT.RIGHT);
-      }
+      fdCombo.left = new FormAttachment(wLabel, margin, SWT.RIGHT);
     } else {
       fdCombo.left = new FormAttachment(middle, 0);
     }
diff --git 
a/ui/src/main/java/org/apache/hop/ui/workflow/actions/ActionBaseDialog.java 
b/ui/src/main/java/org/apache/hop/ui/workflow/actions/ActionBaseDialog.java
index 66a68e1ba1..545bbef2ab 100644
--- a/ui/src/main/java/org/apache/hop/ui/workflow/actions/ActionBaseDialog.java
+++ b/ui/src/main/java/org/apache/hop/ui/workflow/actions/ActionBaseDialog.java
@@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.MessageBox;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.widget.ColumnInfo;
 import org.apache.hop.ui.core.widget.ColumnsResizer;
+import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.TableView;
 import org.apache.hop.ui.core.widget.TextVar;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -52,7 +53,6 @@ import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
@@ -70,11 +70,17 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
 
   protected Button wbBrowse;
 
+  protected Label wlRunConfiguration;
+  protected ComboVar wRunConfiguration;
+
   protected Group gLogFile;
 
   protected Composite wOptions;
 
+  protected Label wlName;
   protected Text wName;
+  protected FormData fdlName;
+  protected FormData fdName;
 
   protected Button wSetLogfile;
 
@@ -82,6 +88,7 @@ public abstract class ActionBaseDialog extends ActionDialog {
   protected TextVar wLogfile;
 
   protected Button wbLogFilename;
+  protected FormData fdbLogFilename;
 
   protected Button wCreateParentFolder;
 
@@ -126,6 +133,8 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
 
   protected Display display;
 
+  protected FormData fdgExecution;
+
   protected LogChannel log;
 
   public ActionBaseDialog(
@@ -152,17 +161,17 @@ public abstract class ActionBaseDialog extends 
ActionDialog {
     wicon.setLayoutData(fdlicon);
     PropsUi.setLook(wicon);
 
-    Label wlName = new Label(shell, SWT.LEFT);
+    wlName = new Label(shell, SWT.LEFT);
     PropsUi.setLook(wlName);
     wlName.setText(BaseMessages.getString(PKG, 
"ActionPipeline.ActionName.Label"));
-    FormData fdlName = new FormData();
+    fdlName = new FormData();
     fdlName.left = new FormAttachment(0, 0);
     fdlName.top = new FormAttachment(0, 0);
     wlName.setLayoutData(fdlName);
 
     wName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
     PropsUi.setLook(wName);
-    FormData fdName = new FormData();
+    fdName = new FormData();
     fdName.right = new FormAttachment(wicon, -5);
     fdName.top = new FormAttachment(wlName, 5);
     fdName.left = new FormAttachment(0, 0);
@@ -199,7 +208,7 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
     fdPath.right = new FormAttachment(wbBrowse, -5);
     wPath.setLayoutData(fdPath);
 
-    Label wlRunConfiguration = new Label(shell, SWT.LEFT);
+    wlRunConfiguration = new Label(shell, SWT.LEFT);
     wlRunConfiguration.setText(
         BaseMessages.getString(PKG, "ActionPipeline.RunConfiguration.Label"));
     PropsUi.setLook(wlRunConfiguration);
@@ -209,14 +218,14 @@ public abstract class ActionBaseDialog extends 
ActionDialog {
     fdlRunConfiguration.right = new FormAttachment(50, 0);
     wlRunConfiguration.setLayoutData(fdlRunConfiguration);
 
-    Control wRunConfiguration = this.createRunConfigurationControl();
+    wRunConfiguration = new ComboVar(variables, shell, SWT.LEFT | SWT.BORDER);
     PropsUi.setLook(wRunConfiguration);
     FormData fdRunConfiguration = new FormData();
     fdRunConfiguration.left = new FormAttachment(0, 0);
-    fdRunConfiguration.right = new FormAttachment(100, 0);
     fdRunConfiguration.top = new FormAttachment(wlRunConfiguration, 
Const.isOSX() ? 0 : 5);
+    fdRunConfiguration.right = new FormAttachment(100, 0);
     wRunConfiguration.setLayoutData(fdRunConfiguration);
-    
+
     CTabFolder wTabFolder = new CTabFolder(shell, SWT.BORDER);
     PropsUi.setLook(wTabFolder, Props.WIDGET_STYLE_TAB);
 
@@ -241,7 +250,7 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
     gExecutionLayout.marginHeight = 15;
     gExecution.setLayout(gExecutionLayout);
 
-    FormData fdgExecution = new FormData();
+    fdgExecution = new FormData();
     fdgExecution.top = new FormAttachment(0, 10);
     fdgExecution.left = new FormAttachment(0, 0);
     fdgExecution.right = new FormAttachment(100, 0);
@@ -285,7 +294,6 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
     fdSpecifyLogFile.left = new FormAttachment(0, 0);
     fdSpecifyLogFile.top = new FormAttachment(0, 0);
     wSetLogfile.setLayoutData(fdSpecifyLogFile);
-    wSetLogfile.addListener(SWT.Selection, e -> setLogFileEnabled());
 
     gLogFile = new Group(wLogging, SWT.SHADOW_ETCHED_IN);
     PropsUi.setLook(gLogFile);
@@ -304,23 +312,23 @@ public abstract class ActionBaseDialog extends 
ActionDialog {
     wlLogfile = new Label(gLogFile, SWT.LEFT);
     PropsUi.setLook(wlLogfile);
     wlLogfile.setText(BaseMessages.getString(PKG, 
"ActionPipeline.NameOfLogfile.Label"));
-    FormData fdlLogfile = new FormData();
-    fdlLogfile.left = new FormAttachment(0, 0);
-    fdlLogfile.top = new FormAttachment(0, 0);
-    wlLogfile.setLayoutData(fdlLogfile);
+    FormData fdlName = new FormData();
+    fdlName.left = new FormAttachment(0, 0);
+    fdlName.top = new FormAttachment(0, 0);
+    wlLogfile.setLayoutData(fdlName);
 
     wLogfile = new TextVar(variables, gLogFile, SWT.SINGLE | SWT.LEFT | 
SWT.BORDER);
     PropsUi.setLook(wLogfile);
-    FormData fdLogfile = new FormData();
-    fdLogfile.width = 250;
-    fdLogfile.left = new FormAttachment(0, 0);
-    fdLogfile.top = new FormAttachment(wlLogfile, 5);
-    wLogfile.setLayoutData(fdLogfile);
+    FormData fdName = new FormData();
+    fdName.width = 250;
+    fdName.left = new FormAttachment(0, 0);
+    fdName.top = new FormAttachment(wlLogfile, 5);
+    wLogfile.setLayoutData(fdName);
 
     wbLogFilename = new Button(gLogFile, SWT.PUSH | SWT.CENTER);
     PropsUi.setLook(wbLogFilename);
     wbLogFilename.setText(BaseMessages.getString(PKG, 
"ActionPipeline.Browse.Label"));
-    FormData fdbLogFilename = new FormData();
+    fdbLogFilename = new FormData();
     fdbLogFilename.top = new FormAttachment(wlLogfile, Const.isOSX() ? 0 : 5);
     fdbLogFilename.left = new FormAttachment(wLogfile, 5);
     wbLogFilename.setLayoutData(fdbLogFilename);
@@ -391,6 +399,14 @@ public abstract class ActionBaseDialog extends 
ActionDialog {
     fdIncludeTime.top = new FormAttachment(wAddDate, 10);
     wAddTime.setLayoutData(fdIncludeTime);
 
+    wSetLogfile.addSelectionListener(
+        new SelectionAdapter() {
+          @Override
+          public void widgetSelected(SelectionEvent selectionEvent) {
+            setLogFileEnabled();
+          }
+        });
+
     wLoggingTab.setControl(wLogging);
 
     FormData fdLogging = new FormData();
@@ -442,7 +458,7 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
     fdGetParams.right = new FormAttachment(100, 0);
     wbGetParams.setLayoutData(fdGetParams);
 
-    final int parameterRows = getParameterCount();
+    final int parameterRows = getParameters() != null ? getParameters().length 
: 0;
 
     ColumnInfo[] colinf =
         new ColumnInfo[] {
@@ -513,7 +529,7 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
 
     FormData fdTabFolder = new FormData();
     fdTabFolder.left = new FormAttachment(0, 0);
-    fdTabFolder.top = new FormAttachment(wRunConfiguration, 20);    
+    fdTabFolder.top = new FormAttachment(wRunConfiguration, 20);
     fdTabFolder.right = new FormAttachment(100, 0);
     fdTabFolder.bottom = new FormAttachment(hSpacer, -15);
     wTabFolder.setLayoutData(fdTabFolder);
@@ -598,7 +614,5 @@ public abstract class ActionBaseDialog extends ActionDialog 
{
 
   protected abstract Image getImage();
 
-  protected abstract int getParameterCount();
-  
-  protected abstract Control createRunConfigurationControl();
+  protected abstract String[] getParameters();
 }
diff --git 
a/ui/src/main/resources/org/apache/hop/ui/workflow/actions/messages/messages_en_US.properties
 
b/ui/src/main/resources/org/apache/hop/ui/workflow/actions/messages/messages_en_US.properties
index 4759fd3971..c85c3f2ef2 100644
--- 
a/ui/src/main/resources/org/apache/hop/ui/workflow/actions/messages/messages_en_US.properties
+++ 
b/ui/src/main/resources/org/apache/hop/ui/workflow/actions/messages/messages_en_US.properties
@@ -37,5 +37,5 @@ ActionPipeline.Parameters.ColumnName.Label=Stream Column Name
 ActionPipeline.Parameters.Parameter.Label=Parameter
 ActionPipeline.Parameters.Value.Label=Value
 ActionPipeline.PrevToParams.Label=Copy results to parameters
-ActionPipeline.RunConfiguration.Label=Run configuration:
+ActionPipeline.RunConfiguration.Label=Run configuration
 ActionPipeline.Specify.Logfile.Label=Specify logfile


Reply via email to