From 0ef067da2bf28e286a7716ccd60b5d20e88111a9 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 14 May 2017 16:55:10 +0800 Subject: [PATCH] backport feature 'JSONField.alternateNames' to android. --- .../fastjson/annotation/JSONField.java | 2 ++ .../fastjson/parser/JavaBeanDeserializer.java | 18 +++++++++- .../com/alibaba/fastjson/util/FieldInfo.java | 16 ++++++++- .../json/bvt/issue_1100/Issue1199.java | 35 +++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/alibaba/json/bvt/issue_1100/Issue1199.java diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONField.java b/src/main/java/com/alibaba/fastjson/annotation/JSONField.java index 669bd3b81..8253422e4 100755 --- a/src/main/java/com/alibaba/fastjson/annotation/JSONField.java +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONField.java @@ -47,4 +47,6 @@ public @interface JSONField { SerializerFeature[] serialzeFeatures() default {}; Feature[] parseFeatures() default {}; + + String[] alternateNames() default {}; } diff --git a/src/main/java/com/alibaba/fastjson/parser/JavaBeanDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/JavaBeanDeserializer.java index 96f3c3c6e..49d32719c 100755 --- a/src/main/java/com/alibaba/fastjson/parser/JavaBeanDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/JavaBeanDeserializer.java @@ -23,6 +23,9 @@ public class JavaBeanDeserializer implements ObjectDeserializer { private final FieldDeserializer[] fieldDeserializers; private final FieldDeserializer[] sortedFieldDeserializers; + + private final Map alterNameFieldDeserializers; + private final Class clazz; public final JavaBeanInfo beanInfo; private ConcurrentMap extraFieldDeserializers; @@ -34,14 +37,23 @@ public class JavaBeanDeserializer implements ObjectDeserializer { public JavaBeanDeserializer(ParserConfig config, Class clazz, Type type, JavaBeanInfo beanInfo){ this.clazz = clazz; this.beanInfo = beanInfo; - + + Map alterNameFieldDeserializers = null; sortedFieldDeserializers = new FieldDeserializer[beanInfo.sortedFields.length]; for (int i = 0, size = beanInfo.sortedFields.length; i < size; ++i) { FieldInfo fieldInfo = beanInfo.sortedFields[i]; FieldDeserializer fieldDeserializer = config.createFieldDeserializer(config, clazz, fieldInfo); sortedFieldDeserializers[i] = fieldDeserializer; + + for (String name : fieldInfo.alternateNames) { + if (alterNameFieldDeserializers == null) { + alterNameFieldDeserializers = new HashMap(); + } + alterNameFieldDeserializers.put(name, fieldDeserializer); + } } + this.alterNameFieldDeserializers = alterNameFieldDeserializers; fieldDeserializers = new FieldDeserializer[beanInfo.fields.length]; for (int i = 0, size = beanInfo.fields.length; i < size; ++i) { @@ -863,6 +875,10 @@ public class JavaBeanDeserializer implements ObjectDeserializer { return sortedFieldDeserializers[mid]; // key found } } + + if (alterNameFieldDeserializers != null) { + return alterNameFieldDeserializers.get(key); + } return null; // key not found. } diff --git a/src/main/java/com/alibaba/fastjson/util/FieldInfo.java b/src/main/java/com/alibaba/fastjson/util/FieldInfo.java index 1c9272e81..d5fb9f7d6 100755 --- a/src/main/java/com/alibaba/fastjson/util/FieldInfo.java +++ b/src/main/java/com/alibaba/fastjson/util/FieldInfo.java @@ -10,6 +10,7 @@ import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import java.util.Arrays; import com.alibaba.fastjson.annotation.JSONField; @@ -37,6 +38,8 @@ public class FieldInfo implements Comparable { public final long nameHashCode; + public final String[] alternateNames; + public FieldInfo(String name, // Class declaringClass, // Class fieldClass, // @@ -76,6 +79,7 @@ public class FieldInfo implements Comparable { this.nameHashCode = hashCode; this.format = null; + this.alternateNames = new String[0]; } public FieldInfo(String name, // @@ -103,6 +107,11 @@ public class FieldInfo implements Comparable { if (format.trim().length() == 0) { format = null; } + + alternateNames = annotation.alternateNames(); + Arrays.sort(alternateNames); + } else { + alternateNames = new String[0]; } this.format = format; @@ -191,10 +200,15 @@ public class FieldInfo implements Comparable { this.fieldType = genericFieldType; this.fieldClass = fieldClass; - + isEnum = (!fieldClass.isArray()) && fieldClass.isEnum(); } + public boolean alternateName(String name) { + int index = Arrays.binarySearch(this.alternateNames, name); + return index >= 0; + } + public static Type getFieldType(Class clazz, Type type, Type fieldType) { if (clazz == null || type == null) { return fieldType; diff --git a/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1199.java b/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1199.java new file mode 100644 index 000000000..9f9c6be43 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/issue_1100/Issue1199.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.issue_1100; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +/** + * Created by wenshao on 14/05/2017. + */ +public class Issue1199 extends TestCase { + public void test_for_issue() throws Exception { + String jsonVal0 = "{\"id\":5001,\"name\":\"Jobs\"}"; + String jsonVal1 = "{\"id\":5382,\"user\":\"Mary\"}"; + String jsonVal2 = "{\"id\":2341,\"person\":\"Bob\"}"; + + Model obj0 = JSON.parseObject(jsonVal0, Model.class); + assertEquals(5001, obj0.id); + assertEquals("Jobs", obj0.name); + + Model obj1 = JSON.parseObject(jsonVal1, Model.class); + assertEquals(5382, obj1.id); + assertEquals("Mary", obj1.name); + + Model obj2 = JSON.parseObject(jsonVal2, Model.class); + assertEquals(2341, obj2.id); + assertEquals("Bob", obj2.name); + } + + public static class Model { + public int id; + + @JSONField(alternateNames = {"user", "person"}) + public String name; + } +}