Skip to content

Commit 69d9f2e

Browse files
committed
#56 support recursive structure decoding
1 parent 5040092 commit 69d9f2e

File tree

5 files changed

+36
-2
lines changed

5 files changed

+36
-2
lines changed

src/main/java/com/jsoniter/Codegen.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ private synchronized static Decoder gen(String cacheKey, Type type) {
6565
if (decoder != null) {
6666
return decoder;
6767
}
68+
addPlaceholderDecoderToSupportRecursiveStructure(cacheKey);
6869
if (mode == DecodingMode.REFLECTION_MODE) {
6970
decoder = ReflectionDecoderFactory.create(clazz, typeArgs);
7071
JsoniterSpi.addNewDecoder(cacheKey, decoder);
@@ -104,6 +105,15 @@ private synchronized static Decoder gen(String cacheKey, Type type) {
104105
}
105106
}
106107

108+
private static void addPlaceholderDecoderToSupportRecursiveStructure(final String cacheKey) {
109+
JsoniterSpi.addNewDecoder(cacheKey, new Decoder() {
110+
@Override
111+
public Object decode(JsonIterator iter) throws IOException {
112+
return JsoniterSpi.getDecoder(cacheKey).decode(iter);
113+
}
114+
});
115+
}
116+
107117
public static boolean canStaticAccess(String cacheKey) {
108118
return generatedClassNames.contains(cacheKey);
109119
}

src/main/java/com/jsoniter/annotation/JsoniterAnnotationSupport.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@ public void updateClassDescriptor(ClassDescriptor desc) {
3131
for (String fieldName : jsonObject.unknownPropertiesWhitelist()) {
3232
Binding binding = new Binding(desc.clazz, desc.lookup, Object.class);
3333
binding.name = fieldName;
34+
binding.fromNames = new String[]{binding.name};
35+
binding.toNames = new String[0];
3436
binding.shouldSkip = true;
3537
desc.fields.add(binding);
3638
}
3739
for (String fieldName : jsonObject.unknownPropertiesBlacklist()) {
3840
Binding binding = new Binding(desc.clazz, desc.lookup, Object.class);
3941
binding.name = fieldName;
42+
binding.fromNames = new String[]{binding.name};
43+
binding.toNames = new String[0];
4044
binding.asExtraWhenPresent = true;
4145
desc.fields.add(binding);
4246
}
@@ -88,6 +92,8 @@ private void detectWrappers(ClassDescriptor desc, List<Method> allMethods) {
8892
if (binding.name == null || binding.name.length() == 0) {
8993
binding.name = paramNames[i];
9094
}
95+
binding.fromNames = new String[]{binding.name};
96+
binding.toNames = new String[]{binding.name};
9197
binding.annotations = paramAnnotations;
9298
setter.parameters.add(binding);
9399
}
@@ -136,6 +142,8 @@ private void detectStaticFactory(ClassDescriptor desc, List<Method> allMethods)
136142
if (binding.name == null || binding.name.length() == 0) {
137143
binding.name = paramNames[i];
138144
}
145+
binding.fromNames = new String[]{binding.name};
146+
binding.toNames = new String[]{binding.name};
139147
binding.annotations = paramAnnotations;
140148
desc.ctor.parameters.add(binding);
141149
}
@@ -163,6 +171,8 @@ private void detectCtor(ClassDescriptor desc) {
163171
if (binding.name == null || binding.name.length() == 0) {
164172
binding.name = paramNames[i];
165173
}
174+
binding.fromNames = new String[]{binding.name};
175+
binding.toNames = new String[]{binding.name};
166176
binding.annotations = paramAnnotations;
167177
desc.ctor.parameters.add(binding);
168178
}

src/main/java/com/jsoniter/output/Codegen.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ private static synchronized Encoder gen(final String cacheKey, Type type) {
9393
JsoniterSpi.addNewEncoder(cacheKey, encoder);
9494
return encoder;
9595
}
96+
addPlaceholderEncoderToSupportRecursiveStructure(cacheKey);
9697
Type[] typeArgs = new Type[0];
9798
Class clazz;
9899
if (type instanceof ParameterizedType) {
@@ -118,7 +119,6 @@ private static synchronized Encoder gen(final String cacheKey, Type type) {
118119
}
119120
}
120121
}
121-
addPlaceholderEncoderToSupportRecursiveStructure(cacheKey);
122122
clazz = chooseAccessibleSuper(clazz);
123123
CodegenResult source = genSource(cacheKey, clazz, typeArgs);
124124
try {

src/test/java/com/jsoniter/TestNested.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.jsoniter;
22

3+
import com.jsoniter.annotation.JsonProperty;
4+
import com.jsoniter.annotation.JsoniterAnnotationSupport;
35
import com.jsoniter.any.Any;
6+
import com.jsoniter.output.EncodingMode;
7+
import com.jsoniter.output.JsonStream;
48
import junit.framework.TestCase;
59
import org.junit.Assert;
610

@@ -58,4 +62,15 @@ public void test_get_all_with_some_invalid_path() throws IOException {
5862
result = any.get('*', 1);
5963
assertEquals("{\"field1\":2}", result.toString());
6064
}
65+
66+
public static class TestObject3 {
67+
public com.jsoniter.output.TestNested.TestObject3 reference;
68+
}
69+
70+
public void test_recursive_class() {
71+
// recursive reference will not be supported
72+
// however recursive structure is supported
73+
com.jsoniter.output.TestNested.TestObject3 obj = new com.jsoniter.output.TestNested.TestObject3();
74+
assertNull(JsonIterator.deserialize("{\"reference\":null}", TestObject3.class).reference);
75+
}
6176
}

src/test/java/com/jsoniter/output/TestNested.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ public void test_recursive_class() {
9999
// however recursive structure is supported
100100
JsoniterAnnotationSupport.enable();
101101
TestObject3 obj = new TestObject3();
102-
JsonStream.setMode(EncodingMode.DYNAMIC_MODE);
103102
assertEquals("{\"reference\":null}", JsonStream.serialize(obj));
104103
}
105104
}

0 commit comments

Comments
 (0)