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