
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