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 */ ReportGenerator(final File projectDirectory)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 */ create()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 createReport(final IBundleCoverage bundleCoverage)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 loadExecutionData()107 private void loadExecutionData() throws IOException { 108 execFileLoader = new ExecFileLoader(); 109 execFileLoader.load(executionDataFile); 110 } 111 analyzeStructure()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 */ main(final String[] args)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