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 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12 package org.jacoco.report.internal.html.table; 13 14 import java.io.IOException; 15 import java.text.DecimalFormat; 16 import java.text.NumberFormat; 17 import java.util.Comparator; 18 import java.util.List; 19 import java.util.Locale; 20 21 import org.jacoco.core.analysis.CounterComparator; 22 import org.jacoco.core.analysis.ICounter; 23 import org.jacoco.core.analysis.ICoverageNode; 24 import org.jacoco.core.analysis.ICoverageNode.CounterEntity; 25 import org.jacoco.report.internal.ReportOutputFolder; 26 import org.jacoco.report.internal.html.HTMLElement; 27 import org.jacoco.report.internal.html.resources.Resources; 28 29 /** 30 * Column that prints the counter values of entities for each item and a summary 31 * in the footer. If the total number of items is zero, no column is emitted at 32 * all. The implementation is stateful, instances must not be used in parallel. 33 */ 34 public abstract class CounterColumn implements IColumnRenderer { 35 36 /** 37 * Creates a new column that shows the total count for the given entity. 38 * 39 * @param entity 40 * counter entity for this column 41 * @param locale 42 * locale for rendering numbers 43 * @return column instance 44 */ newTotal(final CounterEntity entity, final Locale locale)45 public static CounterColumn newTotal(final CounterEntity entity, 46 final Locale locale) { 47 return new CounterColumn(entity, locale, CounterComparator.TOTALITEMS 48 .reverse().on(entity)) { 49 @Override 50 protected int getValue(final ICounter counter) { 51 return counter.getTotalCount(); 52 } 53 }; 54 } 55 56 /** 57 * Creates a new column that shows the missed count for the given entity. 58 * 59 * @param entity 60 * counter entity for this column 61 * @param locale 62 * locale for rendering numbers 63 * @return column instance 64 */ 65 public static CounterColumn newMissed(final CounterEntity entity, 66 final Locale locale) { 67 return new CounterColumn(entity, locale, CounterComparator.MISSEDITEMS 68 .reverse().on(entity)) { 69 @Override 70 protected int getValue(final ICounter counter) { 71 return counter.getMissedCount(); 72 } 73 }; 74 } 75 76 /** 77 * Creates a new column that shows the covered count for the given entity. 78 * 79 * @param entity 80 * counter entity for this column 81 * @param locale 82 * locale for rendering numbers 83 * @return column instance 84 */ 85 public static CounterColumn newCovered(final CounterEntity entity, 86 final Locale locale) { 87 return new CounterColumn(entity, locale, CounterComparator.COVEREDITEMS 88 .reverse().on(entity)) { 89 @Override 90 protected int getValue(final ICounter counter) { 91 return counter.getCoveredCount(); 92 } 93 }; 94 } 95 96 private final CounterEntity entity; 97 98 private final NumberFormat integerFormat; 99 100 private final Comparator<ITableItem> comparator; 101 102 /** 103 * Creates a new column that is based on the {@link ICounter} for the given 104 * entity. 105 * 106 * @param entity 107 * counter entity for this column 108 * @param locale 109 * locale for rendering numbers 110 * @param comparator 111 * comparator for the nodes of this column 112 */ 113 protected CounterColumn(final CounterEntity entity, final Locale locale, 114 final Comparator<ICoverageNode> comparator) { 115 this.entity = entity; 116 this.integerFormat = DecimalFormat.getIntegerInstance(locale); 117 this.comparator = new TableItemComparator(comparator); 118 } 119 120 public boolean init(final List<? extends ITableItem> items, 121 final ICoverageNode total) { 122 for (final ITableItem i : items) { 123 if (i.getNode().getCounter(entity).getTotalCount() > 0) { 124 return true; 125 } 126 } 127 return false; 128 } 129 130 public void footer(final HTMLElement td, final ICoverageNode total, 131 final Resources resources, final ReportOutputFolder base) 132 throws IOException { 133 cell(td, total); 134 } 135 136 public void item(final HTMLElement td, final ITableItem item, 137 final Resources resources, final ReportOutputFolder base) 138 throws IOException { 139 cell(td, item.getNode()); 140 } 141 142 private void cell(final HTMLElement td, final ICoverageNode node) 143 throws IOException { 144 final int value = getValue(node.getCounter(entity)); 145 td.text(integerFormat.format(value)); 146 } 147 148 public Comparator<ITableItem> getComparator() { 149 return comparator; 150 } 151 152 /** 153 * Retrieves the respective value from the counter. 154 * 155 * @param counter 156 * counter object 157 * @return value of interest 158 */ 159 protected abstract int getValue(ICounter counter); 160 161 } 162