1 /** 2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html 3 */ 4 package net.sourceforge.pmd.rules.design; 5 6 import net.sourceforge.pmd.ast.ASTStatement; 7 import net.sourceforge.pmd.ast.ASTSwitchLabel; 8 import net.sourceforge.pmd.ast.ASTSwitchStatement; 9 import net.sourceforge.pmd.stat.DataPoint; 10 import net.sourceforge.pmd.stat.StatisticalRule; 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 StatisticalRule { 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 Object visit(ASTSwitchStatement node, Object data) { 55 SwitchDensity oldData = null; 56 57 if (data instanceof SwitchDensity) { 58 oldData = (SwitchDensity) data; 59 } 60 61 SwitchDensity density = new SwitchDensity(); 62 63 node.childrenAccept(this, density); 64 65 DataPoint point = new DataPoint(); 66 point.setNode(node); 67 point.setScore(density.getDensity()); 68 point.setMessage(getMessage()); 69 70 addDataPoint(point); 71 72 if (data instanceof SwitchDensity) { 73 ((SwitchDensity) data).addStatements(density.getStatementCount()); 74 } 75 return oldData; 76 } 77 78 public Object visit(ASTStatement statement, Object data) { 79 if (data instanceof SwitchDensity) { 80 ((SwitchDensity) data).addStatement(); 81 } 82 83 statement.childrenAccept(this, data); 84 85 return data; 86 } 87 88 public Object visit(ASTSwitchLabel switchLabel, Object data) { 89 if (data instanceof SwitchDensity) { 90 ((SwitchDensity) data).addSwitchLabel(); 91 } 92 93 switchLabel.childrenAccept(this, data); 94 return data; 95 } 96 }