View Javadoc

    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.ASTClassOrInterfaceType;
    9   import net.sourceforge.pmd.ast.ASTName;
    10  import net.sourceforge.pmd.ast.ASTPrimaryExpression;
    11  import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
    12  import net.sourceforge.pmd.ast.ASTThrowStatement;
    13  import net.sourceforge.pmd.ast.SimpleNode;
    14  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
    15  import org.jaxen.JaxenException;
    16
    17  import java.util.Iterator;
    18  import java.util.List;
    19  import java.util.Map;
    20
    21  public class PreserveStackTrace extends AbstractRule {
    22
    23  	public Object visit(ASTCatchStatement node, Object data) {
    24          String target = (((SimpleNode) node.jjtGetChild(0).jjtGetChild(1)).getImage());
    25          List lstThrowStatements = node.findChildrenOfType(ASTThrowStatement.class);
    26          for (Iterator iter = lstThrowStatements.iterator(); iter.hasNext();) {
    27              ASTThrowStatement throwStatement = (ASTThrowStatement) iter.next();
    28              SimpleNode sn = (SimpleNode) throwStatement.jjtGetChild(0).jjtGetChild(0);
    29              if (sn.getClass().equals(ASTCastExpression.class)) {
    30                  ASTPrimaryExpression expr = (ASTPrimaryExpression) sn.jjtGetChild(1);
    31                  if (expr.jjtGetNumChildren() > 1 && expr.jjtGetChild(1).getClass().equals(ASTPrimaryPrefix.class)) {
    32                      RuleContext ctx = (RuleContext) data;
    33                      addViolation(ctx, throwStatement);
    34                  }
    35                  continue;
    36              }
    37              ASTArgumentList args = (ASTArgumentList) throwStatement.getFirstChildOfType(ASTArgumentList.class);
    38
    39              if (args != null) {
    40                  ck(data, target, throwStatement, args);
    41              } else if (args == null) {
    42                  SimpleNode child = (SimpleNode) throwStatement.jjtGetChild(0);
    43                  while (child != null && child.jjtGetNumChildren() > 0
    44                          && !child.getClass().equals(ASTName.class)) {
    45                      child = (SimpleNode) child.jjtGetChild(0);
    46                  }
    47                  if (child != null){
    48                      if( child.getClass().equals(ASTName.class) && (!target.equals(child.getImage()) && !child.hasImageEqualTo(target + ".fillInStackTrace"))) {
    49  	                    Map vars = ((ASTName) child).getScope().getVariableDeclarations();
    50  	                    for (Iterator i = vars.keySet().iterator(); i.hasNext();) {
    51  	                        VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
    52  	                        args = (ASTArgumentList) ((SimpleNode) decl.getNode().jjtGetParent())
    53  	                                .getFirstChildOfType(ASTArgumentList.class);
    54  	                        if (args != null) {
    55  	                            ck(data, target, throwStatement, args);
    56  	                        }
    57  	                    }
    58                      } else if(child.getClass().equals(ASTClassOrInterfaceType.class)){
    59          				addViolation((RuleContext) data, throwStatement);
    60                      }
    61                  }
    62              }
    63          }
    64          return super.visit(node, data);
    65      }
    66
    67  	private void ck(Object data, String target,
    68  			ASTThrowStatement throwStatement, ASTArgumentList args) {
    69  		try {
    70  			List lst = args.findChildNodesWithXPath("//Name[@Image='" + target
    71  					+ "']");
    72  			if (lst.isEmpty()) {
    73  				RuleContext ctx = (RuleContext) data;
    74  				addViolation(ctx, throwStatement);
    75  			}
    76  		} catch (JaxenException e) {
    77  			e.printStackTrace();
    78  		}
    79  	}
    80  }