1 package net.sourceforge.pmd.rules.strictexception; 2 3 import net.sourceforge.pmd.AbstractRule; 4 import net.sourceforge.pmd.ast.ASTCompilationUnit; 5 import net.sourceforge.pmd.ast.ASTConstructorDeclaration; 6 import net.sourceforge.pmd.ast.ASTImportDeclaration; 7 import net.sourceforge.pmd.ast.ASTMethodDeclaration; 8 import net.sourceforge.pmd.ast.ASTName; 9 import net.sourceforge.pmd.ast.Node; 10 11 import java.util.Iterator; 12 import java.util.List; 13 14 /*** 15 * <p/> 16 * 17 * @author <a mailto:trondandersen@c2i.net>Trond Andersen</a> 18 * @version 1.0 19 * @since 1.2 20 */ 21 public class ExceptionSignatureDeclaration extends AbstractRule { 22 23 private boolean junitImported; 24 25 public Object visit(ASTCompilationUnit node, Object o) { 26 junitImported = false; 27 return super.visit(node, o); 28 } 29 30 public Object visit(ASTImportDeclaration node, Object o) { 31 if (node.getImportedName().indexOf("junit") != -1) { 32 junitImported = true; 33 } 34 return super.visit(node, o); 35 } 36 37 public Object visit(ASTMethodDeclaration methodDeclaration, Object o) { 38 if ((methodDeclaration.getMethodName().equals("setUp") || methodDeclaration.getMethodName().equals("tearDown")) && junitImported) { 39 return super.visit(methodDeclaration, o); 40 } 41 42 List exceptionList = methodDeclaration.findChildrenOfType(ASTName.class); 43 if (!hasContent(exceptionList)) { 44 return super.visit(methodDeclaration, o); 45 } 46 47 evaluateExceptions(exceptionList, o); 48 return super.visit(methodDeclaration, o); 49 } 50 51 52 public Object visit(ASTConstructorDeclaration constructorDeclaration, Object o) { 53 List exceptionList = constructorDeclaration.findChildrenOfType(ASTName.class); 54 if (!hasContent(exceptionList)) { 55 return super.visit(constructorDeclaration, o); 56 } 57 58 evaluateExceptions(exceptionList, o); 59 return super.visit(constructorDeclaration, o); 60 } 61 62 /*** 63 * Checks all exceptions for possible violation on the exception declaration. 64 * 65 * @param exceptionList containing all exception for declaration 66 * @param context 67 */ 68 private void evaluateExceptions(List exceptionList, Object context) { 69 ASTName exception; 70 for (Iterator iter = exceptionList.iterator(); iter.hasNext();) { 71 exception = (ASTName) iter.next(); 72 if (hasDeclaredExceptionInSignature(exception)) { 73 addViolation(context, exception); 74 } 75 } 76 } 77 78 /*** 79 * Checks if the given value is defined as <code>Exception</code> and the parent is either 80 * a method or constructor declaration. 81 * 82 * @param exception to evaluate 83 * @return true if <code>Exception</code> is declared and has proper parents 84 */ 85 private boolean hasDeclaredExceptionInSignature(ASTName exception) { 86 return exception.getImage().equals("Exception") && isParentSignatureDeclaration(exception); 87 } 88 89 /*** 90 * @param exception to evaluate 91 * @return true if parent node is either a method or constructor declaration 92 */ 93 private boolean isParentSignatureDeclaration(ASTName exception) { 94 Node parent = exception.jjtGetParent().jjtGetParent(); 95 return parent instanceof ASTMethodDeclaration || parent instanceof ASTConstructorDeclaration; 96 } 97 98 private boolean hasContent(List nameList) { 99 return nameList != null && nameList.size() > 0; 100 } 101 }