CoverageNodeImpl.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 * Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.core.analysis;
13
14import java.util.Collection;
15
16/**
17 * Base implementation for coverage data nodes.
18 *
19 * @author Marc R. Hoffmann
20 * @version 0.4.1.20101007204400
21 */
22public class CoverageNodeImpl implements ICoverageNode {
23
24 private final ElementType elementType;
25
26 private final String name;
27
28 /** Counter for blocks. */
29 protected CounterImpl blockCounter;
30
31 /** Counter for instructions. */
32 protected CounterImpl instructionCounter;
33
34 /** Counter for lines, if this element does not have lines. */
35 protected CounterImpl lineCounter;
36
37 /** Counter for methods. */
38 protected CounterImpl methodCounter;
39
40 /** Counter for classes. */
41 protected CounterImpl classCounter;
42
43 /** Line information if this element has lines. */
44 protected final LinesImpl lines;
45
46 /**
47 * Creates a new coverage data node.
48 *
49 * @param elementType
50 * type of the element represented by this instance
51 * @param name
52 * name of this node
53 * @param hasLines
54 * <code>true</code> id this element has source lines
55 */
56 public CoverageNodeImpl(final ElementType elementType, final String name,
57 final boolean hasLines) {
58 this.elementType = elementType;
59 this.name = name;
60 this.blockCounter = CounterImpl.COUNTER_0_0;
61 this.instructionCounter = CounterImpl.COUNTER_0_0;
62 this.methodCounter = CounterImpl.COUNTER_0_0;
63 this.classCounter = CounterImpl.COUNTER_0_0;
64 this.lineCounter = hasLines ? null : CounterImpl.COUNTER_0_0;
65 this.lines = hasLines ? new LinesImpl() : null;
66 }
67
68 /**
69 * Increments the counters by the values given by another element.
70 *
71 * @param child
72 * counters to add
73 */
74 public void increment(final ICoverageNode child) {
75 blockCounter = blockCounter.increment(child.getBlockCounter());
76 instructionCounter = instructionCounter.increment(child
77 .getInstructionCounter());
78 methodCounter = methodCounter.increment(child.getMethodCounter());
79 classCounter = classCounter.increment(child.getClassCounter());
80 if (lines == null) {
81 lineCounter = lineCounter.increment(child.getLineCounter());
82 } else {
83 lines.increment(child.getLines());
84 }
85 }
86
87 /**
88 * Increments the counters by the values given by the collection of
89 * elements.
90 *
91 * @param children
92 * list of nodes, which counters will be added to this node
93 */
94 public void increment(final Collection<? extends ICoverageNode> children) {
95 for (final ICoverageNode child : children) {
96 increment(child);
97 }
98 }
99
100 // === ICoverageDataNode ===
101
102 public ElementType getElementType() {
103 return elementType;
104 }
105
106 public String getName() {
107 return name;
108 }
109
110 public ICounter getInstructionCounter() {
111 return instructionCounter;
112 }
113
114 public ICounter getBlockCounter() {
115 return blockCounter;
116 }
117
118 public ICounter getLineCounter() {
119 return lines != null ? lines : lineCounter;
120 }
121
122 public ICounter getMethodCounter() {
123 return methodCounter;
124 }
125
126 public ICounter getClassCounter() {
127 return classCounter;
128 }
129
130 public ICounter getCounter(final CounterEntity entity) {
131 switch (entity) {
132 case INSTRUCTION:
133 return getInstructionCounter();
134 case BLOCK:
135 return getBlockCounter();
136 case LINE:
137 return getLineCounter();
138 case METHOD:
139 return getMethodCounter();
140 case CLASS:
141 return getClassCounter();
142 }
143 throw new AssertionError(entity);
144 }
145
146 public ILines getLines() {
147 return lines;
148 }
149
150 public ICoverageNode getPlainCopy() {
151 final boolean hasLines = lines != null;
152 final CoverageNodeImpl copy = new CoverageNodeImpl(elementType, name,
153 hasLines);
154 copy.instructionCounter = CounterImpl.getInstance(instructionCounter);
155 copy.blockCounter = CounterImpl.getInstance(blockCounter);
156 copy.methodCounter = CounterImpl.getInstance(methodCounter);
157 copy.classCounter = CounterImpl.getInstance(classCounter);
158 if (hasLines) {
159 copy.lines.increment(lines);
160 } else {
161 copy.lineCounter = CounterImpl.getInstance(lineCounter);
162 }
163 return copy;
164 }
165
166 @Override
167 public String toString() {
168 final StringBuilder sb = new StringBuilder();
169 sb.append(name).append(" [").append(elementType).append("]");
170 return sb.toString();
171 }
172}