Home | History | Annotate | Download | only in examples
      1 /*******************************************************************************
      2  * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *    Brock Janiczak - initial API and implementation
     10  *
     11  *******************************************************************************/
     12 package org.jacoco.examples;
     13 
     14 import java.io.File;
     15 import java.io.IOException;
     16 
     17 import org.jacoco.core.analysis.Analyzer;
     18 import org.jacoco.core.analysis.CoverageBuilder;
     19 import org.jacoco.core.analysis.IBundleCoverage;
     20 import org.jacoco.core.tools.ExecFileLoader;
     21 import org.jacoco.report.DirectorySourceFileLocator;
     22 import org.jacoco.report.FileMultiReportOutput;
     23 import org.jacoco.report.IReportVisitor;
     24 import org.jacoco.report.html.HTMLFormatter;
     25 
     26 /**
     27  * This example creates a HTML report for eclipse like projects based on a
     28  * single execution data store called jacoco.exec. The report contains no
     29  * grouping information.
     30  *
     31  * The class files under test must be compiled with debug information, otherwise
     32  * source highlighting will not work.
     33  */
     34 public class ReportGenerator {
     35 
     36 	private final String title;
     37 
     38 	private final File executionDataFile;
     39 	private final File classesDirectory;
     40 	private final File sourceDirectory;
     41 	private final File reportDirectory;
     42 
     43 	private ExecFileLoader execFileLoader;
     44 
     45 	/**
     46 	 * Create a new generator based for the given project.
     47 	 *
     48 	 * @param projectDirectory
     49 	 */
     50 	public ReportGenerator(final File projectDirectory) {
     51 		this.title = projectDirectory.getName();
     52 		this.executionDataFile = new File(projectDirectory, "jacoco.exec");
     53 		this.classesDirectory = new File(projectDirectory, "bin");
     54 		this.sourceDirectory = new File(projectDirectory, "src");
     55 		this.reportDirectory = new File(projectDirectory, "coveragereport");
     56 	}
     57 
     58 	/**
     59 	 * Create the report.
     60 	 *
     61 	 * @throws IOException
     62 	 */
     63 	public void create() throws IOException {
     64 
     65 		// Read the jacoco.exec file. Multiple data files could be merged
     66 		// at this point
     67 		loadExecutionData();
     68 
     69 		// Run the structure analyzer on a single class folder to build up
     70 		// the coverage model. The process would be similar if your classes
     71 		// were in a jar file. Typically you would create a bundle for each
     72 		// class folder and each jar you want in your report. If you have
     73 		// more than one bundle you will need to add a grouping node to your
     74 		// report
     75 		final IBundleCoverage bundleCoverage = analyzeStructure();
     76 
     77 		createReport(bundleCoverage);
     78 
     79 	}
     80 
     81 	private void createReport(final IBundleCoverage bundleCoverage)
     82 			throws IOException {
     83 
     84 		// Create a concrete report visitor based on some supplied
     85 		// configuration. In this case we use the defaults
     86 		final HTMLFormatter htmlFormatter = new HTMLFormatter();
     87 		final IReportVisitor visitor = htmlFormatter
     88 				.createVisitor(new FileMultiReportOutput(reportDirectory));
     89 
     90 		// Initialize the report with all of the execution and session
     91 		// information. At this point the report doesn't know about the
     92 		// structure of the report being created
     93 		visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(),
     94 				execFileLoader.getExecutionDataStore().getContents());
     95 
     96 		// Populate the report structure with the bundle coverage information.
     97 		// Call visitGroup if you need groups in your report.
     98 		visitor.visitBundle(bundleCoverage, new DirectorySourceFileLocator(
     99 				sourceDirectory, "utf-8", 4));
    100 
    101 		// Signal end of structure information to allow report to write all
    102 		// information out
    103 		visitor.visitEnd();
    104 
    105 	}
    106 
    107 	private void loadExecutionData() throws IOException {
    108 		execFileLoader = new ExecFileLoader();
    109 		execFileLoader.load(executionDataFile);
    110 	}
    111 
    112 	private IBundleCoverage analyzeStructure() throws IOException {
    113 		final CoverageBuilder coverageBuilder = new CoverageBuilder();
    114 		final Analyzer analyzer = new Analyzer(
    115 				execFileLoader.getExecutionDataStore(), coverageBuilder);
    116 
    117 		analyzer.analyzeAll(classesDirectory);
    118 
    119 		return coverageBuilder.getBundle(title);
    120 	}
    121 
    122 	/**
    123 	 * Starts the report generation process
    124 	 *
    125 	 * @param args
    126 	 *            Arguments to the application. This will be the location of the
    127 	 *            eclipse projects that will be used to generate reports for
    128 	 * @throws IOException
    129 	 */
    130 	public static void main(final String[] args) throws IOException {
    131 		for (int i = 0; i < args.length; i++) {
    132 			final ReportGenerator generator = new ReportGenerator(new File(
    133 					args[i]));
    134 			generator.create();
    135 		}
    136 	}
    137 
    138 }
    139