• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import java.io.OutputStream;
17 
18 import org.jacoco.core.analysis.IClassCoverage;
19 import org.jacoco.core.analysis.ICounter;
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.data.SessionInfo;
24 
25 /**
26  * A {@link XMLElement} with utility methods to create JaCoCo XML reports.
27  */
28 public class ReportElement extends XMLElement {
29 
30 	private static final String PUBID = "-//JACOCO//DTD Report 1.1//EN";
31 
32 	private static final String SYSTEM = "report.dtd";
33 
34 	/**
35 	 * Creates a <code>report</code> root element for a XML report.
36 	 *
37 	 * @param name
38 	 *            value for the name attribute
39 	 * @param encoding
40 	 *            character encoding used for output
41 	 * @param output
42 	 *            output stream will be closed if the root element is closed
43 	 * @throws IOException
44 	 *             in case of problems with the underlying output
45 	 */
ReportElement(final String name, final OutputStream output, final String encoding)46 	public ReportElement(final String name, final OutputStream output,
47 			final String encoding) throws IOException {
48 		super("report", PUBID, SYSTEM, true, encoding, output);
49 		attr("name", name);
50 	}
51 
ReportElement(final String name, final ReportElement parent)52 	private ReportElement(final String name, final ReportElement parent)
53 			throws IOException {
54 		super(name, parent);
55 	}
56 
57 	@Override
element(final String name)58 	public ReportElement element(final String name) throws IOException {
59 		return new ReportElement(name, this);
60 	}
61 
namedElement(final String elementName, final String name)62 	private ReportElement namedElement(final String elementName,
63 			final String name) throws IOException {
64 		final ReportElement element = element(elementName);
65 		element.attr("name", name);
66 		return element;
67 	}
68 
69 	/**
70 	 * Creates a 'sessioninfo' element.
71 	 *
72 	 * @param info
73 	 *            info object to write out
74 	 * @throws IOException
75 	 *             in case of problems with the underlying output
76 	 */
sessioninfo(final SessionInfo info)77 	public void sessioninfo(final SessionInfo info) throws IOException {
78 		final ReportElement sessioninfo = element("sessioninfo");
79 		sessioninfo.attr("id", info.getId());
80 		sessioninfo.attr("start", info.getStartTimeStamp());
81 		sessioninfo.attr("dump", info.getDumpTimeStamp());
82 	}
83 
84 	/**
85 	 * Creates a 'group' element.
86 	 *
87 	 * @param name
88 	 *            value for the name attribute
89 	 * @return 'group' element
90 	 * @throws IOException
91 	 *             in case of problems with the underlying output
92 	 */
group(final String name)93 	public ReportElement group(final String name) throws IOException {
94 		return namedElement("group", name);
95 	}
96 
97 	/**
98 	 * Creates a 'package' element.
99 	 *
100 	 * @param name
101 	 *            value for the name attribute
102 	 * @return 'package' element
103 	 * @throws IOException
104 	 *             in case of problems with the underlying output
105 	 */
packageElement(final String name)106 	public ReportElement packageElement(final String name) throws IOException {
107 		return namedElement("package", name);
108 	}
109 
110 	/**
111 	 * Creates a 'class' element.
112 	 *
113 	 * @param coverage
114 	 *            class coverage node to write out
115 	 * @return 'class' element
116 	 * @throws IOException
117 	 *             in case of problems with the underlying output
118 	 */
classElement(final IClassCoverage coverage)119 	public ReportElement classElement(final IClassCoverage coverage)
120 			throws IOException {
121 		final ReportElement element = namedElement("class", coverage.getName());
122 		element.attr("sourcefilename", coverage.getSourceFileName());
123 		return element;
124 	}
125 
126 	/**
127 	 * Creates a 'method' element.
128 	 *
129 	 * @param coverage
130 	 *            method coverage node to write out
131 	 * @return 'method' element
132 	 * @throws IOException
133 	 *             in case of problems with the underlying output
134 	 */
method(final IMethodCoverage coverage)135 	public ReportElement method(final IMethodCoverage coverage)
136 			throws IOException {
137 		final ReportElement element = namedElement("method",
138 				coverage.getName());
139 		element.attr("desc", coverage.getDesc());
140 		final int line = coverage.getFirstLine();
141 		if (line != -1) {
142 			element.attr("line", line);
143 		}
144 		return element;
145 	}
146 
147 	/**
148 	 * Creates a 'sourcefile' element.
149 	 *
150 	 * @param name
151 	 *            value for the name attribute
152 	 * @return 'sourcefile' element
153 	 * @throws IOException
154 	 *             in case of problems with the underlying output
155 	 */
sourcefile(final String name)156 	public ReportElement sourcefile(final String name) throws IOException {
157 		return namedElement("sourcefile", name);
158 	}
159 
160 	/**
161 	 * Creates a 'line' element.
162 	 *
163 	 * @param nr
164 	 *            line number
165 	 * @param line
166 	 *            line object to write out
167 	 *
168 	 * @throws IOException
169 	 *             in case of problems with the underlying output
170 	 */
line(final int nr, final ILine line)171 	public void line(final int nr, final ILine line) throws IOException {
172 		final ReportElement element = element("line");
173 		element.attr("nr", nr);
174 		counterAttributes(element, "mi", "ci", line.getInstructionCounter());
175 		counterAttributes(element, "mb", "cb", line.getBranchCounter());
176 	}
177 
178 	/**
179 	 * Creates a 'counter' element.
180 	 *
181 	 * @param counterEntity
182 	 *            entity of this counter
183 	 *
184 	 * @param counter
185 	 *            counter object to write out
186 	 *
187 	 * @throws IOException
188 	 *             in case of problems with the underlying output
189 	 */
counter(final CounterEntity counterEntity, final ICounter counter)190 	public void counter(final CounterEntity counterEntity,
191 			final ICounter counter) throws IOException {
192 		final ReportElement counterNode = element("counter");
193 		counterNode.attr("type", counterEntity.name());
194 		counterAttributes(counterNode, "missed", "covered", counter);
195 	}
196 
counterAttributes(final XMLElement element, final String missedattr, final String coveredattr, final ICounter counter)197 	private static void counterAttributes(final XMLElement element,
198 			final String missedattr, final String coveredattr,
199 			final ICounter counter) throws IOException {
200 		element.attr(missedattr, counter.getMissedCount());
201 		element.attr(coveredattr, counter.getCoveredCount());
202 	}
203 
204 }
205