Skip to content

Commit 0ca4860

Browse files
Dreamrouteharawata
authored andcommitted
feature: format class XNode's toString method.
fix: fix zhe test. test: add fomate Xnode toString() method test. fix: support 3+ level format, add 3 test case for every level. fix: fix retract. fix: revert. fix: exchange the test 'expect' and 'actual' refact: only use one StringBuilder in toString method. fix: add comments.
1 parent e0ae4ad commit 0ca4860

File tree

2 files changed

+100
-37
lines changed

2 files changed

+100
-37
lines changed

src/main/java/org/apache/ibatis/parsing/XNode.java

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -316,35 +316,52 @@ public Properties getChildrenAsProperties() {
316316
@Override
317317
public String toString() {
318318
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("</");
319+
this.toString(builder, 0);
320+
return builder.toString();
321+
}
322+
323+
private void toString(StringBuilder builder, int level) {
324+
builder.append("<");
341325
builder.append(name);
342-
builder.append(">");
343-
} else {
344-
builder.append("/>");
345-
}
346-
builder.append("\n");
347-
return builder.toString();
326+
for (Map.Entry<Object, Object> entry : attributes.entrySet()) {
327+
builder.append(" ");
328+
builder.append(entry.getKey());
329+
builder.append("=\"");
330+
builder.append(entry.getValue());
331+
builder.append("\"");
332+
}
333+
List<XNode> children = getChildren();
334+
if (!children.isEmpty()) {
335+
level++;
336+
builder.append(">\n");
337+
for (int k = 0; k < children.size(); k++) {
338+
this.applySpace(builder, level);
339+
children.get(k).toString(builder, level);
340+
}
341+
level--;
342+
this.applySpace(builder, level);
343+
builder.append("</");
344+
builder.append(name);
345+
builder.append(">");
346+
} else if (body != null) {
347+
builder.append(">");
348+
builder.append(body);
349+
builder.append("</");
350+
builder.append(name);
351+
builder.append(">");
352+
} else {
353+
builder.append("/>");
354+
this.applySpace(builder, level);
355+
}
356+
builder.append("\n");
357+
}
358+
359+
private StringBuilder applySpace(StringBuilder builder, int level) {
360+
for (int i=0; i<level; i++) {
361+
// append 4 space, each level retract 4 space base it's parent.
362+
builder.append(" ");
363+
}
364+
return builder;
348365
}
349366

350367
private Properties parseAttributes(Node n) {

src/test/java/org/apache/ibatis/parsing/XPathParserTest.java

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,24 @@
1717

1818
import static org.junit.jupiter.api.Assertions.assertEquals;
1919

20-
import javax.xml.parsers.DocumentBuilder;
21-
import javax.xml.parsers.DocumentBuilderFactory;
2220
import java.io.BufferedReader;
2321
import java.io.IOException;
2422
import java.io.InputStream;
2523
import java.io.Reader;
2624

25+
import javax.xml.parsers.DocumentBuilder;
26+
import javax.xml.parsers.DocumentBuilderFactory;
27+
2728
import org.apache.ibatis.builder.BuilderException;
2829
import org.apache.ibatis.io.Resources;
2930
import org.junit.jupiter.api.Test;
3031
import org.w3c.dom.Document;
31-
import org.xml.sax.*;
32+
import org.xml.sax.InputSource;
3233

3334
class XPathParserTest {
3435
private String resource = "resources/nodelet_test.xml";
3536

36-
//InputStream Source
37+
// InputStream Source
3738
@Test
3839
void constructorWithInputStreamValidationVariablesEntityResolver() throws Exception {
3940

@@ -67,7 +68,7 @@ void constructorWithInputStream() throws IOException {
6768
}
6869
}
6970

70-
//Reader Source
71+
// Reader Source
7172
@Test
7273
void constructorWithReaderValidationVariablesEntityResolver() throws Exception {
7374

@@ -101,7 +102,7 @@ void constructorWithReader() throws IOException {
101102
}
102103
}
103104

104-
//Xml String Source
105+
// Xml String Source
105106
@Test
106107
void constructorWithStringValidationVariablesEntityResolver() throws Exception {
107108
XPathParser parser = new XPathParser(getXmlString(resource), false, null, null);
@@ -126,7 +127,7 @@ void constructorWithString() throws IOException {
126127
testEvalMethod(parser);
127128
}
128129

129-
//Document Source
130+
// Document Source
130131
@Test
131132
void constructorWithDocumentValidationVariablesEntityResolver() {
132133
XPathParser parser = new XPathParser(getDocument(resource), false, null, null);
@@ -161,7 +162,7 @@ private Document getDocument(String resource) {
161162
factory.setCoalescing(false);
162163
factory.setExpandEntityReferences(true);
163164
DocumentBuilder builder = factory.newDocumentBuilder();
164-
return builder.parse(inputSource);//already closed resource in builder.parse method
165+
return builder.parse(inputSource);// already closed resource in builder.parse method
165166
} catch (Exception e) {
166167
throw new BuilderException("Error creating document instance. Cause: " + e, e);
167168
}
@@ -193,4 +194,49 @@ private void testEvalMethod(XPathParser parser) {
193194
assertEquals("employee[${id_var}]_height", node.getValueBasedIdentifier());
194195
}
195196

196-
}
197+
@Test
198+
public void formatXNodeToString() {
199+
XPathParser parser = new XPathParser("<users><user><id>100</id><name>Tom</name><age>30</age><cars><car>BMW</car><car>Audi</car><car>Benz</car></cars></user></users>");
200+
String usersNodeToString = parser.evalNode("/users").toString();
201+
String userNodeToString = parser.evalNode("/users/user").toString();
202+
String carsNodeToString = parser.evalNode("/users/user/cars").toString();
203+
204+
String usersNodeToStringExpect =
205+
"<users>\n" +
206+
" <user>\n" +
207+
" <id>100</id>\n" +
208+
" <name>Tom</name>\n" +
209+
" <age>30</age>\n" +
210+
" <cars>\n" +
211+
" <car>BMW</car>\n" +
212+
" <car>Audi</car>\n" +
213+
" <car>Benz</car>\n" +
214+
" </cars>\n" +
215+
" </user>\n" +
216+
"</users>\n";
217+
218+
String userNodeToStringExpect =
219+
"<user>\n" +
220+
" <id>100</id>\n" +
221+
" <name>Tom</name>\n" +
222+
" <age>30</age>\n" +
223+
" <cars>\n" +
224+
" <car>BMW</car>\n" +
225+
" <car>Audi</car>\n" +
226+
" <car>Benz</car>\n" +
227+
" </cars>\n" +
228+
"</user>\n";
229+
230+
String carsNodeToStringExpect =
231+
"<cars>\n" +
232+
" <car>BMW</car>\n" +
233+
" <car>Audi</car>\n" +
234+
" <car>Benz</car>\n" +
235+
"</cars>\n";
236+
237+
assertEquals(usersNodeToStringExpect, usersNodeToString);
238+
assertEquals(userNodeToStringExpect, userNodeToString);
239+
assertEquals(carsNodeToStringExpect, carsNodeToString);
240+
}
241+
242+
}

0 commit comments

Comments
 (0)