package cucumber.contrib.grammar.pdf; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.FontFactory; import com.itextpdf.text.Phrase; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import cucumber.contrib.grammar.java.ClassEntry; import cucumber.contrib.grammar.java.Grammar; import cucumber.contrib.grammar.java.MethodEntry; import cucumber.contrib.grammar.java.PackageEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.util.function.Consumer; /** * @author <a href="http://twitter.com/aloyer">@aloyer</a> */ public class GrammarPdfReport { private Logger log = LoggerFactory.getLogger(GrammarPdfReport.class); private static final int SUMMARY_NB_COLS = 4; // private BaseColor WHITE = new BaseColor(255, 255, 255); private BaseColor BLACK = new BaseColor(0, 0, 0); // private final Configuration configuration; // private File fileDst; private Document document; private FileOutputStream fileOutputStream; private PdfWriter pdfWriter; public GrammarPdfReport(Configuration configuration) { this.configuration = configuration; } public void init(File fileDst) throws FileNotFoundException, DocumentException { this.fileDst = fileDst; this.document = configuration.createDocument(); this.fileOutputStream = new FileOutputStream(fileDst); // pdfWriter = PdfWriter.getInstance(document, fileOutputStream); pdfWriter.setBoxSize("art", configuration.getDocumentArtBox()); document.open(); } public void emit(Grammar grammar) { emitFirstPages(); try { PdfPTable summaryTable = new PdfPTable(SUMMARY_NB_COLS); summaryTable.setWidths(new float[]{0.5f, 0.5f, 10.0f, 10.0f}); grammar.packages().forEach(emitPackageSummary(summaryTable)); getDocument().add(summaryTable); } catch (DocumentException e) { throw new RuntimeException(e); } } private void emitPackageSummary(PdfPTable summaryTable, PackageEntry packageEntry) { log.debug("Emitting summary for package {}", packageEntry.name()); if (packageEntry.hasClassEntries()) { Phrase phrase = new Phrase(packageEntry.name(), FontFactory.getFont("Arial", 8, WHITE)); PdfPCell packageCell = new PdfPCell(phrase); packageCell.setBackgroundColor(BLACK); packageCell.setColspan(SUMMARY_NB_COLS); summaryTable.addCell(packageCell); packageEntry.classes().forEach(emitClassSummary(summaryTable)); } packageEntry.subPackages().forEach(emitPackageSummary(summaryTable)); } private void emitClassSummary(PdfPTable summaryTable, ClassEntry classEntry) { log.debug("Emitting summary for class {}", classEntry.name()); Phrase phrase = new Phrase(classEntry.name(), FontFactory.getFont("Arial", 12, WHITE)); PdfPCell classCell = new PdfPCell(phrase); classCell.setColspan(SUMMARY_NB_COLS - 1); classCell.setBackgroundColor(BaseColor.DARK_GRAY); classCell.setBorder(Rectangle.NO_BORDER); summaryTable.addCell(emptyCell()); summaryTable.addCell(classCell); classEntry.methods().forEach(emitMethodSummary(summaryTable)); } private void emitMethodSummary(final PdfPTable summaryTable, MethodEntry methodEntry) { log.debug("Emitting summary for method {}", methodEntry.signature()); methodEntry.patterns().forEach(new Consumer<String>() { @Override public void accept(String pattern) { Phrase phrase = new Phrase(pattern, FontFactory.getFont("Arial", 10, BLACK)); PdfPCell patternCell = new PdfPCell(phrase); patternCell.setColspan(SUMMARY_NB_COLS - 2); patternCell.setBorder(Rectangle.BOTTOM); patternCell.setBorderColor(BaseColor.LIGHT_GRAY); summaryTable.addCell(emptyCell(2)); summaryTable.addCell(patternCell); } }); } private PdfPCell emptyCell(int colspan) { PdfPCell pdfPCell = new PdfPCell(new Phrase("")); pdfPCell.setColspan(colspan); pdfPCell.setBorder(Rectangle.NO_BORDER); return pdfPCell; } private PdfPCell emptyCell() { return emptyCell(1); } protected void emitFirstPages() { } public Document getDocument() { return document; } private Consumer<? super MethodEntry> emitMethodSummary(final PdfPTable summaryTable) { return new Consumer<MethodEntry>() { @Override public void accept(MethodEntry methodEntry) { emitMethodSummary(summaryTable, methodEntry); } }; } private Consumer<? super ClassEntry> emitClassSummary(final PdfPTable summaryTable) { return new Consumer<ClassEntry>() { @Override public void accept(ClassEntry classEntry) { emitClassSummary(summaryTable, classEntry); } }; } private Consumer<? super PackageEntry> emitPackageSummary(final PdfPTable summaryTable) { return new Consumer<PackageEntry>() { @Override public void accept(PackageEntry packageEntry) { emitPackageSummary(summaryTable, packageEntry); } }; } public void close() { try { if (document != null) { document.close(); } if (fileOutputStream != null) { fileOutputStream.close(); } log.info("Report generated {}", fileDst.getAbsolutePath()); } catch (Exception e) { throw new RuntimeException("Error while flushing report to disk", e); } } }