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.naming;
5   
6   import java.util.List;
7   
8   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
9   import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
10  import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
11  import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
12  import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
13  import net.sourceforge.pmd.lang.java.ast.ASTName;
14  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15  import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
16  
17  public class MethodNamingConventionsRule extends AbstractJavaRule {
18  
19      private boolean checkNativeMethods;
20  
21      private static final BooleanProperty CHECK_NATIVE_METHODS_DESCRIPTOR = new BooleanProperty("checkNativeMethods",
22              "Check native methods", true, 1.0f);
23  
24      public MethodNamingConventionsRule() {
25          definePropertyDescriptor(CHECK_NATIVE_METHODS_DESCRIPTOR);
26      }
27  
28      public Object visit(ASTCompilationUnit node, Object data) {
29          checkNativeMethods = getProperty(CHECK_NATIVE_METHODS_DESCRIPTOR);
30          return super.visit(node, data);
31      }
32  
33      public Object visit(ASTMethodDeclarator node, Object data) {
34          if (!checkNativeMethods && node.getFirstParentOfType(ASTMethodDeclaration.class).isNative()) {
35              return data;
36          }
37  
38          if (isOverriddenMethod(node)) {
39              return data;
40          }
41  
42          String methodName = node.getImage();
43  
44          if (Character.isUpperCase(methodName.charAt(0))) {
45              addViolationWithMessage(data, node, "Method names should not start with capital letters");
46          }
47          if (methodName.indexOf('_') >= 0) {
48              addViolationWithMessage(data, node, "Method names should not contain underscores");
49          }
50          return data;
51      }
52  
53      private boolean isOverriddenMethod(ASTMethodDeclarator node) {
54          ASTClassOrInterfaceBodyDeclaration declaration = node.getFirstParentOfType(ASTClassOrInterfaceBodyDeclaration.class);
55          List<ASTMarkerAnnotation> annotations = declaration.findDescendantsOfType(ASTMarkerAnnotation.class);
56          for (ASTMarkerAnnotation ann : annotations) {
57              ASTName name = ann.getFirstChildOfType(ASTName.class);
58              if (name != null && name.hasImageEqualTo("Override")) {
59                  return true;
60              }
61          }
62          return false;
63      }
64  }