public Object clone() {
    TextFileOutputMeta retval = (TextFileOutputMeta) super.clone();
    int nrfields = outputFields.length;

    retval.allocate(nrfields);

    for (int i = 0; i < nrfields; i++) {
      retval.outputFields[i] = (TextFileField) outputFields[i].clone();
    }

    return retval;
  }
  public void setDefault() {
    createparentfolder = true; // Default createparentfolder to true
    separator = ";";
    enclosure = "\"";
    specifyingFormat = false;
    dateTimeFormat = null;
    enclosureForced = false;
    disableEnclosureFix = false;
    headerEnabled = true;
    footerEnabled = false;
    fileFormat = "DOS";
    fileCompression = fileCompressionTypeCodes[FILE_COMPRESSION_TYPE_NONE];
    fileName = "file";
    fileAsCommand = false;
    servletOutput = false;
    doNotOpenNewFileInit = false;
    extension = "txt";
    stepNrInFilename = false;
    partNrInFilename = false;
    dateInFilename = false;
    timeInFilename = false;
    padded = false;
    fastDump = false;
    addToResultFilenames = true;
    splitEvery = 0;

    newline = getNewLine(fileFormat);

    int i, nrfields = 0;

    allocate(nrfields);

    for (i = 0; i < nrfields; i++) {
      outputFields[i] = new TextFileField();

      outputFields[i].setName("field" + i);
      outputFields[i].setType("Number");
      outputFields[i].setFormat(" 0,000,000.00;-0,000,000.00");
      outputFields[i].setCurrencySymbol("");
      outputFields[i].setDecimalSymbol(",");
      outputFields[i].setGroupingSymbol(".");
      outputFields[i].setNullString("");
      outputFields[i].setLength(-1);
      outputFields[i].setPrecision(-1);
    }
    fileAppended = false;
  }
  public void readRep(
      Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases)
      throws KettleException {
    try {
      separator = rep.getStepAttributeString(id_step, "separator");
      enclosure = rep.getStepAttributeString(id_step, "enclosure");
      enclosureForced = rep.getStepAttributeBoolean(id_step, "enclosure_forced");
      disableEnclosureFix = rep.getStepAttributeBoolean(id_step, 0, "enclosure_fix_disabled", true);
      createparentfolder = rep.getStepAttributeBoolean(id_step, "create_parent_folder");
      headerEnabled = rep.getStepAttributeBoolean(id_step, "header");
      footerEnabled = rep.getStepAttributeBoolean(id_step, "footer");
      fileFormat = rep.getStepAttributeString(id_step, "format");
      fileCompression = rep.getStepAttributeString(id_step, "compression");
      fileNameInField = rep.getStepAttributeBoolean(id_step, "fileNameInField");
      fileNameField = rep.getStepAttributeString(id_step, "fileNameField");
      if (fileCompression == null) {
        if (rep.getStepAttributeBoolean(id_step, "zipped")) {
          fileCompression = fileCompressionTypeCodes[FILE_COMPRESSION_TYPE_ZIP];
        } else {
          fileCompression = fileCompressionTypeCodes[FILE_COMPRESSION_TYPE_NONE];
        }
      }
      encoding = rep.getStepAttributeString(id_step, "encoding");

      fileName = loadSourceRep(rep, id_step);
      fileAsCommand = rep.getStepAttributeBoolean(id_step, "file_is_command");
      servletOutput = rep.getStepAttributeBoolean(id_step, "file_servlet_output");
      doNotOpenNewFileInit = rep.getStepAttributeBoolean(id_step, "do_not_open_new_file_init");
      extension = rep.getStepAttributeString(id_step, "file_extention");
      fileAppended = rep.getStepAttributeBoolean(id_step, "file_append");
      splitEvery = (int) rep.getStepAttributeInteger(id_step, "file_split");
      stepNrInFilename = rep.getStepAttributeBoolean(id_step, "file_add_stepnr");
      partNrInFilename = rep.getStepAttributeBoolean(id_step, "file_add_partnr");
      dateInFilename = rep.getStepAttributeBoolean(id_step, "file_add_date");
      timeInFilename = rep.getStepAttributeBoolean(id_step, "file_add_time");
      specifyingFormat = rep.getStepAttributeBoolean(id_step, "SpecifyFormat");
      dateTimeFormat = rep.getStepAttributeString(id_step, "date_time_format");

      String AddToResultFiles = rep.getStepAttributeString(id_step, "add_to_result_filenames");
      if (Const.isEmpty(AddToResultFiles)) {
        addToResultFilenames = true;
      } else {
        addToResultFilenames = rep.getStepAttributeBoolean(id_step, "add_to_result_filenames");
      }

      padded = rep.getStepAttributeBoolean(id_step, "file_pad");
      fastDump = rep.getStepAttributeBoolean(id_step, "file_fast_dump");

      newline = getNewLine(fileFormat);

      int nrfields = rep.countNrStepAttributes(id_step, "field_name");

      allocate(nrfields);

      for (int i = 0; i < nrfields; i++) {
        outputFields[i] = new TextFileField();

        outputFields[i].setName(rep.getStepAttributeString(id_step, i, "field_name"));
        outputFields[i].setType(rep.getStepAttributeString(id_step, i, "field_type"));
        outputFields[i].setFormat(rep.getStepAttributeString(id_step, i, "field_format"));
        outputFields[i].setCurrencySymbol(rep.getStepAttributeString(id_step, i, "field_currency"));
        outputFields[i].setDecimalSymbol(rep.getStepAttributeString(id_step, i, "field_decimal"));
        outputFields[i].setGroupingSymbol(rep.getStepAttributeString(id_step, i, "field_group"));
        outputFields[i].setTrimType(
            ValueMeta.getTrimTypeByCode(rep.getStepAttributeString(id_step, i, "field_trim_type")));
        outputFields[i].setNullString(rep.getStepAttributeString(id_step, i, "field_nullif"));
        outputFields[i].setLength((int) rep.getStepAttributeInteger(id_step, i, "field_length"));
        outputFields[i].setPrecision(
            (int) rep.getStepAttributeInteger(id_step, i, "field_precision"));
      }
      endedLine = rep.getStepAttributeString(id_step, "endedLine");

    } catch (Exception e) {
      throw new KettleException("Unexpected error reading step information from the repository", e);
    }
  }
  private void readData(Node stepnode, IMetaStore metastore) throws KettleXMLException {
    try {
      separator = XMLHandler.getTagValue(stepnode, "separator");
      if (separator == null) {
        separator = "";
      }

      enclosure = XMLHandler.getTagValue(stepnode, "enclosure");
      if (enclosure == null) {
        enclosure = "";
      }

      enclosureForced = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "enclosure_forced"));

      String sDisableEnclosureFix = XMLHandler.getTagValue(stepnode, "enclosure_fix_disabled");
      // Default this value to true for backwards compatibility
      if (sDisableEnclosureFix == null) {
        disableEnclosureFix = true;
      } else {
        disableEnclosureFix = "Y".equalsIgnoreCase(sDisableEnclosureFix);
      }

      // Default createparentfolder to true if the tag is missing
      String createParentFolderTagValue = XMLHandler.getTagValue(stepnode, "create_parent_folder");
      createparentfolder =
          (createParentFolderTagValue == null)
              ? true
              : "Y".equalsIgnoreCase(createParentFolderTagValue);

      headerEnabled = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "header"));
      footerEnabled = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "footer"));
      fileFormat = XMLHandler.getTagValue(stepnode, "format");
      fileCompression = XMLHandler.getTagValue(stepnode, "compression");
      if (fileCompression == null) {
        if ("Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "zipped"))) {
          fileCompression = fileCompressionTypeCodes[FILE_COMPRESSION_TYPE_ZIP];
        } else {
          fileCompression = fileCompressionTypeCodes[FILE_COMPRESSION_TYPE_NONE];
        }
      }
      encoding = XMLHandler.getTagValue(stepnode, "encoding");

      endedLine = XMLHandler.getTagValue(stepnode, "endedLine");
      if (endedLine == null) {
        endedLine = "";
      }

      fileName = loadSource(stepnode, metastore);
      fileAsCommand = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "is_command"));
      servletOutput =
          "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "servlet_output"));
      doNotOpenNewFileInit =
          "Y"
              .equalsIgnoreCase(
                  XMLHandler.getTagValue(stepnode, "file", "do_not_open_new_file_init"));
      extension = XMLHandler.getTagValue(stepnode, "file", "extention");
      fileAppended = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "append"));
      stepNrInFilename = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "split"));
      partNrInFilename =
          "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "haspartno"));
      dateInFilename = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "add_date"));
      timeInFilename = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "add_time"));
      specifyingFormat =
          "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "SpecifyFormat"));
      dateTimeFormat = XMLHandler.getTagValue(stepnode, "file", "date_time_format");

      String AddToResultFiles = XMLHandler.getTagValue(stepnode, "file", "add_to_result_filenames");
      if (Const.isEmpty(AddToResultFiles)) {
        addToResultFilenames = true;
      } else {
        addToResultFilenames = "Y".equalsIgnoreCase(AddToResultFiles);
      }

      padded = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "pad"));
      fastDump = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "file", "fast_dump"));
      splitEvery = Const.toInt(XMLHandler.getTagValue(stepnode, "file", "splitevery"), 0);

      newline = getNewLine(fileFormat);

      fileNameInField = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "fileNameInField"));
      fileNameField = XMLHandler.getTagValue(stepnode, "fileNameField");

      Node fields = XMLHandler.getSubNode(stepnode, "fields");
      int nrfields = XMLHandler.countNodes(fields, "field");

      allocate(nrfields);

      for (int i = 0; i < nrfields; i++) {
        Node fnode = XMLHandler.getSubNodeByNr(fields, "field", i);

        outputFields[i] = new TextFileField();
        outputFields[i].setName(XMLHandler.getTagValue(fnode, "name"));
        outputFields[i].setType(XMLHandler.getTagValue(fnode, "type"));
        outputFields[i].setFormat(XMLHandler.getTagValue(fnode, "format"));
        outputFields[i].setCurrencySymbol(XMLHandler.getTagValue(fnode, "currency"));
        outputFields[i].setDecimalSymbol(XMLHandler.getTagValue(fnode, "decimal"));
        outputFields[i].setGroupingSymbol(XMLHandler.getTagValue(fnode, "group"));
        outputFields[i].setTrimType(
            ValueMeta.getTrimTypeByCode(XMLHandler.getTagValue(fnode, "trim_type")));
        outputFields[i].setNullString(XMLHandler.getTagValue(fnode, "nullif"));
        outputFields[i].setLength(Const.toInt(XMLHandler.getTagValue(fnode, "length"), -1));
        outputFields[i].setPrecision(Const.toInt(XMLHandler.getTagValue(fnode, "precision"), -1));
      }
    } catch (Exception e) {
      throw new KettleXMLException("Unable to load step info from XML", e);
    }
  }