1 /*** 2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html 3 */ 4 package net.sourceforge.pmd.rules; 5 6 import net.sourceforge.pmd.AbstractRule; 7 import net.sourceforge.pmd.RuleContext; 8 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration; 9 import net.sourceforge.pmd.ast.ASTMethodDeclarator; 10 import net.sourceforge.pmd.ast.ASTPrimitiveType; 11 import net.sourceforge.pmd.ast.ASTResultType; 12 import net.sourceforge.pmd.symboltable.VariableNameDeclaration; 13 14 import java.text.MessageFormat; 15 import java.util.ArrayList; 16 import java.util.Arrays; 17 import java.util.Iterator; 18 import java.util.List; 19 import java.util.Map; 20 21 public class BeanMembersShouldSerializeRule extends AbstractRule { 22 23 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { 24 if (node.isInterface()) { 25 return data; 26 } 27 28 List methList = new ArrayList(); 29 node.findChildrenOfType(ASTMethodDeclarator.class, methList); 30 31 List getSetMethList = new ArrayList(); 32 for (Iterator i = methList.iterator(); i.hasNext();) { 33 ASTMethodDeclarator meth = (ASTMethodDeclarator) i.next(); 34 if (isBeanAccessor(meth)) { 35 getSetMethList.add(meth); 36 } 37 } 38 String[] methNameArray = new String[getSetMethList.size()]; 39 for (int i = 0; i < getSetMethList.size(); i++) { 40 String methName = ((ASTMethodDeclarator) getSetMethList.get(i)).getImage(); 41 methNameArray[i] = methName; 42 } 43 44 Arrays.sort(methNameArray); 45 46 Map vars = node.getScope().getVariableDeclarations(); 47 for (Iterator i = vars.keySet().iterator(); i.hasNext();) { 48 VariableNameDeclaration decl = (VariableNameDeclaration) i.next(); 49 if (((List) vars.get(decl)).isEmpty() || decl.getAccessNodeParent().isTransient() || decl.getAccessNodeParent().isStatic()) { 50 continue; 51 } 52 String varName = decl.getImage(); 53 varName = varName.substring(0, 1).toUpperCase() + varName.substring(1, varName.length()); 54 boolean hasGetMethod = Arrays.binarySearch(methNameArray, "get" + varName) >= 0 || Arrays.binarySearch(methNameArray, "is" + varName) >= 0; 55 boolean hasSetMethod = Arrays.binarySearch(methNameArray, "set" + varName) >= 0; 56 if (!hasGetMethod || !hasSetMethod) { 57 RuleContext ctx = (RuleContext) data; 58 ctx.getReport().addRuleViolation(createRuleViolation(ctx, decl, MessageFormat.format(getMessage(), new Object[]{decl.getImage()}))); 59 } 60 } 61 return super.visit(node, data); 62 } 63 64 private boolean isBeanAccessor(ASTMethodDeclarator meth) { 65 if (meth.getImage().startsWith("get") || meth.getImage().startsWith("set")) { 66 return true; 67 } 68 if (meth.getImage().startsWith("is")) { 69 ASTResultType ret = (ASTResultType) meth.jjtGetParent().jjtGetChild(0); 70 List primitives = ret.findChildrenOfType(ASTPrimitiveType.class); 71 if (!primitives.isEmpty() && ((ASTPrimitiveType) primitives.get(0)).isBoolean()) { 72 return true; 73 } 74 } 75 return false; 76 } 77 }