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:
David Dixon-Peugh
2002-08-09 01:13:10 +00:00
parent bb683abfc6
commit 683e18f67e
7 changed files with 219 additions and 8 deletions

View File

@ -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();
}

View File

@ -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() {

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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;
}
}

View 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;
}
}

View 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
}
}