/**
   * 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());
  }