View Javadoc

1   /*
2    * Copyright 2010 Capgemini
3    * Licensed under the Apache License, Version 2.0 (the "License"); 
4    * you may not use this file except in compliance with the License. 
5    * You may obtain a copy of the License at 
6    * 
7    * http://www.apache.org/licenses/LICENSE-2.0 
8    * 
9    * Unless required by applicable law or agreed to in writing, software 
10   * distributed under the License is distributed on an "AS IS" BASIS, 
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
12   * See the License for the specific language governing permissions and 
13   * limitations under the License. 
14   * 
15   */
16  package org.xmlfield.core.internal;
17  
18  import static org.apache.commons.lang.StringUtils.substringAfterLast;
19  import static org.apache.commons.lang.StringUtils.substringBefore;
20  import static org.apache.commons.lang.StringUtils.substringBetween;
21  
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.regex.Matcher;
25  import java.util.regex.Pattern;
26  
27  import org.apache.commons.lang.StringUtils;
28  
29  /**
30   * Xpath manipulation methods.
31   * 
32   * @author Nicolas Richeton <nicolas.richeton@capgemini.com>
33   * @author Guillaume Mary <guillaume.mary@capgemini.com>
34   */
35  public class XPathUtils {
36  
37      public static final int TYPE_ATTRIBUTE = 3;
38  
39      public static final int TYPE_TAG = 1;
40  
41      public static final int TYPE_TAG_WITH_ATTRIBUTE = 2;
42  
43      /**
44       * Return element name without any selector.
45       * 
46       * <p>
47       * Attribute names are returned with a starting '@'
48       * 
49       * @param xPath
50       *            the XPath query
51       * @return element name
52       */
53      public static String getElementName(String xPath) {
54          String name = XPathUtils.getElementNameWithSelector(xPath);
55  
56          // Remove org.xmlfield.tests.attribute selector
57          name = substringBefore(name, "[");
58          return name;
59      }
60  
61      public static String getElementNameWithSelector(String xPath) {
62          String name = xPath;
63          if (name.contains("/")) {
64              name = substringAfterLast(name, "/");
65          }
66          return name;
67      }
68  
69      /**
70       * Return element position if it exist.
71       * 
72       * @param xPath
73       *            the XPath query
74       * @return element position
75       */
76      public static int getElementPosition(String xPath) {
77          String name = XPathUtils.getElementNameWithSelector(xPath);
78  
79          // Remove org.xmlfield.tests.attribute selector
80          name = substringBetween(name, "[", "]");
81          if (name == null) {
82              return 1;
83          }
84          return Integer.parseInt(name);
85      }
86  
87      /**
88       * Retrieve the element prefix
89       * 
90       * @param xPath
91       *            the XPath query
92       * @return element prefix
93       */
94      public static String getElementPrefix(String xPath) {
95          String name = XPathUtils.getElementNameWithSelector(xPath);
96  
97          if (name.contains(":")) {
98  
99              return substringBefore(name, ":");
100         }
101 
102         return null;
103 
104     }
105 
106     /**
107      * Returns the selector attributes of this XPath
108      * 
109      * @param xPath
110      *            XPath
111      * @return attributes map
112      */
113     public static Map<String, String> getElementSelectorAttributes(String xPath) {
114         String name = XPathUtils.getElementNameWithSelector(xPath);
115         HashMap<String, String> result = null;
116         if (name.contains("[@")) {
117             result = new HashMap<String, String>();
118             String[] attributes = StringUtils.split(name, "[@");
119             for (String a : attributes) {
120                 if (a.contains("=")) {
121                     String[] aSplitted = a.split("=");
122                     int endIndex = 1;
123                     switch (aSplitted[1].charAt(0)) {
124                     case '\"':
125                     case '\'':
126                         endIndex++;
127 
128                         break;
129                     default:
130                     }
131                     aSplitted[1] = aSplitted[1].substring(1, aSplitted[1].length() - endIndex);
132 
133                     result.put(aSplitted[0], aSplitted[1]);
134                 }
135 
136             }
137 
138         }
139 
140         return result;
141     }
142 
143     /**
144      * Returns the type of the element described by this xPath query. See the following examples :
145      * 
146      * <ul>
147      * <li>/parent/tagname => TYPE_TAG
148      * <li>/parent/@attrname => TYPE_ATTRIBUTE
149      * <li>/parent/tagname[@attrname=attrvalue] => TYPE_TAG_WITH_ATTRIBUTE
150      * </ul>
151      * 
152      * 
153      * @param xPath
154      *            the XPath query
155      * @return TYPE_TAG, TYPE_TAG_WITH_ATTRIBUTE, TYPE_ATTRIBUTE
156      * 
157      * @see XMLFieldUtils#getElementSelectorAttributes(String)
158      * @see getElementName
159      * @see XPathUtils#getElementNameWithSelector(String)
160      * 
161      */
162     public static int getElementType(String xPath) {
163         String name = XPathUtils.getElementNameWithSelector(xPath);
164 
165         if (name.startsWith("@")) {
166             return XPathUtils.TYPE_ATTRIBUTE;
167         }
168 
169         if (name.contains("[@")) {
170             return XPathUtils.TYPE_TAG_WITH_ATTRIBUTE;
171         }
172 
173         return XPathUtils.TYPE_TAG;
174     }
175 
176     /**
177      * Retrieve the xpath element from the specified xpath.
178      * 
179      * @param fieldXPath
180      *            xpath mapped to a field
181      * @return xpath element
182      */
183     public static String getElementXPath(String fieldXPath) {
184         Pattern pattern = Pattern.compile("^(.+)\\/@(.+)$");
185         Matcher matcher = pattern.matcher(fieldXPath);
186         if (matcher.matches()) {
187             return matcher.group(1);
188         }
189         return null;
190     }
191 
192     /**
193      * Retrieve the xpath element from the specified xpath.
194      * 
195      * @param fieldXPath
196      *            xpath mapped to a field
197      * @return xpath element
198      */
199     public static boolean isAttributeXPath(String fieldXPath) {
200         Pattern pattern = Pattern.compile("^(.*)@(.+)$");
201         Matcher matcher = pattern.matcher(fieldXPath);
202         if (matcher.matches()) {
203             return true;
204         }
205         return false;
206     }
207 
208 }