1/******************************************************************************* 2 * Copyright (c) 2009, 2017 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 * Evgeny Mandrikov - initial API and implementation 10 * 11 *******************************************************************************/ 12package org.jacoco.maven; 13 14import java.io.IOException; 15import java.util.List; 16import java.util.Locale; 17 18import org.apache.maven.doxia.siterenderer.Renderer; 19import org.apache.maven.plugin.MojoExecutionException; 20import org.apache.maven.plugins.annotations.Component; 21import org.apache.maven.plugins.annotations.Parameter; 22import org.apache.maven.project.MavenProject; 23import org.apache.maven.reporting.AbstractMavenReport; 24import org.apache.maven.reporting.MavenReportException; 25import org.jacoco.report.IReportGroupVisitor; 26import org.jacoco.report.IReportVisitor; 27 28/** 29 * Base class for creating a code coverage report for tests of a single project 30 * in multiple formats (HTML, XML, and CSV). 31 */ 32public abstract class AbstractReportMojo extends AbstractMavenReport { 33 34 /** 35 * Encoding of the generated reports. 36 */ 37 @Parameter(property = "project.reporting.outputEncoding", defaultValue = "UTF-8") 38 String outputEncoding; 39 40 /** 41 * Name of the root node HTML report pages. 42 * 43 * @since 0.7.7 44 */ 45 @Parameter(defaultValue = "${project.name}") 46 String title; 47 48 /** 49 * Footer text used in HTML report pages. 50 * 51 * @since 0.7.7 52 */ 53 @Parameter 54 String footer; 55 56 /** 57 * Encoding of the source files. 58 */ 59 @Parameter(property = "project.build.sourceEncoding", defaultValue = "UTF-8") 60 String sourceEncoding; 61 62 /** 63 * A list of class files to include in the report. May use wildcard 64 * characters (* and ?). When not specified everything will be included. 65 */ 66 @Parameter 67 List<String> includes; 68 69 /** 70 * A list of class files to exclude from the report. May use wildcard 71 * characters (* and ?). When not specified nothing will be excluded. 72 */ 73 @Parameter 74 List<String> excludes; 75 76 /** 77 * Flag used to suppress execution. 78 */ 79 @Parameter(property = "jacoco.skip", defaultValue = "false") 80 boolean skip; 81 82 /** 83 * Maven project. 84 */ 85 @Parameter(property = "project", readonly = true) 86 MavenProject project; 87 88 /** 89 * Doxia Site Renderer. 90 */ 91 @Component 92 Renderer siteRenderer; 93 94 public String getDescription(final Locale locale) { 95 return getName(locale) + " Coverage Report."; 96 } 97 98 @Override 99 public boolean isExternalReport() { 100 return true; 101 } 102 103 @Override 104 protected MavenProject getProject() { 105 return project; 106 } 107 108 @Override 109 protected Renderer getSiteRenderer() { 110 return siteRenderer; 111 } 112 113 /** 114 * Returns the list of class files to include in the report. 115 * 116 * @return class files to include, may contain wildcard characters 117 */ 118 List<String> getIncludes() { 119 return includes; 120 } 121 122 /** 123 * Returns the list of class files to exclude from the report. 124 * 125 * @return class files to exclude, may contain wildcard characters 126 */ 127 List<String> getExcludes() { 128 return excludes; 129 } 130 131 @Override 132 public boolean canGenerateReport() { 133 if (skip) { 134 getLog().info( 135 "Skipping JaCoCo execution because property jacoco.skip is set."); 136 return false; 137 } 138 if (!canGenerateReportRegardingDataFiles()) { 139 getLog().info( 140 "Skipping JaCoCo execution due to missing execution data file."); 141 return false; 142 } 143 if (!canGenerateReportRegardingClassesDirectory()) { 144 getLog().info( 145 "Skipping JaCoCo execution due to missing classes directory."); 146 return false; 147 } 148 return true; 149 } 150 151 abstract boolean canGenerateReportRegardingDataFiles(); 152 153 abstract boolean canGenerateReportRegardingClassesDirectory(); 154 155 /** 156 * This method is called when the report generation is invoked directly as a 157 * standalone Mojo. 158 */ 159 @Override 160 public void execute() throws MojoExecutionException { 161 if (!canGenerateReport()) { 162 return; 163 } 164 try { 165 executeReport(Locale.getDefault()); 166 } catch (final MavenReportException e) { 167 throw new MojoExecutionException("An error has occurred in " 168 + getName(Locale.ENGLISH) + " report generation.", e); 169 } 170 } 171 172 @Override 173 protected void executeReport(final Locale locale) 174 throws MavenReportException { 175 try { 176 final ReportSupport support = new ReportSupport(getLog()); 177 loadExecutionData(support); 178 addFormatters(support, locale); 179 final IReportVisitor visitor = support.initRootVisitor(); 180 createReport(visitor, support); 181 visitor.visitEnd(); 182 } catch (final IOException e) { 183 throw new MavenReportException("Error while creating report: " 184 + e.getMessage(), e); 185 } 186 } 187 188 abstract void loadExecutionData(final ReportSupport support) 189 throws IOException; 190 191 abstract void addFormatters(final ReportSupport support, final Locale locale) 192 throws IOException; 193 194 abstract void createReport(final IReportGroupVisitor visitor, 195 final ReportSupport support) throws IOException; 196 197} 198