Skip to content

Commit

Permalink
Add NullSafeTypeAdapter to prevent TypeAdapter.nullSafe()
Browse files Browse the repository at this point in the history
from returning nested null-safe type adapters (#2729)
  • Loading branch information
lyubomyr-shaydariv committed Aug 30, 2024
1 parent 93596da commit 48627de
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 16 deletions.
37 changes: 21 additions & 16 deletions gson/src/main/java/com/google/gson/TypeAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -289,24 +289,29 @@ public final T fromJsonTree(JsonElement jsonTree) {
* Note that we didn't need to check for nulls in our type adapter after we used nullSafe.
*/
public final TypeAdapter<T> nullSafe() {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
TypeAdapter.this.write(out, value);
}
if (!NullSafeTypeAdapter.class.isInstance(this)) {
return new NullSafeTypeAdapter();
}
return this;
}

private final class NullSafeTypeAdapter extends TypeAdapter<T> {
@Override
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
TypeAdapter.this.write(out, value);
}
}

@Override
public T read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
return TypeAdapter.this.read(reader);
@Override
public T read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
};
return TypeAdapter.this.read(reader);
}
}
}
21 changes: 21 additions & 0 deletions gson/src/test/java/com/google/gson/TypeAdapterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ public String read(JsonReader in) {
assertThat(adapter.fromJson("null")).isNull();
}

@Test
public void testNullSafe_ReturningNotNestedNullSafeTypeAdapter() throws IOException {
TypeAdapter<String> adapter =
new TypeAdapter<String>() {
@Override
public void write(JsonWriter out, String value) {
throw new AssertionError("unexpected call");
}

@Override
public String read(JsonReader in) {
throw new AssertionError("unexpected call");
}
}.nullSafe();
TypeAdapter<?> nullSafeAdapter = adapter.nullSafe();

assertThat(adapter.toJson(null)).isEqualTo("null");
assertThat(adapter.fromJson("null")).isNull();
assertThat(nullSafeAdapter.nullSafe()).isSameInstanceAs(nullSafeAdapter);
}

/**
* Tests behavior when {@link TypeAdapter#write(JsonWriter, Object)} manually throws {@link
* IOException} which is not caused by writer usage.
Expand Down

0 comments on commit 48627de

Please sign in to comment.