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 if (methodDeclaration.getMethodName().startsWith("test")) { 43 return super.visit(methodDeclaration, o); 44 } 45 46 List exceptionList = methodDeclaration.findChildrenOfType(ASTName.class); 47 if (!exceptionList.isEmpty()) { 48 evaluateExceptions(exceptionList, o); 49 } 50 return super.visit(methodDeclaration, o); 51 } 52 53 54 public Object visit(ASTConstructorDeclaration constructorDeclaration, Object o) { 55 List exceptionList = constructorDeclaration.findChildrenOfType(ASTName.class); 56 if (!exceptionList.isEmpty()) { 57 evaluateExceptions(exceptionList, o); 58 } 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.hasImageEqualTo("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 }