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 }