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