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.codesize;
    5
    6   import java.util.HashMap;
    7   import java.util.List;
    8   import java.util.Map;
    9
    10  import net.sourceforge.pmd.lang.ast.Node;
    11  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
    12  import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
    13  import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
    14  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
    15  import net.sourceforge.pmd.lang.rule.properties.IntegerProperty;
    16  import net.sourceforge.pmd.util.NumericConstants;
    17
    18
    19  public class TooManyFieldsRule extends AbstractJavaRule {
    20
    21      private static final int DEFAULT_MAXFIELDS = 15;
    22
    23      private Map<String, Integer> stats;
    24      private Map<String, ASTClassOrInterfaceDeclaration> nodes;
    25
    26      private static final IntegerProperty MAX_FIELDS_DESCRIPTOR = new IntegerProperty(
    27      		"maxfields", "Max allowable fields",
    28      		1, 300, DEFAULT_MAXFIELDS, 1.0f
    29      		);
    30
    31      public TooManyFieldsRule() {
    32  	definePropertyDescriptor(MAX_FIELDS_DESCRIPTOR);
    33      }
    34
    35      @Override
    36      public Object visit(ASTCompilationUnit node, Object data) {
    37
    38          int maxFields = getProperty(MAX_FIELDS_DESCRIPTOR);
    39
    40          stats = new HashMap<String, Integer>(5);
    41          nodes = new HashMap<String, ASTClassOrInterfaceDeclaration>(5);
    42
    43          List<ASTFieldDeclaration> l = node.findDescendantsOfType(ASTFieldDeclaration.class);
    44
    45          for (ASTFieldDeclaration fd: l) {
    46              if (fd.isFinal() && fd.isStatic()) {
    47                  continue;
    48              }
    49              ASTClassOrInterfaceDeclaration clazz = fd.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
    50              if (clazz != null && !clazz.isInterface()) {
    51                  bumpCounterFor(clazz);
    52              }
    53          }
    54          for (String k : stats.keySet()) {
    55              int val = stats.get(k);
    56              Node n = nodes.get(k);
    57              if (val > maxFields) {
    58                  addViolation(data, n);
    59              }
    60          }
    61          return data;
    62      }
    63
    64      private void bumpCounterFor(ASTClassOrInterfaceDeclaration clazz) {
    65          String key = clazz.getImage();
    66          if (!stats.containsKey(key)) {
    67              stats.put(key, NumericConstants.ZERO);
    68              nodes.put(key, clazz);
    69          }
    70          Integer i = Integer.valueOf(stats.get(key) + 1);
    71          stats.put(key, i);
    72      }
    73  }