Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 134   Methods: 9
NCLOC: 93   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XPathRule.java 90% 75% 44.4% 75.4%
coverage coverage
 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.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    /**
 26    * Rule that tries to match an XPath expression against a DOM
 27    * view of the AST of a "compilation unit".
 28    * <p/>
 29    * This rule needs a property "xpath".
 30    */
 31    public class XPathRule extends CommonAbstractRule {
 32   
 33  2451 public static Class loadClass(ClassLoader classloader, String xpath, String name) {
 34  2451 if (xpath.indexOf('|') != -1) {
 35    //System.err.println(name + " not a dynamic rule: " + xpath.trim().replaceAll("\n", ""));
 36  70 return XPathRule.class;
 37    }
 38  2381 String part = xpath.trim();
 39   
 40    // Need to use DOTALL mode because of potential line terminators
 41  2381 if (!part.matches("(?s)//\\w+\\W.*")) {
 42    //System.err.println(name + " not a dynamic rule: " + xpath.trim().replaceAll("\n", ""));
 43  0 return XPathRule.class;
 44    }
 45   
 46  2381 String tail = part.replaceFirst("^//\\w+", "");
 47  2381 String nodeName = part.substring(2, part.indexOf(tail));
 48   
 49  2381 return DynamicXPathRule.loadClass(classloader, nodeName);
 50    }
 51   
 52    private XPath xpath;
 53    private boolean regexpFunctionRegistered;
 54   
 55    /**
 56    * Evaluate the AST with compilationUnit as root-node, against
 57    * the XPath expression found as property with name "xpath".
 58    * All matches are reported as violations.
 59    *
 60    * @param compilationUnit the Node that is the root of the AST to be checked
 61    * @param data
 62    */
 63  26 public void evaluate(Node compilationUnit, RuleContext data) {
 64  26 try {
 65  26 initializeXPathExpression();
 66  26 List results = xpath.selectNodes(compilationUnit);
 67  26 for (Iterator i = results.iterator(); i.hasNext();) {
 68  18 SimpleNode n = (SimpleNode) i.next();
 69  18 if (n instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) {
 70  1 addViolation(data, n, n.getImage());
 71    } else {
 72  17 addViolation(data, (SimpleNode) n, getMessage());
 73    }
 74    }
 75    } catch (JaxenException ex) {
 76  0 throwJaxenAsRuntime(ex);
 77    }
 78    }
 79   
 80  26 private void initializeXPathExpression() throws JaxenException {
 81  26 if (xpath != null) {
 82  13 return;
 83    }
 84   
 85  13 if (!regexpFunctionRegistered) {
 86  13 MatchesFunction.registerSelfInSimpleContext();
 87  13 regexpFunctionRegistered = true;
 88    }
 89   
 90  13 xpath = new BaseXPath(getStringProperty("xpath"), new DocumentNavigator());
 91  13 if (properties.size() > 1) {
 92  2 SimpleVariableContext vc = new SimpleVariableContext();
 93  2 for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
 94  4 Entry e = (Entry) i.next();
 95  4 if (!"xpath".equals(e.getKey())) {
 96  2 vc.setVariableValue((String) e.getKey(), e.getValue());
 97    }
 98    }
 99  2 xpath.setVariableContext(vc);
 100    }
 101    }
 102   
 103  0 private static void throwJaxenAsRuntime(final JaxenException ex) {
 104  0 throw new RuntimeException() {
 105  0 public void printStackTrace() {
 106  0 super.printStackTrace();
 107  0 ex.printStackTrace();
 108    }
 109   
 110  0 public void printStackTrace(PrintWriter writer) {
 111  0 super.printStackTrace(writer);
 112  0 ex.printStackTrace(writer);
 113    }
 114   
 115  0 public void printStackTrace(PrintStream stream) {
 116  0 super.printStackTrace(stream);
 117  0 ex.printStackTrace(stream);
 118    }
 119   
 120  0 public String getMessage() {
 121  0 return super.getMessage() + ex.getMessage();
 122    }
 123    };
 124    }
 125   
 126    /**
 127    * Apply the rule to all compilation units.
 128    */
 129  26 public void apply(List astCompilationUnits, RuleContext ctx) {
 130  26 for (Iterator i = astCompilationUnits.iterator(); i.hasNext();) {
 131  26 evaluate((Node) i.next(), ctx);
 132    }
 133    }
 134    }