Package org.jacoco.maven

Source Code of org.jacoco.maven.AbstractReportMojo$SourceFileCollection

/*******************************************************************************
* Copyright (c) 2009, 2014 Mountainminds GmbH & Co. KG and Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Evgeny Mandrikov - initial API and implementation
*
*******************************************************************************/
package org.jacoco.maven;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.maven.doxia.siterenderer.Renderer;
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.jacoco.core.analysis.IBundleCoverage;
import org.jacoco.core.analysis.ICoverageNode;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.SessionInfoStore;
import org.jacoco.core.tools.ExecFileLoader;
import org.jacoco.report.FileMultiReportOutput;
import org.jacoco.report.IReportGroupVisitor;
import org.jacoco.report.IReportVisitor;
import org.jacoco.report.ISourceFileLocator;
import org.jacoco.report.MultiReportVisitor;
import org.jacoco.report.csv.CSVFormatter;
import org.jacoco.report.html.HTMLFormatter;
import org.jacoco.report.xml.XMLFormatter;

/**
* Base class for creating a code coverage report for tests of a single project
* in multiple formats (HTML, XML, and CSV).
*/
public abstract class AbstractReportMojo extends AbstractMavenReport {

  /**
   * Encoding of the generated reports.
   *
   * @parameter property="project.reporting.outputEncoding"
   *            default-value="UTF-8"
   */
  String outputEncoding;
  /**
   * Encoding of the source files.
   *
   * @parameter property="project.build.sourceEncoding"
   *            default-value="UTF-8"
   */
  String sourceEncoding;
  /**
   * A list of class files to include in the report. May use wildcard
   * characters (* and ?). When not specified everything will be included.
   *
   * @parameter
   */
  List<String> includes;
  /**
   * A list of class files to exclude from the report. May use wildcard
   * characters (* and ?). When not specified nothing will be excluded.
   *
   * @parameter
   */
  List<String> excludes;
  /**
   * Flag used to suppress execution.
   *
   * @parameter property="jacoco.skip" default-value="false"
   */
  boolean skip;
  /**
   * Maven project.
   *
   * @parameter property="project"
   * @readonly
   */
  MavenProject project;
  /**
   * Doxia Site Renderer.
   *
   * @component
   */
  Renderer siteRenderer;
  SessionInfoStore sessionInfoStore;
  ExecutionDataStore executionDataStore;

  public abstract String getOutputName();

  public abstract String getName(final Locale locale);

  public String getDescription(final Locale locale) {
    return getName(locale) + " Coverage Report.";
  }

  @Override
  public boolean isExternalReport() {
    return true;
  }

  @Override
  protected MavenProject getProject() {
    return project;
  }

  @Override
  protected Renderer getSiteRenderer() {
    return siteRenderer;
  }

  /**
   * Returns the list of class files to include in the report.
   *
   * @return class files to include, may contain wildcard characters
   */
  List<String> getIncludes() {
    return includes;
  }

  /**
   * Returns the list of class files to exclude from the report.
   *
   * @return class files to exclude, may contain wildcard characters
   */
  List<String> getExcludes() {
    return excludes;
  }

  @Override
  public abstract void setReportOutputDirectory(
      final File reportOutputDirectory);

  @Override
  public boolean canGenerateReport() {
    if (skip) {
      getLog().info(
          "Skipping JaCoCo execution because property jacoco.skip is set.");
      return false;
    }
    if (!getDataFile().exists()) {
      getLog().info(
          "Skipping JaCoCo execution due to missing execution data file:"
              + getDataFile());
      return false;
    }
    final File classesDirectory = new File(getProject().getBuild()
        .getOutputDirectory());
    if (!classesDirectory.exists()) {
      getLog().info(
          "Skipping JaCoCo execution due to missing classes directory:"
              + classesDirectory);
      return false;
    }
    return true;
  }

  /**
   * This method is called when the report generation is invoked directly as a
   * standalone Mojo.
   */
  @Override
  public void execute() throws MojoExecutionException {
    if (!canGenerateReport()) {
      return;
    }
    try {
      executeReport(Locale.getDefault());
    } catch (final MavenReportException e) {
      throw new MojoExecutionException("An error has occurred in "
          + getName(Locale.ENGLISH) + " report generation.", e);
    }
  }

  @Override
  protected void executeReport(final Locale locale)
      throws MavenReportException {
    loadExecutionData();
    try {
      final IReportVisitor visitor = createVisitor(locale);
      visitor.visitInfo(sessionInfoStore.getInfos(),
          executionDataStore.getContents());
      createReport(visitor);
      visitor.visitEnd();
    } catch (final IOException e) {
      throw new MavenReportException("Error while creating report: "
          + e.getMessage(), e);
    }
  }

  void loadExecutionData() throws MavenReportException {
    final ExecFileLoader loader = new ExecFileLoader();
    try {
      loader.load(getDataFile());
    } catch (final IOException e) {
      throw new MavenReportException(
          "Unable to read execution data file " + getDataFile()
              + ": " + e.getMessage(), e);
    }
    sessionInfoStore = loader.getSessionInfoStore();
    executionDataStore = loader.getExecutionDataStore();
  }

  void createReport(final IReportGroupVisitor visitor) throws IOException {
    final FileFilter fileFilter = new FileFilter(this.getIncludes(),
        this.getExcludes());
    final BundleCreator creator = new BundleCreator(this.getProject(),
        fileFilter, getLog());
    final IBundleCoverage bundle = creator.createBundle(executionDataStore);
    final SourceFileCollection locator = new SourceFileCollection(
        getCompileSourceRoots(), sourceEncoding);
    checkForMissingDebugInformation(bundle);
    visitor.visitBundle(bundle, locator);
  }

  void checkForMissingDebugInformation(final ICoverageNode node) {
    if (node.getClassCounter().getTotalCount() > 0
        && node.getLineCounter().getTotalCount() == 0) {
      getLog().warn(
          "To enable source code annotation class files have to be compiled with debug information.");
    }
  }

  IReportVisitor createVisitor(final Locale locale) throws IOException {
    final List<IReportVisitor> visitors = new ArrayList<IReportVisitor>();
    getOutputDirectoryFile().mkdirs();
    final XMLFormatter xmlFormatter = new XMLFormatter();
    xmlFormatter.setOutputEncoding(outputEncoding);
    visitors.add(xmlFormatter.createVisitor(new FileOutputStream(new File(
        getOutputDirectoryFile(), "jacoco.xml"))));
    final CSVFormatter csvFormatter = new CSVFormatter();
    csvFormatter.setOutputEncoding(outputEncoding);
    visitors.add(csvFormatter.createVisitor(new FileOutputStream(new File(
        getOutputDirectoryFile(), "jacoco.csv"))));
    final HTMLFormatter htmlFormatter = new HTMLFormatter();
    htmlFormatter.setOutputEncoding(outputEncoding);
    htmlFormatter.setLocale(locale);
    visitors.add(htmlFormatter.createVisitor(new FileMultiReportOutput(
        getOutputDirectoryFile())));
    return new MultiReportVisitor(visitors);
  }

  File resolvePath(final String path) {
    File file = new File(path);
    if (!file.isAbsolute()) {
      file = new File(getProject().getBasedir(), path);
    }
    return file;
  }

  List<File> getCompileSourceRoots() {
    final List<File> result = new ArrayList<File>();
    for (final Object path : getProject().getCompileSourceRoots()) {
      result.add(resolvePath((String) path));
    }
    return result;
  }

  private static class SourceFileCollection implements ISourceFileLocator {

    private final List<File> sourceRoots;
    private final String encoding;

    public SourceFileCollection(final List<File> sourceRoots,
        final String encoding) {
      this.sourceRoots = sourceRoots;
      this.encoding = encoding;
    }

    public Reader getSourceFile(final String packageName,
        final String fileName) throws IOException {
      final String r;
      if (packageName.length() > 0) {
        r = packageName + '/' + fileName;
      } else {
        r = fileName;
      }
      for (final File sourceRoot : sourceRoots) {
        final File file = new File(sourceRoot, r);
        if (file.exists() && file.isFile()) {
          return new InputStreamReader(new FileInputStream(file),
              encoding);
        }
      }
      return null;
    }

    public int getTabWidth() {
      return 4;
    }
  }

  abstract File getDataFile();

  abstract File getOutputDirectoryFile();

}
TOP

Related Classes of org.jacoco.maven.AbstractReportMojo$SourceFileCollection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.