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.typeresolution.rules;
    5
    6   import net.sourceforge.pmd.lang.ast.Node;
    7   import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
    8   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
    9   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
    10  import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
    11  import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
    12  import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
    13  import net.sourceforge.pmd.lang.java.ast.ASTName;
    14  import net.sourceforge.pmd.lang.java.ast.ASTResultType;
    15  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
    16  import net.sourceforge.pmd.util.CollectionUtil;
    17
    18  /**
    19   * This is a separate rule, uses the type resolution facade
    20   */
    21  public class LooseCoupling extends AbstractJavaRule {
    22
    23      @Override
    24      public Object visit(ASTClassOrInterfaceType node, Object data) {
    25      if (methodHasOverride(node)) {
    26          return data;
    27      }
    28  	Node parent = node.getNthParent(3);
    29  	Class<?> clazzType = node.getType();
    30  	boolean isType = CollectionUtil.isCollectionType(clazzType, false);
    31  	if (isType
    32  		&& (parent instanceof ASTFieldDeclaration || parent instanceof ASTFormalParameter || parent instanceof ASTResultType)) {
    33  	    addViolation(data, node, node.getImage());
    34  	}
    35  	return data;
    36      }
    37
    38      private boolean methodHasOverride(Node node) {
    39          ASTClassOrInterfaceBodyDeclaration method = node.getFirstParentOfType(ASTClassOrInterfaceBodyDeclaration.class);
    40          if (method != null && method.jjtGetNumChildren() > 0 && method.jjtGetChild(0) instanceof ASTAnnotation) {
    41              ASTMarkerAnnotation marker = method.getFirstDescendantOfType(ASTMarkerAnnotation.class);
    42              if (marker != null && marker.getFirstChildOfType(ASTName.class) != null) {
    43                  ASTName name = marker.getFirstChildOfType(ASTName.class);
    44                  if (name.getType() == Override.class) {
    45                      return true;
    46                  }
    47              }
    48          }
    49          return false;
    50      }
    51  }