View Javadoc

1   package org.rundeck.api.parser;
2   
3   import org.apache.commons.lang.StringUtils;
4   import org.dom4j.Node;
5   
6   /**
7    * BaseXpathParser is ...
8    *
9    * @author Greg Schueler <greg@simplifyops.com>
10   * @since 2014-04-04
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       * Select appropriate node based on xpath, will automatically look for "result" top-level element and alter xpath if
32       * necessary
33       *
34       * @param node
35       *
36       * @return
37       */
38      private Node selectNode(final Node node) {
39          return selectNodeAndUnwrap(node, xpath);
40      }
41  
42      /**
43       * Select appropriate node based on xpath, will automatically look for "result" top-level element and alter xpath if
44       * necessary
45       * @param node
46       * @param xpath
47       * @return
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       * @param node
61       * @param xpath
62       * @return appropriate xpath to use based on whether node has a 'result' root element
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              //starts with result/... but no result element
78              useXpath = xpath.substring("result".length());
79          }else if (useXpath.startsWith("/result")) {
80              //starts with /result/... but no result element
81              useXpath = xpath.substring("/result".length());
82          }
83          return useXpath;
84      }
85  }