diff --git a/extras/src/main/java/com/google/gson/graph/GraphAdapterBuilder.java b/extras/src/main/java/com/google/gson/graph/GraphAdapterBuilder.java index d158def78d..b9107dbacf 100644 --- a/extras/src/main/java/com/google/gson/graph/GraphAdapterBuilder.java +++ b/extras/src/main/java/com/google/gson/graph/GraphAdapterBuilder.java @@ -76,7 +76,7 @@ public final class GraphAdapterBuilder { public GraphAdapterBuilder() { this.instanceCreators = new HashMap<>(); this.constructorConstructor = - new ConstructorConstructor(instanceCreators, true, Collections.emptyList()); + new ConstructorConstructor(Collections.emptyMap(), true, Collections.emptyList()); } /** @@ -121,6 +121,8 @@ public GraphAdapterBuilder addType(Type type, InstanceCreator instanceCreator * @param gsonBuilder the {@code GsonBuilder} on which to register the graph adapter */ public void registerOn(GsonBuilder gsonBuilder) { + // Create copy to allow reusing GraphAdapterBuilder without affecting adapter factory + Map> instanceCreators = new HashMap<>(this.instanceCreators); Factory factory = new Factory(instanceCreators); gsonBuilder.registerTypeAdapterFactory(factory); for (Map.Entry> entry : instanceCreators.entrySet()) { diff --git a/extras/src/test/java/com/google/gson/graph/GraphAdapterBuilderTest.java b/extras/src/test/java/com/google/gson/graph/GraphAdapterBuilderTest.java index 9c79130d0d..90612a0163 100644 --- a/extras/src/test/java/com/google/gson/graph/GraphAdapterBuilderTest.java +++ b/extras/src/test/java/com/google/gson/graph/GraphAdapterBuilderTest.java @@ -80,6 +80,51 @@ public void testDeserializationDirectSelfReference() { assertThat(suicide.beats).isSameInstanceAs(suicide); } + @Test + public void testAddTypeCustomInstanceCreator() { + GsonBuilder gsonBuilder = new GsonBuilder(); + new GraphAdapterBuilder() + .addType(Company.class, type -> new Company("custom")) + .addType(Employee.class) + .registerOn(gsonBuilder); + Gson gson = gsonBuilder.create(); + + Company company = + gson.fromJson( + "{'0x1':{'employees':['0x2']},'0x2':{'name':'Jesse','company':'0x1'}}", Company.class); + assertThat(company.name).isEqualTo("custom"); + Employee employee = company.employees.get(0); + assertThat(employee.name).isEqualTo("Jesse"); + assertThat(employee.company).isSameInstanceAs(company); + } + + @Test + public void testAddTypeOverwrite() { + GsonBuilder gsonBuilder = new GsonBuilder(); + new GraphAdapterBuilder() + .addType(Company.class, type -> new Company("custom")) + // Overwrite Company creator with different custom one + .addType(Company.class, type -> new Company("custom-2")) + .addType(Employee.class) + .registerOn(gsonBuilder); + Gson gson = gsonBuilder.create(); + + Company company = gson.fromJson("{'0x1':{}}", Company.class); + assertThat(company.name).isEqualTo("custom-2"); + + gsonBuilder = new GsonBuilder(); + new GraphAdapterBuilder() + .addType(Company.class, type -> new Company("custom")) + // Overwrite Company creator with default one + .addType(Company.class) + .addType(Employee.class) + .registerOn(gsonBuilder); + gson = gsonBuilder.create(); + + company = gson.fromJson("{'0x1':{}}", Company.class); + assertThat(company.name).isNull(); + } + @Test public void testSerializeListOfLists() { Type listOfListsType = new TypeToken>>() {}.getType(); @@ -156,10 +201,37 @@ public void testDeserializationWithMultipleTypes() { assertThat(company.name).isEqualTo("Google"); Employee jesse = company.employees.get(0); assertThat(jesse.name).isEqualTo("Jesse"); - assertThat(jesse.company).isEqualTo(company); + assertThat(jesse.company).isSameInstanceAs(company); Employee joel = company.employees.get(1); assertThat(joel.name).isEqualTo("Joel"); - assertThat(joel.company).isEqualTo(company); + assertThat(joel.company).isSameInstanceAs(company); + } + + @Test + public void testBuilderReuse() { + GsonBuilder gsonBuilder = new GsonBuilder(); + GraphAdapterBuilder graphAdapterBuilder = + new GraphAdapterBuilder() + .addType(Company.class, type -> new Company("custom")) + .addType(Employee.class); + graphAdapterBuilder.registerOn(gsonBuilder); + Gson gson = gsonBuilder.create(); + + Company company = gson.fromJson("{'0x1':{}}", Company.class); + assertThat(company.name).isEqualTo("custom"); + + GsonBuilder gsonBuilder2 = new GsonBuilder(); + // Reuse builder and overwrite creator + graphAdapterBuilder.addType(Company.class, type -> new Company("custom-2")); + graphAdapterBuilder.registerOn(gsonBuilder2); + Gson gson2 = gsonBuilder2.create(); + + company = gson2.fromJson("{'0x1':{}}", Company.class); + assertThat(company.name).isEqualTo("custom-2"); + + // But first adapter should not have been affected + company = gson.fromJson("{'0x1':{}}", Company.class); + assertThat(company.name).isEqualTo("custom"); } static class Roshambo {