1 4 package net.sourceforge.pmd.rules; 5 6 import net.sourceforge.pmd.CommonAbstractRule; 7 import net.sourceforge.pmd.RuleContext; 8 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId; 9 import net.sourceforge.pmd.ast.Node; 10 import net.sourceforge.pmd.ast.SimpleNode; 11 import net.sourceforge.pmd.jaxen.DocumentNavigator; 12 import net.sourceforge.pmd.jaxen.MatchesFunction; 13 14 import org.jaxen.BaseXPath; 15 import org.jaxen.JaxenException; 16 import org.jaxen.SimpleVariableContext; 17 import org.jaxen.XPath; 18 19 import java.io.PrintStream ; 20 import java.io.PrintWriter ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map.Entry; 24 25 31 public class XPathRule extends CommonAbstractRule { 32 33 public static Class loadClass(ClassLoader classloader, String xpath, String name) { 34 if (xpath.indexOf('|') != -1) { 35 return XPathRule.class; 37 } 38 String part = xpath.trim(); 39 40 if (!part.matches("(?s)//\\w+\\W.*")) { 42 return XPathRule.class; 44 } 45 46 String tail = part.replaceFirst("^//\\w+", ""); 47 String nodeName = part.substring(2, part.indexOf(tail)); 48 49 return DynamicXPathRule.loadClass(classloader, nodeName); 50 } 51 52 private XPath xpath; 53 private boolean regexpFunctionRegistered; 54 55 63 public void evaluate(Node compilationUnit, RuleContext data) { 64 try { 65 initializeXPathExpression(); 66 List results = xpath.selectNodes(compilationUnit); 67 for (Iterator i = results.iterator(); i.hasNext();) { 68 SimpleNode n = (SimpleNode) i.next(); 69 if (n instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) { 70 addViolation(data, n, n.getImage()); 71 } else { 72 addViolation(data, (SimpleNode) n, getMessage()); 73 } 74 } 75 } catch (JaxenException ex) { 76 throwJaxenAsRuntime(ex); 77 } 78 } 79 80 private void initializeXPathExpression() throws JaxenException { 81 if (xpath != null) { 82 return; 83 } 84 85 if (!regexpFunctionRegistered) { 86 MatchesFunction.registerSelfInSimpleContext(); 87 regexpFunctionRegistered = true; 88 } 89 90 xpath = new BaseXPath(getStringProperty("xpath"), new DocumentNavigator()); 91 if (properties.size() > 1) { 92 SimpleVariableContext vc = new SimpleVariableContext(); 93 for (Iterator i = properties.entrySet().iterator(); i.hasNext();) { 94 Entry e = (Entry) i.next(); 95 if (!"xpath".equals(e.getKey())) { 96 vc.setVariableValue((String ) e.getKey(), e.getValue()); 97 } 98 } 99 xpath.setVariableContext(vc); 100 } 101 } 102 103 private static void throwJaxenAsRuntime(final JaxenException ex) { 104 throw new RuntimeException () { 105 public void printStackTrace() { 106 super.printStackTrace(); 107 ex.printStackTrace(); 108 } 109 110 public void printStackTrace(PrintWriter writer) { 111 super.printStackTrace(writer); 112 ex.printStackTrace(writer); 113 } 114 115 public void printStackTrace(PrintStream stream) { 116 super.printStackTrace(stream); 117 ex.printStackTrace(stream); 118 } 119 120 public String getMessage() { 121 return super.getMessage() + ex.getMessage(); 122 } 123 }; 124 } 125 126 129 public void apply(List astCompilationUnits, RuleContext ctx) { 130 for (Iterator i = astCompilationUnits.iterator(); i.hasNext();) { 131 evaluate((Node) i.next(), ctx); 132 } 133 } 134 } 135 | Popular Tags |