Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue#2436: Throw exception when registering adapter for Object or JsonElement #2479

Merged
merged 18 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
15a11a9
Code changes and tests for #2436 to throw exception when trying to re…
Aug 21, 2023
0218548
#2436 - Updates to User guide & comments to indicate exception cases …
Aug 25, 2023
0701f89
Merge branch 'main' into feature/issue#2436_enhancement
sachinp97 Aug 25, 2023
f96af9b
#2436 - Fixes as per the review comments.
Aug 28, 2023
840b0b3
Merge branch 'google:main' into feature/issue#2436_enhancement
sachinp97 Aug 28, 2023
4c04356
Merge branch 'feature/issue#2436_enhancement' of https://github.com/s…
Aug 28, 2023
11b97ea
Merge branch 'main' into feature/issue#2436_enhancement
sachinp97 Sep 12, 2023
7fca65d
Merge branch 'main' into feature/issue#2436_enhancement
sachinp97 Sep 12, 2023
d9f42d8
#2436 - Refactored as per latest review comments + throwing error mes…
sachinp97 Sep 16, 2023
02605d2
Merge branch 'feature/issue#2436_enhancement' of https://github.com/s…
sachinp97 Sep 16, 2023
5c0ea74
#2436 - added a clarifying comment in a positive test case.
sachinp97 Sep 16, 2023
263a918
#2436 - formatting and minor changes as per review.
sachinp97 Sep 24, 2023
cc01665
Merge branch 'main' into feature/issue#2436_enhancement
sachinp97 Sep 24, 2023
d853261
Update gson/src/main/java/com/google/gson/GsonBuilder.java
sachinp97 Sep 29, 2023
d9025c8
Update gson/src/test/java/com/google/gson/GsonBuilderTest.java
sachinp97 Sep 29, 2023
ba40b41
Update gson/src/test/java/com/google/gson/GsonBuilderTest.java
sachinp97 Sep 29, 2023
a068738
Merge branch 'main' into feature/issue#2436_enhancement
sachinp97 Sep 29, 2023
fcf2551
Merge branch 'main' into feature/issue#2436_enhancement
sachinp97 Oct 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,9 @@ gson.registerTypeAdapter(MyType.class, new MyDeserializer());
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());
```

`registerTypeAdapter` call checks if the type adapter implements more than one of these interfaces and register it for all of them.
`registerTypeAdapter` call checks
1. if the type adapter implements more than one of these interfaces and register it for all of them.
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
2. if the type adapter is for Object class or (JsonElements or any of its subclasses), it throws IllegalArgumentException.
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved

#### Writing a Serializer

Expand Down
22 changes: 17 additions & 5 deletions gson/src/main/java/com/google/gson/GsonBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.ArrayDeque;
Expand Down Expand Up @@ -337,7 +339,7 @@ public GsonBuilder enableComplexMapKeySerialization() {
*
* <p>In general using inner classes with Gson should be avoided; they should be converted to {@code static}
* nested classes if possible.
*
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
*Ø
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.3
*/
Expand Down Expand Up @@ -664,14 +666,16 @@ public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
* @param typeAdapter This object must implement at least one of the {@link TypeAdapter},
* {@link InstanceCreator}, {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @throws IllegalArgumentException if the Type adapter being registered is for Object class or (JsonElements or any of its subclasses)
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
*/
@CanIgnoreReturnValue
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
Objects.requireNonNull(type);
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
$Gson$Preconditions.checkArgument((typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?>
|| typeAdapter instanceof InstanceCreator<?>
|| typeAdapter instanceof TypeAdapter<?>);
|| typeAdapter instanceof TypeAdapter<?>)
&& !isTypeObjectOrJsonElements(type));
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
if (typeAdapter instanceof InstanceCreator<?>) {
instanceCreators.put(type, (InstanceCreator<?>) typeAdapter);
}
Expand All @@ -687,6 +691,12 @@ public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
return this;
}

private boolean isTypeObjectOrJsonElements(Type type) {
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
return (!(type instanceof ParameterizedType) &&
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
(type == Object.class
|| JsonElement.class.isAssignableFrom((Class<?>) type)));
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Register a factory for type adapters. Registering a factory is useful when the type
* adapter needs to be configured based on the type of the field being processed. Gson
Expand Down Expand Up @@ -718,14 +728,16 @@ public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
* @param typeAdapter This object must implement at least one of {@link TypeAdapter},
* {@link JsonSerializer} or {@link JsonDeserializer} interfaces.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @throws IllegalArgumentException if the Type adapter being registered is for a JsonElements or any of its subclasses
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
* @since 1.7
*/
@CanIgnoreReturnValue
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
Objects.requireNonNull(baseType);
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
$Gson$Preconditions.checkArgument((typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?>
|| typeAdapter instanceof TypeAdapter<?>);
|| typeAdapter instanceof TypeAdapter<?>)
&& !JsonElement.class.isAssignableFrom(baseType));
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
if (typeAdapter instanceof JsonDeserializer || typeAdapter instanceof JsonSerializer) {
hierarchyFactories.add(TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
}
Expand Down
29 changes: 29 additions & 0 deletions gson/src/test/java/com/google/gson/GsonBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.gson;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import com.google.gson.stream.JsonReader;
Expand Down Expand Up @@ -254,4 +255,32 @@ public void testSetStrictness() throws IOException {
assertThat(gson.newJsonReader(new StringReader("{}")).getStrictness()).isEqualTo(STRICTNESS);
assertThat(gson.newJsonWriter(new StringWriter()).getStrictness()).isEqualTo(STRICTNESS);
}

@Test
public void testRegisterTypeAdapterForObjectAndJsonElements() {
Type[] types = {
Object.class,
JsonElement.class,
JsonArray.class,
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
};
GsonBuilder gsonBuilder = new GsonBuilder();
for (Type type : types) {
assertThrows(IllegalArgumentException.class, () -> gsonBuilder.registerTypeAdapter(type, NULL_TYPE_ADAPTER));
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
}
}


@Test
public void testRegisterTypeHierarchyAdapterJsonElements() {
Type[] types = {
JsonElement.class,
JsonArray.class,
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
};
GsonBuilder gsonBuilder = new GsonBuilder();
for (Type type : types) {
assertThrows(IllegalArgumentException.class,
() -> gsonBuilder.registerTypeHierarchyAdapter((Class<?>) type, NULL_TYPE_ADAPTER));
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
}
gsonBuilder.registerTypeHierarchyAdapter(Object.class, NULL_TYPE_ADAPTER);
sachinp97 marked this conversation as resolved.
Show resolved Hide resolved
}
}
2 changes: 1 addition & 1 deletion gson/src/test/java/com/google/gson/GsonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void testClonedTypeAdapterFactoryListsAreIndependent() {
Collections.<ReflectionAccessFilter>emptyList());

Gson clone = original.newBuilder()
.registerTypeAdapter(Object.class, new TestTypeAdapter())
.registerTypeAdapter(int.class, new TestTypeAdapter())
.create();

assertThat(clone.factories).hasSize(original.factories.size() + 1);
Expand Down