org.sonar.report.pdf.DefaultPDFReporter.java Source code

Java tutorial

Introduction

Here is the source code for org.sonar.report.pdf.DefaultPDFReporter.java

Source

/*
 * Sonar PDF Report (Maven plugin)
 * Copyright (C) 2010 klicap - ingenieria del puzle
 * dev@sonar.codehaus.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */

package org.sonar.report.pdf;

import java.awt.Color;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Properties;

import org.sonar.report.pdf.entity.Measures;
import org.sonar.report.pdf.entity.Project;
import org.sonar.report.pdf.entity.exception.ReportException;

import com.lowagie.text.BadElementException;
import com.lowagie.text.ChapterAutoNumber;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.List;
import com.lowagie.text.ListItem;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.Section;
import com.lowagie.text.pdf.PdfCell;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

import java.net.URL;

/**
 * Concrete PDFReporter. Implements printPdfBody method. This will be the way to extend PDFReport.
 */
public class DefaultPDFReporter extends PDFReporter {

    private URL logo;
    private String projectKey;
    private String sonarUrl;
    private Properties configProperties;
    private Properties langProperties;

    private final static int indentation = 18;
    private final static int tablePaddingBottom = 5;

    private Document document;

    public DefaultPDFReporter(URL logo, String projectKey, String sonarUrl, Properties configProperties,
            Properties langProperties) {
        this.logo = logo;
        this.projectKey = projectKey;
        this.sonarUrl = sonarUrl;
        this.configProperties = configProperties;
        this.langProperties = langProperties;
        reportType = "default";
    }

    @Override
    protected void printPdfBody(Document document)
            throws DocumentException, IOException, org.dom4j.DocumentException, ReportException {
        this.document = document;
        // Chapter 1
        ChapterAutoNumber chapter1 = new ChapterAutoNumber(
                new Paragraph(getTextProperty("main.chapter1.title"), Style.CHAPTER_FONT));
        chapter1.add(new Paragraph(getTextProperty("main.chapter1.intro"), Style.NORMAL_FONT));
        // Section 1.1
        Section section11 = chapter1
                .addSection(new Paragraph(getTextProperty("main.chapter1.subtitle1"), Style.TITLE_FONT));
        Project project = super.getProject();
        printDashboard(project, section11);
        // Section 1.2
        Section section12 = chapter1
                .addSection(new Paragraph(getTextProperty("main.chapter1.subtitle2"), Style.TITLE_FONT));
        printProjectInfo(project, section12);

        document.add(chapter1);

        // Subprojects Chapters (2, 3, 4, ...)
        Iterator<Project> it = project.getSubprojects().iterator();
        while (it.hasNext()) {
            Project subproject = it.next();
            ChapterAutoNumber subprojectChapter = new ChapterAutoNumber(new Paragraph(
                    getTextProperty("general.module") + ": " + subproject.getName(), Style.TITLE_FONT));
            Section sectionX1 = subprojectChapter
                    .addSection(new Paragraph(getTextProperty("main.chapter2.subtitle2X1"), Style.TITLE_FONT));
            printDashboard(subproject, sectionX1);
            Section sectionX2 = subprojectChapter
                    .addSection(new Paragraph(getTextProperty("main.chapter2.subtitle2X2"), Style.TITLE_FONT));
            printProjectInfo(subproject, sectionX2);
            document.add(subprojectChapter);
        }
    }

    private void printDashboard(Project project, Section section) throws DocumentException {
        PdfPTable dashboard = new PdfPTable(3);
        dashboard.getDefaultCell().setBorderColor(Color.WHITE);
        Font titleFont = new Font(Font.TIMES_ROMAN, 14, Font.BOLD, Color.BLACK);
        Font dataFont = new Font(Font.TIMES_ROMAN, 14, Font.BOLD, Color.GRAY);
        Font dataFont2 = new Font(Font.TIMES_ROMAN, 10, Font.BOLD, new Color(100, 150, 190));

        PdfPTable linesOfCode = new PdfPTable(1);
        linesOfCode.getDefaultCell().setBorderColor(Color.WHITE);
        linesOfCode.addCell(new Phrase(getTextProperty("general.lines_of_code"), titleFont));
        linesOfCode.addCell(new Phrase(project.getMeasure("ncss").getFormatValue(), dataFont));
        linesOfCode.addCell(
                new Phrase(project.getMeasure("packages_count").getFormatValue() + " packages", dataFont2));
        linesOfCode
                .addCell(new Phrase(project.getMeasure("classes_count").getFormatValue() + " classes", dataFont2));
        linesOfCode.addCell(
                new Phrase(project.getMeasure("functions_count").getFormatValue() + " methods", dataFont2));
        linesOfCode.addCell(new Phrase(
                project.getMeasure("duplicated_lines_ratio").getFormatValue() + " duplicated lines", dataFont2));

        PdfPTable comments = new PdfPTable(1);
        comments.getDefaultCell().setBorderColor(Color.WHITE);
        comments.addCell(new Phrase(getTextProperty("general.comments"), titleFont));
        comments.addCell(new Phrase(project.getMeasure("comment_ratio").getFormatValue(), dataFont));
        comments.addCell(
                new Phrase(project.getMeasure("comment_lines").getFormatValue() + " comment lines", dataFont2));

        PdfPTable codeCoverage = new PdfPTable(1);
        codeCoverage.getDefaultCell().setBorderColor(Color.WHITE);
        codeCoverage.addCell(new Phrase(getTextProperty("general.test_count"), titleFont));
        codeCoverage.addCell(new Phrase(project.getMeasure("test_count").getFormatValue(), dataFont));
        codeCoverage.addCell(
                new Phrase(project.getMeasure("test_success_percentage").getFormatValue() + " success", dataFont2));
        codeCoverage
                .addCell(new Phrase(project.getMeasure("code_coverage").getFormatValue() + " coverage", dataFont2));

        PdfPTable complexity = new PdfPTable(1);
        complexity.getDefaultCell().setBorderColor(Color.WHITE);
        complexity.addCell(new Phrase(getTextProperty("general.complexity"), titleFont));
        complexity.addCell(new Phrase(project.getMeasure("ccn_function").getFormatValue(), dataFont));
        complexity.addCell(new Phrase(project.getMeasure("ccn_class").getFormatValue() + " /class", dataFont2));
        complexity.addCell(new Phrase(project.getMeasure("ccn").getFormatValue() + " decision points", dataFont2));

        PdfPTable rulesCompliance = new PdfPTable(1);
        rulesCompliance.getDefaultCell().setBorderColor(Color.WHITE);
        rulesCompliance.addCell(new Phrase(getTextProperty("general.rules_compliance"), titleFont));
        rulesCompliance.addCell(new Phrase(project.getMeasure("rules_compliance").getFormatValue(), dataFont));

        PdfPTable violations = new PdfPTable(1);
        violations.getDefaultCell().setBorderColor(Color.WHITE);
        violations.addCell(new Phrase(getTextProperty("general.violations"), titleFont));
        violations.addCell(new Phrase(project.getMeasure("rules_violations").getFormatValue(), dataFont));

        dashboard.addCell(linesOfCode);
        dashboard.addCell(comments);
        dashboard.addCell(codeCoverage);
        dashboard.addCell(complexity);
        dashboard.addCell(rulesCompliance);
        dashboard.addCell(violations);
        dashboard.setSpacingBefore(8);
        section.add(dashboard);
        Image ccnDistGraph = getCCNDistribution(project);
        if (ccnDistGraph != null) {
            section.add(ccnDistGraph);
            Paragraph imageFoot = new Paragraph(getTextProperty("metrics.ccn_classes_count_distribution"),
                    Style.FOOT_FONT);
            imageFoot.setAlignment(Paragraph.ALIGN_CENTER);
            section.add(imageFoot);
        }
    }

    private void printMeasures(Measures measures, Section section)
            throws org.dom4j.DocumentException, DocumentException {

        PdfPTable versioningTable = new PdfPTable(2);
        formatTable(versioningTable);
        versioningTable.getDefaultCell().setColspan(2);
        versioningTable
                .addCell(new Phrase(super.getTextProperty("general.versioning_information"), Style.TITLE_FONT));
        versioningTable.addCell(measures.getVersion());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd - HH:mm:ss");
        versioningTable.addCell(df.format(measures.getDate()));

        PdfPTable measuresTable = new PdfPTable(2);
        formatTable(measuresTable);

        Iterator<String> it = measures.getMeasuresKeys().iterator();
        measuresTable.addCell(new Phrase(super.getTextProperty("general.metric"), Style.TITLE_FONT));
        measuresTable.addCell(new Phrase(super.getTextProperty("general.value"), Style.TITLE_FONT));
        boolean colorEnabled = true;
        while (it.hasNext()) {
            String measureKey = it.next();
            if (colorEnabled) {
                measuresTable.getDefaultCell().setGrayFill(0.9f);
                colorEnabled = false;
            } else {
                measuresTable.getDefaultCell().setGrayFill(1);
                colorEnabled = true;
            }
            if (!measureKey.equals("ccn_classes_count_distribution")
                    && !measureKey.equals("ccn_classes_percent_distribution")) {
                measuresTable.getDefaultCell().setHorizontalAlignment(PdfCell.ALIGN_LEFT);
                measuresTable.addCell(super.getTextProperty("metrics." + measureKey));
                measuresTable.getDefaultCell().setHorizontalAlignment(PdfCell.ALIGN_CENTER);
                measuresTable.addCell(measures.getMeasure(measureKey).getFormatValue());
            }
        }
        measuresTable.setHeaderRows(1);
        section.add(versioningTable);
        section.add(measuresTable);

    }

    private void formatTable(PdfPTable table) {
        Rectangle page = document.getPageSize();
        table.getDefaultCell().setVerticalAlignment(PdfCell.ALIGN_MIDDLE);
        table.getDefaultCell().setPaddingBottom(tablePaddingBottom);
        table.getDefaultCell().setHorizontalAlignment(PdfCell.ALIGN_CENTER);
        table.setTotalWidth(page.getWidth() - document.leftMargin() - document.rightMargin());
        table.setSpacingBefore(20);
    }

    private void printProjectInfo(Project project, Section section)
            throws DocumentException, org.dom4j.DocumentException {
        List data = new List();
        data.add(new ListItem(super.getTextProperty("general.name") + ": " + project.getName()));
        data.add(new ListItem(super.getTextProperty("general.description") + ": " + project.getDescription()));
        data.add(new ListItem(super.getTextProperty("general.modules") + ": "));

        List sublist = new List();
        if (project.getSubprojects().size() != 0) {
            Iterator<Project> it = project.getSubprojects().iterator();
            while (it.hasNext()) {
                sublist.add(new ListItem(it.next().getName()));
            }
        } else {
            sublist.add(new ListItem(super.getTextProperty("general.no_modules")));
        }

        sublist.setIndentationLeft(indentation);
        data.add(sublist);
        section.add(data);
        printMeasures(project.getMeasures(), section);
    }

    @Override
    protected URL getLogo() {
        return this.logo;
    }

    @Override
    protected String getProjectKey() {
        return this.projectKey;
    }

    @Override
    protected String getSonarUrl() {
        return this.sonarUrl;
    }

    @Override
    protected void printTocTitle(Toc tocDocument) throws DocumentException {
        Paragraph tocTitle = new Paragraph(super.getTextProperty("main.table.of.contents"), Style.TOC_TITLE_FONT);
        tocTitle.setAlignment(Element.ALIGN_CENTER);
        tocDocument.getTocDocument().add(tocTitle);
        tocDocument.getTocDocument().add(Chunk.NEWLINE);
    }

    @Override
    protected void printFrontPage(Document frontPageDocument, PdfWriter frontPageWriter)
            throws org.dom4j.DocumentException, ReportException {
        try {
            URL largeLogo;
            if (super.getConfigProperty("front.page.logo").startsWith("http://")) {
                largeLogo = new URL(super.getConfigProperty("front.page.logo"));
            } else {
                largeLogo = this.getClass().getClassLoader()
                        .getResource(super.getConfigProperty("front.page.logo"));
            }
            Image logoImage = Image.getInstance(largeLogo);
            Rectangle pageSize = frontPageDocument.getPageSize();
            float positionX = pageSize.getWidth() / 2f - logoImage.getWidth() / 2f;
            logoImage.setAbsolutePosition(positionX, pageSize.getHeight() - logoImage.getHeight() - 100);
            frontPageDocument.add(logoImage);

            PdfPTable title = new PdfPTable(1);
            title.getDefaultCell().setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            title.getDefaultCell().setBorder(Rectangle.NO_BORDER);

            String projectRow = super.getTextProperty("general.project") + ": " + super.getProject().getName();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String dateRow = df.format(super.getProject().getMeasures().getDate());
            String descriptionRow = super.getProject().getDescription();

            title.addCell(new Phrase(projectRow, Style.FRONTPAGE_FONT_1));
            title.addCell(new Phrase(descriptionRow, Style.FRONTPAGE_FONT_2));
            title.addCell(new Phrase(dateRow, Style.FRONTPAGE_FONT_3));
            title.setTotalWidth(
                    pageSize.getWidth() - frontPageDocument.leftMargin() - frontPageDocument.rightMargin());
            title.writeSelectedRows(0, -1, frontPageDocument.leftMargin(),
                    pageSize.getHeight() - logoImage.getHeight() - 150, frontPageWriter.getDirectContent());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (BadElementException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected Properties getLangProperties() {
        return langProperties;
    }

    @Override
    protected Properties getReportProperties() {
        return configProperties;
    }
}