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 }