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