Update GsonBuilder API to accept an enum for the serialize Long as string. This will be useful if/when we implement support to serialize a long type as an array of integers.

This commit is contained in:
Joel Leitch 2009-01-11 06:11:29 +00:00
parent 90a4619034
commit e2cfc0cc19
5 changed files with 171 additions and 54 deletions

View File

@ -186,11 +186,11 @@ final class DefaultTypeAdapters {
} }
static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers() { static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers() {
return getDefaultSerializers(false, false); return getDefaultSerializers(false, LongSerializationPolicy.DEFAULT);
} }
static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers( static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers(
boolean serializeSpecialFloatingPointValues, boolean serializeLongsAsString) { boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy) {
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers = ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers =
new ParameterizedTypeHandlerMap<JsonSerializer<?>>(); new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
@ -208,7 +208,7 @@ final class DefaultTypeAdapters {
// Long primitive // Long primitive
DefaultTypeAdapters.LongSerializer longSerializer = DefaultTypeAdapters.LongSerializer longSerializer =
new DefaultTypeAdapters.LongSerializer(serializeLongsAsString); new DefaultTypeAdapters.LongSerializer(longSerializationPolicy);
serializers.registerIfAbsent(Long.class, longSerializer); serializers.registerIfAbsent(Long.class, longSerializer);
serializers.registerIfAbsent(long.class, longSerializer); serializers.registerIfAbsent(long.class, longSerializer);
@ -564,20 +564,14 @@ final class DefaultTypeAdapters {
} }
private static class LongSerializer implements JsonSerializer<Long> { private static class LongSerializer implements JsonSerializer<Long> {
private final boolean serializeAsString; private final LongSerializationPolicy longSerializationPolicy;
private LongSerializer(boolean serializeAsString) { private LongSerializer(LongSerializationPolicy longSerializationPolicy) {
this.serializeAsString = serializeAsString; this.longSerializationPolicy = longSerializationPolicy;
} }
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null) { return longSerializationPolicy.serialize(src);
return JsonNull.createJsonNull();
} else if (serializeAsString) {
return new JsonPrimitive(String.valueOf(src));
} else {
return new JsonPrimitive(src);
}
} }
@Override @Override

View File

@ -16,14 +16,14 @@
package com.google.gson; package com.google.gson;
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
/** /**
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration * <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 * options other than the default. For {@link Gson} with default configuration, it is simpler to
@ -52,12 +52,12 @@ import java.util.List;
public final class GsonBuilder { public final class GsonBuilder {
private double ignoreVersionsAfter; private double ignoreVersionsAfter;
private boolean serializeLongAsString;
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy; private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
private boolean serializeInnerClasses; private boolean serializeInnerClasses;
private final AnonymousAndLocalClassExclusionStrategy anonAndLocalClassExclusionStrategy; private final AnonymousAndLocalClassExclusionStrategy anonAndLocalClassExclusionStrategy;
private final InnerClassExclusionStrategy innerClassExclusionStrategy; private final InnerClassExclusionStrategy innerClassExclusionStrategy;
private boolean excludeFieldsWithoutExposeAnnotation; private boolean excludeFieldsWithoutExposeAnnotation;
private LongSerializationPolicy longSerializationPolicy;
private FieldNamingStrategy fieldNamingPolicy; private FieldNamingStrategy fieldNamingPolicy;
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators; private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers; private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
@ -79,7 +79,6 @@ public final class GsonBuilder {
public GsonBuilder() { public GsonBuilder() {
// setup default values // setup default values
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS; ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
serializeLongAsString = false;
serializeInnerClasses = true; serializeInnerClasses = true;
prettyPrinting = false; prettyPrinting = false;
escapeHtmlChars = true; escapeHtmlChars = true;
@ -87,6 +86,7 @@ public final class GsonBuilder {
innerClassExclusionStrategy = new InnerClassExclusionStrategy(); innerClassExclusionStrategy = new InnerClassExclusionStrategy();
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY; modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
excludeFieldsWithoutExposeAnnotation = false; excludeFieldsWithoutExposeAnnotation = false;
longSerializationPolicy = LongSerializationPolicy.DEFAULT;
fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY; fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY;
instanceCreators = new ParameterizedTypeHandlerMap<InstanceCreator<?>>(); instanceCreators = new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
serializers = new ParameterizedTypeHandlerMap<JsonSerializer<?>>(); serializers = new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
@ -149,19 +149,6 @@ public final class GsonBuilder {
return this; return this;
} }
/**
* Configures Gson to output fields of type {@code long} as {@code String}s instead of a number.
*
* @param value the boolean value on whether or not {@code Gson} should serialize a {@code long}
* field as a {@code String}
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.3
*/
public GsonBuilder serializeLongFieldsAsString(boolean value) {
serializeLongAsString = value;
return this;
}
/** /**
* Configures Gson to exclude inner classes during serialization. * Configures Gson to exclude inner classes during serialization.
* *
@ -173,6 +160,19 @@ public final class GsonBuilder {
return this; return this;
} }
/**
* 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.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.3
*/
public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
this.longSerializationPolicy = serializationPolicy;
return this;
}
/** /**
* Configures Gson to apply a specific naming policy to an object's field during serialization * Configures Gson to apply a specific naming policy to an object's field during serialization
* and deserialization. * and deserialization.
@ -409,7 +409,7 @@ public final class GsonBuilder {
customDeserializers); customDeserializers);
customSerializers.registerIfAbsent(DefaultTypeAdapters.getDefaultSerializers( customSerializers.registerIfAbsent(DefaultTypeAdapters.getDefaultSerializers(
serializeSpecialFloatingPointValues, serializeLongAsString)); serializeSpecialFloatingPointValues, longSerializationPolicy));
customDeserializers.registerIfAbsent(DefaultTypeAdapters.getDefaultDeserializers()); customDeserializers.registerIfAbsent(DefaultTypeAdapters.getDefaultDeserializers());

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2009 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;
/**
* Defines the expected format for a {@code long} or {@code Long} type when its serialized.
*
* @since 1.3
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
public enum LongSerializationPolicy {
/**
* This is the "default" serialization policy that will output a {@code long} object as a JSON
* number. For example, assume an object has a long field named "f" then the serialized output
* would be:
* {@code {"f":123}}.
*/
DEFAULT(new DefaultStrategy()),
/**
* Serializes a long value as a quoted string. For example, assume an object has a long field
* named "f" then the serialized output would be:
* {@code {"f":"123"}}.
*/
STRING(new StringStrategy());
private final Strategy strategy;
private LongSerializationPolicy(Strategy strategy) {
this.strategy = strategy;
}
/**
* Serialize this {@code value} using this serialization policy.
*
* @param value the long value to be serialized into a {@link JsonElement}
* @return the serialized version of {@code value}
*/
public JsonElement serialize(Long value) {
return strategy.serialize(value);
}
private interface Strategy {
JsonElement serialize(Long value);
}
private static class DefaultStrategy implements Strategy {
public JsonElement serialize(Long value) {
return new JsonPrimitive(value);
}
}
private static class StringStrategy implements Strategy {
public JsonElement serialize(Long value) {
return new JsonPrimitive(String.valueOf(value));
}
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2009 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 junit.framework.TestCase;
/**
* Unit test for the {@link LongSerializationPolicy} class.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
public class LongSerializationPolicyTest extends TestCase {
public void testDefaultLongSerialization() throws Exception {
JsonElement element = LongSerializationPolicy.DEFAULT.serialize(1556L);
assertTrue(element.isJsonPrimitive());
JsonPrimitive jsonPrimitive = element.getAsJsonPrimitive();
assertFalse(jsonPrimitive.isString());
assertTrue(jsonPrimitive.isNumber());
assertEquals(1556L, element.getAsLong());
}
public void testStringLongSerialization() throws Exception {
JsonElement element = LongSerializationPolicy.STRING.serialize(1556L);
assertTrue(element.isJsonPrimitive());
JsonPrimitive jsonPrimitive = element.getAsJsonPrimitive();
assertFalse(jsonPrimitive.isNumber());
assertTrue(jsonPrimitive.isString());
assertEquals("1556", element.getAsString());
}
}

View File

@ -24,6 +24,7 @@ import junit.framework.TestCase;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.LongSerializationPolicy;
import com.google.gson.common.TestTypes.CrazyLongTypeAdapter; import com.google.gson.common.TestTypes.CrazyLongTypeAdapter;
/** /**
@ -530,7 +531,7 @@ public class PrimitiveTest extends TestCase {
} }
public void testLongAsStringSerialization() throws Exception { public void testLongAsStringSerialization() throws Exception {
gson = new GsonBuilder().serializeLongFieldsAsString(true).create(); gson = new GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.STRING).create();
String result = gson.toJson(15L); String result = gson.toJson(15L);
assertEquals("\"15\"", result); assertEquals("\"15\"", result);
@ -543,7 +544,7 @@ public class PrimitiveTest extends TestCase {
long value = gson.fromJson("\"15\"", long.class); long value = gson.fromJson("\"15\"", long.class);
assertEquals(15, value); assertEquals(15, value);
gson = new GsonBuilder().serializeLongFieldsAsString(true).create(); gson = new GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.STRING).create();
value = gson.fromJson("\"25\"", long.class); value = gson.fromJson("\"25\"", long.class);
assertEquals(25, value); assertEquals(25, value);
} }