public boolean validateParameters(
      List<ReportParameterMap> reportParameters, Map<String, Object> parameters)
      throws ProviderException {
    parameters = new SingleValueMap(parameters);

    if (reportParameters != null && reportParameters.size() > 0) {
      Iterator<ReportParameterMap> iterator = reportParameters.iterator();
      while (iterator.hasNext()) {
        ReportParameterMap rpMap = iterator.next();

        ReportParameter param = rpMap.getReportParameter();

        if (!parameters.containsKey(param.getName()) && rpMap.isRequired()) {
          throw new ProviderException(LocalStrings.ERROR_PARAMETER_REQUIRED);
        }

        if (param.getType().equals(ReportParameter.TEXT_PARAM)
            || param.getType().equals(ReportParameter.DATE_PARAM)) {
          String value = (String) parameters.get(param.getName());

          if (value != null && value.length() > 0) {
            try {
              validateParameter(param, value);
            } catch (Exception e) {
              throw new ProviderException(e.getMessage());
            }
          } else if (rpMap.isRequired()) {
            throw new ProviderException(LocalStrings.ERROR_PARAMETER_REQUIRED);
          }
        }
      }
    }

    return true;
  }
  private String buildMultipleSelectString(ReportParameter reportParameter, Object[] values) {
    StringBuffer sb = new StringBuffer();

    if (values == null || values.length < 1 || values[0].equals("")) return "";

    for (int j = 0; j < values.length; j++) {
      String value = "";

      if (values[j] instanceof ReportParameterValue) {
        value = ((ReportParameterValue) values[j]).getId().toString();
      } else {
        value = (String) values[j];
      }

      if (j > 0) {
        sb.append(',');
      }

      if (reportParameter.getClassName().equals("java.lang.String")) {
        sb.append("'" + value + "'");
      } else {
        sb.append(value);
      }
    }

    return sb.toString();
  }
  public List<ReportParameter> getAvailableParameters(Report report) throws ProviderException {
    List<ReportParameter> parameters = getReportParameters();

    Iterator<ReportParameter> iterator = parameters.iterator();
    while (iterator.hasNext()) {
      ReportParameter rp = iterator.next();

      Iterator<ReportParameterMap> reportIterator = report.getParameters().iterator();
      while (reportIterator.hasNext()) {
        ReportParameterMap rpMap = reportIterator.next();

        if (rp.getId().equals(rpMap.getReportParameter().getId())) {
          parameters.remove(rp);
          iterator = parameters.iterator();
        }
      }
    }

    return parameters;
  }
  public ReportParameterValue[] getParamValues(
      ReportParameter reportParameter, Map<String, Object> parameters) throws ProviderException {
    if (reportParameter.getType().equals(ReportParameter.QUERY_PARAM)) {
      return getParamValuesFromDataSource(reportParameter, parameters);
    } else if (reportParameter.getType().equals(ReportParameter.LIST_PARAM)) {
      return parseListValues(reportParameter);
    } else if (reportParameter.getType().equals(ReportParameter.BOOLEAN_PARAM)) {
      // default to Yes/No
      if (reportParameter.getData() == null || reportParameter.getData().indexOf("|") == -1) {
        reportParameter.setData("true:Yes|false:No");
      }

      return parseListValues(reportParameter);
    }

    throw new ProviderException(
        reportParameter.getName()
            + ": param-type "
            + reportParameter.getType()
            + " not supported!");
  }
  protected ReportParameterValue[] parseListValues(ReportParameter reportParameter)
      throws ProviderException {
    StringTokenizer st = new StringTokenizer(reportParameter.getData(), "|");

    ReportParameterValue[] values = new ReportParameterValue[st.countTokens()];

    int index = 0;
    while (st.hasMoreTokens()) {
      String token = st.nextToken();
      String id = token;
      String description = token;

      StringTokenizer paramValue = new StringTokenizer(token, ":");
      if (paramValue.countTokens() == 2) {
        id = paramValue.nextToken();
        description = paramValue.nextToken();
      }

      try {
        if (reportParameter.getClassName().equals("java.lang.Integer")) {
          values[index] = new ReportParameterValue(Integer.valueOf(id), description);
        } else if (reportParameter.getClassName().equals("java.lang.Double")) {
          values[index] = new ReportParameterValue(Double.valueOf(id), description);
        } else if (reportParameter.getClassName().equals("java.lang.Long")) {
          values[index] = new ReportParameterValue(Long.valueOf(id), description);
        } else if (reportParameter.getClassName().equals("java.math.BigDecimal")) {
          values[index] = new ReportParameterValue(new BigDecimal(id), description);
        } else {
          values[index] = new ReportParameterValue(id, description);
        }
      } catch (Exception e) {
        throw new ProviderException(
            reportParameter.getData() + " contains invalid " + reportParameter.getClassName());
      }

      index++;
    }

    return values;
  }
  public void loadReportParameterValues(
      List<ReportParameterMap> reportParameters, Map<String, Object> parameters)
      throws ProviderException {
    for (int i = 0; i < reportParameters.size(); i++) {
      ReportParameterMap rpMap = reportParameters.get(i);
      ReportParameter rp = rpMap.getReportParameter();

      try {
        if (rp.getType().equals(ReportParameter.LIST_PARAM)
            || rp.getType().equals(ReportParameter.QUERY_PARAM)
            || rp.getType().equals(ReportParameter.BOOLEAN_PARAM)) {
          if (rp.getValues() == null) // only load once...
          {
            log.debug("loading parameter values: " + rp.getName());
            rp.setValues(getParamValues(rp, parameters));
          }
        }
      } catch (Exception e) {
        log.error("Error loading parameter values: " + rp.getName());
        throw new ProviderException("loadReportParameterValues: " + e.getMessage());
      }
    }
  }
 protected void validateParameter(ReportParameter parameter, String value)
     throws ProviderException {
   try {
     if (parameter.getClassName().equals("java.lang.Double")) {
       new Double(value);
     } else if (parameter.getClassName().equals("java.lang.Integer")) {
       new Integer(value);
     } else if (parameter.getClassName().equals("java.lang.Long")) {
       new Long(value);
     } else if (parameter.getClassName().equals("java.math.BigDecimal")) {
       new BigDecimal(value);
     } else if (parameter.getClassName().equals("java.util.Date")
         || parameter.getClassName().equals("java.sql.Date")
         || parameter.getClassName().equals("java.sql.Timestamp")) {
       try {
         dateProvider.parseDate(value);
       } catch (Exception e) {
         throw new ProviderException(e.getMessage());
       }
     }
   } catch (Exception e) {
     throw new ProviderException(parameter.getDescription() + " Invalid: " + e.getMessage());
   }
 }
  @RequestMapping(value = "developReport/generate", method = RequestMethod.POST)
  public ModelAndView generateReport(
      @RequestParam(value = L_TEMPLATE) final String template,
      @RequestParam(value = "type") final String type,
      @RequestParam(value = L_LOCALE) final String locale,
      final HttpServletRequest request,
      final HttpServletResponse response) {
    if (!showReportDevelopment) {
      return new ModelAndView(new RedirectView("/"));
    }

    List<ReportParameter> params = null;

    try {
      params = getReportParameters(template);
    } catch (Exception e) {
      LOG.error(e.getMessage(), e);
      return showException(L_QCADOO_REPORT_REPORT, e)
          .addObject(L_TEMPLATE, template)
          .addObject("isParameter", true)
          .addObject(L_LOCALE, locale);
    }

    try {
      ReportType reportType = ReportType.valueOf(type.toUpperCase(Locale.ENGLISH));
      Locale reportLocale = new Locale(locale);

      Map<String, Object> parameters = new HashMap<String, Object>();

      for (ReportParameter param : params) {
        param.setValue(request.getParameter("params[" + param.getName() + "]"));
        parameters.put(param.getName(), param.getRawValue());
      }

      byte[] report = reportService.generateReport(template, reportType, parameters, reportLocale);

      response.setContentLength(report.length);
      response.setContentType(reportType.getMimeType());
      response.setHeader("Content-disposition", "attachment; filename=report." + type);
      response.addHeader("Expires", "Tue, 03 Jul 2001 06:00:00 GMT");
      response.addHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
      response.addHeader("Cache-Control", "post-check=0, pre-check=0");
      response.addHeader("Pragma", "no-cache");

      OutputStream out = response.getOutputStream();

      try {
        IOUtils.copy(new ByteArrayInputStream(report), out);
      } catch (IOException e) {
        LOG.error(e.getMessage(), e);
        throw new ReportException(ReportException.Type.ERROR_WHILE_COPYING_REPORT_TO_RESPONSE, e);
      }

      out.flush();

      return null;
    } catch (Exception e) {
      LOG.error(e.getMessage(), e);
      return showException(L_QCADOO_REPORT_REPORT, e)
          .addObject(L_TEMPLATE, template)
          .addObject("isParameter", true)
          .addObject(L_PARAMS, params)
          .addObject(L_LOCALE, locale);
    }
  }
  public Map<String, Object> getReportParametersMap(
      List<ReportParameterMap> reportParameters, Map<String, Object> origParameters)
      throws ProviderException {
    Map<String, Object> map = new HashMap<String, Object>();

    // if multiple selections, use origParameters; otherwise, use
    // parameters
    Map<String, Object> parameters = new SingleValueMap(origParameters);

    Iterator<ReportParameterMap> iterator = reportParameters.iterator();
    while (iterator.hasNext()) {
      ReportParameterMap rpMap = iterator.next();

      ReportParameter reportParameter = rpMap.getReportParameter();

      // if we are expecting multiple selections, convert the array of
      // parameters
      // into a comma-delimited string so that it can be used in the SQL
      // where
      // clause. Otherwise, just expect a simple String
      if (reportParameter.isMultipleSelect()) {
        Object[] values = (String[]) origParameters.get(reportParameter.getName());

        // load up the StringBuffer with the multiple selections.
        String s = buildMultipleSelectString(reportParameter, values);

        // save the parameter into the Map
        if (rpMap.isRequired() || s.length() > 0) {
          map.put(reportParameter.getName(), s);

          log.debug(reportParameter.getName() + " => " + map.get(reportParameter.getName()));
        }
      } else {
        String value = (String) parameters.get(reportParameter.getName());

        if (value != null) {
          try {
            Object object = parseParameter(reportParameter, value);

            if (rpMap.isRequired() || value.length() > 0) {
              map.put(reportParameter.getName(), object);
            }
          } catch (Exception e) {
            log.warn(
                "Error setting parameter: " + reportParameter.getName() + " : " + e.getMessage());
          }
        }
      }
    }

    // always pass drilldown chart parameter to reports if it exists

    String value = (String) parameters.get(ReportChart.DRILLDOWN_PARAMETER);

    if (value != null)
      map.put(ReportChart.DRILLDOWN_PARAMETER, parameters.get(ReportChart.DRILLDOWN_PARAMETER));

    //

    return map;
  }
  protected Object parseParameter(ReportParameter parameter, String value)
      throws ProviderException {
    try {
      if (parameter.getClassName().equals("java.lang.String")) {
        return value;
      } else if (parameter.getClassName().equals("java.lang.Double")) {
        return new Double(value);
      } else if (parameter.getClassName().equals("java.lang.Integer")) {
        return new Integer(value);
      } else if (parameter.getClassName().equals("java.lang.Long")) {
        return new Long(value);
      } else if (parameter.getClassName().equals("java.math.BigDecimal")) {
        return new BigDecimal(value);
      } else if (parameter.getClassName().equals("java.util.Date")) {
        return dateProvider.parseDate(value);
      } else if (parameter.getClassName().equals("java.sql.Date")) {
        return dateProvider.parseDate(value);
      } else if (parameter.getClassName().equals("java.sql.Timestamp")) {
        long time = dateProvider.parseDate(value).getTime();
        return new Timestamp(time);
      } else if (parameter.getClassName().equals("java.lang.Boolean")) {
        return new Boolean(value);
      }
    } catch (Exception e) {
      throw new ProviderException(parameter.getName() + " Invalid: " + e.getMessage());
    }

    throw new ProviderException(parameter.getName() + " currently unsupported!");
  }
  protected ReportParameterValue[] getParamValuesFromDataSource(
      ReportParameter param, Map<String, Object> parameters) throws ProviderException {
    Connection conn = null;
    PreparedStatement pStmt = null;
    ResultSet rs = null;

    try {
      ReportDataSource dataSource = param.getDataSource();
      conn = dataSourceProvider.getConnection(dataSource.getId());

      if (parameters == null || parameters.isEmpty()) {
        pStmt = conn.prepareStatement(param.getData());
      } else {
      }

      rs = pStmt.executeQuery();

      ResultSetMetaData rsMetaData = rs.getMetaData();

      boolean multipleColumns = false;
      if (rsMetaData.getColumnCount() > 1) multipleColumns = true;

      ArrayList<ReportParameterValue> v = new ArrayList<ReportParameterValue>();

      while (rs.next()) {
        ReportParameterValue value = new ReportParameterValue();

        if (param.getClassName().equals("java.lang.String")) {
          value.setId(rs.getString(1));
        } else if (param.getClassName().equals("java.lang.Double")) {
          value.setId(new Double(rs.getDouble(1)));
        } else if (param.getClassName().equals("java.lang.Integer")) {
          value.setId(new Integer(rs.getInt(1)));
        } else if (param.getClassName().equals("java.lang.Long")) {
          value.setId(new Long(rs.getLong(1)));
        } else if (param.getClassName().equals("java.math.BigDecimal")) {
          value.setId(rs.getBigDecimal(1));
        } else if (param.getClassName().equals("java.util.Date")) {
          value.setId(rs.getDate(1));
        } else if (param.getClassName().equals("java.sql.Date")) {
          value.setId(rs.getDate(1));
        } else if (param.getClassName().equals("java.sql.Timestamp")) {
          value.setId(rs.getTimestamp(1));
        }

        if (multipleColumns) {
          value.setDescription(rs.getString(2));
        }

        v.add(value);
      }

      rs.close();

      ReportParameterValue[] values = new ReportParameterValue[v.size()];
      v.toArray(values);

      return values;
    } catch (Exception e) {
      throw new ProviderException("Error retreiving param values from database: " + e.getMessage());
    } finally {
      try {
        if (pStmt != null) pStmt.close();
        if (conn != null) conn.close();
      } catch (Exception c) {
        log.error("Error closing");
      }
    }
  }