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