Merge pull request #730 from google/624
Added support to serialize/deserialize ConcurrentMap and ConcurrentNa…
This commit is contained in:
commit
64107353a3
|
@ -16,10 +16,6 @@
|
|||
|
||||
package com.google.gson.internal;
|
||||
|
||||
import com.google.gson.InstanceCreator;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
@ -37,6 +33,14 @@ import java.util.SortedMap;
|
|||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentNavigableMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import com.google.gson.InstanceCreator;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Returns a function that can construct an instance of a requested type.
|
||||
|
@ -58,7 +62,7 @@ public final class ConstructorConstructor {
|
|||
final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
|
||||
if (typeCreator != null) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return typeCreator.createInstance(type);
|
||||
}
|
||||
};
|
||||
|
@ -70,7 +74,7 @@ public final class ConstructorConstructor {
|
|||
(InstanceCreator<T>) instanceCreators.get(rawType);
|
||||
if (rawTypeCreator != null) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return rawTypeCreator.createInstance(type);
|
||||
}
|
||||
};
|
||||
|
@ -98,7 +102,7 @@ public final class ConstructorConstructor {
|
|||
}
|
||||
return new ObjectConstructor<T>() {
|
||||
@SuppressWarnings("unchecked") // T is the same raw type as is requested
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
try {
|
||||
Object[] args = null;
|
||||
return (T) constructor.newInstance(args);
|
||||
|
@ -130,14 +134,14 @@ public final class ConstructorConstructor {
|
|||
if (Collection.class.isAssignableFrom(rawType)) {
|
||||
if (SortedSet.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new TreeSet<Object>();
|
||||
}
|
||||
};
|
||||
} else if (EnumSet.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
if (type instanceof ParameterizedType) {
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
if (elementType instanceof Class) {
|
||||
|
@ -152,19 +156,19 @@ public final class ConstructorConstructor {
|
|||
};
|
||||
} else if (Set.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new LinkedHashSet<Object>();
|
||||
}
|
||||
};
|
||||
} else if (Queue.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new LinkedList<Object>();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new ArrayList<Object>();
|
||||
}
|
||||
};
|
||||
|
@ -172,22 +176,34 @@ public final class ConstructorConstructor {
|
|||
}
|
||||
|
||||
if (Map.class.isAssignableFrom(rawType)) {
|
||||
if (SortedMap.class.isAssignableFrom(rawType)) {
|
||||
if (ConcurrentNavigableMap.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new ConcurrentSkipListMap<Object, Object>();
|
||||
}
|
||||
};
|
||||
} else if (ConcurrentMap.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
@Override public T construct() {
|
||||
return (T) new ConcurrentHashMap<Object, Object>();
|
||||
}
|
||||
};
|
||||
} else if (SortedMap.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
@Override public T construct() {
|
||||
return (T) new TreeMap<Object, Object>();
|
||||
}
|
||||
};
|
||||
} else if (type instanceof ParameterizedType && !(String.class.isAssignableFrom(
|
||||
TypeToken.get(((ParameterizedType) type).getActualTypeArguments()[0]).getRawType()))) {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new LinkedHashMap<Object, Object>();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
return (T) new LinkedTreeMap<String, Object>();
|
||||
}
|
||||
};
|
||||
|
@ -202,7 +218,7 @@ public final class ConstructorConstructor {
|
|||
return new ObjectConstructor<T>() {
|
||||
private final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create();
|
||||
@SuppressWarnings("unchecked")
|
||||
public T construct() {
|
||||
@Override public T construct() {
|
||||
try {
|
||||
Object newInstance = unsafeAllocator.newInstance(rawType);
|
||||
return (T) newInstance;
|
||||
|
|
|
@ -16,6 +16,18 @@
|
|||
|
||||
package com.google.gson.functional;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentNavigableMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.InstanceCreator;
|
||||
|
@ -33,14 +45,6 @@ import com.google.gson.reflect.TypeToken;
|
|||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Functional test for Json serialization and deserialization for Maps
|
||||
*
|
||||
|
@ -179,6 +183,46 @@ public class MapTest extends TestCase {
|
|||
assertEquals("456", map.get(123));
|
||||
}
|
||||
|
||||
public void testConcurrentMap() throws Exception {
|
||||
Type typeOfMap = new TypeToken<ConcurrentMap<Integer, String>>() {}.getType();
|
||||
ConcurrentMap<Integer, String> map = gson.fromJson("{\"123\":\"456\"}", typeOfMap);
|
||||
assertEquals(1, map.size());
|
||||
assertTrue(map.containsKey(123));
|
||||
assertEquals("456", map.get(123));
|
||||
String json = gson.toJson(map);
|
||||
assertEquals("{\"123\":\"456\"}", json);
|
||||
}
|
||||
|
||||
public void testConcurrentHashMap() throws Exception {
|
||||
Type typeOfMap = new TypeToken<ConcurrentHashMap<Integer, String>>() {}.getType();
|
||||
ConcurrentHashMap<Integer, String> map = gson.fromJson("{\"123\":\"456\"}", typeOfMap);
|
||||
assertEquals(1, map.size());
|
||||
assertTrue(map.containsKey(123));
|
||||
assertEquals("456", map.get(123));
|
||||
String json = gson.toJson(map);
|
||||
assertEquals("{\"123\":\"456\"}", json);
|
||||
}
|
||||
|
||||
public void testConcurrentNavigableMap() throws Exception {
|
||||
Type typeOfMap = new TypeToken<ConcurrentNavigableMap<Integer, String>>() {}.getType();
|
||||
ConcurrentNavigableMap<Integer, String> map = gson.fromJson("{\"123\":\"456\"}", typeOfMap);
|
||||
assertEquals(1, map.size());
|
||||
assertTrue(map.containsKey(123));
|
||||
assertEquals("456", map.get(123));
|
||||
String json = gson.toJson(map);
|
||||
assertEquals("{\"123\":\"456\"}", json);
|
||||
}
|
||||
|
||||
public void testConcurrentSkipListMap() throws Exception {
|
||||
Type typeOfMap = new TypeToken<ConcurrentSkipListMap<Integer, String>>() {}.getType();
|
||||
ConcurrentSkipListMap<Integer, String> map = gson.fromJson("{\"123\":\"456\"}", typeOfMap);
|
||||
assertEquals(1, map.size());
|
||||
assertTrue(map.containsKey(123));
|
||||
assertEquals("456", map.get(123));
|
||||
String json = gson.toJson(map);
|
||||
assertEquals("{\"123\":\"456\"}", json);
|
||||
}
|
||||
|
||||
public void testParameterizedMapSubclassSerialization() {
|
||||
MyParameterizedMap<String, String> map = new MyParameterizedMap<String, String>(10);
|
||||
map.put("a", "b");
|
||||
|
|
Loading…
Reference in New Issue
Block a user