Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 154 |  | Methods: | 8
| NCLOC: | 114 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
StatisticalRule.java | 95.8% | 98.2% | 87.5% | 96.6% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd.stat;
5 |  |
6 |  | import java.util.Iterator;
7 |  | import java.util.List;
8 |  | import java.util.Map;
9 |  | import java.util.Set;
10 |  | import java.util.SortedSet;
11 |  | import java.util.TreeSet;
12 |  |
13 |  | import net.sourceforge.pmd.AbstractRule;
14 |  | import net.sourceforge.pmd.PropertyDescriptor;
15 |  | import net.sourceforge.pmd.RuleContext;
16 |  | import net.sourceforge.pmd.properties.DoubleProperty;
17 |  | import net.sourceforge.pmd.properties.IntegerProperty;
18 |  |
19 |  | /**
20 |  | * @author David Dixon-Peugh
21 |  | * Aug 8, 2002 StatisticalRule.java
22 |  | */
23 |  | public abstract class StatisticalRule extends AbstractRule {
24 |  |
25 |  | public static double DELTA = 0.000005; // Within this range. . .
26 |  |
27 |  | private SortedSet dataPoints = new TreeSet();
28 |  |
29 |  | private int count = 0;
30 |  | private double total = 0.0;
31 |  |
32 |  | private static final PropertyDescriptor sigmaDescriptor = new DoubleProperty(
33 |  | "sigma", "Sigma value", 0, 1.0f
34 |  | );
35 |  |
36 |  | private static final PropertyDescriptor minimumDescriptor = new DoubleProperty(
37 |  | "minimum", "Minimum value", 0, 1.0f
38 |  | );
39 |  |
40 |  | private static final PropertyDescriptor topScoreDescriptor = new IntegerProperty(
41 |  | "topscore", "Top score value", 0, 1.0f
42 |  | );
43 |  |
44 |  | private static final Map propertyDescriptorsByName = asFixedMap( new PropertyDescriptor[] {
45 |  | sigmaDescriptor, minimumDescriptor, topScoreDescriptor
46 |  | });
47 |  |
48 |  |
49 | 23738 | public void addDataPoint(DataPoint point) {
50 | 23738 | count++;
51 | 23738 | total += point.getScore();
52 | 23738 | dataPoints.add(point);
53 |  | }
54 |  |
55 | 194 | public void apply(List acus, RuleContext ctx) {
56 | 194 | visitAll(acus, ctx);
57 |  |
58 | 194 | double deviation;
59 | 194 | double minimum = 0.0;
60 |  |
61 | 194 | if (hasProperty("sigma")) { // TODO - need to come up with a good default value
62 | 108 | deviation = getStdDev();
63 | 108 | double sigma = getDoubleProperty(sigmaDescriptor);
64 | 108 | minimum = getMean() + (sigma * deviation);
65 |  | }
66 |  |
67 | 194 | if (hasProperty("minimum")) { // TODO - need to come up with a good default value
68 | 145 | double mMin = getDoubleProperty(minimumDescriptor);
69 | 145 | if (mMin > minimum) {
70 | 115 | minimum = mMin;
71 |  | }
72 |  | }
73 |  |
74 | 194 | SortedSet newPoints = applyMinimumValue(dataPoints, minimum);
75 |  |
76 | 194 | if (hasProperty("topscore")) { // TODO - need to come up with a good default value
77 | 108 | int topScore = getIntProperty(topScoreDescriptor);
78 | 108 | if (newPoints.size() >= topScore) {
79 | 48 | newPoints = applyTopScore(newPoints, topScore);
80 |  | }
81 |  | }
82 |  |
83 | 194 | makeViolations(ctx, newPoints);
84 |  |
85 | 194 | double low = 0.0d;
86 | 194 | double high = 0.0d;
87 | 194 | if (!dataPoints.isEmpty()) {
88 | 194 | low = ((DataPoint) dataPoints.first()).getScore();
89 | 194 | high = ((DataPoint) dataPoints.last()).getScore();
90 |  | }
91 |  |
92 | 194 | ctx.getReport().addMetric(new Metric(this.getName(), count, total, low, high, getMean(), getStdDev()));
93 |  |
94 | 194 | dataPoints.clear();
95 |  | }
96 |  |
97 | 568 | protected double getMean() {
98 | 568 | return total / count;
99 |  | }
100 |  |
101 | 302 | protected double getStdDev() {
102 | 302 | if (dataPoints.size() < 2) {
103 | 36 | return Double.NaN;
104 |  | }
105 |  |
106 | 266 | Iterator points = dataPoints.iterator();
107 | 266 | double mean = getMean();
108 | 266 | double deltaSq = 0.0;
109 | 266 | double scoreMinusMean;
110 |  |
111 | 266 | while (points.hasNext()) {
112 | 26502 | scoreMinusMean = ((DataPoint) points.next()).getScore() - mean;
113 | 26502 | deltaSq += (scoreMinusMean * scoreMinusMean);
114 |  | }
115 |  |
116 | 266 | return Math.sqrt(deltaSq / (dataPoints.size() - 1));
117 |  | }
118 |  |
119 | 194 | protected SortedSet applyMinimumValue(SortedSet pointSet, double minValue) {
120 | 194 | Iterator points = pointSet.iterator();
121 | 194 | SortedSet RC = new TreeSet();
122 | 194 | double threshold = minValue - DELTA;
123 |  |
124 | 194 | while (points.hasNext()) {
125 | 15738 | DataPoint point = (DataPoint) points.next();
126 |  |
127 | 15738 | if (point.getScore() > threshold) {
128 | 4196 | RC.add(point);
129 |  | }
130 |  | }
131 | 194 | return RC;
132 |  | }
133 |  |
134 | 48 | protected SortedSet applyTopScore(SortedSet points, int topScore) {
135 | 48 | SortedSet s = new TreeSet();
136 | 48 | Object[] arr = points.toArray();
137 | 48 | for (int i = arr.length - 1; i >= (arr.length - topScore); i--) {
138 | 606 | s.add(arr[i]);
139 |  | }
140 | 48 | return s;
141 |  | }
142 |  |
143 | 180 | protected void makeViolations(RuleContext ctx, Set p) {
144 | 180 | Iterator points = p.iterator();
145 | 180 | while (points.hasNext()) {
146 | 2233 | DataPoint point = (DataPoint) points.next();
147 | 2233 | addViolationWithMessage(ctx, point.getNode(), point.getMessage());
148 |  | }
149 |  | }
150 |  |
151 | 0 | protected Map propertiesByName() {
152 | 0 | return propertyDescriptorsByName;
153 |  | }
154 |  | }