Newer
Older
marking / src / main / java / report / FeedbackReportGenerator.java
package report;

import dao.MarkingProperties;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Map;
import model.Student;
import static net.sf.dynamicreports.report.builder.DynamicReports.cmp;
import static net.sf.dynamicreports.report.builder.DynamicReports.field;
import static net.sf.dynamicreports.report.builder.DynamicReports.grp;
import static net.sf.dynamicreports.report.builder.DynamicReports.margin;
import static net.sf.dynamicreports.report.builder.DynamicReports.report;
import static net.sf.dynamicreports.report.builder.DynamicReports.stl;
import static net.sf.dynamicreports.report.builder.DynamicReports.template;
import static net.sf.dynamicreports.report.builder.DynamicReports.type;
import net.sf.dynamicreports.report.builder.FieldBuilder;
import net.sf.dynamicreports.report.builder.component.HorizontalListBuilder;
import net.sf.dynamicreports.report.builder.group.CustomGroupBuilder;
import net.sf.dynamicreports.report.builder.style.StyleBuilder;
import net.sf.dynamicreports.report.constant.HorizontalTextAlignment;
import net.sf.dynamicreports.report.constant.LineStyle;
import net.sf.dynamicreports.report.constant.VerticalTextAlignment;
import net.sf.dynamicreports.report.exception.DRException;
import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;

/**
 *
 * @author Mark George <mark.george@otago.ac.nz>
 */
public class FeedbackReportGenerator {

	private final Collection<Map<String, ?>> data;
	private final String outputDirectory;
	private final String fileNamePrefix;
	private final String title;
	private final String footer;

	public FeedbackReportGenerator(Collection<Map<String, ?>> data, String outputDirectory, String fileNamePrefix, String title, String footer) {
		this.data = data;
		this.outputDirectory = outputDirectory;
		this.fileNamePrefix = fileNamePrefix;
		this.title = title;
		this.footer = footer;
	}

	public void generate(Student student) {

		StyleBuilder labelSty
			= stl.style()
				.bold()
				.setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT)
				.setVerticalTextAlignment(VerticalTextAlignment.MIDDLE);

		StyleBuilder valSty
			= stl.style()
				.setHorizontalTextAlignment(HorizontalTextAlignment.LEFT)
				.setVerticalTextAlignment(VerticalTextAlignment.MIDDLE);

		StyleBuilder markSty
			= stl.style()
				.bold()
				.setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT)
				.setVerticalTextAlignment(VerticalTextAlignment.MIDDLE);

		StyleBuilder criterionSty
			= stl.style()
				.bold()
				.setHorizontalTextAlignment(HorizontalTextAlignment.LEFT)
				.setVerticalTextAlignment(VerticalTextAlignment.MIDDLE);

		FieldBuilder<String> assessment = field("ASSESSMENT", type.stringType());
		FieldBuilder<BigDecimal> outOf = field("OUT_OF", type.bigDecimalType());
		FieldBuilder<String> id = field("STUDENT_ID", type.stringType());
		FieldBuilder<String> name = field("NAME", type.stringType());
		FieldBuilder<BigDecimal> mark = field("MARK", type.bigDecimalType());

		FieldBuilder<String> category = field("CATEGORY", type.stringType());

		CustomGroupBuilder categoryGroup = grp.group(category)
			.setStyle(stl.style().bold().setFontSize(13));

		FieldBuilder<String> criterion = field("CRITERION", type.stringType());
		FieldBuilder<BigDecimal> result = field("RESULT", type.bigDecimalType());
		FieldBuilder<BigDecimal> max = field("MAX", type.bigDecimalType());
		FieldBuilder<String> comment = field("COMMENT", type.stringType());

		HorizontalListBuilder marksHeader;
		HorizontalListBuilder marksDetails;


		if (MarkingProperties.reportShowMax()) {

			marksHeader = cmp.horizontalList().add(
				cmp.text("").setStyle(criterionSty).setWidth(50),
				cmp.text("Mark").setStyle(markSty).setWidth(4),
				cmp.text("/").setStyle(labelSty).setWidth(1),
				cmp.horizontalGap(5),
				cmp.text("Max").setStyle(valSty).setWidth(3)
			);

			marksDetails = cmp.horizontalList()
				.add(
					cmp.text(criterion).setStyle(criterionSty).setWidth(50),
					cmp.text(result).setStyle(markSty).setWidth(4),
					cmp.text("/").setStyle(labelSty).setWidth(1),
					cmp.horizontalGap(5),
					cmp.text(max).setStyle(valSty).setWidth(3)
				);

		} else {
			marksHeader = cmp.horizontalList().add(
				cmp.text("").setStyle(criterionSty).setWidth(50),
				cmp.text("Mark").setStyle(markSty).setWidth(4)
			);

			marksDetails = cmp.horizontalList().add(
				cmp.text(criterion).setStyle(criterionSty).setWidth(50),
				cmp.text(result).setStyle(markSty).setWidth(4)
			);
		}



		try {
			// header
			report()
				.setTemplate(template().setPageMargin(margin(50)))
				.setDataSource(new JRMapCollectionDataSource(data))
				.title(
					cmp.text(title).setStyle(stl.style().setFontSize(14).bold()),
					cmp.verticalGap(10),
					cmp.horizontalList()
						.add(
							cmp.text("Assessment:").setStyle(labelSty).setWidth(15),
							cmp.horizontalGap(5),
							cmp.text(assessment).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("ID:").setStyle(labelSty).setWidth(15),
							cmp.horizontalGap(5),
							cmp.text(id).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Name:").setStyle(labelSty).setWidth(15),
							cmp.horizontalGap(5),
							cmp.text(name).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Mark:").setStyle(labelSty).setWidth(15),
							cmp.horizontalGap(5),
							cmp.text(mark).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Out of:").setStyle(labelSty).setWidth(15),
							cmp.horizontalGap(5),
							cmp.text(outOf).setStyle(valSty)
						),
					cmp.verticalGap(15)
				)
				// details

				.groupBy(categoryGroup).groupHeader(categoryGroup,
				marksHeader,
				cmp.line().setPen(stl.pen(2.0f, LineStyle.DOUBLE)))
				.detail(
					cmp.verticalGap(1),
					marksDetails,
					cmp.horizontalList(
						cmp.horizontalGap(11),
						cmp.text(comment).removeLineWhenBlank()
					).setMinHeight(0),
					cmp.verticalGap(1),
					cmp.line().setPen(stl.penThin())
				)
				.groupFooter(categoryGroup, cmp.verticalGap(18))
				.summary(cmp.text(footer))
				//				.summary(cmp.text("The mark for the bonus tasks is only applied if you lost marks in other components (including the UML diagrams and security audit).  In other words, your total mark is capped at 25."))
				.pageFooter(cmp.pageXofY().setStyle(stl.style().bold()))
				//				.show()

				.toPdf(new FileOutputStream(outputDirectory + "/" + fileNamePrefix + "-" + student.getId() + ".pdf"));
		} catch (FileNotFoundException | DRException ex) {
			throw new RuntimeException(ex);
		}

	}

}