JDependReport.java

package com.reallifedeveloper.maven.jdepend;

import java.io.File;
import java.util.Locale;
import java.util.ResourceBundle;

import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jdepend.xmlui.JDepend;
import lombok.Setter;

import com.reallifedeveloper.maven.jdepend.xml.XmlReport;
import com.reallifedeveloper.maven.jdepend.xml.XmlReportParser;

/**
 * Generates a JDepend report.
 *
 * @author RealLifeDeveloper
 */
@Mojo(name = "report", defaultPhase = LifecyclePhase.SITE)
@Execute(phase = LifecyclePhase.COMPILE)
public class JDependReport extends AbstractMavenReport {

    private static final String RESOURCE_BUNDLE_BASE_NAME = "com.reallifedeveloper.maven.jdepend.jdepend-report";
    private static final String OUTPUT_NAME = "jdepend-report";
    private static final String JDEPEND_FILE_ARGUMENT = "-file";

    /**
     * Directory containing the class files to analyze.
     */
    @Parameter(property = "jdepend.classesDirectory", defaultValue = "${project.build.outputDirectory}")
    @Setter
    private File classesDirectory;

    /**
     * Location of the generated JDepend XML report that is used as the basis of the HTML report generated by this plugin.
     */
    @Parameter(defaultValue = "${project.build.directory}/jdepend-report.xml", readonly = true)
    @Setter
    private File reportFile;

    /**
     * Skip execution of the plugin.
     */
    @Parameter(property = "jdepend.skip", defaultValue = "false")
    @Setter
    private boolean skip;

    @Override
    @SuppressWarnings("PMD.AvoidCatchingGenericException")
    @SuppressFBWarnings(value = "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", justification = "Maven will call canGenerateReport "
            + "before calling this method")
    protected void executeReport(Locale locale) throws MavenReportException {
        if (skip) {
            getLog().info("Skipping execution on behalf of user");
            return;
        }
        try {
            getLog().debug("Running JDepend to generate XML report: reportFile=" + reportFile + ", classesDirectory=" + classesDirectory);
            JDepend.main(new String[] { JDEPEND_FILE_ARGUMENT, reportFile.getPath(), classesDirectory.getPath() });
            XmlReportParser xmlReportParser = new XmlReportParser();
            getLog().debug("Parsing XML file into XmlReport object");
            XmlReport xmlReport = xmlReportParser.parse(reportFile);
            JDependReportRenderer reportRenderer = new JDependReportRenderer(xmlReport, getBundle(locale), getSink());
            getLog().debug("Rendering HTML reportm: outputDirectory=" + outputDirectory);
            reportRenderer.render();
        } catch (Exception e) {
            throw new MavenReportException("Error occurred during JDepend report generation", e);
        }
    }

    @Override
    public boolean canGenerateReport() throws MavenReportException {
        return classesDirectory != null && classesDirectory.canRead() && reportFile != null;
    }

    @Override
    public String getOutputName() {
        return OUTPUT_NAME;
    }

    @Override
    public String getName(Locale locale) {
        return getBundle(locale).getString("jdepend.name");
    }

    @Override
    public String getDescription(Locale locale) {
        return getBundle(locale).getString("jdepend.description");
    }

    @SuppressWarnings("PMD.UseProperClassLoader") // We want the class loader of this class, not the Maven code creating the report.
    private static ResourceBundle getBundle(Locale locale) {
        return ResourceBundle.getBundle(RESOURCE_BUNDLE_BASE_NAME, locale, JDependReport.class.getClassLoader());
    }
}