All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.objectlab.qalab.m2.report.MergeAndChartReport Maven / Gradle / Ivy

////////////////////////////////////////////////////////////////////////////////
//
//                  ObjectLab is sponsoring QALab
//
// Based in London, we are world leaders in the design and development
// of bespoke applications for the Securities Financing markets.
//
// Click here to learn more
//           ___  _     _           _   _          _
//          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
//         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
//         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
//          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
//                   |__/
//
//                   http://www.ObjectLab.co.uk
// ---------------------------------------------------------------------------
//
//QALab is released under the GNU General Public License.
//
//QALab: Collects QA Statistics from your build over time.
//2005+, ObjectLab Ltd
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.
//
//This library 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
//General Public License for more details.
//
//You should have received a copy of the GNU General Public
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
////////////////////////////////////////////////////////////////////////////////
package net.objectlab.qalab.m2.report;

import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import java.io.FileInputStream;
import java.io.InputStream;

import net.objectlab.qalab.m2.BuildStatChartMojo;
import net.objectlab.qalab.m2.QALabStatAllMergeMojo;
import net.objectlab.qalab.m2.util.Utils;
import net.objectlab.qalab.m2.util.XmlTransformer;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;

import org.codehaus.doxia.site.renderer.SiteRenderer;
import javax.xml.transform.TransformerException;

/**
 * *** IMPORTANT USE this Report as part of your reporting section, it merges the data in qalab.xml,
 * creates the charts and generates the chart report, ensure that this report is run AFTER Checkstyle,
 * pmd, Findbugs, Cobertura, etc.
 *
 * @author Benoit Xhenseval.
 * @goal report-merge-chart
 * @phase deploy
 */
public class MergeAndChartReport extends AbstractMavenReport {

    // ~ MERGE fields -------------------------------------------------------
    /**
     * The input file generated by Checkstyle.
     *
     * @parameter expression="${project.build.directory}/checkstyle-result.xml"
     */
    private File checkstyleInputFile = null;

    /**
     * The fully qualified class name for the handler for Checkstyle.
     *
     * @parameter default-value="net.objectlab.qalab.parser.CheckstyleStatMerge"
     */
    private String checkstyleHandler;

    /**
     * The input file generated by PMD.
     *
     * @parameter expression="${project.build.directory}/pmd.xml"
     */
    private File pmdInputFile = null;

    /**
     * The fully qualified class name for the handler for PMD.
     *
     * @parameter default-value="net.objectlab.qalab.parser.PMDStatMerge"
     */
    private String pmdHandler;

    /**
     * The input file generated by PMD CPD.
     *
     * @parameter expression="${project.build.directory}/cpd.xml"
     */
    private File pmdCpdInputFile = null;

    /**
     * The fully qualified class name for the handler for PMD CPD.
     *
     * @parameter default-value="net.objectlab.qalab.parser.PMDCPDStatMerge"
     */
    private String pmdCpdHandler;

    /**
     * The input file generated by FindBugs.
     *
     * @parameter expression="${project.build.directory}/findbugs.xml"
     */
    private File findbugsInputFile = null;

    /**
     * The fully qualified class name for the handler for FindBugs.
     *
     * @parameter default-value="net.objectlab.qalab.parser.FindBugsStatMerge"
     */
    private String findbugsHandler;

    /**
     * The input file generated by Simian.
     *
     * @parameter expression="${project.build.directory}/simian-raw-report.xml"
     */
    private File simianInputFile = null;

    /**
     * The fully qualified class name for the handler for Simian.
     *
     * @parameter default-value="net.objectlab.qalab.parser.SimianStatMerge"
     */
    private String simianHandler;

    /**
     * The input file generated by Cobertura.
     *
     * @parameter expression="${project.reporting.outputDirectory}/cobertura/coverage.xml"
     */
    private File coberturaInputFile = null;

    /**
     * The fully qualified class name for the handler for Cobertura Line.
     *
     * @parameter default-value="net.objectlab.qalab.parser.CoberturaLineStatMerge"
     */
    private String coberturaLineHandler;

    /**
     * The fully qualified class name for the handler for Cobertura Branch.
     *
     * @parameter default-value="net.objectlab.qalab.parser.CoberturaBranchStatMerge"
     */
    private String coberturaBranchHandler;

    /**
     * If true then any debug logging output will be suppressed.
     *
     * @parameter default-value=false
     */
    private boolean quiet = false;

    /**
     * If true then use ONLY DATE for timestamp (use in conjunction action
     * replace).
     *
     * @parameter default-value=true
     */
    private boolean dateOnly = true;

    /**
     * The directory where the source code is.
     *
     * @parameter expression="${project.build.sourceDirectory}"
     */
    private String srcDir;

    /**
     * The timestamp for the stats.
     *
     * @parameter
     */
    private String mergerTimeStamp;

    /**
     * An exporter class name.
     *
     * @parameter default-value="net.objectlab.qalab.exporter.QALabXMLExporter"
     */
    private String exporterClassName = "net.objectlab.qalab.exporter.QALabXMLExporter";

    /**
     * The properties file to use instead of setting them one by one.
     *
     * @parameter
     */
    private File propertiesFile;

    /**
     * the loaded properties from the properties file declared above.
     */
    private Properties theProperties = null;

    // -------------------- CHART GENERATION ------------------------------------------

    /**
     * The directory where the generated html report will go.
     *
     * @parameter expression="${project.reporting.outputDirectory}/qalab"
     * @required
     */
    private File chartOutputDirectory;

    /**
     * The Chart chartWidth.
     *
     * @parameter default-value=750
     */
    private int chartWidth;

    /**
     * The Chart chartHeight.
     *
     * @parameter default-value=500
     */
    private int chartHeight;

    /**
     * If the movingAverage is <= 0 then there is no moving average, otherwise
     * it shows the average based on the last n points, where n is the value of
     * this field.
     *
     * @parameter default-value=0
     */
    private int movingAverage = 0;

    /**
     * If true then generate a summary chart only.
     *
     * @parameter default-value=false
     */
    private boolean chartSummaryOnly = false;

    /**
     * Statistic type to appear on summary chart, defaulted to
     * 'checkstyle,pmd,findbugs,simian,pmd-cpd'.
     *
     * @parameter default-value="checkstyle,pmd,findbugs,simian,pmd-cpd"
     */
    private String summaryTypes = "checkstyle,pmd,findbugs,simian,pmd-cpd";

    /**
     * File prefix for the charts (e.g. cobertura-) Default empty.
     *
     * @parameter default-value=""
     */
    private String chartFilePrefix = "";

    /**
     * X Axis Title
     *
     * @parameter default-value="Date"
     */
    private String xAxisTitle = "Date";

    /**
     * Y Axis Title
     *
     * @parameter default-value="Violation Count / Coverage Percent"
     */
    private String yAxisTitle = "Violation Count / Coverage Percent";

    /**
     * X Axis Title for Summary
     *
     * @parameter default-value="Date"
     */
    private String xAxisSummaryTitle = "Date";

    /**
     * Y Axis Title for Summary
     *
     * @parameter default-value="Violation Count"
     */
    private String yAxisSummaryTitle = "Violation Count";

    // -------------------- CHART REPORT ------------------------------------------

    /**
     * The generated qalab.xml file.
     *
     * @parameter expression="${project.basedir}/qalab.xml"
     */
    private File qalabFile = null;

    /**
     * The xslt stylesheet bundled, either qalab-chart-xdoc.xsl or
     * qalab-chart-html.xsl.
     *
     * @parameter default-value="qalab-chart-xdoc.xsl";
     */
    private String chartBundledXsl = null;

    /**
     * The directory where the generated xdoc/html report will go.
     *
     * @parameter expression="${project.build.directory}/generated-site/xdoc/qalab/"
     * @required
     */
    private String outputDirectory;

    /**
     * Statistic types, defaulted to
     * 'checkstyle,pmd,pmd-cpd,findbugs,simian,cobertura-line,cobertura-branch'.
     *
     * @parameter default-value="checkstyle,pmd,pmd-cpd,findbugs,simian,cobertura-line,cobertura-branch"
     */
    private String types = "checkstyle,pmd,pmd-cpd,findbugs,simian,cobertura-line,cobertura-branch";

    /**
     * The xml input stream.
     */
    private InputStream theXmlStream = null;

    /**
     * The xslt style sheet.
     *
     * @parameter
     */
    private File styleSheet = null;

    /**
     * The xslt style sheet input stream.
     */
    private InputStream theStyleSheetStream = null;

    /**
     * The number of hours to define the time window from now.
     *
     * @parameter default-value="48"
     */
    private String startTimeHoursOffset = "48";

    /**
     * The string version of the actual date computed by the offset set above.
     */
    private String theOffset;

    /**
     * Not sure what this is.
     *
     * @component
     */
    private SiteRenderer siteRenderer;

    /**
     * The maven project.
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * generate the actual report.
     *
     * @param aLocale
     *            ignored.
     * @throws MavenReportException
     *             if anything goes wrong.
     */
    protected final void executeReport(final Locale aLocale) throws MavenReportException {

        getLog().info("QALab: Merge and Chart Report");

        try {
            doMerge();
        } catch (MojoExecutionException e) {
            throw new MavenReportException("Issue during Merge", e);
        }

        try {
            doChart();
        } catch (MojoExecutionException e) {
            throw new MavenReportException("Issue during Chart", e);
        }

        validate();

        getLog().info("Output Directory: " + getOutputDirectory());

        final File outdir = new File(getOutputDirectory());
        if (!outdir.exists()) {
            outdir.mkdirs();
        }
        assert outdir.isDirectory() : "the output directory was not a directory";

        final File output;
        try {
            output = File.createTempFile("qalab", null, outdir);
            assert output != null : "the temp file is null.";

        } catch (IOException ioex) {
            throw new MavenReportException("could not create temp file.", ioex);
        }

        final XmlTransformer t = new XmlTransformer(theXmlStream, theStyleSheetStream, output);
        t.addParameter("targetdir", getOutputDirectory());
        t.addParameter("type", types);
        t.addParameter("offset", theOffset);
        try {
            t.transform();
        } catch (TransformerException tex) {
            throw new MavenReportException("transformation failed.", tex);
        }

        // clean up the temp file when the plugin is done.
        output.deleteOnExit();
    }

    private void doMerge() throws MojoExecutionException {
        QALabStatAllMergeMojo mojo = new QALabStatAllMergeMojo();
        mojo.setCheckstyleHandler(checkstyleHandler);
        mojo.setCheckstyleInputFile(checkstyleInputFile);
        mojo.setPmdCpdHandler(pmdCpdHandler);
        mojo.setPmdCpdInputFile(pmdCpdInputFile);
        mojo.setPmdHandler(pmdHandler);
        mojo.setPmdInputFile(pmdInputFile);
        mojo.setSimianHandler(simianHandler);
        mojo.setSimianInputFile(simianInputFile);
        mojo.setCoberturaBranchHandler(coberturaBranchHandler);
        mojo.setCoberturaInputFile(coberturaInputFile);
        mojo.setCoberturaLineHandler(coberturaLineHandler);
        mojo.setDateOnly(dateOnly);
        mojo.setExporterClassName(exporterClassName);
        mojo.setFindbugsHandler(findbugsHandler);
        mojo.setFindbugsInputFile(findbugsInputFile);
        mojo.setMergerTimeStamp(mergerTimeStamp);
        mojo.setOutputFile(qalabFile);
        mojo.setPropertiesFile(propertiesFile);
        mojo.setQuiet(quiet);
        mojo.setSrcDir(srcDir);
        mojo.setTheProperties(theProperties);
        mojo.setPluginContext(getPluginContext());

        mojo.execute();
    }

    private void doChart() throws MojoExecutionException {
        BuildStatChartMojo mojo = new BuildStatChartMojo();
        mojo.setFilePrefix(chartFilePrefix);
        mojo.setSummaryOnly(chartSummaryOnly);
        mojo.setSummaryTypes(summaryTypes);
        mojo.setHeight(chartHeight);
        mojo.setWidth(chartWidth);
        mojo.setMovingAverage(movingAverage);
        mojo.setQalabFile(qalabFile);
        mojo.setQuiet(quiet);
        mojo.setToDir(chartOutputDirectory);
        mojo.setTypes(types);
        mojo.setPluginContext(getPluginContext());
        mojo.setXAxisSummaryTitle(xAxisSummaryTitle);
        mojo.setXAxisTitle(xAxisTitle);
        mojo.setYAxisSummaryTitle(yAxisSummaryTitle);
        mojo.setYAxisTitle(yAxisTitle);

        mojo.execute();

        // now just the cobertura report.
        mojo.setFilePrefix("cobertura-" + chartFilePrefix);
        mojo.setSummaryOnly(true);
        mojo.setSummaryTypes("cobertura-line,cobertura-branch");
        mojo.setYAxisSummaryTitle("Coverage Percent");
        mojo.execute();
    }

    /**
     * @return "qalab/index"
     * @see org.apache.maven.reporting.MavenReport#getOutputName()
     */
    public final String getOutputName() {
        return "qalab/index";
    }

    /**
     * @return The output directory as configured in your pom.xml.
     * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
     */
    protected final String getOutputDirectory() {
        return outputDirectory;
    }

    /**
     * @return The Maven Project itself. Used internally to get access to Config
     *         params etc.
     * @see org.apache.maven.reporting.AbstractMavenReport#getProject()
     */
    protected final MavenProject getProject() {
        return project;
    }

    /**
     * @return a direct reference to the site renderer.
     * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
     */
    protected final SiteRenderer getSiteRenderer() {
        return siteRenderer;
    }

    /**
     * @param aLocale
     *            The locale.
     * @return The locale specific report name.
     * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
     */
    public final String getName(final Locale aLocale) {
        return getBundle(aLocale).getString("report.qalab.name");
    }

    /**
     * @param aLocale
     *            The locale.
     * @return The locale specific report description.
     * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale)
     */
    public final String getDescription(final Locale aLocale) {
        return getBundle(aLocale).getString("report.qalab.description");
    }

    /**
     * @return true.
     * @see org.apache.maven.reporting.MavenReport#isExternalReport
     */
    public final boolean isExternalReport() {
        return true;
    }

    /**
     * @param aLocale
     *            The locale.
     * @return the resource bundle for this report.
     */
    private static ResourceBundle getBundle(final Locale aLocale) {
        return ResourceBundle.getBundle("qalab-report", aLocale, MergeAndChartReport.class.getClassLoader());
    }

    public void setXAxisSummaryTitle(String xAxisSummaryTitle) {
    	this.xAxisSummaryTitle = xAxisSummaryTitle;
    }

    public void setXAxisTitle(String xAxisTitle) {
    	this.xAxisTitle = xAxisTitle;
    }

    public void setYAxisSummaryTitle(String yAxisSummaryTitle) {
    	this.yAxisSummaryTitle = yAxisSummaryTitle;
    }

    public void setYAxisTitle(String yAxisTitle) {
    	this.yAxisTitle = yAxisTitle;
    }

    /**
     * Validates the parameters supplied by maven 2.
     *
     * @throws MavenReportException
     *             if any supplied params are wrong.
     */
    private void validate() throws MavenReportException {
        try {
            Utils.checkFile(qalabFile, "qalabFile");
            theXmlStream = new FileInputStream(qalabFile);
        } catch (IOException ioex) {
            throw new MavenReportException(ioex.getMessage(), ioex);
        }

        if (styleSheet == null) {
            try {
                theStyleSheetStream = Utils.extractAsInputStream(chartBundledXsl);
            } catch (IOException ioex) {
                throw new MavenReportException("Could not find the default stylesheet. " + ioex.getMessage(), ioex);
            }
        } else {
            try {
                Utils.checkFile(styleSheet, "styleSheet");
                theStyleSheetStream = new FileInputStream(styleSheet);
            } catch (IOException ioex) {
                throw new MavenReportException(ioex.getMessage(), ioex);
            }
        }

        theOffset = Utils.formatDateBasedOnOffset(startTimeHoursOffset);
    }
}
/*
 *                   ObjectLab is sponsoring QALab
 *
 * Based in London, we are world leaders in the design and development
 * of bespoke applications for the securities financing markets.
 *
 * Click here to learn more about us
 *           ___  _     _           _   _          _
 *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
 *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
 *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
 *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
 *                   |__/
 *
 *                     www.ObjectLab.co.uk
 */




© 2015 - 2025 Weber Informatics LLC | Privacy Policy