01: package org.acm.seguin.pmd.rules.strictexception;
02:
03: import org.acm.seguin.pmd.AbstractRule;
04: import org.acm.seguin.pmd.RuleContext;
05: import net.sourceforge.jrefactory.ast.ASTConstructorDeclaration;
06: import net.sourceforge.jrefactory.ast.ASTMethodDeclaration;
07: import net.sourceforge.jrefactory.ast.ASTName;
08: import net.sourceforge.jrefactory.ast.Node;
09:
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
23: .findChildrenOfType(ASTName.class);
24: if (!hasContent(exceptionList)) {
25: return super .visit(methodDeclaration, o);
26: }
27:
28: evaluateExceptions(exceptionList, (RuleContext) o);
29: return super .visit(methodDeclaration, o);
30: }
31:
32: public Object visit(
33: ASTConstructorDeclaration constructorDeclaration, Object o) {
34: List exceptionList = constructorDeclaration
35: .findChildrenOfType(ASTName.class);
36: if (!hasContent(exceptionList)) {
37: return super .visit(constructorDeclaration, o);
38: }
39:
40: evaluateExceptions(exceptionList, (RuleContext) o);
41: return super .visit(constructorDeclaration, o);
42: }
43:
44: /**
45: * Checks all exceptions for possible violation on the exception declaration.
46: * @param exceptionList containing all exception for declaration
47: * @param context
48: */
49: private void evaluateExceptions(List exceptionList,
50: RuleContext context) {
51: ASTName exception = null;
52: for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
53: exception = (ASTName) iter.next();
54: if (hasDeclaredExceptionInSignature(exception)) {
55: context.getReport().addRuleViolation(
56: createRuleViolation(context, exception
57: .getBeginLine()));
58: }
59: }
60: }
61:
62: /**
63: * Checks if the given value is defined as <code>Exception</code> and the parent is either
64: * a method or constructor declaration.
65: * @param exception to evaluate
66: * @return true if <code>Exception</code> is declared and has proper parents
67: */
68: private boolean hasDeclaredExceptionInSignature(ASTName exception) {
69: String image = exception.getImage();
70: return ("Exception".equals(image) || "java.lang.Exception"
71: .equals(image))
72: && isParentSignatureDeclaration(exception);
73: }
74:
75: /**
76: * @param exception to evaluate
77: * @return true if parent node is either a method or constructor declaration
78: */
79: private boolean isParentSignatureDeclaration(ASTName exception) {
80: Node parent = exception.jjtGetParent().jjtGetParent();
81: return parent instanceof ASTMethodDeclaration
82: || parent instanceof ASTConstructorDeclaration;
83: }
84:
85: private boolean hasContent(List nameList) {
86: return (nameList != null && nameList.size() > 0);
87: }
88: }
|