2008-09-01 05:13:32 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008 Google Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package com.google.gson;
|
|
|
|
|
|
|
|
import java.lang.reflect.Type;
|
2011-03-29 23:36:19 +02:00
|
|
|
import java.sql.Timestamp;
|
2008-09-01 05:13:32 +02:00
|
|
|
import java.text.DateFormat;
|
2011-09-28 21:14:46 +02:00
|
|
|
import java.util.ArrayList;
|
2011-12-06 06:09:18 +01:00
|
|
|
import java.util.Collections;
|
2008-09-01 05:13:32 +02:00
|
|
|
import java.util.Date;
|
2011-11-23 07:16:55 +01:00
|
|
|
import java.util.HashMap;
|
2008-09-01 05:13:32 +02:00
|
|
|
import java.util.List;
|
2011-11-23 07:16:55 +01:00
|
|
|
import java.util.Map;
|
2008-09-01 05:13:32 +02:00
|
|
|
|
2011-11-25 06:40:17 +01:00
|
|
|
import com.google.gson.internal.$Gson$Preconditions;
|
|
|
|
import com.google.gson.internal.Excluder;
|
2016-03-28 23:46:02 +02:00
|
|
|
import com.google.gson.internal.bind.TreeTypeAdapter;
|
2011-11-25 06:40:17 +01:00
|
|
|
import com.google.gson.internal.bind.TypeAdapters;
|
|
|
|
import com.google.gson.reflect.TypeToken;
|
2017-03-17 05:16:38 +01:00
|
|
|
import com.google.gson.stream.JsonReader;
|
2011-11-25 06:40:17 +01:00
|
|
|
|
2016-01-17 09:03:04 +01:00
|
|
|
import static com.google.gson.Gson.DEFAULT_COMPLEX_MAP_KEYS;
|
|
|
|
import static com.google.gson.Gson.DEFAULT_ESCAPE_HTML;
|
|
|
|
import static com.google.gson.Gson.DEFAULT_JSON_NON_EXECUTABLE;
|
|
|
|
import static com.google.gson.Gson.DEFAULT_LENIENT;
|
|
|
|
import static com.google.gson.Gson.DEFAULT_PRETTY_PRINT;
|
|
|
|
import static com.google.gson.Gson.DEFAULT_SERIALIZE_NULLS;
|
|
|
|
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
|
|
|
|
2008-09-01 05:13:32 +02:00
|
|
|
/**
|
|
|
|
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
|
|
|
|
* options other than the default. For {@link Gson} with default configuration, it is simpler to
|
|
|
|
* use {@code new Gson()}. {@code GsonBuilder} is best used by creating it, and then invoking its
|
|
|
|
* various configuration methods, and finally calling create.</p>
|
|
|
|
*
|
|
|
|
* <p>The following is an example shows how to use the {@code GsonBuilder} to construct a Gson
|
|
|
|
* instance:
|
|
|
|
*
|
|
|
|
* <pre>
|
|
|
|
* Gson gson = new GsonBuilder()
|
|
|
|
* .registerTypeAdapter(Id.class, new IdTypeAdapter())
|
2011-03-16 08:05:24 +01:00
|
|
|
* .enableComplexMapKeySerialization()
|
2008-09-01 05:13:32 +02:00
|
|
|
* .serializeNulls()
|
|
|
|
* .setDateFormat(DateFormat.LONG)
|
|
|
|
* .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
|
|
|
|
* .setPrettyPrinting()
|
|
|
|
* .setVersion(1.0)
|
|
|
|
* .create();
|
|
|
|
* </pre></p>
|
|
|
|
*
|
2011-04-06 02:35:05 +02:00
|
|
|
* <p>NOTES:
|
|
|
|
* <ul>
|
|
|
|
* <li> the order of invocation of configuration methods does not matter.</li>
|
|
|
|
* <li> The default serialization of {@link Date} and its subclasses in Gson does
|
|
|
|
* not contain time-zone information. So, if you are using date/time instances,
|
2011-04-11 20:09:59 +02:00
|
|
|
* use {@code GsonBuilder} and its {@code setDateFormat} methods.</li>
|
|
|
|
* </ul>
|
2011-04-06 02:35:05 +02:00
|
|
|
* </p>
|
2008-09-01 05:13:32 +02:00
|
|
|
*
|
|
|
|
* @author Inderjeet Singh
|
|
|
|
* @author Joel Leitch
|
2011-11-23 10:26:44 +01:00
|
|
|
* @author Jesse Wilson
|
2008-09-01 05:13:32 +02:00
|
|
|
*/
|
|
|
|
public final class GsonBuilder {
|
2011-11-22 08:37:13 +01:00
|
|
|
private Excluder excluder = Excluder.DEFAULT;
|
2011-11-23 07:16:55 +01:00
|
|
|
private LongSerializationPolicy longSerializationPolicy = LongSerializationPolicy.DEFAULT;
|
|
|
|
private FieldNamingStrategy fieldNamingPolicy = FieldNamingPolicy.IDENTITY;
|
|
|
|
private final Map<Type, InstanceCreator<?>> instanceCreators
|
|
|
|
= new HashMap<Type, InstanceCreator<?>>();
|
2011-12-23 19:27:13 +01:00
|
|
|
private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
2011-11-23 07:16:55 +01:00
|
|
|
/** tree-style hierarchy factories. These come after factories for backwards compatibility. */
|
2011-12-23 19:27:13 +01:00
|
|
|
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
|
2016-01-17 09:03:04 +01:00
|
|
|
private boolean serializeNulls = DEFAULT_SERIALIZE_NULLS;
|
2008-09-01 05:13:32 +02:00
|
|
|
private String datePattern;
|
2011-11-23 07:16:55 +01:00
|
|
|
private int dateStyle = DateFormat.DEFAULT;
|
|
|
|
private int timeStyle = DateFormat.DEFAULT;
|
2016-01-17 09:03:04 +01:00
|
|
|
private boolean complexMapKeySerialization = DEFAULT_COMPLEX_MAP_KEYS;
|
|
|
|
private boolean serializeSpecialFloatingPointValues = DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
|
|
|
private boolean escapeHtmlChars = DEFAULT_ESCAPE_HTML;
|
|
|
|
private boolean prettyPrinting = DEFAULT_PRETTY_PRINT;
|
|
|
|
private boolean generateNonExecutableJson = DEFAULT_JSON_NON_EXECUTABLE;
|
|
|
|
private boolean lenient = DEFAULT_LENIENT;
|
2008-09-01 05:13:32 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
|
|
|
|
* settings. GsonBuilder follows the builder pattern, and it is typically used by first
|
|
|
|
* invoking various configuration methods to set desired options, and finally calling
|
|
|
|
* {@link #create()}.
|
|
|
|
*/
|
|
|
|
public GsonBuilder() {
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures Gson to enable versioning support.
|
|
|
|
*
|
|
|
|
* @param ignoreVersionsAfter any field or type marked with a version higher than this value
|
|
|
|
* are ignored during serialization or deserialization.
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
*/
|
|
|
|
public GsonBuilder setVersion(double ignoreVersionsAfter) {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.withVersion(ignoreVersionsAfter);
|
2008-09-01 05:13:32 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures Gson to excludes all class fields that have the specified modifiers. By default,
|
|
|
|
* Gson will exclude all fields marked transient or static. This method will override that
|
|
|
|
* behavior.
|
|
|
|
*
|
|
|
|
* @param modifiers the field modifiers. You must use the modifiers specified in the
|
|
|
|
* {@link java.lang.reflect.Modifier} class. For example,
|
|
|
|
* {@link java.lang.reflect.Modifier#TRANSIENT},
|
|
|
|
* {@link java.lang.reflect.Modifier#STATIC}.
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
*/
|
|
|
|
public GsonBuilder excludeFieldsWithModifiers(int... modifiers) {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.withModifiers(modifiers);
|
2008-09-01 05:13:32 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2009-03-17 22:15:10 +01:00
|
|
|
/**
|
|
|
|
* Makes the output JSON non-executable in Javascript by prefixing the generated JSON with some
|
2009-10-07 11:23:14 +02:00
|
|
|
* special text. This prevents attacks from third-party sites through script sourcing. See
|
|
|
|
* <a href="http://code.google.com/p/google-gson/issues/detail?id=42">Gson Issue 42</a>
|
|
|
|
* for details.
|
|
|
|
*
|
2009-03-17 22:15:10 +01:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.3
|
|
|
|
*/
|
|
|
|
public GsonBuilder generateNonExecutableJson() {
|
|
|
|
this.generateNonExecutableJson = true;
|
|
|
|
return this;
|
|
|
|
}
|
2009-10-07 11:23:14 +02:00
|
|
|
|
2008-09-01 05:13:32 +02:00
|
|
|
/**
|
|
|
|
* Configures Gson to exclude all fields from consideration for serialization or deserialization
|
|
|
|
* that do not have the {@link com.google.gson.annotations.Expose} annotation.
|
|
|
|
*
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
*/
|
|
|
|
public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.excludeFieldsWithoutExposeAnnotation();
|
2008-09-01 05:13:32 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configure Gson to serialize null fields. By default, Gson omits all fields that are null
|
|
|
|
* during serialization.
|
|
|
|
*
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.2
|
|
|
|
*/
|
|
|
|
public GsonBuilder serializeNulls() {
|
|
|
|
this.serializeNulls = true;
|
|
|
|
return this;
|
|
|
|
}
|
2011-03-29 23:24:26 +02:00
|
|
|
|
2011-03-16 08:05:24 +01:00
|
|
|
/**
|
|
|
|
* Enabling this feature will only change the serialized form if the map key is
|
|
|
|
* a complex type (i.e. non-primitive) in its <strong>serialized</strong> JSON
|
|
|
|
* form. The default implementation of map serialization uses {@code toString()}
|
|
|
|
* on the key; however, when this is called then one of the following cases
|
|
|
|
* apply:
|
|
|
|
*
|
|
|
|
* <h3>Maps as JSON objects</h3>
|
|
|
|
* For this case, assume that a type adapter is registered to serialize and
|
|
|
|
* deserialize some {@code Point} class, which contains an x and y coordinate,
|
2011-03-29 23:24:26 +02:00
|
|
|
* to/from the JSON Primitive string value {@code "(x,y)"}. The Java map would
|
2011-03-16 08:05:24 +01:00
|
|
|
* then be serialized as a {@link JsonObject}.
|
2011-03-29 23:24:26 +02:00
|
|
|
*
|
2011-03-16 08:05:24 +01:00
|
|
|
* <p>Below is an example:
|
|
|
|
* <pre> {@code
|
|
|
|
* Gson gson = new GsonBuilder()
|
|
|
|
* .register(Point.class, new MyPointTypeAdapter())
|
|
|
|
* .enableComplexMapKeySerialization()
|
|
|
|
* .create();
|
|
|
|
*
|
|
|
|
* Map<Point, String> original = new LinkedHashMap<Point, String>();
|
|
|
|
* original.put(new Point(5, 6), "a");
|
|
|
|
* original.put(new Point(8, 8), "b");
|
|
|
|
* System.out.println(gson.toJson(original, type));
|
|
|
|
* }</pre>
|
|
|
|
* The above code prints this JSON object:<pre> {@code
|
|
|
|
* {
|
|
|
|
* "(5,6)": "a",
|
|
|
|
* "(8,8)": "b"
|
|
|
|
* }
|
|
|
|
* }</pre>
|
|
|
|
*
|
|
|
|
* <h3>Maps as JSON arrays</h3>
|
|
|
|
* For this case, assume that a type adapter was NOT registered for some
|
|
|
|
* {@code Point} class, but rather the default Gson serialization is applied.
|
|
|
|
* In this case, some {@code new Point(2,3)} would serialize as {@code
|
|
|
|
* {"x":2,"y":5}}.
|
2011-03-29 23:24:26 +02:00
|
|
|
*
|
2011-03-16 08:05:24 +01:00
|
|
|
* <p>Given the assumption above, a {@code Map<Point, String>} will be
|
|
|
|
* serialize as an array of arrays (can be viewed as an entry set of pairs).
|
2011-03-29 23:24:26 +02:00
|
|
|
*
|
2011-03-16 08:05:24 +01:00
|
|
|
* <p>Below is an example of serializing complex types as JSON arrays:
|
|
|
|
* <pre> {@code
|
|
|
|
* Gson gson = new GsonBuilder()
|
|
|
|
* .enableComplexMapKeySerialization()
|
|
|
|
* .create();
|
|
|
|
*
|
|
|
|
* Map<Point, String> original = new LinkedHashMap<Point, String>();
|
|
|
|
* original.put(new Point(5, 6), "a");
|
|
|
|
* original.put(new Point(8, 8), "b");
|
|
|
|
* System.out.println(gson.toJson(original, type));
|
|
|
|
* }
|
2011-03-29 23:24:26 +02:00
|
|
|
*
|
2011-03-16 08:05:24 +01:00
|
|
|
* The JSON output would look as follows:
|
|
|
|
* <pre> {@code
|
|
|
|
* [
|
|
|
|
* [
|
|
|
|
* {
|
|
|
|
* "x": 5,
|
|
|
|
* "y": 6
|
|
|
|
* },
|
2011-04-11 20:33:46 +02:00
|
|
|
* "a"
|
2011-03-16 08:05:24 +01:00
|
|
|
* ],
|
|
|
|
* [
|
|
|
|
* {
|
|
|
|
* "x": 8,
|
|
|
|
* "y": 8
|
|
|
|
* },
|
|
|
|
* "b"
|
|
|
|
* ]
|
|
|
|
* ]
|
|
|
|
* }</pre>
|
2011-03-29 23:24:26 +02:00
|
|
|
*
|
2011-03-16 08:05:24 +01:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.7
|
|
|
|
*/
|
2011-03-15 16:37:41 +01:00
|
|
|
public GsonBuilder enableComplexMapKeySerialization() {
|
2011-09-12 07:51:17 +02:00
|
|
|
complexMapKeySerialization = true;
|
2011-03-15 16:37:41 +01:00
|
|
|
return this;
|
|
|
|
}
|
2009-01-11 07:11:29 +01:00
|
|
|
|
2008-12-28 03:00:31 +01:00
|
|
|
/**
|
2009-01-11 07:11:29 +01:00
|
|
|
* Configures Gson to exclude inner classes during serialization.
|
2008-12-28 04:23:36 +01:00
|
|
|
*
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
2008-12-28 04:35:07 +01:00
|
|
|
* @since 1.3
|
2008-12-28 04:23:36 +01:00
|
|
|
*/
|
2009-01-11 07:11:29 +01:00
|
|
|
public GsonBuilder disableInnerClassSerialization() {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.disableInnerClassSerialization();
|
2008-12-28 04:23:36 +01:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-01-11 07:11:29 +01:00
|
|
|
* Configures Gson to apply a specific serialization policy for {@code Long} and {@code long}
|
|
|
|
* objects.
|
|
|
|
*
|
|
|
|
* @param serializationPolicy the particular policy to use for serializing longs.
|
2008-12-28 03:00:31 +01:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
2008-12-28 04:35:07 +01:00
|
|
|
* @since 1.3
|
2008-12-28 03:00:31 +01:00
|
|
|
*/
|
2009-01-11 07:11:29 +01:00
|
|
|
public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
|
|
|
|
this.longSerializationPolicy = serializationPolicy;
|
2008-12-28 03:00:31 +01:00
|
|
|
return this;
|
|
|
|
}
|
2009-01-11 07:11:29 +01:00
|
|
|
|
2008-09-01 05:13:32 +02:00
|
|
|
/**
|
|
|
|
* Configures Gson to apply a specific naming policy to an object's field during serialization
|
|
|
|
* and deserialization.
|
|
|
|
*
|
|
|
|
* @param namingConvention the JSON field naming convention to use for serialization and
|
|
|
|
* deserialization.
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
*/
|
|
|
|
public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
|
2011-11-21 06:08:23 +01:00
|
|
|
this.fieldNamingPolicy = namingConvention;
|
|
|
|
return this;
|
2008-09-01 05:13:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures Gson to apply a specific naming policy strategy to an object's field during
|
|
|
|
* serialization and deserialization.
|
|
|
|
*
|
2009-03-11 22:53:02 +01:00
|
|
|
* @param fieldNamingStrategy the actual naming strategy to apply to the fields
|
2008-09-01 05:13:32 +02:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
2009-03-11 22:53:02 +01:00
|
|
|
* @since 1.3
|
2008-09-01 05:13:32 +02:00
|
|
|
*/
|
2009-03-11 22:53:02 +01:00
|
|
|
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
|
2011-11-21 06:08:23 +01:00
|
|
|
this.fieldNamingPolicy = fieldNamingStrategy;
|
2009-10-07 11:23:14 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures Gson to apply a set of exclusion strategies during both serialization and
|
2009-10-09 17:26:34 +02:00
|
|
|
* deserialization. Each of the {@code strategies} will be applied as a disjunction rule.
|
2009-10-07 11:23:14 +02:00
|
|
|
* This means that if one of the {@code strategies} suggests that a field (or class) should be
|
2016-02-15 23:11:23 +01:00
|
|
|
* skipped then that field (or object) is skipped during serialization/deserialization.
|
2009-10-07 11:23:14 +02:00
|
|
|
*
|
|
|
|
* @param strategies the set of strategy object to apply during object (de)serialization.
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.4
|
|
|
|
*/
|
2009-10-08 23:52:56 +02:00
|
|
|
public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
|
2011-11-22 07:07:18 +01:00
|
|
|
for (ExclusionStrategy strategy : strategies) {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.withExclusionStrategy(strategy, true, true);
|
2011-11-22 07:07:18 +01:00
|
|
|
}
|
2011-01-22 23:15:06 +01:00
|
|
|
return this;
|
|
|
|
}
|
2011-03-29 23:24:26 +02:00
|
|
|
|
2011-01-22 23:15:06 +01:00
|
|
|
/**
|
2011-04-11 21:01:07 +02:00
|
|
|
* Configures Gson to apply the passed in exclusion strategy during serialization.
|
2011-04-11 20:52:29 +02:00
|
|
|
* If this method is invoked numerous times with different exclusion strategy objects
|
|
|
|
* then the exclusion strategies that were added will be applied as a disjunction rule.
|
|
|
|
* This means that if one of the added exclusion strategies suggests that a field (or
|
|
|
|
* class) should be skipped then that field (or object) is skipped during its
|
|
|
|
* serialization.
|
2011-01-22 23:15:06 +01:00
|
|
|
*
|
2011-04-11 20:09:59 +02:00
|
|
|
* @param strategy an exclusion strategy to apply during serialization.
|
2011-01-22 23:15:06 +01:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.7
|
|
|
|
*/
|
2011-04-11 20:44:19 +02:00
|
|
|
public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.withExclusionStrategy(strategy, true, false);
|
2008-09-01 05:13:32 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2011-04-05 00:48:34 +02:00
|
|
|
/**
|
2011-04-11 21:01:07 +02:00
|
|
|
* Configures Gson to apply the passed in exclusion strategy during deserialization.
|
2011-04-11 20:52:29 +02:00
|
|
|
* If this method is invoked numerous times with different exclusion strategy objects
|
|
|
|
* then the exclusion strategies that were added will be applied as a disjunction rule.
|
|
|
|
* This means that if one of the added exclusion strategies suggests that a field (or
|
|
|
|
* class) should be skipped then that field (or object) is skipped during its
|
|
|
|
* deserialization.
|
2011-04-05 00:48:34 +02:00
|
|
|
*
|
2011-04-11 20:09:59 +02:00
|
|
|
* @param strategy an exclusion strategy to apply during deserialization.
|
2011-04-05 00:48:34 +02:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.7
|
|
|
|
*/
|
2011-04-11 20:44:19 +02:00
|
|
|
public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) {
|
2011-11-22 08:37:13 +01:00
|
|
|
excluder = excluder.withExclusionStrategy(strategy, false, true);
|
2011-04-05 00:48:34 +02:00
|
|
|
return this;
|
|
|
|
}
|
2011-06-24 23:52:59 +02:00
|
|
|
|
2008-09-01 05:13:32 +02:00
|
|
|
/**
|
|
|
|
* Configures Gson to output Json that fits in a page for pretty printing. This option only
|
|
|
|
* affects Json serialization.
|
|
|
|
*
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
*/
|
|
|
|
public GsonBuilder setPrettyPrinting() {
|
2008-12-30 23:42:36 +01:00
|
|
|
prettyPrinting = true;
|
2008-12-29 00:05:22 +01:00
|
|
|
return this;
|
|
|
|
}
|
2009-01-11 07:11:29 +01:00
|
|
|
|
2016-01-17 09:03:04 +01:00
|
|
|
/**
|
|
|
|
* By default, Gson is strict and only accepts JSON as specified by
|
|
|
|
* <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. This option makes the parser
|
|
|
|
* liberal in what it accepts.
|
|
|
|
*
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @see JsonReader#setLenient(boolean)
|
|
|
|
*/
|
|
|
|
public GsonBuilder setLenient() {
|
|
|
|
lenient = true;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2008-12-29 00:05:22 +01:00
|
|
|
/**
|
2008-12-30 20:03:43 +01:00
|
|
|
* By default, Gson escapes HTML characters such as < > etc. Use this option to configure
|
|
|
|
* Gson to pass-through HTML characters as is.
|
2009-01-11 07:11:29 +01:00
|
|
|
*
|
2008-12-29 00:05:22 +01:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.3
|
|
|
|
*/
|
2008-12-30 20:03:43 +01:00
|
|
|
public GsonBuilder disableHtmlEscaping() {
|
|
|
|
this.escapeHtmlChars = false;
|
2008-12-29 00:05:22 +01:00
|
|
|
return this;
|
|
|
|
}
|
2008-09-01 05:13:32 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures Gson to serialize {@code Date} objects according to the pattern provided. You can
|
|
|
|
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
|
|
|
|
* will be used to decide the serialization format.
|
|
|
|
*
|
2011-03-29 23:36:19 +02:00
|
|
|
* <p>The date format will be used to serialize and deserialize {@link java.util.Date}, {@link
|
|
|
|
* java.sql.Timestamp} and {@link java.sql.Date}.
|
|
|
|
*
|
2008-09-01 05:13:32 +02:00
|
|
|
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
|
|
|
|
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
|
|
|
|
* valid date and time patterns.</p>
|
|
|
|
*
|
|
|
|
* @param pattern the pattern that dates will be serialized/deserialized to/from
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.2
|
|
|
|
*/
|
|
|
|
public GsonBuilder setDateFormat(String pattern) {
|
|
|
|
// TODO(Joel): Make this fail fast if it is an invalid date format
|
|
|
|
this.datePattern = pattern;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures Gson to to serialize {@code Date} objects according to the style value provided.
|
|
|
|
* You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
|
|
|
|
* invocation will be used to decide the serialization format.
|
|
|
|
*
|
|
|
|
* <p>Note that this style value should be one of the predefined constants in the
|
|
|
|
* {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
|
|
|
|
* information on the valid style constants.</p>
|
|
|
|
*
|
|
|
|
* @param style the predefined date style that date objects will be serialized/deserialized
|
|
|
|
* to/from
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.2
|
|
|
|
*/
|
|
|
|
public GsonBuilder setDateFormat(int style) {
|
|
|
|
this.dateStyle = style;
|
|
|
|
this.datePattern = null;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2008-10-13 20:40:20 +02:00
|
|
|
/**
|
|
|
|
* Configures Gson to to serialize {@code Date} objects according to the style value provided.
|
|
|
|
* You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
|
|
|
|
* invocation will be used to decide the serialization format.
|
|
|
|
*
|
|
|
|
* <p>Note that this style value should be one of the predefined constants in the
|
|
|
|
* {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
|
|
|
|
* information on the valid style constants.</p>
|
|
|
|
*
|
|
|
|
* @param dateStyle the predefined date style that date objects will be serialized/deserialized
|
|
|
|
* to/from
|
|
|
|
* @param timeStyle the predefined style for the time portion of the date objects
|
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
* @since 1.2
|
|
|
|
*/
|
|
|
|
public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
|
|
|
|
this.dateStyle = dateStyle;
|
|
|
|
this.timeStyle = timeStyle;
|
|
|
|
this.datePattern = null;
|
|
|
|
return this;
|
|
|
|
}
|
2009-01-11 07:11:29 +01:00
|
|
|
|
2008-09-01 05:13:32 +02:00
|
|
|
/**
|
|
|
|
* Configures Gson for custom serialization or deserialization. This method combines the
|
2011-12-31 06:32:14 +01:00
|
|
|
* registration of an {@link TypeAdapter}, {@link InstanceCreator}, {@link JsonSerializer}, and a
|
2008-09-01 05:13:32 +02:00
|
|
|
* {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements
|
2011-12-31 06:32:14 +01:00
|
|
|
* all the required interfaces for custom serialization with Gson. If a type adapter was
|
|
|
|
* previously registered for the specified {@code type}, it is overwritten.
|
2008-09-01 05:13:32 +02:00
|
|
|
*
|
2012-06-30 04:37:49 +02:00
|
|
|
* <p>This registers the type specified and no other types: you must manually register related
|
|
|
|
* types! For example, applications registering {@code boolean.class} should also register {@code
|
|
|
|
* Boolean.class}.
|
|
|
|
*
|
2008-09-01 05:13:32 +02:00
|
|
|
* @param type the type definition for the type adapter being registered
|
2011-12-31 06:32:14 +01:00
|
|
|
* @param typeAdapter This object must implement at least one of the {@link TypeAdapter},
|
|
|
|
* {@link InstanceCreator}, {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
|
2008-09-01 05:13:32 +02:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
|
|
*/
|
2011-11-23 00:56:10 +01:00
|
|
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
2008-09-01 05:13:32 +02:00
|
|
|
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
|
2011-04-06 02:26:57 +02:00
|
|
|
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
2011-09-28 21:14:46 +02:00
|
|
|
|| typeAdapter instanceof JsonDeserializer<?>
|
|
|
|
|| typeAdapter instanceof InstanceCreator<?>
|
2011-11-23 00:56:10 +01:00
|
|
|
|| typeAdapter instanceof TypeAdapter<?>);
|
2009-09-23 19:45:16 +02:00
|
|
|
if (typeAdapter instanceof InstanceCreator<?>) {
|
2011-11-23 14:38:25 +01:00
|
|
|
instanceCreators.put(type, (InstanceCreator) typeAdapter);
|
2008-09-01 05:13:32 +02:00
|
|
|
}
|
2011-11-20 20:55:01 +01:00
|
|
|
if (typeAdapter instanceof JsonSerializer<?> || typeAdapter instanceof JsonDeserializer<?>) {
|
|
|
|
TypeToken<?> typeToken = TypeToken.get(type);
|
2011-11-23 14:38:25 +01:00
|
|
|
factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
|
2008-09-01 05:13:32 +02:00
|
|
|
}
|
2011-11-23 00:56:10 +01:00
|
|
|
if (typeAdapter instanceof TypeAdapter<?>) {
|
2011-11-23 10:26:44 +01:00
|
|
|
factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
|
2011-09-28 21:14:46 +02:00
|
|
|
}
|
2008-09-01 05:13:32 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2011-11-23 10:26:44 +01:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
* is designed to handle a large number of factories, so you should consider registering
|
|
|
|
* them to be at par with registering an individual type adapter.
|
2011-12-03 00:11:28 +01:00
|
|
|
*
|
|
|
|
* @since 2.1
|
2011-11-23 10:26:44 +01:00
|
|
|
*/
|
2011-12-23 19:27:13 +01:00
|
|
|
public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
|
2011-11-23 10:26:44 +01:00
|
|
|
factories.add(factory);
|
2011-11-23 00:56:10 +01:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-06-22 01:26:06 +02:00
|
|
|
/**
|
|
|
|
* Configures Gson for custom serialization or deserialization for an inheritance type hierarchy.
|
2011-12-31 07:00:28 +01:00
|
|
|
* This method combines the registration of a {@link TypeAdapter}, {@link JsonSerializer} and
|
|
|
|
* a {@link JsonDeserializer}. If a type adapter was previously registered for the specified
|
|
|
|
* type hierarchy, it is overridden. If a type adapter is registered for a specific type in
|
|
|
|
* the type hierarchy, it will be invoked instead of the one registered for the type hierarchy.
|
2010-06-22 01:26:06 +02:00
|
|
|
*
|
|
|
|
* @param baseType the class definition for the type adapter being registered for the base class
|
|
|
|
* or interface
|
2012-04-12 20:27:48 +02:00
|
|
|
* @param typeAdapter This object must implement at least one of {@link TypeAdapter},
|
2011-12-31 07:00:28 +01:00
|
|
|
* {@link JsonSerializer} or {@link JsonDeserializer} interfaces.
|
2010-06-22 01:26:06 +02:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
2010-11-25 00:13:29 +01:00
|
|
|
* @since 1.7
|
2010-06-22 01:26:06 +02:00
|
|
|
*/
|
2011-11-23 00:56:10 +01:00
|
|
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
2010-11-25 01:16:06 +01:00
|
|
|
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
2011-04-06 02:26:57 +02:00
|
|
|
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
2011-11-23 07:16:55 +01:00
|
|
|
|| typeAdapter instanceof JsonDeserializer<?>
|
2011-11-23 00:56:10 +01:00
|
|
|
|| typeAdapter instanceof TypeAdapter<?>);
|
2011-11-23 07:16:55 +01:00
|
|
|
if (typeAdapter instanceof JsonDeserializer || typeAdapter instanceof JsonSerializer) {
|
2017-03-17 05:16:38 +01:00
|
|
|
hierarchyFactories.add(TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
|
2010-06-22 01:26:06 +02:00
|
|
|
}
|
2011-11-23 00:56:10 +01:00
|
|
|
if (typeAdapter instanceof TypeAdapter<?>) {
|
2011-11-23 10:26:44 +01:00
|
|
|
factories.add(TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter));
|
2011-11-23 00:56:10 +01:00
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2008-12-20 02:26:14 +01:00
|
|
|
/**
|
|
|
|
* Section 2.4 of <a href="http://www.ietf.org/rfc/rfc4627.txt">JSON specification</a> disallows
|
2009-01-11 07:11:29 +01:00
|
|
|
* special double values (NaN, Infinity, -Infinity). However,
|
|
|
|
* <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">Javascript
|
2008-12-20 02:26:14 +01:00
|
|
|
* specification</a> (see section 4.3.20, 4.3.22, 4.3.23) allows these values as valid Javascript
|
2009-01-11 07:11:29 +01:00
|
|
|
* values. Moreover, most JavaScript engines will accept these special values in JSON without
|
2008-12-20 02:26:14 +01:00
|
|
|
* problem. So, at a practical level, it makes sense to accept these values as valid JSON even
|
2009-01-11 07:11:29 +01:00
|
|
|
* though JSON specification disallows them.
|
|
|
|
*
|
|
|
|
* <p>Gson always accepts these special values during deserialization. However, it outputs
|
|
|
|
* strictly compliant JSON. Hence, if it encounters a float value {@link Float#NaN},
|
|
|
|
* {@link Float#POSITIVE_INFINITY}, {@link Float#NEGATIVE_INFINITY}, or a double value
|
|
|
|
* {@link Double#NaN}, {@link Double#POSITIVE_INFINITY}, {@link Double#NEGATIVE_INFINITY}, it
|
2008-12-20 02:26:14 +01:00
|
|
|
* will throw an {@link IllegalArgumentException}. This method provides a way to override the
|
|
|
|
* default behavior when you know that the JSON receiver will be able to handle these special
|
2009-01-11 07:11:29 +01:00
|
|
|
* values.
|
|
|
|
*
|
2008-12-20 02:26:14 +01:00
|
|
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
2008-12-28 04:35:07 +01:00
|
|
|
* @since 1.3
|
2008-12-20 02:26:14 +01:00
|
|
|
*/
|
|
|
|
public GsonBuilder serializeSpecialFloatingPointValues() {
|
|
|
|
this.serializeSpecialFloatingPointValues = true;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2008-09-01 05:13:32 +02:00
|
|
|
/**
|
|
|
|
* Creates a {@link Gson} instance based on the current configuration. This method is free of
|
|
|
|
* side-effects to this {@code GsonBuilder} instance and hence can be called multiple times.
|
|
|
|
*
|
|
|
|
* @return an instance of Gson configured with the options currently set in this builder
|
|
|
|
*/
|
|
|
|
public Gson create() {
|
2017-03-17 05:16:38 +01:00
|
|
|
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(this.factories.size() + this.hierarchyFactories.size() + 3);
|
2011-12-06 06:09:18 +01:00
|
|
|
factories.addAll(this.factories);
|
|
|
|
Collections.reverse(factories);
|
2017-03-17 05:16:38 +01:00
|
|
|
Collections.reverse(this.hierarchyFactories);
|
2011-12-06 16:29:48 +01:00
|
|
|
factories.addAll(this.hierarchyFactories);
|
2011-11-23 07:16:55 +01:00
|
|
|
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);
|
2009-10-07 11:23:14 +02:00
|
|
|
|
2011-11-23 07:16:55 +01:00
|
|
|
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
|
|
|
|
serializeNulls, complexMapKeySerialization,
|
2016-01-17 09:03:04 +01:00
|
|
|
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
|
2011-11-23 07:16:55 +01:00
|
|
|
serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
|
2008-09-01 05:13:32 +02:00
|
|
|
}
|
2008-12-28 04:23:36 +01:00
|
|
|
|
2011-11-23 07:16:55 +01:00
|
|
|
private void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
|
2011-12-23 19:27:13 +01:00
|
|
|
List<TypeAdapterFactory> factories) {
|
2011-11-23 07:16:55 +01:00
|
|
|
DefaultDateTypeAdapter dateTypeAdapter;
|
2010-08-19 01:58:52 +02:00
|
|
|
if (datePattern != null && !"".equals(datePattern.trim())) {
|
|
|
|
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
|
|
|
|
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
|
|
|
|
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
|
2011-11-23 07:16:55 +01:00
|
|
|
} else {
|
|
|
|
return;
|
2010-08-19 01:58:52 +02:00
|
|
|
}
|
2009-10-07 11:23:14 +02:00
|
|
|
|
2011-11-23 07:16:55 +01:00
|
|
|
factories.add(TreeTypeAdapter.newFactory(TypeToken.get(Date.class), dateTypeAdapter));
|
|
|
|
factories.add(TreeTypeAdapter.newFactory(TypeToken.get(Timestamp.class), dateTypeAdapter));
|
|
|
|
factories.add(TreeTypeAdapter.newFactory(TypeToken.get(java.sql.Date.class), dateTypeAdapter));
|
2008-09-01 05:13:32 +02:00
|
|
|
}
|
|
|
|
}
|