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  *    Evgeny Mandrikov - initial API and implementation
10  *
11  *******************************************************************************/
12 package org.jacoco.maven;
13 
14 import java.io.IOException;
15 import java.util.List;
16 import java.util.Locale;
17 
18 import org.apache.maven.doxia.siterenderer.Renderer;
19 import org.apache.maven.plugin.MojoExecutionException;
20 import org.apache.maven.plugins.annotations.Component;
21 import org.apache.maven.plugins.annotations.Parameter;
22 import org.apache.maven.project.MavenProject;
23 import org.apache.maven.reporting.AbstractMavenReport;
24 import org.apache.maven.reporting.MavenReportException;
25 import org.jacoco.report.IReportGroupVisitor;
26 import 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  */
32 public 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 
getDescription(final Locale locale)94 	public String getDescription(final Locale locale) {
95 		return getName(locale) + " Coverage Report.";
96 	}
97 
98 	@Override
isExternalReport()99 	public boolean isExternalReport() {
100 		return true;
101 	}
102 
103 	@Override
getProject()104 	protected MavenProject getProject() {
105 		return project;
106 	}
107 
108 	@Override
getSiteRenderer()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 	 */
getIncludes()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 	 */
getExcludes()127 	List<String> getExcludes() {
128 		return excludes;
129 	}
130 
131 	@Override
canGenerateReport()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 
canGenerateReportRegardingDataFiles()151 	abstract boolean canGenerateReportRegardingDataFiles();
152 
canGenerateReportRegardingClassesDirectory()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
execute()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
executeReport(final Locale locale)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 
loadExecutionData(final ReportSupport support)188 	abstract void loadExecutionData(final ReportSupport support)
189 			throws IOException;
190 
addFormatters(final ReportSupport support, final Locale locale)191 	abstract void addFormatters(final ReportSupport support, final Locale locale)
192 			throws IOException;
193 
createReport(final IReportGroupVisitor visitor, final ReportSupport support)194 	abstract void createReport(final IReportGroupVisitor visitor,
195 			final ReportSupport support) throws IOException;
196 
197 }
198