Default support for BitSet. As well, provide more flexibility on getAsBoolean for a JsonPrimitive.

This commit is contained in:
Joel Leitch 2011-04-14 02:42:47 +00:00
parent 4e99d66817
commit c894fb6c23
4 changed files with 97 additions and 4 deletions

View File

@ -17,6 +17,7 @@
package com.google.gson; package com.google.gson;
import com.google.gson.internal.$Gson$Types; import com.google.gson.internal.$Gson$Types;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -33,6 +34,7 @@ import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
@ -74,6 +76,7 @@ final class DefaultTypeAdapters {
private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter(); private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter();
private static final UuidTypeAdapter UUUID_TYPE_ADAPTER = new UuidTypeAdapter(); private static final UuidTypeAdapter UUUID_TYPE_ADAPTER = new UuidTypeAdapter();
private static final LocaleTypeAdapter LOCALE_TYPE_ADAPTER = new LocaleTypeAdapter(); private static final LocaleTypeAdapter LOCALE_TYPE_ADAPTER = new LocaleTypeAdapter();
private static final BitSetTypeAdapter BIT_SET_ADAPTER = new BitSetTypeAdapter();
private static final DefaultInetAddressAdapter INET_ADDRESS_ADAPTER = private static final DefaultInetAddressAdapter INET_ADDRESS_ADAPTER =
new DefaultInetAddressAdapter(); new DefaultInetAddressAdapter();
private static final CollectionTypeAdapter COLLECTION_TYPE_ADAPTER = new CollectionTypeAdapter(); private static final CollectionTypeAdapter COLLECTION_TYPE_ADAPTER = new CollectionTypeAdapter();
@ -129,6 +132,7 @@ final class DefaultTypeAdapters {
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER); map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER); map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER); map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
map.register(BitSet.class, BIT_SET_ADAPTER);
// Add primitive serializers // Add primitive serializers
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER); map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
@ -176,6 +180,7 @@ final class DefaultTypeAdapters {
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER); map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER); map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER); map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
map.register(BitSet.class, BIT_SET_ADAPTER);
// Add primitive deserializers // Add primitive deserializers
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER); map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
@ -530,6 +535,38 @@ final class DefaultTypeAdapters {
} }
} }
private static final class BitSetTypeAdapter implements JsonSerializer<BitSet>, JsonDeserializer<BitSet> {
public JsonElement serialize(BitSet src, Type typeOfSrc, JsonSerializationContext context) {
JsonArray array = new JsonArray();
for (int i = 0; i < src.length(); i++) {
int value = (src.get(i)) ? 1 : 0;
array.add(new JsonPrimitive(value));
}
return array;
}
public BitSet deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
if (!json.isJsonArray()) {
throw new JsonParseException("Expected an array of bits.");
}
BitSet result = new BitSet();
JsonArray array = json.getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
JsonElement element = array.get(i);
if (element.getAsBoolean()) {
result.set(i);
}
}
return result;
}
@Override
public String toString() {
return BitSetTypeAdapter.class.getSimpleName();
}
}
private static final class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL> { private static final class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL> {
public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toExternalForm()); return new JsonPrimitive(src.toExternalForm());

View File

@ -126,7 +126,12 @@ public final class JsonPrimitive extends JsonElement {
*/ */
@Override @Override
public boolean getAsBoolean() { public boolean getAsBoolean() {
return isBoolean() ? getAsBooleanWrapper().booleanValue() : Boolean.parseBoolean(getAsString()); if (isBoolean()) {
return getAsBooleanWrapper().booleanValue();
} else {
String stringValue = getAsString();
return Boolean.parseBoolean(stringValue) || "1".equals(stringValue);
}
} }
/** /**
@ -372,7 +377,7 @@ public final class JsonPrimitive extends JsonElement {
if (primitive.value instanceof Number) { if (primitive.value instanceof Number) {
Number number = (Number) primitive.value; Number number = (Number) primitive.value;
return number instanceof BigInteger || number instanceof Long || number instanceof Integer return number instanceof BigInteger || number instanceof Long || number instanceof Integer
|| number instanceof Short || number instanceof Byte; || number instanceof Short || number instanceof Byte;
} }
return false; return false;
} }

View File

@ -17,9 +17,11 @@
package com.google.gson; package com.google.gson;
import com.google.gson.common.MoreAsserts; import com.google.gson.common.MoreAsserts;
import junit.framework.TestCase;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import junit.framework.TestCase;
/** /**
* Unit test for the {@link JsonPrimitive} class. * Unit test for the {@link JsonPrimitive} class.
@ -33,6 +35,22 @@ public class JsonPrimitiveTest extends TestCase {
assertTrue(json.isBoolean()); assertTrue(json.isBoolean());
assertTrue(json.getAsBoolean()); assertTrue(json.getAsBoolean());
// Extra support for booleans
json = new JsonPrimitive(1);
assertTrue(json.getAsBoolean());
json = new JsonPrimitive("1");
assertTrue(json.getAsBoolean());
json = new JsonPrimitive("true");
assertTrue(json.getAsBoolean());
json = new JsonPrimitive("TrUe");
assertTrue(json.getAsBoolean());
json = new JsonPrimitive("1.3");
assertFalse(json.getAsBoolean());
} }
public void testParsingStringAsBoolean() throws Exception { public void testParsingStringAsBoolean() throws Exception {

View File

@ -22,6 +22,9 @@ import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import junit.framework.TestCase;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -32,6 +35,7 @@ import java.sql.Timestamp;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
@ -43,7 +47,6 @@ import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.UUID; import java.util.UUID;
import junit.framework.TestCase;
/** /**
* Functional test for Json serialization and deserialization for common classes for which default * Functional test for Json serialization and deserialization for common classes for which default
@ -208,6 +211,36 @@ public class DefaultTypeAdaptersTest extends TestCase {
assertEquals("[\"blah\"]", json); assertEquals("[\"blah\"]", json);
} }
public void testBitSetSerialization() throws Exception {
Gson gson = new Gson();
BitSet bits = new BitSet();
bits.set(1);
bits.set(3, 6);
bits.set(9);
String json = gson.toJson(bits);
assertEquals("[0,1,0,1,1,1,0,0,0,1]", json);
}
public void testBitSetDeserialization() throws Exception {
BitSet expected = new BitSet();
expected.set(0);
expected.set(2, 6);
expected.set(8);
Gson gson = new Gson();
String json = gson.toJson(expected);
assertEquals(expected, gson.fromJson(json, BitSet.class));
json = "[1,0,1,1,1,1,0,0,1,0,0,0]";
assertEquals(expected, gson.fromJson(json, BitSet.class));
json = "[\"1\",\"0\",\"1\",\"1\",\"1\",\"1\",\"0\",\"0\",\"1\"]";
assertEquals(expected, gson.fromJson(json, BitSet.class));
json = "[true,false,true,true,true,true,false,false,true,false,false]";
assertEquals(expected, gson.fromJson(json, BitSet.class));
}
public void testDefaultDateSerialization() { public void testDefaultDateSerialization() {
Date now = new Date(); Date now = new Date();
String json = gson.toJson(now); String json = gson.toJson(now);