1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.parsing;
17
18 import static org.junit.jupiter.api.Assertions.assertEquals;
19
20 import java.io.BufferedReader;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.Reader;
24
25 import javax.xml.XMLConstants;
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.parsers.ParserConfigurationException;
29
30 import org.apache.ibatis.builder.BuilderException;
31 import org.apache.ibatis.io.Resources;
32 import org.junit.jupiter.api.Test;
33 import org.w3c.dom.Document;
34 import org.xml.sax.InputSource;
35
36 class XPathParserTest {
37 private final String resource = "nodelet_test.xml";
38
39
40 @Test
41 void constructorWithInputStreamValidationVariablesEntityResolver() throws Exception {
42
43 try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
44 XPathParser parser = new XPathParser(inputStream, false, null, null);
45 testEvalMethod(parser);
46 }
47 }
48
49 @Test
50 void constructorWithInputStreamValidationVariables() throws IOException {
51 try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
52 XPathParser parser = new XPathParser(inputStream, false, null);
53 testEvalMethod(parser);
54 }
55 }
56
57 @Test
58 void constructorWithInputStreamValidation() throws IOException {
59 try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
60 XPathParser parser = new XPathParser(inputStream, false);
61 testEvalMethod(parser);
62 }
63 }
64
65 @Test
66 void constructorWithInputStream() throws IOException {
67 try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
68 XPathParser parser = new XPathParser(inputStream);
69 testEvalMethod(parser);
70 }
71 }
72
73
74 @Test
75 void constructorWithReaderValidationVariablesEntityResolver() throws Exception {
76
77 try (Reader reader = Resources.getResourceAsReader(resource)) {
78 XPathParser parser = new XPathParser(reader, false, null, null);
79 testEvalMethod(parser);
80 }
81 }
82
83 @Test
84 void constructorWithReaderValidationVariables() throws IOException {
85 try (Reader reader = Resources.getResourceAsReader(resource)) {
86 XPathParser parser = new XPathParser(reader, false, null);
87 testEvalMethod(parser);
88 }
89 }
90
91 @Test
92 void constructorWithReaderValidation() throws IOException {
93 try (Reader reader = Resources.getResourceAsReader(resource)) {
94 XPathParser parser = new XPathParser(reader, false);
95 testEvalMethod(parser);
96 }
97 }
98
99 @Test
100 void constructorWithReader() throws IOException {
101 try (Reader reader = Resources.getResourceAsReader(resource)) {
102 XPathParser parser = new XPathParser(reader);
103 testEvalMethod(parser);
104 }
105 }
106
107
108 @Test
109 void constructorWithStringValidationVariablesEntityResolver() throws Exception {
110 XPathParser parser = new XPathParser(getXmlString(resource), false, null, null);
111 testEvalMethod(parser);
112 }
113
114 @Test
115 void constructorWithStringValidationVariables() throws IOException {
116 XPathParser parser = new XPathParser(getXmlString(resource), false, null);
117 testEvalMethod(parser);
118 }
119
120 @Test
121 void constructorWithStringValidation() throws IOException {
122 XPathParser parser = new XPathParser(getXmlString(resource), false);
123 testEvalMethod(parser);
124 }
125
126 @Test
127 void constructorWithString() throws IOException {
128 XPathParser parser = new XPathParser(getXmlString(resource));
129 testEvalMethod(parser);
130 }
131
132
133 @Test
134 void constructorWithDocumentValidationVariablesEntityResolver() {
135 XPathParser parser = new XPathParser(getDocument(resource), false, null, null);
136 testEvalMethod(parser);
137 }
138
139 @Test
140 void constructorWithDocumentValidationVariables() {
141 XPathParser parser = new XPathParser(getDocument(resource), false, null);
142 testEvalMethod(parser);
143 }
144
145 @Test
146 void constructorWithDocumentValidation() {
147 XPathParser parser = new XPathParser(getDocument(resource), false);
148 testEvalMethod(parser);
149 }
150
151 @Test
152 void constructorWithDocument() {
153 XPathParser parser = new XPathParser(getDocument(resource));
154 testEvalMethod(parser);
155 }
156
157 private Document getDocument(String resource) {
158 try {
159 InputSource inputSource = new InputSource(Resources.getResourceAsReader(resource));
160 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
161 String feature = null;
162 try {
163 feature = "http://xml.org/sax/features/external-parameter-entities";
164 factory.setFeature(feature, false);
165
166 feature = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
167 factory.setFeature(feature, false);
168
169 feature = "http://xml.org/sax/features/external-general-entities";
170 factory.setFeature(feature, false);
171
172 factory.setXIncludeAware(false);
173 factory.setExpandEntityReferences(false);
174
175 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
176
177 } catch (ParserConfigurationException e) {
178 throw new IllegalStateException("The feature '" + feature + "' is not supported by your XML processor.", e);
179 }
180 factory.setNamespaceAware(false);
181 factory.setIgnoringComments(true);
182 factory.setIgnoringElementContentWhitespace(false);
183 factory.setCoalescing(false);
184 DocumentBuilder builder = factory.newDocumentBuilder();
185 return builder.parse(inputSource);
186 } catch (Exception e) {
187 throw new BuilderException("Error creating document instance. Cause: " + e, e);
188 }
189 }
190
191 private String getXmlString(String resource) throws IOException {
192 try (BufferedReader bufferedReader = new BufferedReader(Resources.getResourceAsReader(resource))) {
193 StringBuilder sb = new StringBuilder();
194 String temp;
195 while ((temp = bufferedReader.readLine()) != null) {
196 sb.append(temp);
197 }
198 return sb.toString();
199 }
200 }
201
202 enum EnumTest {
203 YES, NO
204 }
205
206 private void testEvalMethod(XPathParser parser) {
207 assertEquals((Long) 1970L, parser.evalLong("/employee/birth_date/year"));
208 assertEquals((Long) 1970L, parser.evalNode("/employee/birth_date/year").getLongBody());
209 assertEquals((short) 6, (short) parser.evalShort("/employee/birth_date/month"));
210 assertEquals((Integer) 15, parser.evalInteger("/employee/birth_date/day"));
211 assertEquals((Integer) 15, parser.evalNode("/employee/birth_date/day").getIntBody());
212 assertEquals((Float) 5.8f, parser.evalFloat("/employee/height"));
213 assertEquals((Float) 5.8f, parser.evalNode("/employee/height").getFloatBody());
214 assertEquals((Double) 5.8d, parser.evalDouble("/employee/height"));
215 assertEquals((Double) 5.8d, parser.evalNode("/employee/height").getDoubleBody());
216 assertEquals((Double) 5.8d, parser.evalNode("/employee").evalDouble("height"));
217 assertEquals("${id_var}", parser.evalString("/employee/@id"));
218 assertEquals("${id_var}", parser.evalNode("/employee/@id").getStringBody());
219 assertEquals("${id_var}", parser.evalNode("/employee").evalString("@id"));
220 assertEquals(Boolean.TRUE, parser.evalBoolean("/employee/active"));
221 assertEquals(Boolean.TRUE, parser.evalNode("/employee/active").getBooleanBody());
222 assertEquals(Boolean.TRUE, parser.evalNode("/employee").evalBoolean("active"));
223 assertEquals(EnumTest.YES, parser.evalNode("/employee/active").getEnumAttribute(EnumTest.class, "bot"));
224 assertEquals((Float) 3.2f, parser.evalNode("/employee/active").getFloatAttribute("score"));
225 assertEquals((Double) 3.2d, parser.evalNode("/employee/active").getDoubleAttribute("score"));
226
227 assertEquals("<id>\n ${id_var}\n</id>", parser.evalNode("/employee/@id").toString().trim());
228 assertEquals(7, parser.evalNodes("/employee/*").size());
229 XNode node = parser.evalNode("/employee/height");
230 assertEquals("employee/height", node.getPath());
231 assertEquals("employee[${id_var}]_height", node.getValueBasedIdentifier());
232 }
233
234 }