Fixed nullSafe usage. (#1555)
The JsonSerializer/Deserializer adapters used to ignore this attribute which result in inconsistent behaviour for annotated adapters. Fixes #1553 Signed-off-by: Dmitry Bufistov <dmitry@midokura.com> Co-authored-by: Dmitry Bufistov <dmitry@midokura.com>
This commit is contained in:
parent
98f2bbf4c1
commit
46b97bf156
@ -55,6 +55,7 @@ public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapte
|
||||
Object instance = constructorConstructor.get(TypeToken.get(annotation.value())).construct();
|
||||
|
||||
TypeAdapter<?> typeAdapter;
|
||||
boolean nullSafe = annotation.nullSafe();
|
||||
if (instance instanceof TypeAdapter) {
|
||||
typeAdapter = (TypeAdapter<?>) instance;
|
||||
} else if (instance instanceof TypeAdapterFactory) {
|
||||
@ -66,7 +67,8 @@ public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapte
|
||||
JsonDeserializer<?> deserializer = instance instanceof JsonDeserializer
|
||||
? (JsonDeserializer) instance
|
||||
: null;
|
||||
typeAdapter = new TreeTypeAdapter(serializer, deserializer, gson, type, null);
|
||||
typeAdapter = new TreeTypeAdapter(serializer, deserializer, gson, type, null, nullSafe);
|
||||
nullSafe = false;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid attempt to bind an instance of "
|
||||
+ instance.getClass().getName() + " as a @JsonAdapter for " + type.toString()
|
||||
@ -74,7 +76,7 @@ public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapte
|
||||
+ " JsonSerializer or JsonDeserializer.");
|
||||
}
|
||||
|
||||
if (typeAdapter != null && annotation.nullSafe()) {
|
||||
if (typeAdapter != null && nullSafe) {
|
||||
typeAdapter = typeAdapter.nullSafe();
|
||||
}
|
||||
|
||||
|
@ -45,17 +45,24 @@ public final class TreeTypeAdapter<T> extends TypeAdapter<T> {
|
||||
private final TypeToken<T> typeToken;
|
||||
private final TypeAdapterFactory skipPast;
|
||||
private final GsonContextImpl context = new GsonContextImpl();
|
||||
private final boolean nullSafe;
|
||||
|
||||
/** The delegate is lazily created because it may not be needed, and creating it may fail. */
|
||||
private volatile TypeAdapter<T> delegate;
|
||||
|
||||
public TreeTypeAdapter(JsonSerializer<T> serializer, JsonDeserializer<T> deserializer,
|
||||
Gson gson, TypeToken<T> typeToken, TypeAdapterFactory skipPast) {
|
||||
Gson gson, TypeToken<T> typeToken, TypeAdapterFactory skipPast, boolean nullSafe) {
|
||||
this.serializer = serializer;
|
||||
this.deserializer = deserializer;
|
||||
this.gson = gson;
|
||||
this.typeToken = typeToken;
|
||||
this.skipPast = skipPast;
|
||||
this.nullSafe = nullSafe;
|
||||
}
|
||||
|
||||
public TreeTypeAdapter(JsonSerializer<T> serializer, JsonDeserializer<T> deserializer,
|
||||
Gson gson, TypeToken<T> typeToken, TypeAdapterFactory skipPast) {
|
||||
this(serializer, deserializer, gson, typeToken, skipPast, true);
|
||||
}
|
||||
|
||||
@Override public T read(JsonReader in) throws IOException {
|
||||
@ -63,7 +70,7 @@ public final class TreeTypeAdapter<T> extends TypeAdapter<T> {
|
||||
return delegate().read(in);
|
||||
}
|
||||
JsonElement value = Streams.parse(in);
|
||||
if (value.isJsonNull()) {
|
||||
if (nullSafe && value.isJsonNull()) {
|
||||
return null;
|
||||
}
|
||||
return deserializer.deserialize(value, typeToken.getType(), context);
|
||||
@ -74,7 +81,7 @@ public final class TreeTypeAdapter<T> extends TypeAdapter<T> {
|
||||
delegate().write(out, value);
|
||||
return;
|
||||
}
|
||||
if (value == null) {
|
||||
if (nullSafe && value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
|
@ -161,4 +161,22 @@ public final class JsonAdapterSerializerDeserializerTest extends TestCase {
|
||||
return new JsonPrimitive("BaseIntegerAdapter");
|
||||
}
|
||||
}
|
||||
|
||||
public void testJsonAdapterNullSafe() {
|
||||
Gson gson = new Gson();
|
||||
String json = gson.toJson(new Computer3(null, null));
|
||||
assertEquals("{\"user1\":\"UserSerializerDeserializer\"}", json);
|
||||
Computer3 computer3 = gson.fromJson("{\"user1\":null, \"user2\":null}", Computer3.class);
|
||||
assertEquals("UserSerializerDeserializer", computer3.user1.name);
|
||||
assertNull(computer3.user2);
|
||||
}
|
||||
|
||||
private static final class Computer3 {
|
||||
@JsonAdapter(value = UserSerializerDeserializer.class, nullSafe = false) final User user1;
|
||||
@JsonAdapter(value = UserSerializerDeserializer.class) final User user2;
|
||||
Computer3(User user1, User user2) {
|
||||
this.user1 = user1;
|
||||
this.user2 = user2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user