/**
   * Processes a binary request for a report in binary format. The request should contain the
   * following parameters:
   *
   * <dl>
   *   <dt><code>reportId</code>
   *   <dd>The ID of the report to download.
   *   <dt><code>format</code>
   *   <dd>The file format of the report. Possible values:
   *       <ul>
   *         <li><code>html</code>
   *         <li><code>pdf</code>
   *         <li><code>rtf</code>
   *         <li><code>doc</code>
   *         <li><code>xml</code>
   *       </ul>
   * </dl>
   *
   * @param binaryRequestContext The context of the binary request.
   */
  public void process(BinaryRequestContext binaryRequestContext) {
    ReportDAO reportDAO = DAOFactory.getInstance().getReportDAO();
    MagicKeyDAO magicKeyDAO = DAOFactory.getInstance().getMagicKeyDAO();

    Long reportId = binaryRequestContext.getLong("reportId");
    String formatParameter = binaryRequestContext.getString("format");
    ReportOutputFormat outputFormat = Enum.valueOf(ReportOutputFormat.class, formatParameter);

    StringBuilder magicKeyBuilder =
        new StringBuilder()
            .append(Long.toHexString(reportId))
            .append('-')
            .append(Long.toHexString(System.currentTimeMillis()))
            .append('-')
            .append(Long.toHexString(Thread.currentThread().getId()));

    MagicKey magicKey = magicKeyDAO.create(magicKeyBuilder.toString(), MagicKeyScope.REQUEST);

    Report report = reportDAO.findById(reportId);

    String reportName = report.getName().toLowerCase().replaceAll("[^a-z0-9\\.]", "_");
    String reportsContextPath = System.getProperty("reports.contextPath");

    StringBuilder urlBuilder =
        new StringBuilder()
            .append(reportsContextPath)
            .append("/preview")
            .append("?magicKey=")
            .append(magicKey.getName())
            .append("&__report=reports/")
            .append(reportId)
            .append(".rptdesign")
            .append("&__format=")
            .append(outputFormat.name());

    Map<String, String[]> parameterMap = binaryRequestContext.getRequest().getParameterMap();
    for (String parameterName : parameterMap.keySet()) {
      if (!reservedParameters.contains(parameterName)) {
        String[] values = parameterMap.get(parameterName);
        for (String value : values) {
          // TODO ISO-8859-1 should be UTF-8, once Birt's parameter dialog form has its
          // accept-charset="UTF-8" set
          try {
            urlBuilder
                .append('&')
                .append(parameterName)
                .append('=')
                .append(URLEncoder.encode(value, "ISO-8859-1"));
          } catch (UnsupportedEncodingException e) {
            throw new SmvcRuntimeException(e);
          }
        }
      }
    }

    binaryRequestContext.setFileName(reportName + '.' + outputFormat.getExt());
    binaryRequestContext.setContentUrl(urlBuilder.toString());
  }
  /**
   * Processes the page request by including the corresponding JSP page to the response.
   *
   * @param pageRequestContext Page request context
   */
  public void process(PageRequestContext pageRequestContext) {
    ReportDAO reportDAO = DAOFactory.getInstance().getReportDAO();

    List<Report> reports = reportDAO.listByContextType(ReportContextType.Common);
    Collections.sort(
        reports,
        new Comparator<Report>() {
          @Override
          public int compare(Report o1, Report o2) {
            String s1 = o1.getCategory() == null ? null : o1.getCategory().getName();
            String s2 = o2.getCategory() == null ? null : o2.getCategory().getName();
            int cmp = s1 == null ? 1 : s2 == null ? -1 : s1.compareToIgnoreCase(s2);
            if (cmp == 0) {
              cmp = o1.getName().compareToIgnoreCase(o2.getName());
            }
            return cmp;
          }
        });

    pageRequestContext.getRequest().setAttribute("reports", reports);
    pageRequestContext.setIncludeJSP("/templates/reports/listreports.jsp");
  }