Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
206 changes: 32 additions & 174 deletions gson/src/main/java/com/google/gson/Gson.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,18 @@

package com.google.gson;

import static com.google.gson.internal.bind.TypeAdapters.atomicLongAdapter;
import static com.google.gson.internal.bind.TypeAdapters.atomicLongArrayAdapter;
import static com.google.gson.GsonBuilder.newImmutableList;

import com.google.gson.annotations.JsonAdapter;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.Excluder;
import com.google.gson.internal.GsonBuildConfig;
import com.google.gson.internal.Primitives;
import com.google.gson.internal.Streams;
import com.google.gson.internal.bind.ArrayTypeAdapter;
import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
import com.google.gson.internal.bind.DefaultDateTypeAdapter;
import com.google.gson.internal.bind.JsonAdapterAnnotationTypeAdapterFactory;
import com.google.gson.internal.bind.JsonTreeReader;
import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.internal.bind.MapTypeAdapterFactory;
import com.google.gson.internal.bind.NumberTypeAdapter;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
import com.google.gson.internal.bind.SerializationDelegatingTypeAdapter;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.internal.sql.SqlTypesSupport;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
Expand All @@ -49,17 +39,12 @@
import java.io.StringReader;
import java.io.Writer;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;

/**
* This is the main class for using Gson. Gson is typically used by first constructing a Gson
Expand Down Expand Up @@ -149,21 +134,6 @@
*/
public final class Gson {

static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
// Strictness of `null` is the legacy mode where some Gson APIs are always lenient
static final Strictness DEFAULT_STRICTNESS = null;
static final FormattingStyle DEFAULT_FORMATTING_STYLE = FormattingStyle.COMPACT;
static final boolean DEFAULT_ESCAPE_HTML = true;
static final boolean DEFAULT_SERIALIZE_NULLS = false;
static final boolean DEFAULT_COMPLEX_MAP_KEYS = false;
static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false;
static final boolean DEFAULT_USE_JDK_UNSAFE = true;
static final String DEFAULT_DATE_PATTERN = null;
static final FieldNamingStrategy DEFAULT_FIELD_NAMING_STRATEGY = FieldNamingPolicy.IDENTITY;
static final ToNumberStrategy DEFAULT_OBJECT_TO_NUMBER_STRATEGY = ToNumberPolicy.DOUBLE;
static final ToNumberStrategy DEFAULT_NUMBER_TO_NUMBER_STRATEGY =
ToNumberPolicy.LAZILY_PARSED_NUMBER;

private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";

/**
Expand Down Expand Up @@ -250,144 +220,40 @@ public final class Gson {
* </ul>
*/
public Gson() {
this(
Excluder.DEFAULT,
DEFAULT_FIELD_NAMING_STRATEGY,
Collections.emptyMap(),
DEFAULT_SERIALIZE_NULLS,
DEFAULT_COMPLEX_MAP_KEYS,
DEFAULT_JSON_NON_EXECUTABLE,
DEFAULT_ESCAPE_HTML,
DEFAULT_FORMATTING_STYLE,
DEFAULT_STRICTNESS,
DEFAULT_SPECIALIZE_FLOAT_VALUES,
DEFAULT_USE_JDK_UNSAFE,
LongSerializationPolicy.DEFAULT,
DEFAULT_DATE_PATTERN,
DateFormat.DEFAULT,
DateFormat.DEFAULT,
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(),
DEFAULT_OBJECT_TO_NUMBER_STRATEGY,
DEFAULT_NUMBER_TO_NUMBER_STRATEGY,
Collections.emptyList());
this(GsonBuilder.DEFAULT);
}

Gson(
Excluder excluder,
FieldNamingStrategy fieldNamingStrategy,
Map<Type, InstanceCreator<?>> instanceCreators,
boolean serializeNulls,
boolean complexMapKeySerialization,
boolean generateNonExecutableGson,
boolean htmlSafe,
FormattingStyle formattingStyle,
Strictness strictness,
boolean serializeSpecialFloatingPointValues,
boolean useJdkUnsafe,
LongSerializationPolicy longSerializationPolicy,
String datePattern,
int dateStyle,
int timeStyle,
List<TypeAdapterFactory> builderFactories,
List<TypeAdapterFactory> builderHierarchyFactories,
List<TypeAdapterFactory> factoriesToBeAdded,
ToNumberStrategy objectToNumberStrategy,
ToNumberStrategy numberToNumberStrategy,
List<ReflectionAccessFilter> reflectionFilters) {
this.excluder = excluder;
this.fieldNamingStrategy = fieldNamingStrategy;
this.instanceCreators = instanceCreators;
this.constructorConstructor =
new ConstructorConstructor(instanceCreators, useJdkUnsafe, reflectionFilters);
this.serializeNulls = serializeNulls;
this.complexMapKeySerialization = complexMapKeySerialization;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.formattingStyle = formattingStyle;
this.strictness = strictness;
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
this.useJdkUnsafe = useJdkUnsafe;
this.longSerializationPolicy = longSerializationPolicy;
this.datePattern = datePattern;
this.dateStyle = dateStyle;
this.timeStyle = timeStyle;
this.builderFactories = builderFactories;
this.builderHierarchyFactories = builderHierarchyFactories;
this.objectToNumberStrategy = objectToNumberStrategy;
this.numberToNumberStrategy = numberToNumberStrategy;
this.reflectionFilters = reflectionFilters;

List<TypeAdapterFactory> factories = new ArrayList<>();

// built-in type adapters that cannot be overridden
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.getFactory(objectToNumberStrategy));

// the excluder must precede all adapters that handle user-defined types
factories.add(excluder);

// users' type adapters
factories.addAll(factoriesToBeAdded);

// type adapters for basic platform types
factories.add(TypeAdapters.STRING_FACTORY);
factories.add(TypeAdapters.INTEGER_FACTORY);
factories.add(TypeAdapters.BOOLEAN_FACTORY);
factories.add(TypeAdapters.BYTE_FACTORY);
factories.add(TypeAdapters.SHORT_FACTORY);
TypeAdapter<Number> longAdapter = longSerializationPolicy.typeAdapter();
factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
factories.add(TypeAdapters.newFactory(double.class, Double.class, doubleAdapter()));
factories.add(TypeAdapters.newFactory(float.class, Float.class, floatAdapter()));
factories.add(NumberTypeAdapter.getFactory(numberToNumberStrategy));
factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
factories.add(
TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
factories.add(TypeAdapters.CHARACTER_FACTORY);
factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
factories.add(TypeAdapters.BIG_DECIMAL_FACTORY);
factories.add(TypeAdapters.BIG_INTEGER_FACTORY);
// Add adapter for LazilyParsedNumber because user can obtain it from Gson and then try to
// serialize it again
factories.add(TypeAdapters.LAZILY_PARSED_NUMBER_FACTORY);
factories.add(TypeAdapters.URL_FACTORY);
factories.add(TypeAdapters.URI_FACTORY);
factories.add(TypeAdapters.UUID_FACTORY);
factories.add(TypeAdapters.CURRENCY_FACTORY);
factories.add(TypeAdapters.LOCALE_FACTORY);
factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
factories.add(TypeAdapters.BIT_SET_FACTORY);
factories.add(DefaultDateTypeAdapter.DEFAULT_STYLE_FACTORY);
factories.add(TypeAdapters.CALENDAR_FACTORY);
factories.addAll(SqlTypesSupport.SQL_TYPE_FACTORIES);
TypeAdapterFactory javaTimeFactory = TypeAdapters.javaTimeTypeAdapterFactory();
if (javaTimeFactory != null) {
factories.add(javaTimeFactory);
Gson(GsonBuilder builder) {
this.excluder = builder.excluder;
this.fieldNamingStrategy = builder.fieldNamingPolicy;
this.instanceCreators = new HashMap<>(builder.instanceCreators);
this.serializeNulls = builder.serializeNulls;
this.complexMapKeySerialization = builder.complexMapKeySerialization;
this.generateNonExecutableJson = builder.generateNonExecutableJson;
this.htmlSafe = builder.escapeHtmlChars;
this.formattingStyle = builder.formattingStyle;
this.strictness = builder.strictness;
this.serializeSpecialFloatingPointValues = builder.serializeSpecialFloatingPointValues;
this.useJdkUnsafe = builder.useJdkUnsafe;
this.longSerializationPolicy = builder.longSerializationPolicy;
this.datePattern = builder.datePattern;
this.dateStyle = builder.dateStyle;
this.timeStyle = builder.timeStyle;
this.builderFactories = newImmutableList(builder.factories);
this.builderHierarchyFactories = newImmutableList(builder.hierarchyFactories);
this.objectToNumberStrategy = builder.objectToNumberStrategy;
this.numberToNumberStrategy = builder.numberToNumberStrategy;
this.reflectionFilters = newImmutableList(builder.reflectionFilters);
if (builder == GsonBuilder.DEFAULT) {
this.constructorConstructor = GsonBuilder.DEFAULT_CONSTRUCTOR_CONSTRUCTOR;
this.jsonAdapterFactory = GsonBuilder.DEFAULT_JSON_ADAPTER_ANNOTATION_TYPE_ADAPTER_FACTORY;
this.factories = GsonBuilder.DEFAULT_TYPE_ADAPTER_FACTORIES;
} else {
this.constructorConstructor =
new ConstructorConstructor(instanceCreators, useJdkUnsafe, reflectionFilters);
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
this.factories = builder.createFactories(constructorConstructor, jsonAdapterFactory);
}
factories.add(ArrayTypeAdapter.FACTORY);
factories.add(TypeAdapters.CLASS_FACTORY);

// type adapters for composite and user-defined types
factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(
new ReflectiveTypeAdapterFactory(
constructorConstructor,
fieldNamingStrategy,
excluder,
jsonAdapterFactory,
reflectionFilters));

this.factories = Collections.unmodifiableList(factories);
}

/**
Expand Down Expand Up @@ -439,14 +305,6 @@ public boolean htmlSafe() {
return htmlSafe;
}

private TypeAdapter<Number> floatAdapter() {
return serializeSpecialFloatingPointValues ? TypeAdapters.FLOAT : TypeAdapters.FLOAT_STRICT;
}

private TypeAdapter<Number> doubleAdapter() {
return serializeSpecialFloatingPointValues ? TypeAdapters.DOUBLE : TypeAdapters.DOUBLE_STRICT;
}

/**
* Returns the type adapter for {@code type}.
*
Expand Down
Loading