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.ast.ASTCompilationUnit;
8   import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
9   import net.sourceforge.pmd.ast.SimpleNode;
10  import net.sourceforge.pmd.jaxen.DocumentNavigator;
11  import org.jaxen.BaseXPath;
12  import org.jaxen.JaxenException;
13  import org.jaxen.SimpleVariableContext;
14  import org.jaxen.XPath;
15  
16  import java.io.PrintStream;
17  import java.io.PrintWriter;
18  import java.text.MessageFormat;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.Map.Entry;
22  
23  public class XPathRule extends AbstractRule {
24  
25      private XPath xpath;
26  
27      public Object visit(ASTCompilationUnit compilationUnit, Object data) {
28          try {
29              initializeXPathExpression();
30              List results = xpath.selectNodes(compilationUnit);
31              for (Iterator i = results.iterator(); i.hasNext();) {
32                  SimpleNode n = (SimpleNode) i.next();
33                  String msg = getMessage();
34                  if (n instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) {
35                      msg = MessageFormat.format(msg, new Object[]{n.getImage()});
36                  }
37                  addViolation(data, n, msg);
38              }
39          } catch (JaxenException ex) {
40              throwJaxenAsRuntime(ex);
41          }
42          return data;
43      }
44  
45      private void initializeXPathExpression() throws JaxenException {
46          if (xpath != null) {
47              return;
48          }
49          xpath = new BaseXPath(getStringProperty("xpath"), new DocumentNavigator());
50          if (properties.size() > 1) {
51              SimpleVariableContext vc = new SimpleVariableContext();
52              for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
53                  Entry e = (Entry) i.next();
54                  if (!"xpath".equals(e.getKey())) {
55                      vc.setVariableValue((String)e.getKey(), e.getValue());
56                  }
57              }
58              xpath.setVariableContext(vc);
59          }
60      }
61  
62      private static void throwJaxenAsRuntime(final JaxenException ex) {
63          throw new RuntimeException() {
64              public void printStackTrace() {
65                  super.printStackTrace();
66                  ex.printStackTrace();
67              }
68              public void printStackTrace(PrintWriter writer) {
69                  super.printStackTrace(writer);
70                  ex.printStackTrace(writer);
71              }
72              public void printStackTrace(PrintStream stream) {
73                  super.printStackTrace(stream);
74                  ex.printStackTrace(stream);
75              }
76              public String getMessage() {
77                  return super.getMessage() + ex.getMessage();
78              }
79          };
80      }
81  }