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