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 }