Skip to content

Commit 58fb2a8

Browse files
committed
add test for transient field getter
1 parent e43f62a commit 58fb2a8

File tree

3 files changed

+50
-34
lines changed

3 files changed

+50
-34
lines changed

src/main/java/com/jsoniter/spi/Binding.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public class Binding {
2525
public boolean asExtraWhenPresent;
2626
public boolean isNullable = true;
2727
public boolean isCollectionValueNullable = true;
28-
public boolean isTransient;
2928
public OmitValue defaultValueToOmit;
3029
// then this property will not be unknown
3130
// but we do not want to bind it anywhere

src/main/java/com/jsoniter/spi/ClassDescriptor.java

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.lang.reflect.*;
44
import java.util.*;
55

6+
import static java.lang.reflect.Modifier.isTransient;
7+
68
public class ClassDescriptor {
79

810
public ClassInfo classInfo;
@@ -30,10 +32,9 @@ public static ClassDescriptor getDecodingClassDescriptor(ClassInfo classInfo, bo
3032
desc.clazz = clazz;
3133
desc.lookup = lookup;
3234
desc.ctor = getCtor(clazz);
33-
Map<String, Binding> allFields = getFields(lookup, classInfo, includingPrivate);
34-
desc.setters = getSetters(lookup, classInfo, includingPrivate, allFields);
35+
desc.setters = getSetters(lookup, classInfo, includingPrivate);
3536
desc.getters = new ArrayList<Binding>();
36-
desc.fields = omitTransient(allFields);
37+
desc.fields = getFields(lookup, classInfo, includingPrivate);
3738
desc.bindingTypeWrappers = new ArrayList<WrapperDescriptor>();
3839
desc.keyValueTypeWrappers = new ArrayList<Method>();
3940
desc.unwrappers = new ArrayList<UnwrapperDescriptor>();
@@ -86,9 +87,8 @@ public static ClassDescriptor getEncodingClassDescriptor(ClassInfo classInfo, bo
8687
desc.classInfo = classInfo;
8788
desc.clazz = clazz;
8889
desc.lookup = lookup;
89-
Map<String, Binding> allFields = getFields(lookup, classInfo, includingPrivate);
90-
desc.getters = getGetters(lookup, classInfo, includingPrivate, allFields);
91-
desc.fields = omitTransient(allFields);
90+
desc.fields = getFields(lookup, classInfo, includingPrivate);
91+
desc.getters = getGetters(lookup, classInfo, includingPrivate);
9292
desc.bindingTypeWrappers = new ArrayList<WrapperDescriptor>();
9393
desc.keyValueTypeWrappers = new ArrayList<Method>();
9494
desc.unwrappers = new ArrayList<UnwrapperDescriptor>();
@@ -113,16 +113,7 @@ public static ClassDescriptor getEncodingClassDescriptor(ClassInfo classInfo, bo
113113
return desc;
114114
}
115115

116-
private static List<Binding> omitTransient(Map<String, Binding> map) {
117-
List<Binding> out = new ArrayList<Binding>();
118-
for (Binding binding : map.values()) {
119-
if (!binding.isTransient) {
120-
out.add(binding);
121-
}
122-
}
123-
return out;
124-
}
125-
116+
// TODO: do not remove, set fromNames to []
126117
private static void decodingDeduplicate(ClassDescriptor desc) {
127118
HashMap<String, Binding> byName = new HashMap<String, Binding>();
128119
for (Binding field : desc.fields) {
@@ -190,6 +181,7 @@ private static void decodingDeduplicate(ClassDescriptor desc) {
190181
}
191182
}
192183

184+
// TODO: do not remove, set toNames to []
193185
private static void encodingDeduplicate(ClassDescriptor desc) {
194186
HashMap<String, Binding> byName = new HashMap<String, Binding>();
195187
for (Binding field : desc.fields) {
@@ -200,7 +192,6 @@ private static void encodingDeduplicate(ClassDescriptor desc) {
200192
byName.put(toName, field);
201193
}
202194
}
203-
204195
for (Binding getter : new ArrayList<Binding>(desc.getters)) {
205196
for (String toName : getter.toNames) {
206197
Binding existing = byName.get(toName);
@@ -235,8 +226,8 @@ private static ConstructorDescriptor getCtor(Class clazz) {
235226
return cctor;
236227
}
237228

238-
private static Map<String, Binding> getFields(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
239-
Map<String, Binding> output = new LinkedHashMap<String, Binding>();// To ensure fields order
229+
private static List<Binding> getFields(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
230+
ArrayList<Binding> bindings = new ArrayList<Binding>();
240231
for (Field field : getAllFields(classInfo.clazz, includingPrivate)) {
241232
if (Modifier.isStatic(field.getModifiers())) {
242233
continue;
@@ -247,21 +238,24 @@ private static Map<String, Binding> getFields(Map<String, Type> lookup, ClassInf
247238
if (includingPrivate) {
248239
field.setAccessible(true);
249240
}
250-
Binding binding = createBindingFromField(lookup, classInfo, field, Modifier.isTransient(field.getModifiers()));
251-
output.put(binding.name, binding);
241+
Binding binding = createBindingFromField(lookup, classInfo, field);
242+
if (isTransient(field.getModifiers())) {
243+
binding.toNames = new String[0];
244+
binding.fromNames = new String[0];
245+
}
246+
bindings.add(binding);
252247
}
253-
return output;
248+
return bindings;
254249
}
255250

256-
private static Binding createBindingFromField(Map<String, Type> lookup, ClassInfo classInfo, Field field, boolean isTransient) {
251+
private static Binding createBindingFromField(Map<String, Type> lookup, ClassInfo classInfo, Field field) {
257252
try {
258253
Binding binding = new Binding(classInfo, lookup, field.getGenericType());
259254
binding.fromNames = new String[]{field.getName()};
260255
binding.toNames = new String[]{field.getName()};
261256
binding.name = field.getName();
262257
binding.annotations = field.getAnnotations();
263258
binding.field = field;
264-
binding.isTransient = isTransient;
265259
return binding;
266260
} catch (Exception e) {
267261
throw new JsonException("failed to create binding for field: " + field, e);
@@ -281,7 +275,7 @@ private static List<Field> getAllFields(Class clazz, boolean includingPrivate) {
281275
return allFields;
282276
}
283277

284-
private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate, Map<String, Binding> allFields) {
278+
private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
285279
ArrayList<Binding> setters = new ArrayList<Binding>();
286280
for (Method method : getAllMethods(classInfo.clazz, includingPrivate)) {
287281
if (Modifier.isStatic(method.getModifiers())) {
@@ -306,9 +300,14 @@ private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo clas
306300
}
307301
try {
308302
String fromName = translateSetterName(methodName);
309-
Binding field = allFields.get(fromName);
303+
Field field = null;
304+
try {
305+
field = method.getDeclaringClass().getDeclaredField(fromName);
306+
} catch (NoSuchFieldException e) {
307+
// ignore
308+
}
310309
Binding setter = new Binding(classInfo, lookup, paramTypes[0]);
311-
if (!(field == null) && field.isTransient) {
310+
if (field != null && isTransient(field.getModifiers())) {
312311
setter.fromNames = new String[0];
313312
} else {
314313
setter.fromNames = new String[]{fromName};
@@ -348,7 +347,7 @@ private static String translateSetterName(String methodName) {
348347
return fromName;
349348
}
350349

351-
private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate, Map<String, Binding> allFields) {
350+
private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
352351
ArrayList<Binding> getters = new ArrayList<Binding>();
353352
for (Method method : getAllMethods(classInfo.clazz, includingPrivate)) {
354353
if (Modifier.isStatic(method.getModifiers())) {
@@ -368,12 +367,17 @@ private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo clas
368367
continue;
369368
}
370369
String toName = methodName.substring("get".length());
371-
char[] fromNameChars = toName.toCharArray();
372-
fromNameChars[0] = Character.toLowerCase(fromNameChars[0]);
373-
toName = new String(fromNameChars);
370+
char[] toNameChars = toName.toCharArray();
371+
toNameChars[0] = Character.toLowerCase(toNameChars[0]);
372+
toName = new String(toNameChars);
374373
Binding getter = new Binding(classInfo, lookup, method.getGenericReturnType());
375-
Binding field = allFields.get(toName);
376-
if (!(field == null) && field.isTransient) {
374+
Field field = null;
375+
try {
376+
field = method.getDeclaringClass().getDeclaredField(toName);
377+
} catch (NoSuchFieldException e) {
378+
// ignore
379+
}
380+
if (field != null && isTransient(field.getModifiers())) {
377381
getter.toNames = new String[0];
378382
} else {
379383
getter.toNames = new String[]{toName};

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,17 @@ public void test_omit_selft_defined() {
417417
.build();
418418
assertEquals("{}", JsonStream.serialize(cfg, new TestObject18()));
419419
}
420+
421+
public static class TestObject19 {
422+
public transient int hello;
423+
424+
public int getHello() {
425+
return hello;
426+
}
427+
}
428+
429+
public void test_transient_field_getter() {
430+
String output = JsonStream.serialize(new TestObject19());
431+
assertEquals("{}", output);
432+
}
420433
}

0 commit comments

Comments
 (0)