1 4 package net.sourceforge.pmd.rules.design; 5 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 11 import net.sourceforge.pmd.AbstractRule; 12 import net.sourceforge.pmd.PropertyDescriptor; 13 import net.sourceforge.pmd.ast.ASTAssignmentOperator; 14 import net.sourceforge.pmd.ast.ASTCompilationUnit; 15 import net.sourceforge.pmd.ast.ASTFieldDeclaration; 16 import net.sourceforge.pmd.ast.ASTIfStatement; 17 import net.sourceforge.pmd.ast.ASTMethodDeclaration; 18 import net.sourceforge.pmd.ast.ASTName; 19 import net.sourceforge.pmd.ast.ASTNullLiteral; 20 import net.sourceforge.pmd.ast.ASTPrimaryExpression; 21 import net.sourceforge.pmd.ast.ASTPrimaryPrefix; 22 import net.sourceforge.pmd.ast.ASTPrimarySuffix; 23 import net.sourceforge.pmd.ast.ASTStatementExpression; 24 import net.sourceforge.pmd.ast.ASTSynchronizedStatement; 25 import net.sourceforge.pmd.properties.BooleanProperty; 26 27 public class NonThreadSafeSingleton extends AbstractRule { 28 29 private Map fieldDecls = new HashMap (); 30 31 private boolean checkNonStaticMethods = true; 32 private boolean checkNonStaticFields = true; 33 34 private static final PropertyDescriptor checkNonStaticMethodsDescriptor = new BooleanProperty( 35 "checkNonStaticMethods", "Check for non-static methods.", true, 1.0f 36 ); 37 private static final PropertyDescriptor checkNonStaticFieldsDescriptor = new BooleanProperty( 38 "checkNonStaticFields", "Check for non-static fields.", true, 2.0f 39 ); 40 41 private static final Map propertyDescriptorsByName = asFixedMap(new PropertyDescriptor[] { 42 checkNonStaticMethodsDescriptor, checkNonStaticFieldsDescriptor 43 }); 44 45 50 public Object visit(ASTCompilationUnit node, Object data) { 51 fieldDecls.clear(); 52 checkNonStaticMethods = getBooleanProperty(checkNonStaticMethodsDescriptor); 53 checkNonStaticFields = getBooleanProperty(checkNonStaticFieldsDescriptor); 54 return super.visit(node, data); 55 } 56 57 public Object visit(ASTFieldDeclaration node, Object data) { 58 if (checkNonStaticFields || node.isStatic()) { 59 fieldDecls.put(node.getVariableName(), node); 60 } 61 return super.visit(node, data); 62 } 63 64 public Object visit(ASTMethodDeclaration node, Object data) { 65 66 if ((checkNonStaticMethods && !node.isStatic()) || node.isSynchronized()) { 67 return super.visit(node, data); 68 } 69 70 List ifStatements = node.findChildrenOfType(ASTIfStatement.class); 71 for (Iterator iter = ifStatements.iterator(); iter.hasNext();) { 72 ASTIfStatement ifStatement = (ASTIfStatement) iter.next(); 73 if (ifStatement.getFirstParentOfType(ASTSynchronizedStatement.class) == null) { 74 ASTNullLiteral NullLiteral = (ASTNullLiteral) ifStatement.getFirstChildOfType(ASTNullLiteral.class); 75 76 if (NullLiteral == null) { 77 continue; 78 } 79 ASTName Name = (ASTName) ifStatement.getFirstChildOfType(ASTName.class); 80 if (Name == null || !fieldDecls.containsKey(Name.getImage())) { 81 continue; 82 } 83 List assigmnents = ifStatement.findChildrenOfType(ASTAssignmentOperator.class); 84 boolean violation = false; 85 for (int ix = 0; ix < assigmnents.size(); ix++) { 86 ASTAssignmentOperator oper = (ASTAssignmentOperator) assigmnents.get(ix); 87 if (!oper.jjtGetParent().getClass().equals(ASTStatementExpression.class)) { 88 continue; 89 } 90 ASTStatementExpression expr = (ASTStatementExpression) oper.jjtGetParent(); 91 if (expr.jjtGetChild(0).getClass().equals(ASTPrimaryExpression.class) && ((ASTPrimaryExpression) expr.jjtGetChild(0)).jjtGetChild(0).getClass().equals(ASTPrimaryPrefix.class)) { 92 ASTPrimaryPrefix pp = (ASTPrimaryPrefix) ((ASTPrimaryExpression) expr.jjtGetChild(0)).jjtGetChild(0); 93 String name = null; 94 if (pp.usesThisModifier()) { 95 ASTPrimarySuffix priSuf = (ASTPrimarySuffix)expr.getFirstChildOfType(ASTPrimarySuffix.class); 96 name = priSuf.getImage(); 97 } else { 98 ASTName astName = (ASTName) pp.jjtGetChild(0); 99 name = astName.getImage(); 100 } 101 if (fieldDecls.containsKey(name)) { 102 violation = true; 103 } 104 } 105 } 106 if (violation) { 107 addViolation(data, ifStatement); 108 } 109 } 110 } 111 return super.visit(node, data); 112 } 113 114 117 protected Map propertiesByName() { 118 return propertyDescriptorsByName; 119 } 120 } 121 | Popular Tags |