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.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Map;
import javax.swing.JOptionPane;
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) {

		if (!Files.exists(Paths.get(this.outputDirectory))) {
			JOptionPane.showMessageDialog(null, "Report folder does not exist.  Please create it.\n\nPath should be:\n" + this.outputDirectory, "Report Folder Does Not Exist", JOptionPane.WARNING_MESSAGE);
			throw new RuntimeException("Report folder does not exist");
		}

		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<BigDecimal> special = field("SPECIAL", 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("Out Of").setStyle(valSty).setWidth(4)
			);

			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(4)
				);

		} 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(18),
							cmp.horizontalGap(5),
							cmp.text(assessment).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("ID:").setStyle(labelSty).setWidth(18),
							cmp.horizontalGap(5),
							cmp.text(id).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Name:").setStyle(labelSty).setWidth(18),
							cmp.horizontalGap(5),
							cmp.text(name).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Mark:").setStyle(labelSty).setWidth(18),
							cmp.horizontalGap(5),
							cmp.text(mark).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Out of:").setStyle(labelSty).setWidth(18),
							cmp.horizontalGap(5),
							cmp.text(outOf).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("Bonus:").setStyle(labelSty).setWidth(18),
							cmp.horizontalGap(5),
							cmp.text(special).setStyle(valSty)
						)
						.newRow().add(
							cmp.text("").setStyle(labelSty).setWidth(18),
							cmp.horizontalGap(5),
							cmp.text("(bonus not included in the above mark)").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))
				.pageFooter(cmp.pageXofY().setStyle(stl.style().bold()))

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

	}

}