1 4 package net.sourceforge.pmd.rules; 5 6 import java.util.Map ; 7 8 import net.sourceforge.pmd.AbstractRule; 9 import net.sourceforge.pmd.PropertyDescriptor; 10 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; 11 import net.sourceforge.pmd.ast.ASTCompilationUnit; 12 import net.sourceforge.pmd.ast.ASTFieldDeclaration; 13 import net.sourceforge.pmd.ast.ASTName; 14 import net.sourceforge.pmd.ast.ASTPrimitiveType; 15 import net.sourceforge.pmd.ast.ASTType; 16 import net.sourceforge.pmd.ast.ASTVariableDeclarator; 17 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId; 18 import net.sourceforge.pmd.ast.AccessNode; 19 import net.sourceforge.pmd.properties.StringProperty; 20 21 public class VariableNamingConventions extends AbstractRule { 22 23 private String [] staticPrefixes; 24 private String [] staticSuffixes; 25 private String [] memberPrefixes; 26 private String [] memberSuffixes; 27 28 private static final PropertyDescriptor staticPrefixesDescriptor = new StringProperty( 29 "staticPrefix", "Static prefixes", new String [] {""}, 1.0f , ',' 30 ); 31 32 private static final PropertyDescriptor staticSuffixesDescriptor = new StringProperty( 33 "staticSuffix", "Static suffixes", new String [] {""}, 2.0f , ',' 34 ); 35 36 private static final PropertyDescriptor memberPrefixesDescriptor = new StringProperty( 37 "memberPrefix", "Member prefixes", new String [] {""}, 3.0f , ',' 38 ); 39 40 private static final PropertyDescriptor memberSuffixesDescriptor = new StringProperty( 41 "memberSuffix", "Member suffixes", new String [] {""}, 4.0f , ',' 42 ); 43 44 private static final Map propertyDescriptorsByName = asFixedMap( new PropertyDescriptor[] { 45 staticPrefixesDescriptor, staticSuffixesDescriptor, 46 memberPrefixesDescriptor, memberSuffixesDescriptor 47 }); 48 49 52 protected Map propertiesByName() { 53 return propertyDescriptorsByName; 54 } 55 56 public Object visit(ASTCompilationUnit node, Object data) { 57 init(); 58 return super.visit(node, data); 59 } 60 61 protected void init() { 62 staticPrefixes = getStringProperties(staticPrefixesDescriptor); 63 staticSuffixes = getStringProperties(staticSuffixesDescriptor); 64 memberPrefixes = getStringProperties(memberPrefixesDescriptor); 65 memberSuffixes = getStringProperties(memberSuffixesDescriptor); 66 } 67 68 public Object visit(ASTFieldDeclaration node, Object data) { 69 return checkNames(node, data); 70 } 71 72 private Object checkNames(ASTFieldDeclaration node, Object data) { 73 ASTType childNodeType = (ASTType) node.jjtGetChild(0); 74 String varType = ""; 75 if (childNodeType.jjtGetChild(0) instanceof ASTName) { 76 varType = ((ASTName) childNodeType.jjtGetChild(0)).getImage(); 77 } else if (childNodeType.jjtGetChild(0) instanceof ASTPrimitiveType) { 78 varType = ((ASTPrimitiveType) childNodeType.jjtGetChild(0)).getImage(); 79 } 80 if (varType != null && varType.length() > 0) { 81 ASTVariableDeclarator childNodeName = (ASTVariableDeclarator) node.jjtGetChild(1); 83 ASTVariableDeclaratorId childNodeId = (ASTVariableDeclaratorId) childNodeName.jjtGetChild(0); 84 String varName = childNodeId.getImage(); 85 86 if (varName.equals("serialVersionUID") || (node.isFinal() && !node.isStatic() && !node.isInterfaceMember())) { 87 return data; 88 } 89 90 if ((node.isStatic() && node.isFinal()) || (node.jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node.jjtGetParent().jjtGetParent().jjtGetParent()).isInterface())) { 93 if (!varName.equals(varName.toUpperCase())) { 94 addViolationWithMessage(data, childNodeName, "Variables that are final and static should be in all caps."); 95 } 96 return data; 97 } 98 99 String strippedVarName = null; 100 if (node.isStatic()) { 101 strippedVarName = normalizeStaticVariableName(varName); 102 } else { 103 strippedVarName = normalizeMemberVariableName(varName); 104 } 105 106 if (strippedVarName.indexOf('_') >= 0) { 107 addViolationWithMessage(data, childNodeName, "Variables that are not final should not contain underscores (except for underscores in standard prefix/suffix)."); 108 } 109 if (Character.isUpperCase(varName.charAt(0))) { 110 addViolationWithMessage(data, childNodeName, "Variables should start with a lowercase character"); 111 } 112 } 113 return data; 114 } 115 116 private String normalizeMemberVariableName(String varName) { 117 return stripSuffix(stripPrefix(varName, memberPrefixes), memberSuffixes); 118 } 119 120 private String normalizeStaticVariableName(String varName) { 121 return stripSuffix(stripPrefix(varName, staticPrefixes), staticSuffixes); 122 } 123 124 private String stripSuffix(String varName, String [] suffix) { 125 if (suffix != null) { 126 for (int i = 0; i < suffix.length; i++) { 127 if (varName.endsWith(suffix[i])) { 128 varName = varName.substring(0, varName.length() - suffix[i].length()); 129 break; 130 } 131 } 132 } 133 return varName; 134 } 135 136 private String stripPrefix(String varName, String [] prefix) { 137 if (prefix == null) { 138 return varName; 139 } 140 for (int i = 0; i < prefix.length; i++) { 141 if (varName.startsWith(prefix[i])) { 142 return varName.substring(prefix[i].length()); 143 } 144 } 145 return varName; 146 } 147 } 148 | Popular Tags |