@SuppressWarnings({"rawtypes", "unchecked"})
  public JasperReportBuilder build() throws DRException {
    JasperReportBuilder report = report();

    report
        .setTemplate(Templates.reportTemplate)
        .title(Templates.createTitleComponent("DynamicReport"));

    DynamicReport dynamicReport = data.getDynamicReport();
    List<DynamicColumn> columns = dynamicReport.getColumns();
    Map<String, TextColumnBuilder> drColumns = new HashMap<String, TextColumnBuilder>();

    for (DynamicColumn column : columns) {
      TextColumnBuilder drColumn =
          col.column(
              column.getTitle(), column.getName(), (DRIDataType) type.detectType(column.getType()));
      if (column.getPattern() != null) {
        drColumn.setPattern(column.getPattern());
      }
      if (column.getHorizontalAlignment() != null) {
        drColumn.setHorizontalAlignment(column.getHorizontalAlignment());
      }
      drColumns.put(column.getName(), drColumn);
      report.columns(drColumn);
    }

    for (String group : dynamicReport.getGroups()) {
      ColumnGroupBuilder group2 = grp.group(drColumns.get(group));
      report.groupBy(group2);

      for (String subtotal : dynamicReport.getSubtotals()) {
        report.subtotalsAtGroupFooter(group2, sbt.sum(drColumns.get(subtotal)));
      }
    }

    for (String subtotal : dynamicReport.getSubtotals()) {
      report.subtotalsAtSummary(sbt.sum(drColumns.get(subtotal)));
    }

    if (dynamicReport.getTitle() != null) {
      TextFieldBuilder<String> title =
          cmp.text(dynamicReport.getTitle())
              .setStyle(Templates.bold12CenteredStyle)
              .setHorizontalAlignment(HorizontalAlignment.CENTER);
      report.addTitle(title);
    }
    if (dynamicReport.isShowPageNumber()) {
      PageXofYBuilder pageXofY = cmp.pageXofY().setStyle(Templates.boldCenteredStyle);
      report.addPageFooter(pageXofY);
    }
    report.setDataSource(data.createDataSource());

    return report;
  }
 protected void addExpression(TextColumnBuilder<?> column) {
   Validate.notNull(column, "column must not be null");
   this.expressions.add(column.build());
 }