1 package net.sourceforge.pmd.rules.design;
2
3 import net.sourceforge.pmd.AbstractRule;
4 import net.sourceforge.pmd.RuleContext;
5 import net.sourceforge.pmd.ast.ASTArgumentList;
6 import net.sourceforge.pmd.ast.ASTCastExpression;
7 import net.sourceforge.pmd.ast.ASTCatchStatement;
8 import net.sourceforge.pmd.ast.ASTPrimaryExpression;
9 import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
10 import net.sourceforge.pmd.ast.ASTThrowStatement;
11 import net.sourceforge.pmd.ast.SimpleNode;
12
13 import java.util.Iterator;
14 import java.util.List;
15
16 import org.jaxen.JaxenException;
17
18 public class PreserveStackTrace extends AbstractRule {
19
20 public Object visit(ASTCatchStatement node, Object data) {
21 String target = (((SimpleNode) node.jjtGetChild(0).jjtGetChild(1)).getImage());
22 List lstThrowStatements = node.findChildrenOfType(ASTThrowStatement.class);
23 for (Iterator iter = lstThrowStatements.iterator(); iter.hasNext();) {
24 ASTThrowStatement throwStatement = (ASTThrowStatement) iter.next();
25 SimpleNode sn = (SimpleNode)throwStatement.jjtGetChild(0).jjtGetChild(0);
26 if(sn.getClass().equals(ASTCastExpression.class)){
27 ASTPrimaryExpression expr = (ASTPrimaryExpression)sn.jjtGetChild(1);
28 if(expr.jjtGetNumChildren()> 1 && expr.jjtGetChild(1).getClass().equals(ASTPrimaryPrefix.class)) {
29 RuleContext ctx = (RuleContext) data;
30 addViolation(ctx, throwStatement);
31 }
32 continue;
33 }
34 ASTArgumentList args = (ASTArgumentList) throwStatement.getFirstChildOfType(ASTArgumentList.class);
35
36 if (args != null) {
37 try {
38 List lst = args.findChildNodesWithXPath("//Name[@Image='" + target + "']");
39 if (lst.size() == 0) {
40 RuleContext ctx = (RuleContext) data;
41 addViolation(ctx, throwStatement);
42 }
43 } catch (JaxenException e) {
44 e.printStackTrace();
45 }
46 } else if (args == null) {
47 SimpleNode child = (SimpleNode) throwStatement.jjtGetChild(0);
48 while (child != null && child.jjtGetNumChildren() > 0 && !child.getClass().getName().equals("net.sourceforge.pmd.ast.ASTName")) {
49 child = (SimpleNode) child.jjtGetChild(0);
50 }
51 if (child != null && (!target.equals(child.getImage()) && !child.getImage().equals(target + ".fillInStackTrace"))) {
52 RuleContext ctx = (RuleContext) data;
53 addViolation(ctx, throwStatement);
54 }
55 }
56 }
57 return super.visit(node, data);
58 }
59 }