Skip to content

Commit 38a9d30

Browse files
committed
refactor, add ExtraTypeProvider
1 parent a7266cc commit 38a9d30

File tree

8 files changed

+105
-38
lines changed

8 files changed

+105
-38
lines changed

src/main/java/com/alibaba/fastjson/JSON.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@
3434
import com.alibaba.fastjson.parser.JSONLexer;
3535
import com.alibaba.fastjson.parser.JSONToken;
3636
import com.alibaba.fastjson.parser.ParserConfig;
37+
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
38+
import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider;
3739
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
3840
import com.alibaba.fastjson.parser.deserializer.ParseProcess;
39-
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
4041
import com.alibaba.fastjson.serializer.BeforeFilter;
4142
import com.alibaba.fastjson.serializer.JSONSerializer;
4243
import com.alibaba.fastjson.serializer.NameFilter;
@@ -231,8 +232,12 @@ public static final <T> T parseObject(String input, Type clazz, ParserConfig con
231232

232233
DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);
233234

235+
if (processor instanceof ExtraTypeProvider) {
236+
parser.getExtraTypeProviders().add((ExtraTypeProvider) processor);
237+
}
238+
234239
if (processor instanceof ExtraProcessor) {
235-
parser.getRedudantProcessors().add((ExtraProcessor) processor);
240+
parser.getExtraProcessors().add((ExtraProcessor) processor);
236241
}
237242

238243
T value = (T) parser.parseObject(clazz);

src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,15 @@
5656
import com.alibaba.fastjson.JSONException;
5757
import com.alibaba.fastjson.JSONObject;
5858
import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;
59+
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
60+
import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider;
5961
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
6062
import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer;
6163
import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
6264
import com.alibaba.fastjson.parser.deserializer.ListResolveFieldDeserializer;
6365
import com.alibaba.fastjson.parser.deserializer.LongDeserializer;
6466
import com.alibaba.fastjson.parser.deserializer.MapResolveFieldDeserializer;
6567
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
66-
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
6768
import com.alibaba.fastjson.parser.deserializer.StringDeserializer;
6869
import com.alibaba.fastjson.util.TypeUtils;
6970

@@ -96,7 +97,8 @@ public class DefaultJSONParser extends AbstractJSONParser implements Closeable {
9697

9798
private int resolveStatus = NONE;
9899

99-
private List<ExtraProcessor> redudantProcessors = null;
100+
private List<ExtraTypeProvider> extraTypeProviders = null;
101+
private List<ExtraProcessor> extraProcessors = null;
100102

101103
static {
102104
primitiveClasses.add(boolean.class);
@@ -1073,17 +1075,28 @@ public ResolveTask getLastResolveTask() {
10731075
return resolveTaskList.get(resolveTaskList.size() - 1);
10741076
}
10751077

1076-
public List<ExtraProcessor> getRedudantProcessors() {
1077-
if (redudantProcessors == null) {
1078-
redudantProcessors = new ArrayList<ExtraProcessor>(2);
1078+
public List<ExtraProcessor> getExtraProcessors() {
1079+
if (extraProcessors == null) {
1080+
extraProcessors = new ArrayList<ExtraProcessor>(2);
10791081
}
1080-
return redudantProcessors;
1082+
return extraProcessors;
10811083
}
1082-
1083-
public List<ExtraProcessor> getRedudantProcessorsDirect() {
1084-
return redudantProcessors;
1084+
1085+
public List<ExtraProcessor> getExtraProcessorsDirect() {
1086+
return extraProcessors;
1087+
}
1088+
1089+
public List<ExtraTypeProvider> getExtraTypeProviders() {
1090+
if (extraTypeProviders == null) {
1091+
extraTypeProviders = new ArrayList<ExtraTypeProvider>(2);
1092+
}
1093+
return extraTypeProviders;
10851094
}
10861095

1096+
public List<ExtraTypeProvider> getExtraTypeProvidersDirect() {
1097+
return extraTypeProviders;
1098+
}
1099+
10871100
public void setContext(ParseContext context) {
10881101
if (isEnabled(Feature.DisableCircularReferenceDetect)) {
10891102
return;

src/main/java/com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@
33
import java.lang.reflect.Type;
44
import java.util.Map;
55

6-
import com.alibaba.fastjson.JSONException;
76
import com.alibaba.fastjson.parser.DefaultJSONParser;
8-
import com.alibaba.fastjson.parser.Feature;
97
import com.alibaba.fastjson.parser.JSONLexer;
108
import com.alibaba.fastjson.parser.ParserConfig;
11-
import com.alibaba.fastjson.serializer.FilterUtils;
129
import com.alibaba.fastjson.util.FieldInfo;
1310

1411
public abstract class ASMJavaBeanDeserializer implements ObjectDeserializer {
@@ -69,14 +66,7 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T
6966
}
7067

7168
if (fieldDeserializer == null) {
72-
if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
73-
throw new JSONException("setter not found, class " + serializer.getClass() + ", property " + key);
74-
}
75-
76-
lexer.nextTokenWithColon();
77-
Object value = parser.parse();
78-
FilterUtils.processRedundant(parser, object, key, value);
79-
69+
this.serializer.parseExtra(parser, object, key);
8070
return false;
8171
}
8272

src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44

5+
56
public interface ExtraProcessor extends ParseProcess {
6-
void process(Object object, String key, Object value);
7+
void processExtra(Object object, String key, Object value);
78
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.alibaba.fastjson.parser.deserializer;
2+
3+
import java.lang.reflect.Type;
4+
5+
6+
public interface ExtraTypeProvider extends ParseProcess {
7+
Type getExtraType(Object object, String key);
8+
}

src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,7 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T
329329
}
330330

331331
if (fieldDeserializer == null) {
332-
if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
333-
throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
334-
}
335-
336-
lexer.nextTokenWithColon();
337-
Object value = parser.parse(); // skip
338-
FilterUtils.processRedundant(parser, object, key, value);
332+
parseExtra(parser, object, key);
339333

340334
return false;
341335
}
@@ -347,6 +341,24 @@ public boolean parseField(DefaultJSONParser parser, String key, Object object, T
347341
return true;
348342
}
349343

344+
void parseExtra(DefaultJSONParser parser, Object object, String key) {
345+
final JSONLexer lexer = parser.getLexer(); // xxx
346+
if (!lexer.isEnabled(Feature.IgnoreNotMatch)) {
347+
throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
348+
}
349+
350+
lexer.nextTokenWithColon();
351+
Type type = FilterUtils.getExtratype(parser, object, key);
352+
Object value;
353+
if (type == null) {
354+
value = parser.parse(); // skip
355+
} else {
356+
value = parser.parseObject(type);
357+
}
358+
359+
FilterUtils.processExtra(parser, object, key, value);
360+
}
361+
350362
public int getFastMatchToken() {
351363
return JSONToken.LBRACE;
352364
}

src/main/java/com/alibaba/fastjson/serializer/FilterUtils.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
package com.alibaba.fastjson.serializer;
22

3+
import java.lang.reflect.Type;
34
import java.util.List;
45

56
import com.alibaba.fastjson.parser.DefaultJSONParser;
67
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
8+
import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider;
79

810
public class FilterUtils {
9-
10-
public static void processRedundant(DefaultJSONParser parser, Object object, String key, Object value) {
11-
List<ExtraProcessor> redudantProcessors = parser.getRedudantProcessorsDirect();
12-
if (redudantProcessors == null) {
11+
public static Type getExtratype(DefaultJSONParser parser, Object object, String key) {
12+
List<ExtraTypeProvider> extraTypeProviders = parser.getExtraTypeProvidersDirect();
13+
if (extraTypeProviders == null) {
14+
return null;
15+
}
16+
17+
Type type = null;
18+
for (ExtraTypeProvider extraProvider : extraTypeProviders) {
19+
type = extraProvider.getExtraType(object, key);
20+
}
21+
return type;
22+
}
23+
24+
public static void processExtra(DefaultJSONParser parser, Object object, String key, Object value) {
25+
List<ExtraProcessor> extraProcessors = parser.getExtraProcessorsDirect();
26+
if (extraProcessors == null) {
1327
return;
1428
}
15-
for (ExtraProcessor process : redudantProcessors) {
16-
process.process(object, key, value);
29+
for (ExtraProcessor process : extraProcessors) {
30+
process.processExtra(object, key, value);
1731
}
1832
}
1933

src/test/java/com/alibaba/json/bvt/parser/RedundantTest.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.alibaba.json.bvt.parser;
22

3+
import java.lang.reflect.Type;
34
import java.util.HashMap;
45
import java.util.Map;
56

@@ -9,12 +10,13 @@
910

1011
import com.alibaba.fastjson.JSON;
1112
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
13+
import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider;
1214

1315
public class RedundantTest extends TestCase {
1416

15-
public void test_0() throws Exception {
17+
public void test_extra() throws Exception {
1618
ExtraProcessor processor = new ExtraProcessor() {
17-
public void process(Object object, String key, Object value) {
19+
public void processExtra(Object object, String key, Object value) {
1820
VO vo = (VO) object;
1921
vo.getAttributes().put(key, value);
2022
}
@@ -24,6 +26,28 @@ public void process(Object object, String key, Object value) {
2426
Assert.assertEquals(123, vo.getId());
2527
Assert.assertEquals("abc", vo.getAttributes().get("name"));
2628
}
29+
30+
public void test_extraWithType() throws Exception {
31+
class MyExtraProcessor implements ExtraProcessor, ExtraTypeProvider {
32+
public void processExtra(Object object, String key, Object value) {
33+
VO vo = (VO) object;
34+
vo.getAttributes().put(key, value);
35+
}
36+
37+
public Type getExtraType(Object object, String key) {
38+
if ("value".equals(key)) {
39+
return int.class;
40+
}
41+
return null;
42+
}
43+
};
44+
ExtraProcessor processor = new MyExtraProcessor();
45+
46+
VO vo = JSON.parseObject("{\"id\":123,\"value\":\"123456\"}", VO.class, processor);
47+
Assert.assertEquals(123, vo.getId());
48+
Assert.assertEquals(123456, vo.getAttributes().get("value"));
49+
}
50+
2751

2852
public static class VO {
2953

0 commit comments

Comments
 (0)