Support writing maps with non-string keys

This commit is contained in:
Jesse Wilson 2011-09-09 08:17:20 +00:00
parent f50cce6d14
commit cdd5d80b85
2 changed files with 12 additions and 15 deletions

View File

@ -31,7 +31,7 @@ import java.util.Map;
/** /**
* Adapt a map whose keys are any type. * Adapt a map whose keys are any type.
*/ */
public final class GsonCompatibleMapTypeAdapter<V> extends TypeAdapter<Map<String, V>> { public final class GsonCompatibleMapTypeAdapter<V> extends TypeAdapter<Map<?, V>> {
public static final Factory FACTORY = new Factory() { public static final Factory FACTORY = new Factory() {
public <T> TypeAdapter<T> create(MiniGson context, TypeToken<T> typeToken) { public <T> TypeAdapter<T> create(MiniGson context, TypeToken<T> typeToken) {
Type type = typeToken.getType(); Type type = typeToken.getType();
@ -71,7 +71,7 @@ public final class GsonCompatibleMapTypeAdapter<V> extends TypeAdapter<Map<Strin
this.constructor = constructor; this.constructor = constructor;
} }
public Map<String, V> read(JsonReader reader) throws IOException { public Map<?, V> read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (reader.peek() == JsonToken.NULL) {
reader.nextNull(); // TODO: does this belong here? reader.nextNull(); // TODO: does this belong here?
return null; return null;
@ -82,24 +82,21 @@ public final class GsonCompatibleMapTypeAdapter<V> extends TypeAdapter<Map<Strin
while (reader.hasNext()) { while (reader.hasNext()) {
String key = reader.nextName(); String key = reader.nextName();
V value = valueTypeAdapter.read(reader); V value = valueTypeAdapter.read(reader);
map.put(key, value); map.put(key, value); // TODO: convert to the map's key type?
} }
reader.endObject(); reader.endObject();
return map; return map;
} }
public void write(JsonWriter writer, Map<String, V> map) throws IOException { public void write(JsonWriter writer, Map<?, V> map) throws IOException {
if (map == null) { if (map == null) {
writer.nullValue(); // TODO: better policy here? writer.nullValue(); // TODO: better policy here?
return; return;
} }
writer.beginObject(); writer.beginObject();
for (Map.Entry<String, V> entry : map.entrySet()) { for (Map.Entry<?, V> entry : map.entrySet()) {
String key = entry.getKey(); String key = String.valueOf(entry.getKey());
if (key == null) {
key = "null";
}
writer.name(key); writer.name(key);
valueTypeAdapter.write(writer, entry.getValue()); valueTypeAdapter.write(writer, entry.getValue());
} }

View File

@ -52,8 +52,8 @@ public class CircularReferenceTest extends TestCase {
try { try {
gson.toJson(a); gson.toJson(a);
fail("Circular types should not get printed!"); fail("Circular types should not get printed!");
} catch (IllegalStateException expected) { } catch (IllegalStateException expected) {
assertTrue(expected.getMessage().contains("children")); assertTrue(expected.getMessage().contains("children"));
} }
} }
@ -74,7 +74,7 @@ public class CircularReferenceTest extends TestCase {
try { try {
gson.toJson(objA); gson.toJson(objA);
fail("Circular reference to self can not be serialized!"); fail("Circular reference to self can not be serialized!");
} catch (IllegalStateException expected) { } catch (IllegalStateException expected) {
assertTrue(expected.getMessage().contains("children")); assertTrue(expected.getMessage().contains("children"));
} }
} }
@ -89,12 +89,12 @@ public class CircularReferenceTest extends TestCase {
obj.addProperty("property", "value"); obj.addProperty("property", "value");
obj.add("child", context.serialize(src.child)); obj.add("child", context.serialize(src.child));
return obj; return obj;
} }
}).create(); }).create();
try { try {
gson.toJson(obj); gson.toJson(obj);
fail("Circular reference to self can not be serialized!"); fail("Circular reference to self can not be serialized!");
} catch (IllegalStateException expected) { } catch (IllegalStateException expected) {
assertTrue(expected.getMessage().contains("Offending")); assertTrue(expected.getMessage().contains("Offending"));
} }
} }
@ -119,7 +119,7 @@ public class CircularReferenceTest extends TestCase {
private static class ContainsReferenceToSelfType { private static class ContainsReferenceToSelfType {
Collection<ContainsReferenceToSelfType> children = new ArrayList<ContainsReferenceToSelfType>(); Collection<ContainsReferenceToSelfType> children = new ArrayList<ContainsReferenceToSelfType>();
} }
private static class ClassWithSelfReference { private static class ClassWithSelfReference {
ClassWithSelfReference child; ClassWithSelfReference child;
} }