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 details
			HorizontalListBuilder headerDetails = 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)
				 );

			if (MarkingProperties.showBonusOnReport()) {
				headerDetails.newRow().add(
					 cmp.text("Bonus:").setStyle(labelSty).setWidth(18),
					 cmp.horizontalGap(5),
					 cmp.text(special).setStyle(valSty)
				)
					
					 .newRow().add(
						  cmp.verticalGap(20),
						  cmp.horizontalGap(5),
						  cmp.text("Note: the Bonus is not included in the Mark.").setStyle(valSty)
					 );
			}

			// header
			report()
				 .setTemplate(template().setPageMargin(margin(50)))
				 .setDataSource(new JRMapCollectionDataSource(data))
				 .title(
					  cmp.text(title).setStyle(stl.style().setFontSize(14).bold()),
					  cmp.verticalGap(10),
					  headerDetails,
					  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);
		}

	}

}