1 /******************************************************************************* 2 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors 3 * This program and the accompanying materials are made available under 4 * the terms of the Eclipse Public License 2.0 which is available at 5 * http://www.eclipse.org/legal/epl-2.0 6 * 7 * SPDX-License-Identifier: EPL-2.0 8 * 9 * Contributors: 10 * Marc R. Hoffmann - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.report.internal.xml; 14 15 import java.io.IOException; 16 17 import org.jacoco.core.analysis.IBundleCoverage; 18 import org.jacoco.core.analysis.IClassCoverage; 19 import org.jacoco.core.analysis.ICounter; 20 import org.jacoco.core.analysis.ICoverageNode; 21 import org.jacoco.core.analysis.ICoverageNode.CounterEntity; 22 import org.jacoco.core.analysis.ILine; 23 import org.jacoco.core.analysis.IMethodCoverage; 24 import org.jacoco.core.analysis.IPackageCoverage; 25 import org.jacoco.core.analysis.ISourceFileCoverage; 26 import org.jacoco.core.analysis.ISourceNode; 27 28 /** 29 * Serializes coverage data as XML fragments. 30 */ 31 public final class XMLCoverageWriter { 32 33 /** 34 * Writes the structure of a given bundle. 35 * 36 * @param bundle 37 * bundle coverage data 38 * @param element 39 * container element for the bundle data 40 * @throws IOException 41 * if XML can't be written to the underlying output 42 */ writeBundle(final IBundleCoverage bundle, final ReportElement element)43 public static void writeBundle(final IBundleCoverage bundle, 44 final ReportElement element) throws IOException { 45 for (final IPackageCoverage p : bundle.getPackages()) { 46 writePackage(p, element); 47 } 48 writeCounters(bundle, element); 49 } 50 writePackage(final IPackageCoverage p, final ReportElement parent)51 private static void writePackage(final IPackageCoverage p, 52 final ReportElement parent) throws IOException { 53 final ReportElement element = parent.packageElement(p.getName()); 54 for (final IClassCoverage c : p.getClasses()) { 55 writeClass(c, element); 56 } 57 for (final ISourceFileCoverage s : p.getSourceFiles()) { 58 writeSourceFile(s, element); 59 } 60 writeCounters(p, element); 61 } 62 writeClass(final IClassCoverage c, final ReportElement parent)63 private static void writeClass(final IClassCoverage c, 64 final ReportElement parent) throws IOException { 65 final ReportElement element = parent.classElement(c); 66 for (final IMethodCoverage m : c.getMethods()) { 67 writeMethod(m, element); 68 } 69 writeCounters(c, element); 70 } 71 writeMethod(final IMethodCoverage m, final ReportElement parent)72 private static void writeMethod(final IMethodCoverage m, 73 final ReportElement parent) throws IOException { 74 final ReportElement element = parent.method(m); 75 writeCounters(m, element); 76 } 77 writeSourceFile(final ISourceFileCoverage s, final ReportElement parent)78 private static void writeSourceFile(final ISourceFileCoverage s, 79 final ReportElement parent) throws IOException { 80 final ReportElement element = parent.sourcefile(s.getName()); 81 writeLines(s, element); 82 writeCounters(s, element); 83 } 84 85 /** 86 * Writes all non-zero counters of the given node. 87 * 88 * @param node 89 * node to retrieve counters from 90 * @param parent 91 * container for the counter elements 92 * @throws IOException 93 * if XML can't be written to the underlying output 94 */ writeCounters(final ICoverageNode node, final ReportElement parent)95 public static void writeCounters(final ICoverageNode node, 96 final ReportElement parent) throws IOException { 97 for (final CounterEntity counterEntity : CounterEntity.values()) { 98 final ICounter counter = node.getCounter(counterEntity); 99 if (counter.getTotalCount() > 0) { 100 parent.counter(counterEntity, counter); 101 } 102 } 103 } 104 writeLines(final ISourceNode source, final ReportElement parent)105 private static void writeLines(final ISourceNode source, 106 final ReportElement parent) throws IOException { 107 final int last = source.getLastLine(); 108 for (int nr = source.getFirstLine(); nr <= last; nr++) { 109 final ILine line = source.getLine(nr); 110 if (line.getStatus() != ICounter.EMPTY) { 111 parent.line(nr, line); 112 } 113 } 114 } 115 XMLCoverageWriter()116 private XMLCoverageWriter() { 117 } 118 119 } 120