protected JRCompilationSourceCode generateClass() throws JRException {
    StringBuffer sb = new StringBuffer();

    generateClassStart(sb);

    generateDeclarations(sb);

    generateInitMethod(sb);
    generateInitParamsMethod(sb);
    if (fieldsMap != null) {
      generateInitFieldsMethod(sb);
    }
    generateInitVarsMethod(sb);

    List<JRExpression> expressions = sourceTask.getExpressions();
    sb.append(generateMethod(JRExpression.EVALUATION_DEFAULT, expressions));
    if (sourceTask.isOnlyDefaultEvaluation()) {
      List<JRExpression> empty = new ArrayList<JRExpression>();
      sb.append(generateMethod(JRExpression.EVALUATION_OLD, empty));
      sb.append(generateMethod(JRExpression.EVALUATION_ESTIMATED, empty));
    } else {
      sb.append(generateMethod(JRExpression.EVALUATION_OLD, expressions));
      sb.append(generateMethod(JRExpression.EVALUATION_ESTIMATED, expressions));
    }

    sb.append("}\n");

    String code = sb.toString();
    JRExpression[] lineExpressions = parseSourceLines(code);
    return new JRDefaultCompilationSourceCode(code, lineExpressions);
  }
  protected JRClassGenerator(JRSourceCompileTask sourceTask) {
    this.sourceTask = sourceTask;

    parametersMap = sourceTask.getParametersMap();
    fieldsMap = sourceTask.getFieldsMap();
    variablesMap = sourceTask.getVariablesMap();
    variables = sourceTask.getVariables();
  }
  protected final void generateClassStart(StringBuffer sb) {
    sb.append("/*\n");
    sb.append(" * Generated by JasperReports - ");
    sb.append((new SimpleDateFormat()).format(new java.util.Date()));
    sb.append("\n");
    sb.append(" */\n");
    sb.append("import net.sf.jasperreports.engine.*;\n");
    sb.append("import net.sf.jasperreports.engine.fill.*;\n");
    sb.append("\n");
    sb.append("import java.util.*;\n");
    sb.append("import java.math.*;\n");
    sb.append("import java.text.*;\n");
    sb.append("import java.io.*;\n");
    sb.append("import java.net.*;\n");
    sb.append("\n");

    /*   */
    String[] imports = sourceTask.getImports();
    if (imports != null && imports.length > 0) {
      for (int i = 0; i < imports.length; i++) {
        sb.append("import ");
        sb.append(imports[i]);
        sb.append(";\n");
      }
    }

    /*   */
    sb.append("\n");
    sb.append("\n");
    sb.append("/**\n");
    sb.append(" *\n");
    sb.append(" */\n");
    sb.append("public class ");
    sb.append(sourceTask.getUnitName());
    sb.append(" extends JREvaluator\n");
    sb.append("{\n");
    sb.append("\n");
    sb.append("\n");
    sb.append("    /**\n");
    sb.append("     *\n");
    sb.append("     */\n");
  }
 protected JRExpression getLineExpression(String line) {
   JRExpression expression = null;
   int exprIdStart = line.indexOf(SOURCE_EXPRESSION_ID_START);
   if (exprIdStart >= 0) {
     exprIdStart += SOURCE_EXPRESSION_ID_START_LENGTH;
     int exprIdEnd = line.indexOf('$', exprIdStart);
     if (exprIdEnd >= 0) {
       try {
         int exprId = Integer.parseInt(line.substring(exprIdStart, exprIdEnd));
         expression = sourceTask.getExpression(exprId);
       } catch (NumberFormatException e) {
         // ignore
       }
     }
   }
   return expression;
 }
 protected void appendExpressionComment(StringBuffer sb, JRExpression expression) {
   sb.append(" //");
   sb.append(SOURCE_EXPRESSION_ID_START);
   sb.append(sourceTask.getExpressionId(expression));
   sb.append(SOURCE_EXPRESSION_ID_END);
 }
  private String generateMethod(Iterator<JRExpression> it, int index, byte evaluationType)
      throws JRException {
    StringBuffer sb = new StringBuffer();

    /*   */
    sb.append("    /**\n");
    sb.append("     *\n");
    sb.append("     */\n");
    if (index > 0) {
      sb.append("    private Object evaluate");
      sb.append(methodSuffixMap.get(new Byte(evaluationType)));
      sb.append(index);
    } else {
      sb.append("    public Object evaluate");
      sb.append(methodSuffixMap.get(new Byte(evaluationType)));
    }
    sb.append("(int id) throws Throwable\n");
    sb.append("    {\n");
    sb.append("        Object value = null;\n");
    sb.append("\n");
    sb.append("        switch (id)\n");
    sb.append("        {\n");

    for (int i = 0; it.hasNext() && i < EXPR_MAX_COUNT_PER_METHOD; i++) {
      JRExpression expression = it.next();

      sb.append("            case ");
      sb.append(sourceTask.getExpressionId(expression));
      sb.append(" : \n");
      sb.append("            {\n");
      sb.append("                value = ");
      sb.append(this.generateExpression(expression, evaluationType));
      sb.append(";");
      appendExpressionComment(sb, expression);
      sb.append("\n");
      sb.append("                break;\n");
      sb.append("            }\n");
    }

    /*   */
    sb.append("           default :\n");
    sb.append("           {\n");
    if (it.hasNext()) {
      sb.append("               value = evaluate");
      sb.append(methodSuffixMap.get(new Byte(evaluationType)));
      sb.append(index + 1);
      sb.append("(id);\n");
    }
    sb.append("           }\n");
    sb.append("        }\n");
    sb.append("        \n");
    sb.append("        return value;\n");
    sb.append("    }\n");
    sb.append("\n");
    sb.append("\n");

    if (it.hasNext()) {
      sb.append(generateMethod(it, index + 1, evaluationType));
    }

    return sb.toString();
  }