View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.rules;
5   
6   import net.sourceforge.pmd.AbstractRule;
7   import net.sourceforge.pmd.RuleContext;
8   import net.sourceforge.pmd.ast.ASTCompilationUnit;
9   import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
10  import net.sourceforge.pmd.ast.SimpleNode;
11  import net.sourceforge.pmd.ast.ASTPackageDeclaration;
12  import net.sourceforge.pmd.ast.Node;
13  import net.sourceforge.pmd.jaxen.DocumentNavigator;
14  import org.jaxen.BaseXPath;
15  import org.jaxen.JaxenException;
16  import org.jaxen.XPath;
17  
18  import java.io.PrintStream;
19  import java.io.PrintWriter;
20  import java.text.MessageFormat;
21  import java.util.Iterator;
22  
23  public class XPathRule extends AbstractRule {
24  
25      private XPath xpath;
26  
27      public Object visit(ASTCompilationUnit node, Object data) {
28          try {
29              findPackageName(node);
30              init();
31              for (Iterator iter = xpath.selectNodes(node).iterator(); iter.hasNext();) {
32                  SimpleNode actualNode = (SimpleNode) iter.next();
33                  RuleContext ctx = (RuleContext) data;
34                  String msg = getMessage();
35                  if (actualNode instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) {
36                      msg = MessageFormat.format(msg, new Object[]{actualNode.getImage()});
37                  }
38                  ctx.getReport().addRuleViolation(createRuleViolation(ctx, actualNode, msg));
39              }
40          } catch (JaxenException ex) {
41              throwJaxenAsRuntime(ex);
42          }
43          return data;
44      }
45  
46      private void findPackageName(ASTCompilationUnit node) {
47          for (int i=0; i<node.jjtGetNumChildren(); i++) {
48              Node n = node.jjtGetChild(i);
49              if (n instanceof ASTPackageDeclaration) {
50                  String name = ((SimpleNode)n.jjtGetChild(0)).getImage();
51                  setPackageName(name);
52                  break;
53              }
54          }
55      }
56  
57      private void init() throws JaxenException {
58          if (xpath == null) {
59              String path = getStringProperty("xpath");
60              String subst = getStringProperty("subst");
61              if (subst != null && subst.length() > 0) {
62                  path = MessageFormat.format(path, new String[]{subst});
63              }
64              xpath = new BaseXPath(path, new DocumentNavigator());
65          }
66      }
67  
68      private static void throwJaxenAsRuntime(final JaxenException ex) {
69          throw new RuntimeException() {
70              public void printStackTrace() {
71                  super.printStackTrace();
72                  ex.printStackTrace();
73              }
74  
75              public void printStackTrace(PrintWriter writer) {
76                  super.printStackTrace(writer);
77                  ex.printStackTrace(writer);
78              }
79  
80              public void printStackTrace(PrintStream stream) {
81                  super.printStackTrace(stream);
82                  ex.printStackTrace(stream);
83              }
84  
85              public String getMessage() {
86                  return super.getMessage() + ex.getMessage();
87              }
88          };
89      }
90  }