Add newBuilder() API (#1142)
* Add Gson.newBuilder API. * Remove redundant test. * Address Codacy comments. * Reduce visibility of GsonBuilder constructor.
This commit is contained in:
parent
a8f7acd618
commit
08bbb226f1
|
@ -25,6 +25,7 @@ import java.io.Writer;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -124,18 +125,28 @@ public final class Gson {
|
||||||
|
|
||||||
private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>();
|
private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>();
|
||||||
|
|
||||||
private final List<TypeAdapterFactory> factories;
|
|
||||||
private final ConstructorConstructor constructorConstructor;
|
private final ConstructorConstructor constructorConstructor;
|
||||||
|
|
||||||
private final Excluder excluder;
|
|
||||||
private final FieldNamingStrategy fieldNamingStrategy;
|
|
||||||
private final boolean serializeNulls;
|
|
||||||
private final boolean htmlSafe;
|
|
||||||
private final boolean generateNonExecutableJson;
|
|
||||||
private final boolean prettyPrinting;
|
|
||||||
private final boolean lenient;
|
|
||||||
private final JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory;
|
private final JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory;
|
||||||
|
|
||||||
|
final List<TypeAdapterFactory> factories;
|
||||||
|
|
||||||
|
final Excluder excluder;
|
||||||
|
final FieldNamingStrategy fieldNamingStrategy;
|
||||||
|
final Map<Type, InstanceCreator<?>> instanceCreators;
|
||||||
|
final boolean serializeNulls;
|
||||||
|
final boolean complexMapKeySerialization;
|
||||||
|
final boolean generateNonExecutableJson;
|
||||||
|
final boolean htmlSafe;
|
||||||
|
final boolean prettyPrinting;
|
||||||
|
final boolean lenient;
|
||||||
|
final boolean serializeSpecialFloatingPointValues;
|
||||||
|
final String datePattern;
|
||||||
|
final int dateStyle;
|
||||||
|
final int timeStyle;
|
||||||
|
final LongSerializationPolicy longSerializationPolicy;
|
||||||
|
final List<TypeAdapterFactory> builderFactories;
|
||||||
|
final List<TypeAdapterFactory> builderHierarchyFactories;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a Gson object with default configuration. The default configuration has the
|
* Constructs a Gson object with default configuration. The default configuration has the
|
||||||
* following settings:
|
* following settings:
|
||||||
|
@ -175,23 +186,36 @@ public final class Gson {
|
||||||
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
|
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
|
||||||
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
|
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
|
||||||
DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
|
DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
|
||||||
LongSerializationPolicy.DEFAULT, Collections.<TypeAdapterFactory>emptyList());
|
LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT, DateFormat.DEFAULT,
|
||||||
|
Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
|
||||||
|
Collections.<TypeAdapterFactory>emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
|
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
|
||||||
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
|
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
|
||||||
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
|
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
|
||||||
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
|
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
|
||||||
LongSerializationPolicy longSerializationPolicy,
|
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
|
||||||
List<TypeAdapterFactory> typeAdapterFactories) {
|
int timeStyle, List<TypeAdapterFactory> builderFactories,
|
||||||
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
List<TypeAdapterFactory> builderHierarchyFactories,
|
||||||
|
List<TypeAdapterFactory> factoriesToBeAdded) {
|
||||||
this.excluder = excluder;
|
this.excluder = excluder;
|
||||||
this.fieldNamingStrategy = fieldNamingStrategy;
|
this.fieldNamingStrategy = fieldNamingStrategy;
|
||||||
|
this.instanceCreators = instanceCreators;
|
||||||
|
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
||||||
this.serializeNulls = serializeNulls;
|
this.serializeNulls = serializeNulls;
|
||||||
|
this.complexMapKeySerialization = complexMapKeySerialization;
|
||||||
this.generateNonExecutableJson = generateNonExecutableGson;
|
this.generateNonExecutableJson = generateNonExecutableGson;
|
||||||
this.htmlSafe = htmlSafe;
|
this.htmlSafe = htmlSafe;
|
||||||
this.prettyPrinting = prettyPrinting;
|
this.prettyPrinting = prettyPrinting;
|
||||||
this.lenient = lenient;
|
this.lenient = lenient;
|
||||||
|
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
|
||||||
|
this.longSerializationPolicy = longSerializationPolicy;
|
||||||
|
this.datePattern = datePattern;
|
||||||
|
this.dateStyle = dateStyle;
|
||||||
|
this.timeStyle = timeStyle;
|
||||||
|
this.builderFactories = builderFactories;
|
||||||
|
this.builderHierarchyFactories = builderHierarchyFactories;
|
||||||
|
|
||||||
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||||
|
|
||||||
|
@ -202,8 +226,8 @@ public final class Gson {
|
||||||
// the excluder must precede all adapters that handle user-defined types
|
// the excluder must precede all adapters that handle user-defined types
|
||||||
factories.add(excluder);
|
factories.add(excluder);
|
||||||
|
|
||||||
// user's type adapters
|
// users' type adapters
|
||||||
factories.addAll(typeAdapterFactories);
|
factories.addAll(factoriesToBeAdded);
|
||||||
|
|
||||||
// type adapters for basic platform types
|
// type adapters for basic platform types
|
||||||
factories.add(TypeAdapters.STRING_FACTORY);
|
factories.add(TypeAdapters.STRING_FACTORY);
|
||||||
|
@ -255,6 +279,16 @@ public final class Gson {
|
||||||
this.factories = Collections.unmodifiableList(factories);
|
this.factories = Collections.unmodifiableList(factories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new GsonBuilder containing all custom factories and configuration used by the current
|
||||||
|
* instance.
|
||||||
|
*
|
||||||
|
* @return a GsonBuilder instance.
|
||||||
|
*/
|
||||||
|
public GsonBuilder newBuilder() {
|
||||||
|
return new GsonBuilder(this);
|
||||||
|
}
|
||||||
|
|
||||||
public Excluder excluder() {
|
public Excluder excluder() {
|
||||||
return excluder;
|
return excluder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,31 @@ public final class GsonBuilder {
|
||||||
public GsonBuilder() {
|
public GsonBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a GsonBuilder instance from a Gson instance. The newly constructed GsonBuilder
|
||||||
|
* has the same configuration as the previously built Gson instance.
|
||||||
|
*
|
||||||
|
* @param gson the gson instance whose configuration should by applied to a new GsonBuilder.
|
||||||
|
*/
|
||||||
|
GsonBuilder(Gson gson) {
|
||||||
|
this.excluder = gson.excluder;
|
||||||
|
this.fieldNamingPolicy = gson.fieldNamingStrategy;
|
||||||
|
this.instanceCreators.putAll(gson.instanceCreators);
|
||||||
|
this.serializeNulls = gson.serializeNulls;
|
||||||
|
this.complexMapKeySerialization = gson.complexMapKeySerialization;
|
||||||
|
this.generateNonExecutableJson = gson.generateNonExecutableJson;
|
||||||
|
this.escapeHtmlChars = gson.htmlSafe;
|
||||||
|
this.prettyPrinting = gson.prettyPrinting;
|
||||||
|
this.lenient = gson.lenient;
|
||||||
|
this.serializeSpecialFloatingPointValues = gson.serializeSpecialFloatingPointValues;
|
||||||
|
this.longSerializationPolicy = gson.longSerializationPolicy;
|
||||||
|
this.datePattern = gson.datePattern;
|
||||||
|
this.dateStyle = gson.dateStyle;
|
||||||
|
this.timeStyle = gson.timeStyle;
|
||||||
|
this.factories.addAll(gson.builderFactories);
|
||||||
|
this.hierarchyFactories.addAll(gson.builderHierarchyFactories);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures Gson to enable versioning support.
|
* Configures Gson to enable versioning support.
|
||||||
*
|
*
|
||||||
|
@ -572,7 +597,9 @@ public final class GsonBuilder {
|
||||||
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
|
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
|
||||||
serializeNulls, complexMapKeySerialization,
|
serializeNulls, complexMapKeySerialization,
|
||||||
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
|
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
|
||||||
serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
|
serializeSpecialFloatingPointValues, longSerializationPolicy,
|
||||||
|
datePattern, dateStyle, timeStyle,
|
||||||
|
this.factories, this.hierarchyFactories, factories);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -17,8 +17,12 @@
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.internal.Excluder;
|
import com.google.gson.internal.Excluder;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
@ -43,12 +47,34 @@ public final class GsonTest extends TestCase {
|
||||||
public void testOverridesDefaultExcluder() {
|
public void testOverridesDefaultExcluder() {
|
||||||
Gson gson = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
|
Gson gson = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
|
||||||
new HashMap<Type, InstanceCreator<?>>(), true, false, true, false,
|
new HashMap<Type, InstanceCreator<?>>(), true, false, true, false,
|
||||||
true, true, false, LongSerializationPolicy.DEFAULT,
|
true, true, false, LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
|
||||||
new ArrayList<TypeAdapterFactory>());
|
DateFormat.DEFAULT, new ArrayList<TypeAdapterFactory>(),
|
||||||
|
new ArrayList<TypeAdapterFactory>(), new ArrayList<TypeAdapterFactory>());
|
||||||
|
|
||||||
assertEquals(CUSTOM_EXCLUDER, gson.excluder());
|
assertEquals(CUSTOM_EXCLUDER, gson.excluder());
|
||||||
assertEquals(CUSTOM_FIELD_NAMING_STRATEGY, gson.fieldNamingStrategy());
|
assertEquals(CUSTOM_FIELD_NAMING_STRATEGY, gson.fieldNamingStrategy());
|
||||||
assertEquals(true, gson.serializeNulls());
|
assertEquals(true, gson.serializeNulls());
|
||||||
assertEquals(false, gson.htmlSafe());
|
assertEquals(false, gson.htmlSafe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testClonedTypeAdapterFactoryListsAreIndependent() {
|
||||||
|
Gson original = new Gson(CUSTOM_EXCLUDER, CUSTOM_FIELD_NAMING_STRATEGY,
|
||||||
|
new HashMap<Type, InstanceCreator<?>>(), true, false, true, false,
|
||||||
|
true, true, false, LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT,
|
||||||
|
DateFormat.DEFAULT, new ArrayList<TypeAdapterFactory>(),
|
||||||
|
new ArrayList<TypeAdapterFactory>(), new ArrayList<TypeAdapterFactory>());
|
||||||
|
|
||||||
|
Gson clone = original.newBuilder()
|
||||||
|
.registerTypeAdapter(Object.class, new TestTypeAdapter())
|
||||||
|
.create();
|
||||||
|
|
||||||
|
assertEquals(original.factories.size() + 1, clone.factories.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class TestTypeAdapter extends TypeAdapter<Object> {
|
||||||
|
@Override public void write(JsonWriter out, Object value) throws IOException {
|
||||||
|
// Test stub.
|
||||||
|
}
|
||||||
|
@Override public Object read(JsonReader in) throws IOException { return null; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user