1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.parsing;
17
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Properties;
22
23 import org.w3c.dom.CharacterData;
24 import org.w3c.dom.Element;
25 import org.w3c.dom.NamedNodeMap;
26 import org.w3c.dom.Node;
27 import org.w3c.dom.NodeList;
28
29
30
31
32 public class XNode {
33
34 private Node node;
35 private String name;
36 private String body;
37 private Properties attributes;
38 private Properties variables;
39 private XPathParser xpathParser;
40
41 public XNode(XPathParser xpathParser, Node node, Properties variables) {
42 this.xpathParser = xpathParser;
43 this.node = node;
44 this.name = node.getNodeName();
45 this.variables = variables;
46 this.attributes = parseAttributes(node);
47 this.body = parseBody(node);
48 }
49
50 public XNode newXNode(Node node) {
51 return new XNode(xpathParser, node, variables);
52 }
53
54 public XNode getParent() {
55 Node parent = node.getParentNode();
56 if (parent == null || !(parent instanceof Element)) {
57 return null;
58 } else {
59 return new XNode(xpathParser, parent, variables);
60 }
61 }
62
63 public String getPath() {
64 StringBuilder builder = new StringBuilder();
65 Node current = node;
66 while (current != null && current instanceof Element) {
67 if (current != node) {
68 builder.insert(0, "/");
69 }
70 builder.insert(0, current.getNodeName());
71 current = current.getParentNode();
72 }
73 return builder.toString();
74 }
75
76 public String getValueBasedIdentifier() {
77 StringBuilder builder = new StringBuilder();
78 XNode current = this;
79 while (current != null) {
80 if (current != this) {
81 builder.insert(0, "_");
82 }
83 String value = current.getStringAttribute("id",
84 current.getStringAttribute("value",
85 current.getStringAttribute("property", null)));
86 if (value != null) {
87 value = value.replace('.', '_');
88 builder.insert(0, "]");
89 builder.insert(0,
90 value);
91 builder.insert(0, "[");
92 }
93 builder.insert(0, current.getName());
94 current = current.getParent();
95 }
96 return builder.toString();
97 }
98
99 public String evalString(String expression) {
100 return xpathParser.evalString(node, expression);
101 }
102
103 public Boolean evalBoolean(String expression) {
104 return xpathParser.evalBoolean(node, expression);
105 }
106
107 public Double evalDouble(String expression) {
108 return xpathParser.evalDouble(node, expression);
109 }
110
111 public List<XNode> evalNodes(String expression) {
112 return xpathParser.evalNodes(node, expression);
113 }
114
115 public XNode evalNode(String expression) {
116 return xpathParser.evalNode(node, expression);
117 }
118
119 public Node getNode() {
120 return node;
121 }
122
123 public String getName() {
124 return name;
125 }
126
127 public String getStringBody() {
128 return getStringBody(null);
129 }
130
131 public String getStringBody(String def) {
132 if (body == null) {
133 return def;
134 } else {
135 return body;
136 }
137 }
138
139 public Boolean getBooleanBody() {
140 return getBooleanBody(null);
141 }
142
143 public Boolean getBooleanBody(Boolean def) {
144 if (body == null) {
145 return def;
146 } else {
147 return Boolean.valueOf(body);
148 }
149 }
150
151 public Integer getIntBody() {
152 return getIntBody(null);
153 }
154
155 public Integer getIntBody(Integer def) {
156 if (body == null) {
157 return def;
158 } else {
159 return Integer.parseInt(body);
160 }
161 }
162
163 public Long getLongBody() {
164 return getLongBody(null);
165 }
166
167 public Long getLongBody(Long def) {
168 if (body == null) {
169 return def;
170 } else {
171 return Long.parseLong(body);
172 }
173 }
174
175 public Double getDoubleBody() {
176 return getDoubleBody(null);
177 }
178
179 public Double getDoubleBody(Double def) {
180 if (body == null) {
181 return def;
182 } else {
183 return Double.parseDouble(body);
184 }
185 }
186
187 public Float getFloatBody() {
188 return getFloatBody(null);
189 }
190
191 public Float getFloatBody(Float def) {
192 if (body == null) {
193 return def;
194 } else {
195 return Float.parseFloat(body);
196 }
197 }
198
199 public <T extends Enum<T>> T getEnumAttribute(Class<T> enumType, String name) {
200 return getEnumAttribute(enumType, name, null);
201 }
202
203 public <T extends Enum<T>> T getEnumAttribute(Class<T> enumType, String name, T def) {
204 String value = getStringAttribute(name);
205 if (value == null) {
206 return def;
207 } else {
208 return Enum.valueOf(enumType, value);
209 }
210 }
211
212 public String getStringAttribute(String name) {
213 return getStringAttribute(name, null);
214 }
215
216 public String getStringAttribute(String name, String def) {
217 String value = attributes.getProperty(name);
218 if (value == null) {
219 return def;
220 } else {
221 return value;
222 }
223 }
224
225 public Boolean getBooleanAttribute(String name) {
226 return getBooleanAttribute(name, null);
227 }
228
229 public Boolean getBooleanAttribute(String name, Boolean def) {
230 String value = attributes.getProperty(name);
231 if (value == null) {
232 return def;
233 } else {
234 return Boolean.valueOf(value);
235 }
236 }
237
238 public Integer getIntAttribute(String name) {
239 return getIntAttribute(name, null);
240 }
241
242 public Integer getIntAttribute(String name, Integer def) {
243 String value = attributes.getProperty(name);
244 if (value == null) {
245 return def;
246 } else {
247 return Integer.parseInt(value);
248 }
249 }
250
251 public Long getLongAttribute(String name) {
252 return getLongAttribute(name, null);
253 }
254
255 public Long getLongAttribute(String name, Long def) {
256 String value = attributes.getProperty(name);
257 if (value == null) {
258 return def;
259 } else {
260 return Long.parseLong(value);
261 }
262 }
263
264 public Double getDoubleAttribute(String name) {
265 return getDoubleAttribute(name, null);
266 }
267
268 public Double getDoubleAttribute(String name, Double def) {
269 String value = attributes.getProperty(name);
270 if (value == null) {
271 return def;
272 } else {
273 return Double.parseDouble(value);
274 }
275 }
276
277 public Float getFloatAttribute(String name) {
278 return getFloatAttribute(name, null);
279 }
280
281 public Float getFloatAttribute(String name, Float def) {
282 String value = attributes.getProperty(name);
283 if (value == null) {
284 return def;
285 } else {
286 return Float.parseFloat(value);
287 }
288 }
289
290 public List<XNode> getChildren() {
291 List<XNode> children = new ArrayList<XNode>();
292 NodeList nodeList = node.getChildNodes();
293 if (nodeList != null) {
294 for (int i = 0, n = nodeList.getLength(); i < n; i++) {
295 Node node = nodeList.item(i);
296 if (node.getNodeType() == Node.ELEMENT_NODE) {
297 children.add(new XNode(xpathParser, node, variables));
298 }
299 }
300 }
301 return children;
302 }
303
304 public Properties getChildrenAsProperties() {
305 Properties properties = new Properties();
306 for (XNode child : getChildren()) {
307 String name = child.getStringAttribute("name");
308 String value = child.getStringAttribute("value");
309 if (name != null && value != null) {
310 properties.setProperty(name, value);
311 }
312 }
313 return properties;
314 }
315
316 @Override
317 public String toString() {
318 StringBuilder builder = new StringBuilder();
319 builder.append("<");
320 builder.append(name);
321 for (Map.Entry<Object, Object> entry : attributes.entrySet()) {
322 builder.append(" ");
323 builder.append(entry.getKey());
324 builder.append("=\"");
325 builder.append(entry.getValue());
326 builder.append("\"");
327 }
328 List<XNode> children = getChildren();
329 if (!children.isEmpty()) {
330 builder.append(">\n");
331 for (XNode node : children) {
332 builder.append(node.toString());
333 }
334 builder.append("</");
335 builder.append(name);
336 builder.append(">");
337 } else if (body != null) {
338 builder.append(">");
339 builder.append(body);
340 builder.append("</");
341 builder.append(name);
342 builder.append(">");
343 } else {
344 builder.append("/>");
345 }
346 builder.append("\n");
347 return builder.toString();
348 }
349
350 private Properties parseAttributes(Node n) {
351 Properties attributes = new Properties();
352 NamedNodeMap attributeNodes = n.getAttributes();
353 if (attributeNodes != null) {
354 for (int i = 0; i < attributeNodes.getLength(); i++) {
355 Node attribute = attributeNodes.item(i);
356 String value = PropertyParser.parse(attribute.getNodeValue(), variables);
357 attributes.put(attribute.getNodeName(), value);
358 }
359 }
360 return attributes;
361 }
362
363 private String parseBody(Node node) {
364 String data = getBodyData(node);
365 if (data == null) {
366 NodeList children = node.getChildNodes();
367 for (int i = 0; i < children.getLength(); i++) {
368 Node child = children.item(i);
369 data = getBodyData(child);
370 if (data != null) {
371 break;
372 }
373 }
374 }
375 return data;
376 }
377
378 private String getBodyData(Node child) {
379 if (child.getNodeType() == Node.CDATA_SECTION_NODE
380 || child.getNodeType() == Node.TEXT_NODE) {
381 String data = ((CharacterData) child).getData();
382 data = PropertyParser.parse(data, variables);
383 return data;
384 }
385 return null;
386 }
387
388 }