1 package org.rundeck.api.parser;
2
3 import org.apache.commons.lang.StringUtils;
4 import org.dom4j.Node;
5
6
7
8
9
10
11
12 public abstract class BaseXpathParser<T> implements XmlNodeParser<T> {
13 private String xpath;
14
15 public BaseXpathParser() {
16 }
17
18 public BaseXpathParser(String xpath) {
19
20 this.xpath = xpath;
21 }
22
23 public abstract T parse(Node node);
24
25 @Override
26 public final T parseXmlNode(Node node) {
27 return parse(selectNode(node));
28 }
29
30
31
32
33
34
35
36
37
38 private Node selectNode(final Node node) {
39 return selectNodeAndUnwrap(node, xpath);
40 }
41
42
43
44
45
46
47
48
49 public static Node selectNodeAndUnwrap(final Node node, final String xpath) {
50 String useXpath = unwrapXpath(node, xpath);
51
52 if (StringUtils.isNotEmpty(useXpath)) {
53 return node.selectSingleNode(useXpath);
54 } else {
55 return node;
56 }
57 }
58
59
60
61
62
63
64 public static String unwrapXpath(final Node node, final String xpath) {
65 boolean rootResult = node.getName() == null && "result".equals(node.getDocument().getRootElement().getName());
66 boolean isEmpty = StringUtils.isEmpty(xpath);
67 String useXpath = xpath;
68 if (isEmpty) {
69 if (rootResult) {
70 useXpath = "result/*";
71 }
72 } else if (rootResult) {
73 if (!useXpath.startsWith("result") &&!useXpath.startsWith("/result") && !useXpath.startsWith("//")) {
74 useXpath = "result/" + xpath;
75 }
76 } else if (useXpath.startsWith("result") ) {
77
78 useXpath = xpath.substring("result".length());
79 }else if (useXpath.startsWith("/result")) {
80
81 useXpath = xpath.substring("/result".length());
82 }
83 return useXpath;
84 }
85 }