1 4 package net.sourceforge.pmd.rules; 5 6 import java.util.ArrayList ; 7 import java.util.Arrays ; 8 import java.util.Iterator ; 9 import java.util.List ; 10 import java.util.Map ; 11 12 import net.sourceforge.pmd.AbstractRule; 13 import net.sourceforge.pmd.PropertyDescriptor; 14 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; 15 import net.sourceforge.pmd.ast.ASTCompilationUnit; 16 import net.sourceforge.pmd.ast.ASTMethodDeclarator; 17 import net.sourceforge.pmd.ast.ASTPrimitiveType; 18 import net.sourceforge.pmd.ast.ASTResultType; 19 import net.sourceforge.pmd.ast.SimpleNode; 20 import net.sourceforge.pmd.properties.StringProperty; 21 import net.sourceforge.pmd.symboltable.MethodNameDeclaration; 22 import net.sourceforge.pmd.symboltable.VariableNameDeclaration; 23 24 public class BeanMembersShouldSerializeRule extends AbstractRule { 25 26 private String prefixProperty; 27 28 private static final PropertyDescriptor prefixDescriptor = new StringProperty( 29 "prefix", "Prefix somethingorother?", "", 1.0f 30 ); 31 32 private static final Map propertyDescriptorsByName = asFixedMap(prefixDescriptor); 33 34 35 public Object visit(ASTCompilationUnit node, Object data) { 36 prefixProperty = getStringProperty(prefixDescriptor); 37 super.visit(node, data); 38 return data; 39 } 40 41 private static String [] imagesOf(List simpleNodes) { 42 43 String [] imageArray = new String [simpleNodes.size()]; 44 45 for (int i = 0; i < simpleNodes.size(); i++) { 46 imageArray[i] = ((SimpleNode) simpleNodes.get(i)).getImage(); 47 } 48 return imageArray; 49 } 50 51 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { 52 if (node.isInterface()) { 53 return data; 54 } 55 56 Map methods = node.getScope().getEnclosingClassScope().getMethodDeclarations(); 57 List getSetMethList = new ArrayList (methods.size()); 58 for (Iterator i = methods.keySet().iterator(); i.hasNext();) { 59 ASTMethodDeclarator mnd = ((MethodNameDeclaration) i.next()).getMethodNameDeclaratorNode(); 60 if (isBeanAccessor(mnd)) { 61 getSetMethList.add(mnd); 62 } 63 } 64 65 String [] methNameArray = imagesOf(getSetMethList); 66 67 Arrays.sort(methNameArray); 68 69 Map vars = node.getScope().getVariableDeclarations(); 70 for (Iterator i = vars.keySet().iterator(); i.hasNext();) { 71 VariableNameDeclaration decl = (VariableNameDeclaration) i.next(); 72 if (((List ) vars.get(decl)).isEmpty() || decl.getAccessNodeParent().isTransient() || decl.getAccessNodeParent().isStatic()) { 73 continue; 74 } 75 String varName = trimIfPrefix(decl.getImage()); 76 varName = varName.substring(0, 1).toUpperCase() + varName.substring(1, varName.length()); 77 boolean hasGetMethod = Arrays.binarySearch(methNameArray, "get" + varName) >= 0 || Arrays.binarySearch(methNameArray, "is" + varName) >= 0; 78 boolean hasSetMethod = Arrays.binarySearch(methNameArray, "set" + varName) >= 0; 79 if (!hasGetMethod || !hasSetMethod) { 80 addViolation(data, decl.getNode(), decl.getImage()); 81 } 82 } 83 return super.visit(node, data); 84 } 85 86 private String trimIfPrefix(String img) { 87 if (prefixProperty != null && img.startsWith(prefixProperty)) { 88 return img.substring(prefixProperty.length()); 89 } 90 return img; 91 } 92 93 private boolean isBeanAccessor(ASTMethodDeclarator meth) { 94 95 String methodName = meth.getImage(); 96 97 if (methodName.startsWith("get") || methodName.startsWith("set")) { 98 return true; 99 } 100 if (methodName.startsWith("is")) { 101 ASTResultType ret = (ASTResultType) meth.jjtGetParent().jjtGetChild(0); 102 List primitives = ret.findChildrenOfType(ASTPrimitiveType.class); 103 if (!primitives.isEmpty() && ((ASTPrimitiveType) primitives.get(0)).isBoolean()) { 104 return true; 105 } 106 } 107 return false; 108 } 109 110 113 protected Map propertiesByName() { 114 return propertyDescriptorsByName; 115 } 116 } 117 | Popular Tags |