XMLReportNodeHandler.java
1/*******************************************************************************
2 * Copyright (c) 2009, 2010 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 * Brock Janiczak - initial API and implementation
10 * Marc R. Hoffmann - generalized structure
11 *
12 * $Id: $
13 *******************************************************************************/
14package org.jacoco.report.xml;
15
16import java.io.IOException;
17
18import org.jacoco.core.analysis.ClassCoverage;
19import org.jacoco.core.analysis.ICounter;
20import org.jacoco.core.analysis.ICoverageNode;
21import org.jacoco.core.analysis.MethodCoverage;
22import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
23import org.jacoco.core.analysis.ICoverageNode.ElementType;
24import org.jacoco.report.IReportVisitor;
25import org.jacoco.report.ISourceFileLocator;
26
27/**
28 * Report visitor that transforms the report structure into XML elements.
29 *
30 * @author Brock Janiczak
31 * @version $Revision: $
32 */
33class XMLReportNodeHandler implements IReportVisitor {
34
35 protected final XMLElement element;
36
37 protected final ICoverageNode node;
38
39 /**
40 * New handler for the given coverage node.
41 *
42 * @param element
43 * XML-Element representing this coverage node. The start tag
44 * must not be closed yet to allow adding additional attributes.
45 * @param node
46 * corresponding coverage node
47 * @throws IOException
48 * in case of problems with the underlying writer
49 */
50 public XMLReportNodeHandler(final XMLElement element,
51 final ICoverageNode node) throws IOException {
52 this.element = element;
53 this.node = node;
54 element.attr("name", node.getName());
55 }
56
57 public IReportVisitor visitChild(final ICoverageNode node)
58 throws IOException {
59 final ElementType type = node.getElementType();
60 switch (type) {
61 case GROUP:
62 case BUNDLE:
63 return new XMLReportNodeHandler(element.element("group"), node);
64 case PACKAGE:
65 return new XMLReportNodeHandler(element.element("package"), node);
66 case CLASS:
67 final XMLElement classChild = element.element("class");
68 addClassAttributes(classChild, (ClassCoverage) node);
69 return new XMLReportNodeHandler(classChild, node);
70 case METHOD:
71 final XMLElement methodChild = element.element("method");
72 addMethodAttributes(methodChild, (MethodCoverage) node);
73 return new XMLReportNodeHandler(methodChild, node);
74 }
75 return IReportVisitor.NOP;
76 }
77
78 public void visitEnd(final ISourceFileLocator sourceFileLocator)
79 throws IOException {
80 for (final CounterEntity counterEntity : CounterEntity.values()) {
81 createCounterElement(counterEntity);
82 }
83 this.element.close();
84 }
85
86 private void createCounterElement(final CounterEntity counterEntity)
87 throws IOException {
88 final ICounter counter = node.getCounter(counterEntity);
89 if (counter.getTotalCount() > 0) {
90 final XMLElement counterNode = this.element.element("counter");
91 counterNode.attr("type", counterEntity.name());
92 counterNode.attr("covered", counter.getCoveredCount());
93 counterNode.attr("missed", counter.getMissedCount());
94 counterNode.close();
95 }
96 }
97
98 private static void addClassAttributes(final XMLElement element,
99 final ClassCoverage node) throws IOException {
100 if (node.getSignature() != null) {
101 element.attr("signature", node.getSignature());
102 }
103 if (node.getSuperName() != null) {
104 element.attr("superclass", node.getSuperName());
105 }
106 if (node.getInterfaceNames() != null) {
107 boolean first = true;
108 final StringBuilder builder = new StringBuilder();
109 for (final String iface : node.getInterfaceNames()) {
110 if (first) {
111 first = false;
112 } else {
113 builder.append(' ');
114 }
115 builder.append(iface);
116 }
117 element.attr("interfaces", builder.toString());
118 }
119 }
120
121 private static void addMethodAttributes(final XMLElement element,
122 final MethodCoverage node) throws IOException {
123 element.attr("desc", node.getDesc());
124 final String signature = node.getSignature();
125 if (signature != null) {
126 element.attr("signature", signature);
127 }
128 }
129
130}