Permalink
Browse files

Merge with Gson 2.8.2

  • Loading branch information...
amogilev committed Dec 7, 2017
2 parents 7e6d749 + d90f63d commit 3312dfd3b31628b2164be7076041bf16ce23a1a5
@@ -33,7 +33,7 @@
// copied from https://gist.github.com/swankjesse/20df26adaf639ed7fd160f145a0b661a
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
for (Class<?> t = type.getRawType(); t != Object.class; t = t.getSuperclass()) {
for (Class<?> t = type.getRawType(); (t != Object.class) && (t.getSuperclass() != null); t = t.getSuperclass()) {
for (Method m : t.getDeclaredMethods()) {
if (m.isAnnotationPresent(PostConstruct.class)) {
m.setAccessible(true);
@@ -73,4 +73,4 @@ public PostConstructAdapter(TypeAdapter<T> delegate, Method method) {
delegate.write(out, value);
}
}
}
}
@@ -23,6 +23,9 @@
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.List;
public class PostConstructAdapterFactoryTest extends TestCase {
public void test() throws Exception {
Gson gson = new GsonBuilder()
@@ -37,14 +40,73 @@ public void test() throws Exception {
}
}
public void testList() {
MultipleSandwiches sandwiches = new MultipleSandwiches(Arrays.asList(
new Sandwich("white", "cheddar"),
new Sandwich("whole wheat", "swiss")));
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new PostConstructAdapterFactory()).create();
// Throws NullPointerException without the fix in https://github.com/google/gson/pull/1103
String json = gson.toJson(sandwiches);
assertEquals("{\"sandwiches\":[{\"bread\":\"white\",\"cheese\":\"cheddar\"},{\"bread\":\"whole wheat\",\"cheese\":\"swiss\"}]}", json);
MultipleSandwiches sandwichesFromJson = gson.fromJson(json, MultipleSandwiches.class);
assertEquals(sandwiches, sandwichesFromJson);
}
static class Sandwich {
String bread;
String cheese;
public String bread;
public String cheese;
@PostConstruct void validate() {
public Sandwich(String bread, String cheese) {
this.bread = bread;
this.cheese = cheese;
}
@PostConstruct private void validate() {
if (bread.equals("cheesey bread") && cheese != null) {
throw new IllegalArgumentException("too cheesey");
}
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Sandwich)) {
return false;
}
final Sandwich other = (Sandwich) o;
if (this.bread == null ? other.bread != null : !this.bread.equals(other.bread)) {
return false;
}
if (this.cheese == null ? other.cheese != null : !this.cheese.equals(other.cheese)) {
return false;
}
return true;
}
}
static class MultipleSandwiches {
public List<Sandwich> sandwiches;
public MultipleSandwiches(List<Sandwich> sandwiches) {
this.sandwiches = sandwiches;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof MultipleSandwiches)) {
return false;
}
final MultipleSandwiches other = (MultipleSandwiches) o;
if (this.sandwiches == null ? other.sandwiches != null : !this.sandwiches.equals(other.sandwiches)) {
return false;
}
return true;
}
}
}
@@ -85,6 +85,10 @@ public DefaultDateTypeAdapter(Class<? extends Date> dateType, int dateStyle, int
// See issue 162
@Override
public void write(JsonWriter out, Date value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
synchronized (localFormat) {
String dateFormatAsString = enUsFormat.format(value);
out.value(dateFormatAsString);
@@ -93,8 +97,9 @@ public void write(JsonWriter out, Date value) throws IOException {
@Override
public Date read(JsonReader in) throws IOException {
if (in.peek() != JsonToken.STRING) {
throw new JsonParseException("The date should be a string value");
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
Date date = deserializeToDate(in.nextString());
if (dateType == Date.class) {
@@ -136,9 +136,13 @@ public boolean hasModifier(int modifier) {
}
/**
* This is exposed internally only for the removing synthetic fields from the JSON output.
* Returns the value of the field represented by this {@code Field}, on
* the specified object. The value is automatically wrapped in an
* object if it has a primitive type.
*
* @return true if the field is synthetic; otherwise false
* @return the value of the represented field in object
* {@code obj}; primitive values are wrapped in an appropriate
* object before being returned
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@@ -806,7 +806,8 @@ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOExce
* @param <T> the type of the desired object
* @param json the string from which the object is to be deserialized
* @param classOfT the class of T
* @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null}.
* @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null}
* or if {@code json} is empty.
* @throws JsonSyntaxException if json is not a valid representation for an object of type
* classOfT
*/
@@ -624,8 +624,11 @@ public Gson create() {
factories.addAll(this.factories);
Collections.reverse(factories);
Collections.reverse(this.hierarchyFactories);
factories.addAll(this.hierarchyFactories);
List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>(this.hierarchyFactories);
Collections.reverse(hierarchyFactories);
factories.addAll(hierarchyFactories);
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);
return factories;
@@ -44,8 +44,12 @@ public JsonArray(int capacity) {
elements = new ArrayList<JsonElement>(capacity);
}
/**
* Creates a deep copy of this element and all its children
* @since 2.8.2
*/
@Override
JsonArray deepCopy() {
public JsonArray deepCopy() {
if (!elements.isEmpty()) {
JsonArray result = new JsonArray(elements.size());
for (JsonElement element : elements) {
@@ -34,8 +34,9 @@
/**
* Returns a deep copy of this element. Immutable elements like primitives
* and nulls are not copied.
* @since 2.8.2
*/
abstract JsonElement deepCopy();
public abstract JsonElement deepCopy();
/**
* provides check for verifying if this element is an array or not.
@@ -40,8 +40,12 @@ public JsonNull() {
// Do nothing
}
/**
* Returns the same instance since it is an immutable value
* @since 2.8.2
*/
@Override
JsonNull deepCopy() {
public JsonNull deepCopy() {
return INSTANCE;
}
@@ -33,8 +33,12 @@
private final LinkedTreeMap<String, JsonElement> members =
new LinkedTreeMap<String, JsonElement>();
/**
* Creates a deep copy of this element and all its children
* @since 2.8.2
*/
@Override
JsonObject deepCopy() {
public JsonObject deepCopy() {
JsonObject result = new JsonObject();
for (Map.Entry<String, JsonElement> entry : members.entrySet()) {
result.add(entry.getKey(), entry.getValue().deepCopy());
@@ -85,8 +85,12 @@ public JsonPrimitive(Character c) {
setValue(primitive);
}
/**
* Returns the same value as primitives are immutable.
* @since 2.8.2
*/
@Override
JsonPrimitive deepCopy() {
public JsonPrimitive deepCopy() {
return this;
}
@@ -256,7 +256,7 @@ public void apply(Object instance) {
return (T) newInstance;
} catch (Exception e) {
throw new RuntimeException(("Unable to invoke no-args constructor for " + type + ". "
+ "Register an InstanceCreator with Gson for this type may fix this problem."), e);
+ "Registering an InstanceCreator with Gson for this type may fix this problem."), e);
}
}
};
@@ -491,10 +491,10 @@ public JsonWriter value(Boolean value) throws IOException {
* @return this writer.
*/
public JsonWriter value(double value) throws IOException {
if (Double.isNaN(value) || Double.isInfinite(value)) {
writeDeferredName();
if (!lenient && (Double.isNaN(value) || Double.isInfinite(value))) {
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
}
writeDeferredName();
beforeValue();
out.append(Double.toString(value));
return this;
@@ -161,6 +161,20 @@ public void testInvalidDatePattern() throws Exception {
} catch (IllegalArgumentException expected) { }
}
public void testNullValue() throws Exception {
DefaultDateTypeAdapter adapter = new DefaultDateTypeAdapter(Date.class);
assertNull(adapter.fromJson("null"));
assertEquals("null", adapter.toJson(null, null));
}
public void testUnexpectedToken() throws Exception {
try {
DefaultDateTypeAdapter adapter = new DefaultDateTypeAdapter(Date.class);
adapter.fromJson("{}");
fail("Unexpected token should fail.");
} catch (IllegalStateException expected) { }
}
private void assertFormatted(String formatted, DefaultDateTypeAdapter adapter) {
assertEquals(toLiteral(formatted), adapter.toJson(new Date(0), null));
}
@@ -109,3 +109,6 @@ public void testRecursiveTypeVariablesResolve12() throws Exception {
assertNotNull(adapter);
}
}
@@ -16,11 +16,12 @@
package com.google.gson.stream;
import junit.framework.TestCase;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import junit.framework.TestCase;
@SuppressWarnings("resource")
public final class JsonWriterTest extends TestCase {
@@ -213,6 +214,30 @@ public void testNonFiniteBoxedDoubles() throws IOException {
}
}
public void testNonFiniteDoublesWhenLenient() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setLenient(true);
jsonWriter.beginArray();
jsonWriter.value(Double.NaN);
jsonWriter.value(Double.NEGATIVE_INFINITY);
jsonWriter.value(Double.POSITIVE_INFINITY);
jsonWriter.endArray();
assertEquals("[NaN,-Infinity,Infinity]", stringWriter.toString());
}
public void testNonFiniteBoxedDoublesWhenLenient() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setLenient(true);
jsonWriter.beginArray();
jsonWriter.value(Double.valueOf(Double.NaN));
jsonWriter.value(Double.valueOf(Double.NEGATIVE_INFINITY));
jsonWriter.value(Double.valueOf(Double.POSITIVE_INFINITY));
jsonWriter.endArray();
assertEquals("[NaN,-Infinity,Infinity]", stringWriter.toString());
}
public void testDoubles() throws IOException {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);

0 comments on commit 3312dfd

Please sign in to comment.