forked from phoedos/pmd
Adding Statistical Rule (in package net.sourceforge.pmd.stat)
Requires "getDoubleParameter" and "hasParameter" git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@665 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -29,6 +29,10 @@ public class MockRule implements Rule {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean hasProperty( String name ) {
|
||||
return properties.containsKey( name );
|
||||
}
|
||||
|
||||
public void addProperty(String name, String value) {
|
||||
properties.put(name, value);
|
||||
}
|
||||
@ -37,6 +41,10 @@ public class MockRule implements Rule {
|
||||
return Integer.parseInt(properties.getProperty(name));
|
||||
}
|
||||
|
||||
public double getDoubleProperty(String name) {
|
||||
return Double.parseDouble(properties.getProperty(name));
|
||||
}
|
||||
|
||||
public boolean getBooleanProperty(String name) {
|
||||
return Boolean.valueOf(properties.getProperty(name)).booleanValue();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class RuleSetFactoryTest extends TestCase {
|
||||
private static final String SINGLE_RULE_WITH_PROPS = "<?xml version=\"1.0\"?>" +
|
||||
"<ruleset name=\"test\">\r\n<description>testdesc</description>" +
|
||||
"<rule name=\"MockRuleName\" message=\"avoid the mock rule\" class=\"test.net.sourceforge.pmd.MockRule\">" +
|
||||
"<description>testdesc2</description><properties><property name=\"fooBoolean\" value=\"true\"/><property name=\"foo\" value=\"bar\"/><property name=\"fooint\" value=\"2\"/></properties>" +
|
||||
"<description>testdesc2</description><properties><property name=\"fooBoolean\" value=\"true\"/><property name=\"fooDouble\" value=\"1.0\" /><property name=\"foo\" value=\"bar\"/><property name=\"fooint\" value=\"2\"/></properties>" +
|
||||
"</rule></ruleset>";
|
||||
|
||||
private static final String SINGLE_RULE_NO_PROPS = "<?xml version=\"1.0\"?>" +
|
||||
@ -51,10 +51,20 @@ public class RuleSetFactoryTest extends TestCase {
|
||||
RuleSetFactory rsf = new RuleSetFactory();
|
||||
RuleSet rs = rsf.createRuleSet(new ByteArrayInputStream(SINGLE_RULE_WITH_PROPS.getBytes()));
|
||||
Rule r = (Rule)rs.getRules().iterator().next();
|
||||
|
||||
assertTrue( r.hasProperty("foo"));
|
||||
assertEquals("bar", r.getStringProperty("foo"));
|
||||
assertEquals(2, r.getIntProperty("fooint"));
|
||||
|
||||
assertTrue( r.hasProperty("fooBoolean"));
|
||||
assertTrue(r.getBooleanProperty("fooBoolean"));
|
||||
assertEquals("testdesc2", r.getDescription());
|
||||
|
||||
assertTrue( r.hasProperty("fooDouble"));
|
||||
assertEquals( 1.0, r.getDoubleProperty("fooDouble"),
|
||||
0.05 );
|
||||
|
||||
assertTrue( !r.hasProperty("BuggleFish"));
|
||||
}
|
||||
|
||||
public void testCreateSingleRuleNoPropsSet() {
|
||||
|
@ -31,11 +31,18 @@ public abstract class AbstractRule
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public boolean hasProperty( String name ) {
|
||||
return properties.containsKey( name );
|
||||
}
|
||||
|
||||
public void addProperty(String name, String value) {
|
||||
properties.put(name, value);
|
||||
}
|
||||
|
||||
public double getDoubleProperty(String name) {
|
||||
return Double.parseDouble(properties.getProperty(name));
|
||||
}
|
||||
|
||||
public int getIntProperty(String name) {
|
||||
return Integer.parseInt(properties.getProperty(name));
|
||||
}
|
||||
|
@ -10,8 +10,10 @@ public interface Rule {
|
||||
public void setMessage(String message);
|
||||
public void setDescription(String description);
|
||||
public void apply(List astCompilationUnits, RuleContext ctx);
|
||||
public boolean hasProperty(String name);
|
||||
public void addProperty(String name, String value);
|
||||
public int getIntProperty(String name);
|
||||
public boolean getBooleanProperty(String name);
|
||||
public String getStringProperty(String name);
|
||||
public double getDoubleProperty(String name);
|
||||
}
|
||||
|
@ -16,13 +16,13 @@ public class LongClassRule
|
||||
public LongClassRule() { }
|
||||
|
||||
public Object visit( ASTClassDeclaration decl, Object data ) {
|
||||
RuleContext ctx = (RuleContext) data;
|
||||
RuleContext ctx = (RuleContext) data;
|
||||
|
||||
if ((decl.getEndLine() - decl.getBeginLine()) > getIntProperty("minimumLength")) {
|
||||
ctx.getReport().addRuleViolation( createRuleViolation( ctx,
|
||||
decl.getBeginLine(),
|
||||
getMessage() ));
|
||||
}
|
||||
return null;
|
||||
if ((decl.getEndLine() - decl.getBeginLine()) > getIntProperty("minimumLength")) {
|
||||
ctx.getReport().addRuleViolation( createRuleViolation( ctx,
|
||||
decl.getBeginLine(),
|
||||
getMessage() ));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
100
pmd/src/net/sourceforge/pmd/stat/DataPoint.java
Normal file
100
pmd/src/net/sourceforge/pmd/stat/DataPoint.java
Normal file
@ -0,0 +1,100 @@
|
||||
package net.sourceforge.pmd.stat;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
|
||||
/**
|
||||
* @author David Dixon-Peugh
|
||||
* Aug 8, 2002 DataPoint.java
|
||||
*/
|
||||
public class DataPoint
|
||||
implements java.lang.Comparable
|
||||
{
|
||||
private int lineNumber;
|
||||
private double score;
|
||||
private String message;
|
||||
private Rule rule;
|
||||
/**
|
||||
* Constructor for DataPoint.
|
||||
*/
|
||||
public DataPoint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public int compareTo( Object object) {
|
||||
Double lhs = new Double( score );
|
||||
Double rhs = new Double( ((DataPoint) object).getScore());
|
||||
return lhs.compareTo(rhs);
|
||||
}
|
||||
/**
|
||||
* Returns the lineNumber.
|
||||
* @return int
|
||||
*/
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lineNumber.
|
||||
* @param lineNumber The lineNumber to set
|
||||
*/
|
||||
public void setLineNumber(int lineNumber) {
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message.
|
||||
* @return String
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rule.
|
||||
* @return Rule
|
||||
*/
|
||||
public Rule getRule() {
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message.
|
||||
* @param message The message to set
|
||||
*/
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rule.
|
||||
* @param rule The rule to set
|
||||
*/
|
||||
public void setRule(Rule rule) {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the score.
|
||||
* @return double
|
||||
*/
|
||||
public double getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the score.
|
||||
* @param score The score to set
|
||||
*/
|
||||
public void setScore(double score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the score.
|
||||
* @param score The score to set
|
||||
*/
|
||||
public void setScore(int score) {
|
||||
this.score = (double) score;
|
||||
}
|
||||
|
||||
}
|
84
pmd/src/net/sourceforge/pmd/stat/StatisticalRule.java
Normal file
84
pmd/src/net/sourceforge/pmd/stat/StatisticalRule.java
Normal file
@ -0,0 +1,84 @@
|
||||
package net.sourceforge.pmd.stat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.sourceforge.pmd.AbstractRule;
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.RuleViolation;
|
||||
|
||||
/**
|
||||
* @author David Dixon-Peugh
|
||||
* Aug 8, 2002 StatisticalRule.java
|
||||
*/
|
||||
public abstract class StatisticalRule extends AbstractRule {
|
||||
private SortedSet dataPoints =
|
||||
new TreeSet();
|
||||
|
||||
public void addDataPoint( DataPoint point )
|
||||
{
|
||||
}
|
||||
|
||||
public void apply( List acus, RuleContext ctx ) {
|
||||
visitAll( acus, ctx );
|
||||
|
||||
if (hasProperty("minimum")) {
|
||||
applyMinimumValue( ctx, getDoubleProperty("minimumValue") );
|
||||
}
|
||||
|
||||
if (hasProperty("sigma")) {
|
||||
applySigma( ctx, getDoubleProperty("sigma"));
|
||||
}
|
||||
|
||||
if (hasProperty("topscore")) {
|
||||
applyTopScore(ctx, getIntProperty("topscore"));
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyMinimumValue( RuleContext ctx,
|
||||
double minValue )
|
||||
{
|
||||
Iterator points = dataPoints.iterator();
|
||||
|
||||
while (points.hasNext()) {
|
||||
DataPoint point = (DataPoint) points.next();
|
||||
|
||||
if (point.getScore() > minValue) {
|
||||
ctx.getReport().addRuleViolation(
|
||||
this.createRuleViolation(
|
||||
ctx,
|
||||
point.getLineNumber(),
|
||||
point.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void applySigma( RuleContext ctx,
|
||||
double sigma )
|
||||
{
|
||||
Iterator points = dataPoints.iterator();
|
||||
|
||||
int count = 0;
|
||||
double total = 0.0;
|
||||
double mean = 0.0;
|
||||
|
||||
while (points.hasNext()) {
|
||||
count++;
|
||||
DataPoint point = (DataPoint) points.next();
|
||||
total += point.getScore();
|
||||
}
|
||||
|
||||
mean = total / count;
|
||||
// TODO: Calculate StdDev
|
||||
// TODO: Identify things outside range.
|
||||
}
|
||||
|
||||
protected void applyTopScore( RuleContext ctx,
|
||||
int topScore )
|
||||
{
|
||||
// TODO: Identify the top scorers
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user