Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 115 |  | Methods: | 8
| NCLOC: | 81 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
XPathRule.java | 93.8% | 71.9% | 37.5% | 73.2% |

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 |  | import org.jaxen.BaseXPath;
14 |  | import org.jaxen.JaxenException;
15 |  | import org.jaxen.SimpleVariableContext;
16 |  | import org.jaxen.XPath;
17 |  |
18 |  | import java.io.PrintStream;
19 |  | import java.io.PrintWriter;
20 |  | import java.util.Iterator;
21 |  | import java.util.List;
22 |  | import java.util.Map.Entry;
23 |  |
24 |  | /**
25 |  | * Rule that tries to match an XPath expression against a DOM
26 |  | * view of the AST of a "compilation unit".
27 |  | * <p/>
28 |  | * This rule needs a property "xpath".
29 |  | */
30 |  | public class XPathRule extends CommonAbstractRule {
31 |  |
32 |  | private XPath xpath;
33 |  | private boolean regexpFunctionRegistered;
34 |  |
35 |  | /**
36 |  | * Evaluate the AST with compilationUnit as root-node, against
37 |  | * the XPath expression found as property with name "xpath".
38 |  | * All matches are reported as violations.
39 |  | *
40 |  | * @param compilationUnit the Node that is the root of the AST to be checked
41 |  | * @param data
42 |  | * @return
43 |  | */
44 | 440 | public void evaluate(Node compilationUnit, RuleContext data) {
45 | 440 | try {
46 | 440 | initializeXPathExpression();
47 | 440 | List results = xpath.selectNodes(compilationUnit);
48 | 440 | for (Iterator i = results.iterator(); i.hasNext();) {
49 | 243 | SimpleNode n = (SimpleNode) i.next();
50 | 243 | if (n instanceof ASTVariableDeclaratorId && getBooleanProperty("pluginname")) {
51 | 12 | addViolation(data, n, n.getImage());
52 |  | } else {
53 | 231 | addViolation(data, (SimpleNode) n, getMessage());
54 |  | }
55 |  | }
56 |  | } catch (JaxenException ex) {
57 | 0 | throwJaxenAsRuntime(ex);
58 |  | }
59 |  | }
60 |  |
61 | 440 | private void initializeXPathExpression() throws JaxenException {
62 | 440 | if (xpath != null) {
63 | 314 | return;
64 |  | }
65 |  |
66 | 126 | if (!regexpFunctionRegistered) {
67 | 126 | MatchesFunction.registerSelfInSimpleContext();
68 | 126 | regexpFunctionRegistered = true;
69 |  | }
70 |  |
71 | 126 | xpath = new BaseXPath(getStringProperty("xpath"), new DocumentNavigator());
72 | 126 | if (properties.size() > 1) {
73 | 15 | SimpleVariableContext vc = new SimpleVariableContext();
74 | 15 | for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
75 | 33 | Entry e = (Entry) i.next();
76 | 33 | if (!"xpath".equals(e.getKey())) {
77 | 18 | vc.setVariableValue((String) e.getKey(), e.getValue());
78 |  | }
79 |  | }
80 | 15 | xpath.setVariableContext(vc);
81 |  | }
82 |  | }
83 |  |
84 | 0 | private static void throwJaxenAsRuntime(final JaxenException ex) {
85 | 0 | throw new RuntimeException() {
86 | 0 | public void printStackTrace() {
87 | 0 | super.printStackTrace();
88 | 0 | ex.printStackTrace();
89 |  | }
90 |  |
91 | 0 | public void printStackTrace(PrintWriter writer) {
92 | 0 | super.printStackTrace(writer);
93 | 0 | ex.printStackTrace(writer);
94 |  | }
95 |  |
96 | 0 | public void printStackTrace(PrintStream stream) {
97 | 0 | super.printStackTrace(stream);
98 | 0 | ex.printStackTrace(stream);
99 |  | }
100 |  |
101 | 0 | public String getMessage() {
102 | 0 | return super.getMessage() + ex.getMessage();
103 |  | }
104 |  | };
105 |  | }
106 |  |
107 |  | /**
108 |  | * Apply the rule to all compilation units.
109 |  | */
110 | 440 | public void apply(List astCompilationUnits, RuleContext ctx) {
111 | 440 | for (Iterator i = astCompilationUnits.iterator(); i.hasNext();) {
112 | 440 | evaluate((Node) i.next(), ctx);
113 |  | }
114 |  | }
115 |  | }