1 package org.softnetwork.xml.dom.xpath;
2
3 import java.util.List;
4 import java.util.StringTokenizer;
5 import org.w3c.dom.Attr;
6 import org.w3c.dom.Element;
7 import org.w3c.dom.Node;
8
9 /**
10 * @author stephane.manciot@ebiznext.com
11 *
12 */
13 class XPathToken implements XPath {
14
15 private String name;
16
17 private String value;
18
19 private boolean equality;
20
21 private boolean positionedElement;
22
23 private boolean lastElement;
24
25 private int position = -1;
26
27 private boolean inequality;
28
29 private boolean attribute;
30
31 private String token;
32
33 private boolean test;
34
35 XPathToken(String token) throws XPathFormatException {
36 this.token = token;
37 int equalityPos = -1;
38 test = (equalityPos = token.indexOf(XPATH_EQUALITY)) > 0;
39 if (test) {
40 inequality = (token.charAt(equalityPos - 1) == '!');
41 equality = !inequality;
42 String left = null;
43 String right = token.substring(equalityPos + 1);
44 if (inequality)
45 left = token.substring(0, equalityPos - 1);
46 else
47 left = token.substring(0, equalityPos);
48 name = left;
49 value = new StringTokenizer(right, "'").nextToken();
50 positionedElement = name.equals(XPATH_POS_FUNCTION);
51 } else {
52 name = token;
53 try {
54 position = Integer.parseInt(name);
55 positionedElement = true;
56 } catch (NumberFormatException e) {
57 }
58 }
59 lastElement = name.equals(XPATH_LAST_POS_FUNCTION);
60 attribute = name.startsWith(XPATH_ATTRIBUTE);
61 if (attribute)
62 name = name.substring(1);
63 }
64
65 public String toString() {
66 String str = ((test) ? ((isAttribute()) ? "Attribute " : "")
67 + getName() + " must be "
68 + ((isInequality()) ? "different" : "equal") + " to "
69 + getValue() : getToken());
70 return str;
71 }
72
73 /**
74 * @return Renvoie token.
75 */
76 public String getToken() {
77 return token;
78 }
79
80 /**
81 * @return Returns the attribute.
82 */
83 public boolean isAttribute() {
84 return attribute;
85 }
86
87 /**
88 * @return Returns the inequality.
89 */
90 public boolean isInequality() {
91 return inequality;
92 }
93
94 /**
95 * @return Returns the name.
96 */
97 public String getName() {
98 return name;
99 }
100
101 /**
102 * @return Returns the value.
103 */
104 public String getValue() {
105 return value;
106 }
107
108 /**
109 * @return Returns the positionedElement.
110 */
111 public boolean isPositionedElement() {
112 return positionedElement;
113 }
114
115 /**
116 * @return Returns the position.
117 */
118 public int getPosition() {
119 return position;
120 }
121
122 /**
123 * @return Returns the lastElement.
124 */
125 public boolean isLastElement() {
126 return lastElement;
127 }
128
129 /**
130 * @return Returns the equality.
131 */
132 public boolean isEquality() {
133 return equality;
134 }
135
136 public Element[] selectElements(Element current)
137 throws XPathFormatException {
138 if (isEquality() || isInequality()) {
139 if (isPositionedElement()) {
140 try {
141 int value = Integer.parseInt(getValue());
142 if (XPathTools.getElementPosition(current) == value)
143 return (isEquality()) ? new Element[] { current }
144 : EMPTY;
145 else
146 return (isInequality()) ? new Element[] { current }
147 : EMPTY;
148 } catch (NumberFormatException n) {
149 throw new XPathFormatException(getToken(), n.getMessage());
150 }
151 } else if (isAttribute()) {
152 if (getValue().equals(current.getAttribute(name)))
153 return (isEquality()) ? new Element[] { current } : EMPTY;
154 else
155 return (isInequality()) ? new Element[] { current } : EMPTY;
156 } else if (name.equals(XPATH_TEXT_FUNCTION))
157 if (current.getNodeValue().equals(getValue()))
158 return (isEquality()) ? new Element[] { current } : EMPTY;
159 else
160 return (isInequality()) ? new Element[] { current } : EMPTY;
161 } else if (isLastElement()) {
162 ;
163 } else if (isAttribute()) {
164 return (current.getAttribute(getName()) != null) ? new Element[] { current }
165 : EMPTY;
166 } else if (isPositionedElement()) {
167 try {
168 if (XPathTools.getElementPosition(current) == getPosition())
169 return new Element[] { current };
170 else
171 return EMPTY;
172 } catch (NumberFormatException n) {
173 throw new XPathFormatException(getToken(), n.getMessage());
174 }
175 } else {
176 List list = XPathTools.getNamedElements(current, name);
177 if (list != null)
178 return (Element[])list.toArray(new Element[0]);
179 }
180 return EMPTY;
181 }
182
183 public Node[] selectNodes(Node current) throws XPathFormatException {
184 if (isEquality() || isInequality()) {
185 if (isPositionedElement()) {
186 if (current instanceof Element)
187 try {
188 int value = Integer.parseInt(getValue());
189 if (XPathTools.getElementPosition((Element) current) == value)
190 return (isEquality()) ? new Node[] { current }
191 : EMPTY_NODES;
192 else
193 return (isInequality()) ? new Node[] { current }
194 : EMPTY_NODES;
195 } catch (NumberFormatException n) {
196 throw new XPathFormatException(getToken(), n
197 .getMessage());
198 }
199 return EMPTY_NODES;
200 } else if (isAttribute()) {
201 if (current instanceof Element)
202 if (getValue().equals(
203 ((Element) current).getAttribute(name)))
204 return (isEquality()) ? new Node[] { current }
205 : EMPTY_NODES;
206 else
207 return (isInequality()) ? new Node[] { current }
208 : EMPTY_NODES;
209
210
211 } else if (name.equals(XPATH_TEXT_FUNCTION))
212 if (current.getNodeValue().equals(getValue()))
213 return (isEquality()) ? new Node[] { current }
214 : EMPTY_NODES;
215 else
216 return (isInequality()) ? new Node[] { current }
217 : EMPTY_NODES;
218 } else if (isLastElement()) {
219 ;
220 } else if (isAttribute()) {
221 if (isFilter())
222 if (current instanceof Element)
223 return (((Element) current).getAttribute(getName()) != null) ? new Node[] { current }
224 : EMPTY_NODES;
225 else
226 return EMPTY_NODES;
227 else if (current instanceof Element) {
228 Attr a = ((Element) current).getAttributeNode(getName());
229 return (a != null) ? new Node[] { a } : EMPTY_NODES;
230 } else if (current instanceof Attr)
231 return (current.getNodeName().equals(getName())) ? new Node[] { current }
232 : EMPTY_NODES;
233 return EMPTY_NODES;
234 } else if (isPositionedElement()) {
235 try {
236 if (current instanceof Element
237 && XPathTools.getElementPosition((Element) current) == getPosition())
238 return new Node[] { current };
239 else
240 return EMPTY_NODES;
241 } catch (NumberFormatException n) {
242 throw new XPathFormatException(getToken(), n.getMessage());
243 }
244 } else if (current instanceof Element) {
245 List list = XPathTools.getNamedElements((Element)current, name);
246 if (list != null)
247 return (Element[])list.toArray(new Element[0]);
248 }
249 return EMPTY_NODES;
250 }
251
252 protected boolean isFilter() {
253 return false;
254 }
255
256 }