/**
   * Performs the export.
   *
   * @param context the page context
   * @param i18n the internationalization package to use.
   */
  public void doExport(PageContext context, I18n i18n) {

    String filterId = new TopTotalEnqueuesFilter().getFilterId();

    RunningJobsInfoDAO dao = RunningJobsInfoDAO.getInstance();
    InMemoryFrontierReport report = dao.getFrontierReport(jobId, filterId);

    HttpServletResponse resp = (HttpServletResponse) context.getResponse();
    resp.setHeader("Content-Type", "text/plain");
    resp.setHeader(
        "Content-Disposition",
        "Attachment; filename=" + filterId + "-" + report.getJobName() + ".csv");

    PrintWriter pw;
    try {
      pw = new PrintWriter(resp.getOutputStream());
    } catch (IOException e) {
      HTMLUtils.forwardWithErrorMessage(
          context, i18n, e, "errorMsg;running.job.details.frontier.exportAsCsv");
      throw new ForwardedToErrorPage("Error in frontier report CSV export", e);
    }

    FrontierReportCsvExport.outputAsCsv(report, pw, ";");
    pw.close();
  }
    @Override
    public void run() {

      synchronized (gen) {
        gen.chartFile = null;
      }

      long jobId = gen.jobId;

      StartedJobInfo[] fullHistory = RunningJobsInfoDAO.getInstance().getFullJobHistory(jobId);

      LinkedList<Double> timeValues = new LinkedList<Double>();
      LinkedList<Double> progressValues = new LinkedList<Double>();
      LinkedList<Double> urlValues = new LinkedList<Double>();

      for (StartedJobInfo sji : fullHistory) {
        timeValues.add((double) sji.getElapsedSeconds());
        progressValues.add(sji.getProgress());
        urlValues.add((double) sji.getQueuedFilesCount());
      }

      // Refresh the history png image for the job.
      File pngFile = new File(gen.outputFolder, jobId + "-history.png");

      File newPngFile;
      try {
        newPngFile =
            File.createTempFile(jobId + "-history", "." + System.currentTimeMillis() + ".png");
      } catch (IOException e) {
        LOG.warn("Failed to create temp PNG file for job " + jobId);
        return;
      }

      long startTime = System.currentTimeMillis();
      gen.generatePngChart(
          newPngFile,
          CHART_RESOLUTION[0],
          CHART_RESOLUTION[1],
          null, // no chart title
          I18N.getString(gen.locale, "running.job.details.chart.legend.crawlTime"),
          new String[] {
            I18N.getString(gen.locale, "running.job.details.chart.legend.progress"),
            I18N.getString(gen.locale, "running.job.details.chart.legend.queuedUris")
          },
          NumberUtils.toPrimitiveArray(timeValues),
          new double[][] {new double[] {0, 100}, null},
          new double[][] {
            NumberUtils.toPrimitiveArray(progressValues), NumberUtils.toPrimitiveArray(urlValues)
          },
          new Color[] {Color.blue, Color.green.darker()},
          new String[] {"%", ""},
          false,
          Color.lightGray.brighter().brighter());

      long genTime = System.currentTimeMillis() - startTime;
      LOG.info(
          "Generated history chart for job "
              + jobId
              + " in "
              + (genTime < TimeUtils.SECOND_IN_MILLIS
                  ? genTime + " ms"
                  : StringUtils.formatDuration(genTime / TimeUtils.SECOND_IN_MILLIS))
              + ".");

      synchronized (gen) {
        // Overwrite old file, then delete temp file
        try {
          FileUtils.copyFile(newPngFile, pngFile);
          FileUtils.remove(newPngFile);
        } catch (IOFailure iof) {
          LOG.error("IOFailure while copying PNG file", iof);
        }
        gen.chartFile = pngFile;
      }
    }