public void loadXML(
      Node entrynode,
      List<DatabaseMeta> databases,
      List<SlaveServer> slaveServers,
      Repository rep,
      IMetaStore metaStore)
      throws KettleXMLException {
    try {
      super.loadXML(entrynode, databases, slaveServers);
      setFileName(XMLHandler.getTagValue(entrynode, "filename"));
      setWorkDirectory(XMLHandler.getTagValue(entrynode, "work_directory"));
      argFromPrevious =
          "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "arg_from_previous"));
      execPerRow = "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "exec_per_row"));
      setLogfile = "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "set_logfile"));
      setAppendLogfile =
          "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "set_append_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"));
      insertScript = "Y".equalsIgnoreCase(XMLHandler.getTagValue(entrynode, "insertScript"));

      script = XMLHandler.getTagValue(entrynode, "script");

      // How many arguments?
      int argnr = 0;
      while (XMLHandler.getTagValue(entrynode, "argument" + argnr) != null) {
        argnr++;
      }
      arguments = new String[argnr];

      // Read them all...
      // THIS IS A VERY BAD WAY OF READING/SAVING AS IT MAKES
      // THE XML "DUBIOUS". DON'T REUSE IT.
      for (int a = 0; a < argnr; a++) {
        arguments[a] = XMLHandler.getTagValue(entrynode, "argument" + a);
      }
    } catch (KettleException e) {
      throw new KettleXMLException("Unable to load job entry of type 'shell' from XML node", e);
    }
  }
  // Load the jobentry from repository
  public void loadRep(
      Repository rep,
      IMetaStore metaStore,
      ObjectId id_jobentry,
      List<DatabaseMeta> databases,
      List<SlaveServer> slaveServers)
      throws KettleException {
    try {
      setFileName(rep.getJobEntryAttributeString(id_jobentry, "file_name"));
      setWorkDirectory(rep.getJobEntryAttributeString(id_jobentry, "work_directory"));
      argFromPrevious = rep.getJobEntryAttributeBoolean(id_jobentry, "arg_from_previous");
      execPerRow = rep.getJobEntryAttributeBoolean(id_jobentry, "exec_per_row");

      setLogfile = rep.getJobEntryAttributeBoolean(id_jobentry, "set_logfile");
      setAppendLogfile = rep.getJobEntryAttributeBoolean(id_jobentry, "set_append_logfile");
      addDate = rep.getJobEntryAttributeBoolean(id_jobentry, "add_date");
      addTime = rep.getJobEntryAttributeBoolean(id_jobentry, "add_time");
      logfile = rep.getJobEntryAttributeString(id_jobentry, "logfile");
      logext = rep.getJobEntryAttributeString(id_jobentry, "logext");
      logFileLevel =
          LogLevel.getLogLevelForCode(rep.getJobEntryAttributeString(id_jobentry, "loglevel"));
      insertScript = rep.getJobEntryAttributeBoolean(id_jobentry, "insertScript");

      script = rep.getJobEntryAttributeString(id_jobentry, "script");
      // How many arguments?
      int argnr = rep.countNrJobEntryAttributes(id_jobentry, "argument");
      arguments = new String[argnr];

      // Read them all...
      for (int a = 0; a < argnr; a++) {
        arguments[a] = rep.getJobEntryAttributeString(id_jobentry, a, "argument");
      }
    } catch (KettleDatabaseException dbe) {
      throw new KettleException(
          "Unable to load job entry of type 'shell' from the repository with id_jobentry="
              + id_jobentry,
          dbe);
    }
  }
  public JobExecutionConfiguration(Node trecNode) throws KettleException {
    this();

    executingLocally = "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "exec_local"));

    executingRemotely = "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "exec_remote"));
    Node remoteHostNode = XMLHandler.getSubNode(trecNode, SlaveServer.XML_TAG);
    if (remoteHostNode != null) {
      remoteServer = new SlaveServer(remoteHostNode);
    }
    passingExport = "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "pass_export"));
    expandingRemoteJob =
        "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "expand_remote_job"));

    // Read the variables...
    //
    Node varsNode = XMLHandler.getSubNode(trecNode, "variables");
    int nrVariables = XMLHandler.countNodes(varsNode, "variable");
    for (int i = 0; i < nrVariables; i++) {
      Node argNode = XMLHandler.getSubNodeByNr(varsNode, "variable", i);
      String name = XMLHandler.getTagValue(argNode, "name");
      String value = XMLHandler.getTagValue(argNode, "value");
      if (!Utils.isEmpty(name) && !Utils.isEmpty(value)) {
        variables.put(name, value);
      }
    }

    // Read the arguments...
    //
    Node argsNode = XMLHandler.getSubNode(trecNode, "arguments");
    int nrArguments = XMLHandler.countNodes(argsNode, "argument");
    for (int i = 0; i < nrArguments; i++) {
      Node argNode = XMLHandler.getSubNodeByNr(argsNode, "argument", i);
      String name = XMLHandler.getTagValue(argNode, "name");
      String value = XMLHandler.getTagValue(argNode, "value");
      if (!Utils.isEmpty(name) && !Utils.isEmpty(value)) {
        arguments.put(name, value);
      }
    }

    // Read the parameters...
    //
    Node parmsNode = XMLHandler.getSubNode(trecNode, "parameters");
    int nrParams = XMLHandler.countNodes(parmsNode, "parameter");
    for (int i = 0; i < nrParams; i++) {
      Node parmNode = XMLHandler.getSubNodeByNr(parmsNode, "parameter", i);
      String name = XMLHandler.getTagValue(parmNode, "name");
      String value = XMLHandler.getTagValue(parmNode, "value");
      if (!Utils.isEmpty(name)) {
        params.put(name, value);
      }
    }

    replayDate = XMLHandler.stringToDate(XMLHandler.getTagValue(trecNode, "replay_date"));
    safeModeEnabled = "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "safe_mode"));
    logLevel = LogLevel.getLogLevelForCode(XMLHandler.getTagValue(trecNode, "log_level"));
    clearingLog = "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "clear_log"));

    startCopyName = XMLHandler.getTagValue(trecNode, "start_copy_name");
    startCopyNr = Const.toInt(XMLHandler.getTagValue(trecNode, "start_copy_nr"), 0);

    gatheringMetrics = "Y".equalsIgnoreCase(XMLHandler.getTagValue(trecNode, "gather_metrics"));

    String sPassedBatchId = XMLHandler.getTagValue(trecNode, "passedBatchId");
    if (!StringUtils.isEmpty(sPassedBatchId)) {
      passedBatchId = Long.parseLong(sPassedBatchId);
    }

    Node resultNode = XMLHandler.getSubNode(trecNode, Result.XML_TAG);
    if (resultNode != null) {
      try {
        previousResult = new Result(resultNode);
      } catch (KettleException e) {
        throw new KettleException("Unable to hydrate previous result", e);
      }
    }

    // Try to get a handle to the repository from here...
    //
    Node repNode = XMLHandler.getSubNode(trecNode, "repository");
    if (repNode != null) {
      String repositoryName = XMLHandler.getTagValue(repNode, "name");
      String username = XMLHandler.getTagValue(repNode, "login");
      String password = Encr.decryptPassword(XMLHandler.getTagValue(repNode, "password"));
      connectRepository(repositoryName, username, password);
    }
  }