From c894fb6c2321231c3793a2092650596d53f37e41 Mon Sep 17 00:00:00 2001 From: Joel Leitch Date: Thu, 14 Apr 2011 02:42:47 +0000 Subject: [PATCH] Default support for BitSet. As well, provide more flexibility on getAsBoolean for a JsonPrimitive. --- .../com/google/gson/DefaultTypeAdapters.java | 37 +++++++++++++++++++ .../java/com/google/gson/JsonPrimitive.java | 9 ++++- .../com/google/gson/JsonPrimitiveTest.java | 20 +++++++++- .../functional/DefaultTypeAdaptersTest.java | 35 +++++++++++++++++- 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java index 54282353..2547faf9 100644 --- a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java +++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java @@ -17,6 +17,7 @@ package com.google.gson; import com.google.gson.internal.$Gson$Types; + import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.math.BigDecimal; @@ -33,6 +34,7 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.BitSet; import java.util.Calendar; import java.util.Collection; import java.util.Date; @@ -74,6 +76,7 @@ final class DefaultTypeAdapters { private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter(); private static final UuidTypeAdapter UUUID_TYPE_ADAPTER = new UuidTypeAdapter(); 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 = new DefaultInetAddressAdapter(); 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(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER); map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER); + map.register(BitSet.class, BIT_SET_ADAPTER); // Add primitive serializers map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER); @@ -176,6 +180,7 @@ final class DefaultTypeAdapters { map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER); map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER); map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER); + map.register(BitSet.class, BIT_SET_ADAPTER); // Add primitive deserializers map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER); @@ -530,6 +535,38 @@ final class DefaultTypeAdapters { } } + private static final class BitSetTypeAdapter implements JsonSerializer, JsonDeserializer { + 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, JsonDeserializer { public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(src.toExternalForm()); diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java index 9ba5beb8..f9bce4b4 100644 --- a/gson/src/main/java/com/google/gson/JsonPrimitive.java +++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java @@ -126,7 +126,12 @@ public final class JsonPrimitive extends JsonElement { */ @Override 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) { Number number = (Number) primitive.value; return number instanceof BigInteger || number instanceof Long || number instanceof Integer - || number instanceof Short || number instanceof Byte; + || number instanceof Short || number instanceof Byte; } return false; } diff --git a/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java b/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java index ec69de53..62a1cc75 100644 --- a/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java +++ b/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java @@ -17,9 +17,11 @@ package com.google.gson; import com.google.gson.common.MoreAsserts; + +import junit.framework.TestCase; + import java.math.BigDecimal; import java.math.BigInteger; -import junit.framework.TestCase; /** * Unit test for the {@link JsonPrimitive} class. @@ -33,6 +35,22 @@ public class JsonPrimitiveTest extends TestCase { assertTrue(json.isBoolean()); 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 { diff --git a/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java b/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java index 55921595..3b8a027d 100644 --- a/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java +++ b/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java @@ -22,6 +22,9 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; @@ -32,6 +35,7 @@ import java.sql.Timestamp; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.BitSet; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -43,7 +47,6 @@ import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; import java.util.UUID; -import junit.framework.TestCase; /** * 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); } + 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() { Date now = new Date(); String json = gson.toJson(now);