Skip to content
Commits on Source (3)
......@@ -13,4 +13,8 @@ release.properties
*.iws
classes
.gradle
local.properties
build
.DS_Store
language: java
jdk:
- oraclejdk7
- openjdk7
- oraclejdk8
install: mvn -f gson install -DskipTests=true
......
Change Log
==========
## Version 2.8.4
_2018-05-01_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.3...gson-parent-2.8.4)
* Added a new FieldNamingPolicy, `LOWER_CASE_WITH_DOTS` that mapps JSON name `someFieldName` to `some.field.name`
* Fixed issue https://github.com/google/gson/issues/1305 by removing compile/runtime dependency on `sun.misc.Unsafe`
## Version 2.8.3
_2018-04-27_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.2...gson-parent-2.8.3)
* Added a new API, `GsonBuilder.newBuilder()` that clones the current builder
* Preserving DateFormatter behavior on JDK 9
* Numerous other bugfixes
## Version 2.8.2
_2017-09-19_ [GitHub Diff](https://github.com/google/gson/compare/gson-parent-2.8.1...gson-parent-2.8.2)
* Introduced a new API, `JsonElement.deepCopy()`
......
......@@ -5,9 +5,9 @@
[![Javadoc](https://javadoc-emblem.rhcloud.com/doc/com.google.code.gson/gson/badge.svg)](http://www.javadoc.io/doc/com.google.code.gson/gson)
Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object.
Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
Gson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.
There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.
There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.
### Gson Goals
* Provide simple `toJson()` and `fromJson()` methods to convert Java objects to JSON and vice-versa
......@@ -17,20 +17,35 @@ There are a few open-source projects that can convert Java objects to JSON. Howe
* Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types)
### Gson Download and Maven
* To use Gson in Android
```gradle
dependencies {
implementation 'com.google.code.gson:gson:2.8.4'
}
```
* [Gson Download](https://maven-badges.herokuapp.com/maven-central/com.google.code.gson/gson) downloads at Maven Central
* For Maven check "Dependency Information" tab, on the left side.
* To use Gson with Maven
```xml
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.4</version>
</dependency>
```
### Gson Documentation
* Gson [API](http://www.javadoc.io/doc/com.google.code.gson/gson): Javadocs for the current Gson release
* Gson [user guide](https://github.com/google/gson/blob/master/UserGuide.md): This guide contains examples on how to use Gson in your code.
* Gson [Roadmap](https://github.com/google/gson/blob/master/CHANGELOG.md): Details of changes in the recent versions
* Gson [design document](https://github.com/google/gson/blob/master/GsonDesignDocument.md): This document discusses issues we faced while designing Gson. It also include a comparison of Gson with other Java libraries that can be used for Json conversion
* Gson [design document](https://github.com/google/gson/blob/master/GsonDesignDocument.md): This document discusses issues we faced while designing Gson. It also includes a comparison of Gson with other Java libraries that can be used for Json conversion
Please use the [google-gson Google group](http://groups.google.com/group/google-gson) to discuss Gson, or to post questions.
Please use the [google-gson Google group](http://groups.google.com/group/google-gson) to discuss Gson, or to post questions.
### Gson-related Content Created by Third Parties
* [Gson Tutorial](http://www.studytrails.com/java/json/java-google-json-introduction.jsp) by `StudyTrails`
* [Gson Tutorial Series](https://futurestud.io/tutorials/gson-getting-started-with-java-json-serialization-deserialization) by `Future Studio`
* [Gson API Report](https://abi-laboratory.pro/java/tracker/timeline/gson/)
### License
......
#Gson Release Process
# Gson Release Process
The following is a step-by-step procedure for releasing a new version of Google-Gson.
1. Go through all open bugs and identify which will be fixed in this release. Mark all others with an appropriate release tag. Identify duplicates, and close the bugs that will never be fixed. Fix all bugs for the release, and mark them fixed.
1. (obsolete step) Edit [`pom.xml`](pom.xml) and update the versions listed for Export-Package to the target version. Also add any new Java packages that have been introduced in Gson.
1. Ensure all changelists are code-reviewed and have +1
1. (obsolete step) Ensure that your `~/.m2/settings.xml` is configured properly (see steps below)
1. `cd gson` to the parent directory; ensure there are no open files and all changes are committed.
1. Run `mvn release:clean`
1. Do a dry run: `mvn release:prepare -DdryRun=true`
1. Start the release: `mvn release:prepare`
* Answer questions: usually the defaults are fine.
* This will do a full build, change version from `-SNAPSHOT` to the released version, commit and create the tags. It will then change the version to `-SNAPSHOT` for the next release.
1. Ensure you have defined `sonatype-nexus-staging` in your Maven `settings.xml` and run:
```bash
mvn -s /home/<username>/.m2/settings.xml release:perform
```
1. [Log in to Nexus repository manager](https://oss.sonatype.org/index.html#welcome) at Sonatype and close the staging repository for Gson. If you run into an error regarding missing signatures, you need to manually upload the artifacts using `mvn gpg:sign-and-deploy-file` for Gson binary, source and Javadoc jars.
```bash
cp -r ~/.m2/repository/com/google/code/gson/gson/1.7.2 /tmp
cd /tmp/1.7.2
mvn gpg:sign-and-deploy-file \
-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \
-DrepositoryId=sonatype-nexus-staging \
-DpomFile=gson-1.7.2.pom \
-Dfile=gson-1.7.2-javadoc.jar \
-Dclassifier=javadoc
mvn gpg:sign-and-deploy-file \
-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \
-DrepositoryId=sonatype-nexus-staging \
-DpomFile=gson-1.7.2.pom \
-Dfile=gson-1.7.2-sources.jar \
-Dclassifier=sources
mvn gpg:sign-and-deploy-file \
-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \
-DrepositoryId=sonatype-nexus-staging \
-DpomFile=gson-1.7.2.pom \
-Dfile=gson-1.7.2.jar
```
1. Close the Gson repository. Download and sanity check all downloads. Do not skip this step! Once you release the staging repository, there is no going back. It will get synced with Maven central and you will not be able to update or delete anything. Your only recourse will be to release a new version of Gson and hope that no one uses the old one.
* Answer questions: usually the defaults are fine.
* This will do a full build, change version from `-SNAPSHOT` to the released version, commit and create the tags. It will then change the version to `-SNAPSHOT` for the next release.
1. Complete the release: `mvn release:perform`
1. [Log in to Nexus repository manager](https://oss.sonatype.org/index.html#welcome) at Sonatype and close the staging repository for Gson.
1. Download and sanity check all downloads. Do not skip this step! Once you release the staging repository, there is no going back. It will get synced with Maven central and you will not be able to update or delete anything. Your only recourse will be to release a new version of Gson and hope that no one uses the old one.
1. Release the staging repository for Gson. Gson will now get synced to Maven central with-in the next hour. For issues consult [Sonatype Guide](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8.ReleaseIt).
1. Update the version in the [Using Gson with Maven2 page](https://github.com/google/gson/blob/master/UserGuide.md#TOC-Gson-With-Maven)
......@@ -58,16 +25,16 @@ The following is a step-by-step procedure for releasing a new version of Google-
This section was borrowed heavily from [Doclava release process](http://code.google.com/p/doclava/wiki/ProcessRelease).
1. Install/Configure GPG following this [guide](http://www.sonatype.com/people/2010/01/how-to-generate-pgp-signatures-with-maven/).
2. [Create encrypted passwords](http://maven.apache.org/guides/mini/guide-encryption.html).
3. Create `~/.m2/settings.xml` similar to as described in [Doclava release process](https://code.google.com/p/doclava/wiki/ProcessRelease).
4. Now for deploying a snapshot repository, use `mvn deploy`.
1. [Create encrypted passwords](http://maven.apache.org/guides/mini/guide-encryption.html).
1. Create `~/.m2/settings.xml` similar to as described in [Doclava release process](https://code.google.com/p/doclava/wiki/ProcessRelease).
1. Now for deploying a snapshot repository, use `mvn deploy`.
## Getting Maven Publishing Privileges
Based on [Gson group thread](https://groups.google.com/d/topic/google-gson/DHWJHVFpIBg/discussion):
1. [Sign up for a Sonatype account](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide) following instructions under (2) on that page
2. Ask one of the existing members of the repository to create a JIRA ticket (Step 3 of above document) to add you to the publisher list.
1. Ask one of the existing members of the repository to create a JIRA ticket (Step 3 of above document) to add you to the publisher list.
## Running Benchmarks or Tests on Android
......
......@@ -5,6 +5,7 @@
3. [Gson Performance and Scalability](#TOC-Gson-Performance-and-Scalability)
4. [Gson Users](#TOC-Gson-Users)
5. [Using Gson](#TOC-Using-Gson)
* [Using Gson with Gradle/Android](#TOC-Gson-With-Gradle)
* [Using Gson with Maven](#TOC-Gson-With-Maven)
* [Primitives Examples](#TOC-Primitives-Examples)
* [Object Examples](#TOC-Object-Examples)
......@@ -70,6 +71,12 @@ The primary class to use is [`Gson`](gson/src/main/java/com/google/gson/Gson.jav
The Gson instance does not maintain any state while invoking Json operations. So, you are free to reuse the same object for multiple Json serialization and deserialization operations.
## <a name="TOC-Gson-With-Gradle"></a>Using Gson with Gradle/Android
```
dependencies {
compile 'com.google.code.gson:gson:2.8.4'
}
```
## <a name="TOC-Gson-With-Maven"></a>Using Gson with Maven
To use Gson with Maven2/3, you can use the Gson version available in Maven Central by adding the following dependency:
......@@ -79,7 +86,7 @@ To use Gson with Maven2/3, you can use the Gson version available in Maven Centr
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
<version>2.8.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
......@@ -137,14 +144,14 @@ BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
#### <a name="TOC-Finer-Points-with-Objects"></a>**Finer Points with Objects**
* It is perfectly fine (and recommended) to use private fields
* It is perfectly fine (and recommended) to use private fields.
* There is no need to use any annotations to indicate a field is to be included for serialization and deserialization. All fields in the current class (and from all super classes) are included by default.
* If a field is marked transient, (by default) it is ignored and not included in the JSON serialization or deserialization.
* This implementation handles nulls correctly
* While serializing, a null field is skipped from the output
* While deserializing, a missing entry in JSON results in setting the corresponding field in the object to null
* If a field is _synthetic_, it is ignored and not included in JSON serialization or deserialization
* Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization
* This implementation handles nulls correctly.
* While serializing, a null field is omitted from the output.
* While deserializing, a missing entry in JSON results in setting the corresponding field in the object to its default value: null for object types, zero for numeric types, and false for booleans.
* If a field is _synthetic_, it is ignored and not included in JSON serialization or deserialization.
* Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization.
### <a name="TOC-Nested-Classes-including-Inner-Classes-"></a>Nested Classes (including Inner Classes)
......
buildscript {
repositories {
mavenCentral()
}
}
allprojects {
repositories {
mavenCentral()
}
}
File mode changed from 100755 to 100644
#Fri Apr 27 17:41:01 PDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
apply plugin: 'java'
apply plugin: 'maven'
group = 'com.google.code.gson'
version = '2.8.4-SNAPSHOT'
sourceCompatibility = 1.6
targetCompatibility = 1.6
sourceSets.main.java.exclude("**/module-info.java")
dependencies {
testCompile "junit:junit:4.12"
}
......@@ -4,7 +4,7 @@
<parent>
<groupId>com.google.code.gson</groupId>
<artifactId>gson-parent</artifactId>
<version>2.8.2</version>
<version>2.8.5</version>
</parent>
<artifactId>gson</artifactId>
......@@ -17,7 +17,7 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
......@@ -56,6 +56,23 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filtering-java-templates</id>
<goals>
<goal>filter-sources</goal>
</goals>
<configuration>
<sourceDirectory>${basedir}/src/main/java-templates</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java-templates</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright (C) 2018 The Gson authors
*
* 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.internal;
/**
* Build configuration for Gson. This file is automatically populated by
* templating-maven-plugin and .java/.class files are generated for use in Gson.
*
* @author Inderjeet Singh
*/
public final class GsonBuildConfig {
// Based on https://stackoverflow.com/questions/2469922/generate-a-version-java-file-in-maven
/** This field is automatically populated by Maven when a build is triggered */
public static final String VERSION = "${project.version}";
private GsonBuildConfig() { }
}
module com.google.gson {
exports com.google.gson;
exports com.google.gson.annotations;
exports com.google.gson.reflect;
exports com.google.gson.stream;
requires java.sql;
}
......@@ -22,9 +22,13 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import com.google.gson.internal.JavaVersion;
import com.google.gson.internal.PreJava9DateFormatProvider;
import com.google.gson.internal.bind.util.ISO8601Utils;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
......@@ -42,42 +46,63 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
private static final String SIMPLE_NAME = "DefaultDateTypeAdapter";
private final Class<? extends Date> dateType;
private final DateFormat enUsFormat;
private final DateFormat localFormat;
/**
* List of 1 or more different date formats used for de-serialization attempts.
* The first of them is used for serialization as well.
*/
private final List<DateFormat> dateFormats = new ArrayList<DateFormat>();
DefaultDateTypeAdapter(Class<? extends Date> dateType) {
this(dateType,
DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US),
DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
this.dateType = verifyDateType(dateType);
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
if (JavaVersion.isJava9OrLater()) {
dateFormats.add(PreJava9DateFormatProvider.getUSDateTimeFormat(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
}
DefaultDateTypeAdapter(Class<? extends Date> dateType, String datePattern) {
this(dateType, new SimpleDateFormat(datePattern, Locale.US), new SimpleDateFormat(datePattern));
this.dateType = verifyDateType(dateType);
dateFormats.add(new SimpleDateFormat(datePattern, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(new SimpleDateFormat(datePattern));
}
}
DefaultDateTypeAdapter(Class<? extends Date> dateType, int style) {
this(dateType, DateFormat.getDateInstance(style, Locale.US), DateFormat.getDateInstance(style));
this.dateType = verifyDateType(dateType);
dateFormats.add(DateFormat.getDateInstance(style, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(DateFormat.getDateInstance(style));
}
if (JavaVersion.isJava9OrLater()) {
dateFormats.add(PreJava9DateFormatProvider.getUSDateFormat(style));
}
}
public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
this(Date.class,
DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US),
DateFormat.getDateTimeInstance(dateStyle, timeStyle));
this(Date.class, dateStyle, timeStyle);
}
public DefaultDateTypeAdapter(Class<? extends Date> dateType, int dateStyle, int timeStyle) {
this(dateType,
DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US),
DateFormat.getDateTimeInstance(dateStyle, timeStyle));
this.dateType = verifyDateType(dateType);
dateFormats.add(DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(DateFormat.getDateTimeInstance(dateStyle, timeStyle));
}
if (JavaVersion.isJava9OrLater()) {
dateFormats.add(PreJava9DateFormatProvider.getUSDateTimeFormat(dateStyle, timeStyle));
}
}
DefaultDateTypeAdapter(final Class<? extends Date> dateType, DateFormat enUsFormat, DateFormat localFormat) {
private static Class<? extends Date> verifyDateType(Class<? extends Date> dateType) {
if ( dateType != Date.class && dateType != java.sql.Date.class && dateType != Timestamp.class ) {
throw new IllegalArgumentException("Date type must be one of " + Date.class + ", " + Timestamp.class + ", or " + java.sql.Date.class + " but was " + dateType);
}
this.dateType = dateType;
this.enUsFormat = enUsFormat;
this.localFormat = localFormat;
return dateType;
}
// These methods need to be synchronized since JDK DateFormat classes are not thread-safe
......@@ -88,8 +113,8 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
out.nullValue();
return;
}
synchronized (localFormat) {
String dateFormatAsString = enUsFormat.format(value);
synchronized(dateFormats) {
String dateFormatAsString = dateFormats.get(0).format(value);
out.value(dateFormatAsString);
}
}
......@@ -114,13 +139,12 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
}
private Date deserializeToDate(String s) {
synchronized (localFormat) {
try {
return localFormat.parse(s);
} catch (ParseException ignored) {}
try {
return enUsFormat.parse(s);
} catch (ParseException ignored) {}
synchronized (dateFormats) {
for (DateFormat dateFormat : dateFormats) {
try {
return dateFormat.parse(s);
} catch (ParseException ignored) {}
}
try {
return ISO8601Utils.parse(s, new ParsePosition(0));
} catch (ParseException e) {
......@@ -131,9 +155,11 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(SIMPLE_NAME);
sb.append('(').append(localFormat.getClass().getSimpleName()).append(')');
return sb.toString();
DateFormat defaultFormat = dateFormats.get(0);
if (defaultFormat instanceof SimpleDateFormat) {
return SIMPLE_NAME + '(' + ((SimpleDateFormat) defaultFormat).toPattern() + ')';
} else {
return SIMPLE_NAME + '(' + defaultFormat.getClass().getSimpleName() + ')';
}
}
}
......@@ -114,6 +114,29 @@ public enum FieldNamingPolicy implements FieldNamingStrategy {
@Override public String translateName(Field f) {
return separateCamelCase(f.getName(), "-").toLowerCase(Locale.ENGLISH);
}
},
/**
* Using this naming policy with Gson will modify the Java Field name from its camel cased
* form to a lower case field name where each word is separated by a dot (.).
*
* <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
* <ul>
* <li>someFieldName ---> some.field.name</li>
* <li>_someFieldName ---> _some.field.name</li>
* <li>aStringField ---> a.string.field</li>
* <li>aURL ---> a.u.r.l</li>
* </ul>
* Using dots in JavaScript is not recommended since dot is also used for a member sign in
* expressions. This requires that a field named with dots is always accessed as a quoted
* property like {@code myobject['my.field']}. Accessing it as an object field
* {@code myobject.my.field} will result in an unintended javascript expression.
* @since 2.8
*/
LOWER_CASE_WITH_DOTS() {
@Override public String translateName(Field f) {
return separateCamelCase(f.getName(), ".").toLowerCase(Locale.ENGLISH);
}
};
/**
......
......@@ -25,6 +25,7 @@ import java.io.Writer;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
......@@ -36,6 +37,7 @@ import java.util.concurrent.atomic.AtomicLongArray;
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;
......@@ -124,18 +126,28 @@ public final class Gson {
private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>();
private final List<TypeAdapterFactory> factories;
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;
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
* following settings:
......@@ -175,23 +187,36 @@ public final class Gson {
Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
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,
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy,
List<TypeAdapterFactory> typeAdapterFactories) {
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List<TypeAdapterFactory> builderFactories,
List<TypeAdapterFactory> builderHierarchyFactories,
List<TypeAdapterFactory> factoriesToBeAdded) {
this.excluder = excluder;
this.fieldNamingStrategy = fieldNamingStrategy;
this.instanceCreators = instanceCreators;
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
this.serializeNulls = serializeNulls;
this.complexMapKeySerialization = complexMapKeySerialization;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.prettyPrinting = prettyPrinting;
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>();
......@@ -202,8 +227,8 @@ public final class Gson {
// the excluder must precede all adapters that handle user-defined types
factories.add(excluder);
// user's type adapters
factories.addAll(typeAdapterFactories);
// users' type adapters
factories.addAll(factoriesToBeAdded);
// type adapters for basic platform types
factories.add(TypeAdapters.STRING_FACTORY);
......@@ -255,6 +280,16 @@ public final class Gson {
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() {
return excluder;
}
......@@ -427,7 +462,7 @@ public final class Gson {
return candidate;
}
}
throw new IllegalArgumentException("GSON cannot handle " + type);
throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
} finally {
threadCalls.remove(type);
......@@ -669,6 +704,8 @@ public final class Gson {
((TypeAdapter<Object>) adapter).write(writer, src);
} catch (IOException e) {
throw new JsonIOException(e);
} catch (AssertionError e) {
throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
......@@ -745,6 +782,8 @@ public final class Gson {
Streams.write(jsonElement, writer);
} catch (IOException e) {
throw new JsonIOException(e);
} catch (AssertionError e) {
throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
......@@ -901,6 +940,8 @@ public final class Gson {
} catch (IOException e) {
// TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
throw new JsonSyntaxException(e);
} catch (AssertionError e) {
throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);
} finally {
reader.setLenient(oldLenient);
}
......
......@@ -104,6 +104,31 @@ public final class 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.
*
......@@ -572,7 +597,9 @@ public final class GsonBuilder {
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
serializeNulls, complexMapKeySerialization,
generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient,
serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
serializeSpecialFloatingPointValues, longSerializationPolicy,
datePattern, dateStyle, timeStyle,
this.factories, this.hierarchyFactories, factories);
}
@SuppressWarnings("unchecked")
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -275,6 +275,10 @@ public final class $Gson$Types {
* @param supertype a superclass of, or interface implemented by, this.
*/
static Type getSupertype(Type context, Class<?> contextRawType, Class<?> supertype) {
if (context instanceof WildcardType) {
// wildcards are useless for resolving supertypes. As the upper bound has the same raw type, use it instead
context = ((WildcardType)context).getUpperBounds()[0];
}
checkArgument(supertype.isAssignableFrom(contextRawType));
return resolve(context, contextRawType,
$Gson$Types.getGenericSupertype(context, contextRawType, supertype));
......