1 4 package net.sourceforge.pmd.rules; 5 6 import net.sourceforge.pmd.AbstractRule; 7 import net.sourceforge.pmd.PropertyDescriptor; 8 import net.sourceforge.pmd.ast.ASTBlock; 9 import net.sourceforge.pmd.ast.ASTClassOrInterfaceType; 10 import net.sourceforge.pmd.ast.ASTCompilationUnit; 11 import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration; 12 import net.sourceforge.pmd.ast.ASTMethodDeclaration; 13 import net.sourceforge.pmd.ast.ASTName; 14 import net.sourceforge.pmd.ast.ASTReferenceType; 15 import net.sourceforge.pmd.ast.ASTTryStatement; 16 import net.sourceforge.pmd.ast.ASTType; 17 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId; 18 import net.sourceforge.pmd.ast.Node; 19 import net.sourceforge.pmd.properties.StringProperty; 20 21 import java.util.ArrayList ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 import java.util.StringTokenizer ; 28 29 41 public class CloseResource extends AbstractRule { 42 43 private Set types = new HashSet (); 44 45 46 private Set closeTargets = new HashSet (); 47 private static final PropertyDescriptor closeTargetsDescriptor = new StringProperty("closeTargets", 48 "Methods which may close this resource", "", 1.0f); 49 50 private static final PropertyDescriptor typesDescriptor = new StringProperty("types", 51 "Types that are affected by this rule", "", 2.0f); 52 53 private static final Map propertyDescriptorsByName = asFixedMap(new PropertyDescriptor[] { typesDescriptor, closeTargetsDescriptor }); 54 55 protected Map propertiesByName() { 56 return propertyDescriptorsByName; 57 }; 58 59 public Object visit(ASTCompilationUnit node, Object data) { 60 if (closeTargets.isEmpty() && getStringProperty(closeTargetsDescriptor) != null) { 61 for (StringTokenizer st = new StringTokenizer (getStringProperty(closeTargetsDescriptor), ","); st.hasMoreTokens();) { 62 closeTargets.add(st.nextToken()); 63 } 64 } 65 if (types.isEmpty() && getStringProperty(typesDescriptor) != null) { 66 for (StringTokenizer st = new StringTokenizer (getStringProperty(typesDescriptor), ","); st.hasMoreTokens();) { 67 types.add(st.nextToken()); 68 } 69 } 70 return super.visit(node, data); 71 } 72 73 public Object visit(ASTMethodDeclaration node, Object data) { 74 List vars = node.findChildrenOfType(ASTLocalVariableDeclaration.class); 75 List ids = new ArrayList (); 76 77 for (Iterator it = vars.iterator(); it.hasNext();) { 79 ASTLocalVariableDeclaration var = (ASTLocalVariableDeclaration) it.next(); 80 ASTType type = var.getTypeNode(); 81 82 if (type.jjtGetChild(0) instanceof ASTReferenceType) { 83 ASTReferenceType ref = (ASTReferenceType) type.jjtGetChild(0); 84 if (ref.jjtGetChild(0) instanceof ASTClassOrInterfaceType) { 85 ASTClassOrInterfaceType clazz = (ASTClassOrInterfaceType) ref.jjtGetChild(0); 86 if (types.contains(clazz.getImage())) { 87 ASTVariableDeclaratorId id = (ASTVariableDeclaratorId) var.jjtGetChild(1).jjtGetChild(0); 88 ids.add(id); 89 } 90 } 91 } 92 } 93 94 for (int i = 0; i < ids.size(); i++) { 96 ASTVariableDeclaratorId x = (ASTVariableDeclaratorId) ids.get(i); 97 ensureClosed((ASTLocalVariableDeclaration) x.jjtGetParent().jjtGetParent(), x, data); 98 } 99 return data; 100 } 101 102 private void ensureClosed(ASTLocalVariableDeclaration var, 103 ASTVariableDeclaratorId id, Object data) { 104 String target = id.getImage() + ".close"; 107 Node n = var; 108 109 while (!((n = n.jjtGetParent()) instanceof ASTBlock)) ; 110 111 ASTBlock top = (ASTBlock) n; 112 113 List tryblocks = new ArrayList (); 114 top.findChildrenOfType(ASTTryStatement.class, tryblocks, true); 115 116 boolean closed = false; 117 118 for (Iterator it = tryblocks.iterator(); it.hasNext();) { 122 ASTTryStatement t = (ASTTryStatement) it.next(); 123 124 if ((t.getBeginLine() > id.getBeginLine()) && (t.hasFinally())) { 125 ASTBlock f = (ASTBlock) t.getFinally().jjtGetChild(0); 126 List names = new ArrayList (); 127 f.findChildrenOfType(ASTName.class, names, true); 128 for (Iterator it2 = names.iterator(); it2.hasNext();) { 129 String name = ((ASTName) it2.next()).getImage(); 130 if (name.equals(target) || closeTargets.contains(name)) { 131 closed = true; 132 } 133 } 134 } 135 } 136 137 if (!closed) { 139 ASTType type = (ASTType) var.jjtGetChild(0); 140 ASTReferenceType ref = (ASTReferenceType) type.jjtGetChild(0); 141 ASTClassOrInterfaceType clazz = (ASTClassOrInterfaceType) ref.jjtGetChild(0); 142 addViolation(data, id, clazz.getImage()); 143 } 144 } 145 } 146 | Popular Tags |