Skip to content

Commit 3aa7a88

Browse files
committed
Fix #86
1 parent a171d07 commit 3aa7a88

File tree

2 files changed

+40
-21
lines changed

2 files changed

+40
-21
lines changed

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

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

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

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ public static ClassDescriptor getDecodingClassDescriptor(ClassInfo classInfo, bo
3030
desc.clazz = clazz;
3131
desc.lookup = lookup;
3232
desc.ctor = getCtor(clazz);
33-
desc.fields = getFields(lookup, classInfo, includingPrivate);
34-
desc.setters = getSetters(lookup, classInfo, includingPrivate);
33+
Map<String, Binding> allFields = getFields(lookup, classInfo, includingPrivate);
34+
desc.setters = getSetters(lookup, classInfo, includingPrivate, allFields);
3535
desc.getters = new ArrayList<Binding>();
36+
desc.fields = omitTransient(allFields);
3637
desc.bindingTypeWrappers = new ArrayList<WrapperDescriptor>();
3738
desc.keyValueTypeWrappers = new ArrayList<Method>();
3839
desc.unwrappers = new ArrayList<UnwrapperDescriptor>();
@@ -85,8 +86,9 @@ public static ClassDescriptor getEncodingClassDescriptor(ClassInfo classInfo, bo
8586
desc.classInfo = classInfo;
8687
desc.clazz = clazz;
8788
desc.lookup = lookup;
88-
desc.fields = getFields(lookup, classInfo, includingPrivate);
89-
desc.getters = getGetters(lookup, classInfo, includingPrivate);
89+
Map<String, Binding> allFields = getFields(lookup, classInfo, includingPrivate);
90+
desc.getters = getGetters(lookup, classInfo, includingPrivate, allFields);
91+
desc.fields = omitTransient(allFields);
9092
desc.bindingTypeWrappers = new ArrayList<WrapperDescriptor>();
9193
desc.keyValueTypeWrappers = new ArrayList<Method>();
9294
desc.unwrappers = new ArrayList<UnwrapperDescriptor>();
@@ -111,6 +113,16 @@ public static ClassDescriptor getEncodingClassDescriptor(ClassInfo classInfo, bo
111113
return desc;
112114
}
113115

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+
114126
private static void decodingDeduplicate(ClassDescriptor desc) {
115127
HashMap<String, Binding> byName = new HashMap<String, Binding>();
116128
for (Binding field : desc.fields) {
@@ -223,35 +235,33 @@ private static ConstructorDescriptor getCtor(Class clazz) {
223235
return cctor;
224236
}
225237

226-
private static List<Binding> getFields(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
227-
ArrayList<Binding> bindings = new ArrayList<Binding>();
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
228240
for (Field field : getAllFields(classInfo.clazz, includingPrivate)) {
229241
if (Modifier.isStatic(field.getModifiers())) {
230242
continue;
231243
}
232-
if (Modifier.isTransient(field.getModifiers())) {
233-
continue;
234-
}
235244
if (!includingPrivate && !Modifier.isPublic(field.getType().getModifiers())) {
236245
continue;
237246
}
238247
if (includingPrivate) {
239248
field.setAccessible(true);
240249
}
241-
Binding binding = createBindingFromField(lookup, classInfo, field);
242-
bindings.add(binding);
250+
Binding binding = createBindingFromField(lookup, classInfo, field, Modifier.isTransient(field.getModifiers()));
251+
output.put(binding.name, binding);
243252
}
244-
return bindings;
253+
return output;
245254
}
246255

247-
private static Binding createBindingFromField(Map<String, Type> lookup, ClassInfo classInfo, Field field) {
256+
private static Binding createBindingFromField(Map<String, Type> lookup, ClassInfo classInfo, Field field, boolean isTransient) {
248257
try {
249258
Binding binding = new Binding(classInfo, lookup, field.getGenericType());
250259
binding.fromNames = new String[]{field.getName()};
251260
binding.toNames = new String[]{field.getName()};
252261
binding.name = field.getName();
253262
binding.annotations = field.getAnnotations();
254263
binding.field = field;
264+
binding.isTransient = isTransient;
255265
return binding;
256266
} catch (Exception e) {
257267
throw new JsonException("failed to create binding for field: " + field, e);
@@ -271,7 +281,7 @@ private static List<Field> getAllFields(Class clazz, boolean includingPrivate) {
271281
return allFields;
272282
}
273283

274-
private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
284+
private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate, Map<String, Binding> allFields) {
275285
ArrayList<Binding> setters = new ArrayList<Binding>();
276286
for (Method method : getAllMethods(classInfo.clazz, includingPrivate)) {
277287
if (Modifier.isStatic(method.getModifiers())) {
@@ -296,12 +306,16 @@ private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo clas
296306
}
297307
try {
298308
String fromName = translateSetterName(methodName);
299-
Binding binding = new Binding(classInfo, lookup, paramTypes[0]);
300-
binding.fromNames = new String[]{fromName};
301-
binding.name = fromName;
302-
binding.method = method;
303-
binding.annotations = method.getAnnotations();
304-
setters.add(binding);
309+
Binding field = allFields.get(fromName);
310+
if (!(field == null) && field.isTransient) {
311+
continue;
312+
}
313+
Binding setter = new Binding(classInfo, lookup, paramTypes[0]);
314+
setter.fromNames = new String[]{fromName};
315+
setter.name = fromName;
316+
setter.method = method;
317+
setter.annotations = method.getAnnotations();
318+
setters.add(setter);
305319
} catch (Exception e) {
306320
throw new JsonException("failed to create binding from setter: " + method, e);
307321
}
@@ -333,7 +347,7 @@ private static String translateSetterName(String methodName) {
333347
return fromName;
334348
}
335349

336-
private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate) {
350+
private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo classInfo, boolean includingPrivate, Map<String, Binding> allFields) {
337351
ArrayList<Binding> getters = new ArrayList<Binding>();
338352
for (Method method : getAllMethods(classInfo.clazz, includingPrivate)) {
339353
if (Modifier.isStatic(method.getModifiers())) {
@@ -356,6 +370,10 @@ private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo clas
356370
char[] fromNameChars = toName.toCharArray();
357371
fromNameChars[0] = Character.toLowerCase(fromNameChars[0]);
358372
toName = new String(fromNameChars);
373+
Binding field = allFields.get(toName);
374+
if (!(field == null) && field.isTransient) {
375+
continue;
376+
}
359377
Binding getter = new Binding(classInfo, lookup, method.getGenericReturnType());
360378
getter.toNames = new String[]{toName};
361379
getter.name = toName;

0 commit comments

Comments
 (0)