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.basic;
    5
    6   import java.util.HashMap;
    7   import java.util.HashSet;
    8   import java.util.Map;
    9   import java.util.Set;
    10
    11  import net.sourceforge.pmd.lang.ast.Node;
    12  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
    13  import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
    14  import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
    15  import net.sourceforge.pmd.lang.java.ast.ASTName;
    16  import net.sourceforge.pmd.lang.java.ast.ASTType;
    17  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
    18  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
    19  import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement;
    20  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
    21
    22  /**
    23   * Rule that verifies, that the return values of next(), first(), last(), etc.
    24   * calls to a java.sql.ResultSet are actually verified.
    25   *
    26   */
    27  public class CheckResultSetRule extends AbstractJavaRule {
    28
    29      private Map<String, Node> resultSetVariables = new HashMap<String, Node>();
    30
    31      private static Set<String> methods = new HashSet<String>();
    32      static {
    33          methods.add(".next");
    34          methods.add(".previous");
    35          methods.add(".last");
    36          methods.add(".first");
    37      }
    38
    39      @Override
    40      public Object visit(ASTLocalVariableDeclaration node, Object data) {
    41          ASTClassOrInterfaceType type = node.getFirstChildOfType(ASTType.class).getFirstDescendantOfType(ASTClassOrInterfaceType.class);
    42          if (type != null
    43                  && ((type.getType() != null && "java.sql.ResultSet".equals(type.getType().getName())) || "ResultSet"
    44                          .equals(type.getImage()))) {
    45              ASTVariableDeclarator declarator = node.getFirstChildOfType(ASTVariableDeclarator.class);
    46              if (declarator != null) {
    47                  ASTName name = declarator.getFirstDescendantOfType(ASTName.class);
    48                  if (name != null && name.getImage().endsWith("executeQuery")) {
    49
    50                      ASTVariableDeclaratorId id = declarator.getFirstChildOfType(ASTVariableDeclaratorId.class);
    51                      resultSetVariables.put(id.getImage(), node);
    52                  }
    53              }
    54          }
    55          return super.visit(node, data);
    56      }
    57
    58      @Override
    59      public Object visit(ASTName node, Object data) {
    60          String image = node.getImage();
    61          String var = getResultSetVariableName(image);
    62          if (var != null && resultSetVariables.containsKey(var)
    63              && node.getFirstParentOfType(ASTIfStatement.class)== null
    64              && node.getFirstParentOfType(ASTWhileStatement.class) == null) {
    65
    66              addViolation(data, resultSetVariables.get(var));
    67          }
    68          return super.visit(node, data);
    69      }
    70
    71      private String getResultSetVariableName(String image) {
    72          if (image.contains(".")) {
    73              for (String method : methods) {
    74                  if (image.endsWith(method)) {
    75                      return image.substring(0, image.lastIndexOf(method));
    76                  }
    77              }
    78          }
    79          return null;
    80      }
    81  }