Skip to content

Commit 31c6904

Browse files
author
zzz
committed
wip
1 parent 7f37780 commit 31c6904

File tree

5 files changed

+65
-40
lines changed

5 files changed

+65
-40
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ A special tag `<item>` automatically recognized as a `<wheel>` being inside a co
4343

4444
Parser usage:
4545

46-
CarXml root = XmlTreeParser.parse(CarXml.class, xmlContent);
46+
CarXml root = FreeFormXmlParser.parse(CarXml.class, xmlContent);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package parser;
2+
3+
import org.apache.commons.lang3.StringUtils;
4+
import org.apache.commons.lang3.math.NumberUtils;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
import java.lang.reflect.Field;
9+
10+
public class DefaultPropertyBinder implements PropertyBinder {
11+
private static final Logger log = LoggerFactory.getLogger(DefaultPropertyBinder.class);
12+
13+
public static DefaultPropertyBinder INSTANCE = new DefaultPropertyBinder();
14+
15+
private DefaultPropertyBinder() {}
16+
17+
@Override
18+
public void setFieldFromStringValue(Object object, Field field, String stringValue) {
19+
try {
20+
Class<?> fieldType = field.getType();
21+
field.setAccessible(true);
22+
if (fieldType.equals(String.class)) {
23+
field.set(object, stringValue);
24+
} else if (fieldType == boolean.class || fieldType == Boolean.class) {
25+
if (StringUtils.isNotEmpty(stringValue)) {
26+
field.set(object, Boolean.parseBoolean(stringValue));
27+
}
28+
} else if (fieldType == int.class || fieldType == Integer.class) {
29+
field.set(object, NumberUtils.toInt(stringValue, 0));
30+
} else if (fieldType == long.class || fieldType == Long.class) {
31+
field.set(object, NumberUtils.toLong(stringValue, 0L));
32+
} else {
33+
log.warn("The field type is unsupported for assignment yet: {}", field);
34+
}
35+
} catch (IllegalAccessException e) {
36+
log.warn("Failed assigning property {} from value {}: " + e.getMessage(), field, stringValue);
37+
}
38+
}
39+
40+
}

src/main/java/parser/XmlTreeParser.java renamed to src/main/java/parser/FreeFormXmlParser.java

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package parser;
22

3-
import org.apache.commons.lang3.StringUtils;
4-
import org.apache.commons.lang3.math.NumberUtils;
53
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
75
import org.xml.sax.Attributes;
@@ -26,12 +24,13 @@
2624
/**
2725
* todo start using generics
2826
*/
29-
public class XmlTreeParser extends DefaultHandler {
27+
public class FreeFormXmlParser extends DefaultHandler {
3028

31-
private final static Logger log = LoggerFactory.getLogger(XmlTreeParser.class);
29+
private final static Logger log = LoggerFactory.getLogger(FreeFormXmlParser.class);
3230

3331
private final Class rootClass;
3432
private final String xmlContent;
33+
private final PropertyBinder propertyBinder;
3534
private Object rootNode;
3635

3736
private final Stack<NodeInfo> nodes = new Stack<>();
@@ -48,13 +47,18 @@ public static class BindingException extends RuntimeException {
4847
}
4948
}
5049

51-
public XmlTreeParser(Class rootClass, String xmlContent) {
50+
public FreeFormXmlParser(Class rootClass, String xmlContent, PropertyBinder propertyBinder) {
5251
this.rootClass = rootClass;
5352
this.xmlContent = xmlContent;
53+
this.propertyBinder = propertyBinder;
5454
}
5555

5656
public static <T> T parse(Class<T> rootClass, String xmlContent) throws IOException, SAXException, ParserConfigurationException {
57-
XmlTreeParser parser = new XmlTreeParser(rootClass, xmlContent);
57+
return parse(rootClass, xmlContent, DefaultPropertyBinder.INSTANCE);
58+
}
59+
60+
public static <T> T parse(Class<T> rootClass, String xmlContent, PropertyBinder propertyBinder) throws IOException, SAXException, ParserConfigurationException {
61+
FreeFormXmlParser parser = new FreeFormXmlParser(rootClass, xmlContent, propertyBinder);
5862
return (T) parser.parse();
5963
}
6064

@@ -277,38 +281,12 @@ private Class getListElementType(Field field) {
277281
private void setFieldFromStringValue(Object object, String attrName, String value) {
278282
try {
279283
Field field = object.getClass().getDeclaredField(attrName);
280-
setFieldFromStringValue(object, field, value);
284+
propertyBinder.setFieldFromStringValue(object, field, value);
281285
} catch (NoSuchFieldException e) {
282286
log.debug("there is no property {}.{} in the Java model - no assignment performed", object.getClass().getName(), attrName);
283287
}
284288
}
285289

286-
private void setFieldFromStringValue(Object object, Field field, String stringValue) {
287-
try {
288-
Class<?> fieldType = field.getType();
289-
field.setAccessible(true);
290-
if (fieldType.equals(String.class)) {
291-
field.set(object, stringValue);
292-
} else if (isBoolean(fieldType)) {
293-
if (StringUtils.isNotEmpty(stringValue)) {
294-
field.set(object, Boolean.parseBoolean(stringValue));
295-
}
296-
} else if (fieldType == int.class || fieldType == Integer.class) {
297-
field.set(object, NumberUtils.toInt(stringValue, 0));
298-
} else if (fieldType == long.class || fieldType == Long.class) {
299-
field.set(object, NumberUtils.toLong(stringValue, 0L));
300-
} else {
301-
log.warn("The field type is unsupported for assignment yet: {}", field);
302-
}
303-
} catch (IllegalAccessException e) {
304-
log.warn("Failed assigning property {} from value {}: " + e.getMessage(), field, stringValue);
305-
}
306-
}
307-
308-
private boolean isBoolean(Class<?> type) {
309-
return type == boolean.class || type == Boolean.class;
310-
}
311-
312290
public static InputSource makeStringInputSource(String content) {
313291
return new InputSource(new StringReader(content));
314292
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package parser;
2+
3+
import java.lang.reflect.Field;
4+
5+
public interface PropertyBinder {
6+
void setFieldFromStringValue(Object object, Field field, String stringValue);
7+
}

src/test/java/parser/XmlTreeParserTest.java renamed to src/test/java/parser/FreeFormXmlParserTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
import static junit.framework.Assert.assertEquals;
1010

11-
public class XmlTreeParserTest {
11+
public class FreeFormXmlParserTest {
1212

13-
private static final Logger log = LoggerFactory.getLogger(XmlTreeParserTest.class);
13+
private static final Logger log = LoggerFactory.getLogger(FreeFormXmlParserTest.class);
1414

1515
public static class CarXml {
1616
public List<Wheel> wheels;
@@ -34,7 +34,7 @@ public void test_types() throws Exception {
3434
"<root>\n" +
3535
" <thing string='Jon' integerNumber='200' longNumber='500'/>\n" +
3636
"</root>";
37-
TypeBindingXml.Thing thing = XmlTreeParser.parse(TypeBindingXml.class, xmlContent).thing;
37+
TypeBindingXml.Thing thing = FreeFormXmlParser.parse(TypeBindingXml.class, xmlContent).thing;
3838
//log.debug("thing: {}", thing);
3939
assertEquals("Jon", thing.string);
4040
assertEquals(200, thing.integerNumber);
@@ -50,7 +50,7 @@ public void test_single_tag_form_works_inside_a_collection() throws Exception {
5050
" <wheel name='two'/>\n" +
5151
" </wheels>\n" +
5252
"</root>";
53-
CarXml root = XmlTreeParser.parse(CarXml.class, xmlContent);
53+
CarXml root = FreeFormXmlParser.parse(CarXml.class, xmlContent);
5454
List<CarXml.Wheel> wheels = root.wheels;
5555
assertEquals(2, wheels.size());
5656
assertEquals("one", wheels.get(0).name);
@@ -64,7 +64,7 @@ public void test_single_tag_form_works_outside_a_collection() throws Exception {
6464
" <wheel name='one'/>\n" +
6565
" <wheel name='two'/>\n" +
6666
"</root>";
67-
CarXml root = XmlTreeParser.parse(CarXml.class, xmlContent);
67+
CarXml root = FreeFormXmlParser.parse(CarXml.class, xmlContent);
6868
List<CarXml.Wheel> wheels = root.wheels;
6969
assertEquals(2, wheels.size());
7070
assertEquals("one", wheels.get(0).name);
@@ -80,7 +80,7 @@ public void test_special_tag_name_item_works_in_a_collection() throws Exception
8080
" <wheel name='two'/>\n" +
8181
" </wheels>\n" +
8282
"</root>";
83-
CarXml root = XmlTreeParser.parse(CarXml.class, xmlContent);
83+
CarXml root = FreeFormXmlParser.parse(CarXml.class, xmlContent);
8484
List<CarXml.Wheel> wheels = root.wheels;
8585
assertEquals(2, wheels.size());
8686
assertEquals("one", wheels.get(0).name);

0 commit comments

Comments
 (0)