1 package net.sourceforge.pmd.stat;
2
3 import net.sourceforge.pmd.AbstractRule;
4 import net.sourceforge.pmd.RuleContext;
5
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Set;
9 import java.util.SortedSet;
10 import java.util.TreeSet;
11
12 /***
13 * @author David Dixon-Peugh
14 * Aug 8, 2002 StatisticalRule.java
15 */
16 public abstract class StatisticalRule extends AbstractRule {
17 public static double DELTA = 0.000005; // Within this range. . .
18
19 private SortedSet dataPoints = new TreeSet();
20
21 private int count = 0;
22 private double total = 0.0;
23 private double totalSquared = 0.0;
24
25 public void addDataPoint(DataPoint point) {
26 count++;
27 total += point.getScore();
28 totalSquared += point.getScore() * point.getScore();
29 dataPoints.add(point);
30 }
31
32 public void apply(List acus, RuleContext ctx) {
33 visitAll(acus, ctx);
34
35 double deviation;
36 double minimum = 0.0;
37
38 if (hasProperty("sigma")) {
39 deviation = getStdDev();
40 double sigma = getDoubleProperty("sigma");
41
42 minimum = getMean() + (sigma * deviation);
43 }
44
45 if (hasProperty("minimum")) {
46 double mMin = getDoubleProperty("minimum");
47 if (mMin > minimum) {
48 minimum = mMin;
49 }
50 }
51
52 SortedSet newPoints = applyMinimumValue(dataPoints, minimum);
53
54 if (hasProperty("topscore")) {
55 int topScore = getIntProperty("topscore");
56 if (newPoints.size() >= topScore) {
57 newPoints = applyTopScore(newPoints, topScore);
58 }
59 }
60
61 makeViolations(ctx, newPoints);
62
63 double low = 0.0d;
64 double high = 0.0d;
65 if (!dataPoints.isEmpty()) {
66 low = ((DataPoint) dataPoints.first()).getScore();
67 high = ((DataPoint) dataPoints.last()).getScore();
68 }
69
70 ctx.getReport().addMetric(new Metric(this.getName(), count, total, low, high, getMean(), getStdDev()));
71
72 dataPoints.clear();
73 }
74
75 protected double getMean() {
76 return total / count;
77 }
78
79 protected double getStdDev() {
80 Iterator points = dataPoints.iterator();
81 double mean = getMean();
82 double deltaSq = 0.0;
83
84 if (dataPoints.size() < 2) {
85 return Double.NaN;
86 }
87
88 while (points.hasNext()) {
89 DataPoint point = (DataPoint) points.next();
90 deltaSq += ((point.getScore() - mean) * (point.getScore() - mean));
91 }
92
93 return Math.sqrt( deltaSq / (dataPoints.size() - 1));
94 }
95
96 protected SortedSet applyMinimumValue(SortedSet pointSet, double minValue) {
97 Iterator points = pointSet.iterator();
98 SortedSet RC = new TreeSet();
99
100 while (points.hasNext()) {
101 DataPoint point = (DataPoint) points.next();
102
103 if (point.getScore() > (minValue - DELTA)) {
104 RC.add(point);
105 }
106 }
107 return RC;
108 }
109
110 protected SortedSet applyTopScore(SortedSet points, int topScore) {
111 SortedSet RC = new TreeSet();
112 for (int i = 0; i < topScore; i++) {
113 DataPoint point = (DataPoint) points.last();
114 points.remove(point);
115
116 RC.add(point);
117 }
118
119 return RC;
120 }
121
122 protected void makeViolations(RuleContext ctx, Set dataPoints) {
123 Iterator points = dataPoints.iterator();
124 while (points.hasNext()) {
125 DataPoint point = (DataPoint) points.next();
126 ctx.getReport().addRuleViolation(this.createRuleViolation(ctx, point.getLineNumber(), point.getMessage()));
127 }
128 }
129 }
This page was automatically generated by Maven