HTMLFormatter.java revision 398ee59bebad6835dab57b60157eff16d511709e
1/*******************************************************************************
2 * Copyright (c) 2009, 2015 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 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.report.html;
13
14import java.io.IOException;
15import java.util.Collection;
16import java.util.List;
17import java.util.Locale;
18
19import org.jacoco.core.analysis.IBundleCoverage;
20import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
21import org.jacoco.core.data.ExecutionData;
22import org.jacoco.core.data.SessionInfo;
23import org.jacoco.report.ILanguageNames;
24import org.jacoco.report.IMultiReportOutput;
25import org.jacoco.report.IReportGroupVisitor;
26import org.jacoco.report.IReportVisitor;
27import org.jacoco.report.ISourceFileLocator;
28import org.jacoco.report.JavaNames;
29import org.jacoco.report.internal.ReportOutputFolder;
30import org.jacoco.report.internal.html.HTMLGroupVisitor;
31import org.jacoco.report.internal.html.IHTMLReportContext;
32import org.jacoco.report.internal.html.ILinkable;
33import org.jacoco.report.internal.html.index.ElementIndex;
34import org.jacoco.report.internal.html.index.IIndexUpdate;
35import org.jacoco.report.internal.html.page.BundlePage;
36import org.jacoco.report.internal.html.page.ReportPage;
37import org.jacoco.report.internal.html.page.SessionsPage;
38import org.jacoco.report.internal.html.resources.Resources;
39import org.jacoco.report.internal.html.resources.Styles;
40import org.jacoco.report.internal.html.table.BarColumn;
41import org.jacoco.report.internal.html.table.CounterColumn;
42import org.jacoco.report.internal.html.table.LabelColumn;
43import org.jacoco.report.internal.html.table.PercentageColumn;
44import org.jacoco.report.internal.html.table.Table;
45
46/**
47 * Formatter for coverage reports in multiple HTML pages.
48 */
49public class HTMLFormatter implements IHTMLReportContext {
50
51	private ILanguageNames languageNames = new JavaNames();
52
53	private Locale locale = Locale.getDefault();
54
55	private String footerText = "";
56
57	private String outputEncoding = "UTF-8";
58
59	private Resources resources;
60
61	private ElementIndex index;
62
63	private SessionsPage sessionsPage;
64
65	private Table table;
66
67	/**
68	 * New instance with default settings.
69	 */
70	public HTMLFormatter() {
71	}
72
73	/**
74	 * Sets the implementation for language name display. Java language names
75	 * are defined by default.
76	 *
77	 * @param languageNames
78	 *            converter for language specific names
79	 */
80	public void setLanguageNames(final ILanguageNames languageNames) {
81		this.languageNames = languageNames;
82	}
83
84	/**
85	 * Sets the locale used for report rendering. The current default locale is
86	 * used by default.
87	 *
88	 * @param locale
89	 *            locale used for report rendering
90	 */
91	public void setLocale(final Locale locale) {
92		this.locale = locale;
93	}
94
95	/**
96	 * Sets the optional text that should be included in every footer page.
97	 *
98	 * @param footerText
99	 *            footer text
100	 */
101	public void setFooterText(final String footerText) {
102		this.footerText = footerText;
103	}
104
105	/**
106	 * Sets the encoding used for generated HTML pages. Default is UTF-8.
107	 *
108	 * @param outputEncoding
109	 *            HTML output encoding
110	 */
111	public void setOutputEncoding(final String outputEncoding) {
112		this.outputEncoding = outputEncoding;
113	}
114
115	// === IHTMLReportContext ===
116
117	public ILanguageNames getLanguageNames() {
118		return languageNames;
119	}
120
121	public Resources getResources() {
122		return resources;
123	}
124
125	public Table getTable() {
126		if (table == null) {
127			table = createTable();
128		}
129		return table;
130	}
131
132	private Table createTable() {
133		final Table t = new Table();
134		t.add("Element", null, new LabelColumn(), false);
135		t.add("Missed Instructions", Styles.BAR, new BarColumn(CounterEntity.INSTRUCTION,
136				locale), true);
137		t.add("Cov.", Styles.CTR2,
138				new PercentageColumn(CounterEntity.INSTRUCTION, locale), false);
139		t.add("Missed Branches", Styles.BAR, new BarColumn(CounterEntity.BRANCH, locale),
140				false);
141		t.add("Cov.", Styles.CTR2, new PercentageColumn(CounterEntity.BRANCH, locale),
142				false);
143		addMissedTotalColumns(t, "Cxty", CounterEntity.COMPLEXITY);
144		addMissedTotalColumns(t, "Lines", CounterEntity.LINE);
145		addMissedTotalColumns(t, "Methods", CounterEntity.METHOD);
146		addMissedTotalColumns(t, "Classes", CounterEntity.CLASS);
147		return t;
148	}
149
150	private void addMissedTotalColumns(final Table table, final String label,
151			final CounterEntity entity) {
152		table.add("Missed", Styles.CTR1,
153				CounterColumn.newMissed(entity, locale), false);
154		table.add(label, Styles.CTR2, CounterColumn.newTotal(entity, locale),
155				false);
156	}
157
158	public String getFooterText() {
159		return footerText;
160	}
161
162	public ILinkable getSessionsPage() {
163		return sessionsPage;
164	}
165
166	public String getOutputEncoding() {
167		return outputEncoding;
168	}
169
170	public IIndexUpdate getIndexUpdate() {
171		return index;
172	}
173
174	public Locale getLocale() {
175		return locale;
176	}
177
178	/**
179	 * Creates a new visitor to write a report to the given output.
180	 *
181	 * @param output
182	 *            output to write the report to
183	 * @return visitor to emit the report data to
184	 * @throws IOException
185	 *             in case of problems with the output stream
186	 */
187	public IReportVisitor createVisitor(final IMultiReportOutput output)
188			throws IOException {
189		final ReportOutputFolder root = new ReportOutputFolder(output);
190		resources = new Resources(root);
191		resources.copyResources();
192		index = new ElementIndex(root);
193		return new IReportVisitor() {
194
195			private List<SessionInfo> sessionInfos;
196			private Collection<ExecutionData> executionData;
197
198			private HTMLGroupVisitor groupHandler;
199
200			public void visitInfo(final List<SessionInfo> sessionInfos,
201					final Collection<ExecutionData> executionData)
202					throws IOException {
203				this.sessionInfos = sessionInfos;
204				this.executionData = executionData;
205			}
206
207			public void visitBundle(final IBundleCoverage bundle,
208					final ISourceFileLocator locator) throws IOException {
209				final BundlePage page = new BundlePage(bundle, null, locator,
210						root, HTMLFormatter.this);
211				createSessionsPage(page);
212				page.render();
213			}
214
215			public IReportGroupVisitor visitGroup(final String name)
216					throws IOException {
217				groupHandler = new HTMLGroupVisitor(null, root,
218						HTMLFormatter.this, name);
219				createSessionsPage(groupHandler.getPage());
220				return groupHandler;
221
222			}
223
224			private void createSessionsPage(final ReportPage rootpage) {
225				sessionsPage = new SessionsPage(sessionInfos, executionData,
226						index, rootpage, root, HTMLFormatter.this);
227			}
228
229			public void visitEnd() throws IOException {
230				if (groupHandler != null) {
231					groupHandler.visitEnd();
232				}
233				sessionsPage.render();
234				output.close();
235			}
236		};
237	}
238}
239