View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.design;
5   
6   import net.sourceforge.pmd.lang.java.ast.ASTStatement;
7   import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel;
8   import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
9   import net.sourceforge.pmd.lang.java.rule.AbstractStatisticalJavaRule;
10  import net.sourceforge.pmd.stat.DataPoint;
11  
12  /**
13   * @author David Dixon-Peugh
14   *
15   *         <p/>
16   *         Switch Density - This is the number of statements over the
17   *         number of cases within a switch.  The higher the value, the
18   *         more work each case is doing.
19   *         <p/>
20   *         Its my theory, that when the Switch Density is high, you should
21   *         start looking at Subclasses or State Pattern to alleviate the
22   *         problem.
23   */
24  public class SwitchDensityRule extends AbstractStatisticalJavaRule {
25  
26      private static class SwitchDensity {
27          private int labels = 0;
28          private int stmts = 0;
29  
30          public void addSwitchLabel() {
31              labels++;
32          }
33  
34          public void addStatement() {
35              stmts++;
36          }
37  
38          public void addStatements(int stmtCount) {
39              stmts += stmtCount;
40          }
41  
42          public int getStatementCount() {
43              return stmts;
44          }
45  
46          public double getDensity() {
47              if (labels == 0) {
48                  return 0;
49              }
50              return (double) stmts / (double) labels;
51          }
52      }
53      
54      public SwitchDensityRule() {
55  	super();
56  	setProperty(MINIMUM_DESCRIPTOR, 10d);
57      }
58  
59      public Object visit(ASTSwitchStatement node, Object data) {
60          SwitchDensity oldData = null;
61  
62          if (data instanceof SwitchDensity) {
63              oldData = (SwitchDensity) data;
64          }
65  
66          SwitchDensity density = new SwitchDensity();
67  
68          node.childrenAccept(this, density);
69  
70          DataPoint point = new DataPoint();
71          point.setNode(node);
72          point.setScore(density.getDensity());
73          point.setMessage(getMessage());
74  
75          addDataPoint(point);
76  
77          if (data instanceof SwitchDensity) {
78              ((SwitchDensity) data).addStatements(density.getStatementCount());
79          }
80          return oldData;
81      }
82  
83      public Object visit(ASTStatement statement, Object data) {
84          if (data instanceof SwitchDensity) {
85              ((SwitchDensity) data).addStatement();
86          }
87  
88          statement.childrenAccept(this, data);
89  
90          return data;
91      }
92  
93      public Object visit(ASTSwitchLabel switchLabel, Object data) {
94          if (data instanceof SwitchDensity) {
95              ((SwitchDensity) data).addSwitchLabel();
96          }
97  
98          switchLabel.childrenAccept(this, data);
99          return data;
100     }
101 }