Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 120   Methods: 4
NCLOC: 95   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
NonThreadSafeSingleton.java 83.3% 87.5% 75% 85.3%
coverage coverage
 1    /**
 2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 3    */
 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    // public NonThreadSafeSingleton() {
 46    // checkNonStaticMethods = super.getBooleanProperty("checkNonStaticMethods");
 47    // checkNonStaticFields = super.getBooleanProperty("checkNonStaticFields");
 48    // }
 49   
 50  8 public Object visit(ASTCompilationUnit node, Object data) {
 51  8 fieldDecls.clear();
 52  8 checkNonStaticMethods = getBooleanProperty(checkNonStaticMethodsDescriptor);
 53  8 checkNonStaticFields = getBooleanProperty(checkNonStaticFieldsDescriptor);
 54  8 return super.visit(node, data);
 55    }
 56   
 57  10 public Object visit(ASTFieldDeclaration node, Object data) {
 58  10 if (checkNonStaticFields || node.isStatic()) {
 59  9 fieldDecls.put(node.getVariableName(), node);
 60    }
 61  10 return super.visit(node, data);
 62    }
 63   
 64  8 public Object visit(ASTMethodDeclaration node, Object data) {
 65   
 66  8 if ((checkNonStaticMethods && !node.isStatic()) || node.isSynchronized()) {
 67  2 return super.visit(node, data);
 68    }
 69   
 70  6 List ifStatements = node.findChildrenOfType(ASTIfStatement.class);
 71  6 for (Iterator iter = ifStatements.iterator(); iter.hasNext();) {
 72  7 ASTIfStatement ifStatement = (ASTIfStatement) iter.next();
 73  7 if (ifStatement.getFirstParentOfType(ASTSynchronizedStatement.class) == null) {
 74  6 ASTNullLiteral NullLiteral = (ASTNullLiteral) ifStatement.getFirstChildOfType(ASTNullLiteral.class);
 75   
 76  6 if (NullLiteral == null) {
 77  0 continue;
 78    }
 79  6 ASTName Name = (ASTName) ifStatement.getFirstChildOfType(ASTName.class);
 80  6 if (Name == null || !fieldDecls.containsKey(Name.getImage())) {
 81  1 continue;
 82    }
 83  5 List assigmnents = ifStatement.findChildrenOfType(ASTAssignmentOperator.class);
 84  5 boolean violation = false;
 85  5 for (int ix = 0; ix < assigmnents.size(); ix++) {
 86  6 ASTAssignmentOperator oper = (ASTAssignmentOperator) assigmnents.get(ix);
 87  6 if (!oper.jjtGetParent().getClass().equals(ASTStatementExpression.class)) {
 88  0 continue;
 89    }
 90  6 ASTStatementExpression expr = (ASTStatementExpression) oper.jjtGetParent();
 91  6 if (expr.jjtGetChild(0).getClass().equals(ASTPrimaryExpression.class) && ((ASTPrimaryExpression) expr.jjtGetChild(0)).jjtGetChild(0).getClass().equals(ASTPrimaryPrefix.class)) {
 92  6 ASTPrimaryPrefix pp = (ASTPrimaryPrefix) ((ASTPrimaryExpression) expr.jjtGetChild(0)).jjtGetChild(0);
 93  6 String name = null;
 94  6 if (pp.usesThisModifier()) {
 95  0 ASTPrimarySuffix priSuf = (ASTPrimarySuffix)expr.getFirstChildOfType(ASTPrimarySuffix.class);
 96  0 name = priSuf.getImage();
 97    } else {
 98  6 ASTName astName = (ASTName) pp.jjtGetChild(0);
 99  6 name = astName.getImage();
 100    }
 101  6 if (fieldDecls.containsKey(name)) {
 102  5 violation = true;
 103    }
 104    }
 105    }
 106  5 if (violation) {
 107  4 addViolation(data, ifStatement);
 108    }
 109    }
 110    }
 111  6 return super.visit(node, data);
 112    }
 113   
 114    /**
 115    * @return Map
 116    */
 117  0 protected Map propertiesByName() {
 118  0 return propertyDescriptorsByName;
 119    }
 120    }