Refactoring: Separated type handler maps into two types: one for system-specified handlers and one for user-specified. system-specified handlers are the ones that Gson comes with (DefaultTypeAdapters).
This commit is contained in:
parent
f74dffc6fd
commit
9196b23251
@ -120,35 +120,35 @@ final class DefaultTypeAdapters {
|
|||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
|
||||||
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
||||||
|
|
||||||
map.register(URL.class, URL_TYPE_ADAPTER);
|
map.register(URL.class, URL_TYPE_ADAPTER, true);
|
||||||
map.register(URI.class, URI_TYPE_ADAPTER);
|
map.register(URI.class, URI_TYPE_ADAPTER, true);
|
||||||
map.register(UUID.class, UUUID_TYPE_ADAPTER);
|
map.register(UUID.class, UUUID_TYPE_ADAPTER, true);
|
||||||
map.register(Locale.class, LOCALE_TYPE_ADAPTER);
|
map.register(Locale.class, LOCALE_TYPE_ADAPTER, true);
|
||||||
map.register(Date.class, DATE_TYPE_ADAPTER);
|
map.register(Date.class, DATE_TYPE_ADAPTER, true);
|
||||||
map.register(java.sql.Date.class, JAVA_SQL_DATE_TYPE_ADAPTER);
|
map.register(java.sql.Date.class, JAVA_SQL_DATE_TYPE_ADAPTER, true);
|
||||||
map.register(Timestamp.class, DATE_TYPE_ADAPTER);
|
map.register(Timestamp.class, DATE_TYPE_ADAPTER, true);
|
||||||
map.register(Time.class, TIME_TYPE_ADAPTER);
|
map.register(Time.class, TIME_TYPE_ADAPTER, true);
|
||||||
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true);
|
||||||
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true);
|
||||||
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
|
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER, true);
|
||||||
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
|
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER, true);
|
||||||
map.register(BitSet.class, BIT_SET_ADAPTER);
|
map.register(BitSet.class, BIT_SET_ADAPTER, true);
|
||||||
|
|
||||||
// Add primitive serializers
|
// Add primitive serializers
|
||||||
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
|
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER, true);
|
||||||
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER);
|
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER, true);
|
||||||
map.register(Byte.class, BYTE_TYPE_ADAPTER);
|
map.register(Byte.class, BYTE_TYPE_ADAPTER, true);
|
||||||
map.register(byte.class, BYTE_TYPE_ADAPTER);
|
map.register(byte.class, BYTE_TYPE_ADAPTER, true);
|
||||||
map.register(Character.class, CHARACTER_TYPE_ADAPTER);
|
map.register(Character.class, CHARACTER_TYPE_ADAPTER, true);
|
||||||
map.register(char.class, CHARACTER_TYPE_ADAPTER);
|
map.register(char.class, CHARACTER_TYPE_ADAPTER, true);
|
||||||
map.register(Integer.class, INTEGER_TYPE_ADAPTER);
|
map.register(Integer.class, INTEGER_TYPE_ADAPTER, true);
|
||||||
map.register(int.class, INTEGER_TYPE_ADAPTER);
|
map.register(int.class, INTEGER_TYPE_ADAPTER, true);
|
||||||
map.register(Number.class, NUMBER_TYPE_ADAPTER);
|
map.register(Number.class, NUMBER_TYPE_ADAPTER, true);
|
||||||
map.register(Short.class, SHORT_TYPE_ADAPTER);
|
map.register(Short.class, SHORT_TYPE_ADAPTER, true);
|
||||||
map.register(short.class, SHORT_TYPE_ADAPTER);
|
map.register(short.class, SHORT_TYPE_ADAPTER, true);
|
||||||
map.register(String.class, STRING_TYPE_ADAPTER);
|
map.register(String.class, STRING_TYPE_ADAPTER, true);
|
||||||
map.register(StringBuilder.class, STRING_BUILDER_TYPE_ADAPTER);
|
map.register(StringBuilder.class, STRING_BUILDER_TYPE_ADAPTER, true);
|
||||||
map.register(StringBuffer.class, STRING_BUFFER_TYPE_ADAPTER);
|
map.register(StringBuffer.class, STRING_BUFFER_TYPE_ADAPTER, true);
|
||||||
|
|
||||||
map.makeUnmodifiable();
|
map.makeUnmodifiable();
|
||||||
return map;
|
return map;
|
||||||
@ -157,10 +157,10 @@ final class DefaultTypeAdapters {
|
|||||||
private static ParameterizedTypeHandlerMap<JsonSerializer<?>> createDefaultHierarchySerializers() {
|
private static ParameterizedTypeHandlerMap<JsonSerializer<?>> createDefaultHierarchySerializers() {
|
||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
|
||||||
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
||||||
map.registerForTypeHierarchy(Enum.class, ENUM_TYPE_ADAPTER);
|
map.registerForTypeHierarchy(Enum.class, ENUM_TYPE_ADAPTER, true);
|
||||||
map.registerForTypeHierarchy(InetAddress.class, INET_ADDRESS_ADAPTER);
|
map.registerForTypeHierarchy(InetAddress.class, INET_ADDRESS_ADAPTER, true);
|
||||||
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
|
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER, true);
|
||||||
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
|
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER, true);
|
||||||
map.makeUnmodifiable();
|
map.makeUnmodifiable();
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@ -168,41 +168,41 @@ final class DefaultTypeAdapters {
|
|||||||
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultDeserializers() {
|
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultDeserializers() {
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
|
||||||
new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
||||||
map.register(URL.class, wrapDeserializer(URL_TYPE_ADAPTER));
|
map.register(URL.class, wrapDeserializer(URL_TYPE_ADAPTER), true);
|
||||||
map.register(URI.class, wrapDeserializer(URI_TYPE_ADAPTER));
|
map.register(URI.class, wrapDeserializer(URI_TYPE_ADAPTER), true);
|
||||||
map.register(UUID.class, wrapDeserializer(UUUID_TYPE_ADAPTER));
|
map.register(UUID.class, wrapDeserializer(UUUID_TYPE_ADAPTER), true);
|
||||||
map.register(Locale.class, wrapDeserializer(LOCALE_TYPE_ADAPTER));
|
map.register(Locale.class, wrapDeserializer(LOCALE_TYPE_ADAPTER), true);
|
||||||
map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER));
|
map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER), true);
|
||||||
map.register(java.sql.Date.class, wrapDeserializer(JAVA_SQL_DATE_TYPE_ADAPTER));
|
map.register(java.sql.Date.class, wrapDeserializer(JAVA_SQL_DATE_TYPE_ADAPTER), true);
|
||||||
map.register(Timestamp.class, wrapDeserializer(TIMESTAMP_DESERIALIZER));
|
map.register(Timestamp.class, wrapDeserializer(TIMESTAMP_DESERIALIZER), true);
|
||||||
map.register(Time.class, wrapDeserializer(TIME_TYPE_ADAPTER));
|
map.register(Time.class, wrapDeserializer(TIME_TYPE_ADAPTER), true);
|
||||||
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true);
|
||||||
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true);
|
||||||
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
|
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER, true);
|
||||||
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
|
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER, true);
|
||||||
map.register(BitSet.class, BIT_SET_ADAPTER);
|
map.register(BitSet.class, BIT_SET_ADAPTER, true);
|
||||||
|
|
||||||
// Add primitive deserializers
|
// Add primitive deserializers
|
||||||
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
|
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER, true);
|
||||||
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER);
|
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER, true);
|
||||||
map.register(Byte.class, BYTE_TYPE_ADAPTER);
|
map.register(Byte.class, BYTE_TYPE_ADAPTER, true);
|
||||||
map.register(byte.class, BYTE_TYPE_ADAPTER);
|
map.register(byte.class, BYTE_TYPE_ADAPTER, true);
|
||||||
map.register(Character.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
|
map.register(Character.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER), true);
|
||||||
map.register(char.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
|
map.register(char.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER), true);
|
||||||
map.register(Double.class, DOUBLE_TYPE_ADAPTER);
|
map.register(Double.class, DOUBLE_TYPE_ADAPTER, true);
|
||||||
map.register(double.class, DOUBLE_TYPE_ADAPTER);
|
map.register(double.class, DOUBLE_TYPE_ADAPTER, true);
|
||||||
map.register(Float.class, FLOAT_TYPE_ADAPTER);
|
map.register(Float.class, FLOAT_TYPE_ADAPTER, true);
|
||||||
map.register(float.class, FLOAT_TYPE_ADAPTER);
|
map.register(float.class, FLOAT_TYPE_ADAPTER, true);
|
||||||
map.register(Integer.class, INTEGER_TYPE_ADAPTER);
|
map.register(Integer.class, INTEGER_TYPE_ADAPTER, true);
|
||||||
map.register(int.class, INTEGER_TYPE_ADAPTER);
|
map.register(int.class, INTEGER_TYPE_ADAPTER, true);
|
||||||
map.register(Long.class, LONG_DESERIALIZER);
|
map.register(Long.class, LONG_DESERIALIZER, true);
|
||||||
map.register(long.class, LONG_DESERIALIZER);
|
map.register(long.class, LONG_DESERIALIZER, true);
|
||||||
map.register(Number.class, NUMBER_TYPE_ADAPTER);
|
map.register(Number.class, NUMBER_TYPE_ADAPTER, true);
|
||||||
map.register(Short.class, SHORT_TYPE_ADAPTER);
|
map.register(Short.class, SHORT_TYPE_ADAPTER, true);
|
||||||
map.register(short.class, SHORT_TYPE_ADAPTER);
|
map.register(short.class, SHORT_TYPE_ADAPTER, true);
|
||||||
map.register(String.class, wrapDeserializer(STRING_TYPE_ADAPTER));
|
map.register(String.class, wrapDeserializer(STRING_TYPE_ADAPTER), true);
|
||||||
map.register(StringBuilder.class, wrapDeserializer(STRING_BUILDER_TYPE_ADAPTER));
|
map.register(StringBuilder.class, wrapDeserializer(STRING_BUILDER_TYPE_ADAPTER), true);
|
||||||
map.register(StringBuffer.class, wrapDeserializer(STRING_BUFFER_TYPE_ADAPTER));
|
map.register(StringBuffer.class, wrapDeserializer(STRING_BUFFER_TYPE_ADAPTER), true);
|
||||||
|
|
||||||
map.makeUnmodifiable();
|
map.makeUnmodifiable();
|
||||||
return map;
|
return map;
|
||||||
@ -211,10 +211,10 @@ final class DefaultTypeAdapters {
|
|||||||
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultHierarchyDeserializers() {
|
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultHierarchyDeserializers() {
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
|
||||||
new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
||||||
map.registerForTypeHierarchy(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER));
|
map.registerForTypeHierarchy(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER), true);
|
||||||
map.registerForTypeHierarchy(InetAddress.class, wrapDeserializer(INET_ADDRESS_ADAPTER));
|
map.registerForTypeHierarchy(InetAddress.class, wrapDeserializer(INET_ADDRESS_ADAPTER), true);
|
||||||
map.registerForTypeHierarchy(Collection.class, wrapDeserializer(COLLECTION_TYPE_ADAPTER));
|
map.registerForTypeHierarchy(Collection.class, wrapDeserializer(COLLECTION_TYPE_ADAPTER), true);
|
||||||
map.registerForTypeHierarchy(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER));
|
map.registerForTypeHierarchy(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER), true);
|
||||||
map.makeUnmodifiable();
|
map.makeUnmodifiable();
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ final class DefaultTypeAdapters {
|
|||||||
|
|
||||||
// Map Instance Creators
|
// Map Instance Creators
|
||||||
map.registerForTypeHierarchy(Map.class,
|
map.registerForTypeHierarchy(Map.class,
|
||||||
new DefaultConstructorCreator<Map>(LinkedHashMap.class, allocator));
|
new DefaultConstructorCreator<Map>(LinkedHashMap.class, allocator), true);
|
||||||
|
|
||||||
// Add Collection type instance creators
|
// Add Collection type instance creators
|
||||||
DefaultConstructorCreator<List> listCreator =
|
DefaultConstructorCreator<List> listCreator =
|
||||||
@ -238,10 +238,10 @@ final class DefaultTypeAdapters {
|
|||||||
new DefaultConstructorCreator<Set>(HashSet.class, allocator);
|
new DefaultConstructorCreator<Set>(HashSet.class, allocator);
|
||||||
DefaultConstructorCreator<SortedSet> sortedSetCreator =
|
DefaultConstructorCreator<SortedSet> sortedSetCreator =
|
||||||
new DefaultConstructorCreator<SortedSet>(TreeSet.class, allocator);
|
new DefaultConstructorCreator<SortedSet>(TreeSet.class, allocator);
|
||||||
map.registerForTypeHierarchy(Collection.class, listCreator);
|
map.registerForTypeHierarchy(Collection.class, listCreator, true);
|
||||||
map.registerForTypeHierarchy(Queue.class, queueCreator);
|
map.registerForTypeHierarchy(Queue.class, queueCreator, true);
|
||||||
map.registerForTypeHierarchy(Set.class, setCreator);
|
map.registerForTypeHierarchy(Set.class, setCreator, true);
|
||||||
map.registerForTypeHierarchy(SortedSet.class, sortedSetCreator);
|
map.registerForTypeHierarchy(SortedSet.class, sortedSetCreator, true);
|
||||||
|
|
||||||
map.makeUnmodifiable();
|
map.makeUnmodifiable();
|
||||||
return map;
|
return map;
|
||||||
|
@ -387,6 +387,7 @@ public final class GsonBuilder {
|
|||||||
deserializeExclusionStrategies.add(strategy);
|
deserializeExclusionStrategies.add(strategy);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures Gson to output Json that fits in a page for pretty printing. This option only
|
* Configures Gson to output Json that fits in a page for pretty printing. This option only
|
||||||
* affects Json serialization.
|
* affects Json serialization.
|
||||||
@ -488,16 +489,20 @@ public final class GsonBuilder {
|
|||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
*/
|
*/
|
||||||
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
|
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
|
||||||
|
return registerTypeAdapter(type, typeAdapter, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GsonBuilder registerTypeAdapter(Type type, Object typeAdapter, boolean isSystem) {
|
||||||
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
||||||
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
||||||
if (typeAdapter instanceof InstanceCreator<?>) {
|
if (typeAdapter instanceof InstanceCreator<?>) {
|
||||||
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter);
|
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
if (typeAdapter instanceof JsonSerializer<?>) {
|
if (typeAdapter instanceof JsonSerializer<?>) {
|
||||||
registerSerializer(type, (JsonSerializer<?>) typeAdapter);
|
registerSerializer(type, (JsonSerializer<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
if (typeAdapter instanceof JsonDeserializer<?>) {
|
if (typeAdapter instanceof JsonDeserializer<?>) {
|
||||||
registerDeserializer(type, (JsonDeserializer<?>) typeAdapter);
|
registerDeserializer(type, (JsonDeserializer<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -514,8 +519,8 @@ public final class GsonBuilder {
|
|||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
*/
|
*/
|
||||||
private <T> GsonBuilder registerInstanceCreator(Type typeOfT,
|
private <T> GsonBuilder registerInstanceCreator(Type typeOfT,
|
||||||
InstanceCreator<? extends T> instanceCreator) {
|
InstanceCreator<? extends T> instanceCreator, boolean isSystem) {
|
||||||
instanceCreators.register(typeOfT, instanceCreator);
|
instanceCreators.register(typeOfT, instanceCreator, isSystem);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,8 +534,9 @@ public final class GsonBuilder {
|
|||||||
* @param serializer the custom serializer
|
* @param serializer the custom serializer
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
*/
|
*/
|
||||||
private <T> GsonBuilder registerSerializer(Type typeOfT, final JsonSerializer<T> serializer) {
|
private <T> GsonBuilder registerSerializer(Type typeOfT, JsonSerializer<T> serializer,
|
||||||
serializers.register(typeOfT, serializer);
|
boolean isSystem) {
|
||||||
|
serializers.register(typeOfT, serializer, isSystem);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,8 +550,9 @@ public final class GsonBuilder {
|
|||||||
* @param deserializer the custom deserializer
|
* @param deserializer the custom deserializer
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
*/
|
*/
|
||||||
private <T> GsonBuilder registerDeserializer(Type typeOfT, JsonDeserializer<T> deserializer) {
|
private <T> GsonBuilder registerDeserializer(Type typeOfT, JsonDeserializer<T> deserializer,
|
||||||
deserializers.register(typeOfT, new JsonDeserializerExceptionWrapper<T>(deserializer));
|
boolean isSystem) {
|
||||||
|
deserializers.register(typeOfT, new JsonDeserializerExceptionWrapper<T>(deserializer), isSystem);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,36 +574,41 @@ public final class GsonBuilder {
|
|||||||
* @since 1.7
|
* @since 1.7
|
||||||
*/
|
*/
|
||||||
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
||||||
|
return registerTypeHierarchyAdapter(baseType, typeAdapter, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter,
|
||||||
|
boolean isSystem) {
|
||||||
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
||||||
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
||||||
if (typeAdapter instanceof InstanceCreator<?>) {
|
if (typeAdapter instanceof InstanceCreator<?>) {
|
||||||
registerInstanceCreatorForTypeHierarchy(baseType, (InstanceCreator<?>) typeAdapter);
|
registerInstanceCreatorForTypeHierarchy(baseType, (InstanceCreator<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
if (typeAdapter instanceof JsonSerializer<?>) {
|
if (typeAdapter instanceof JsonSerializer<?>) {
|
||||||
registerSerializerForTypeHierarchy(baseType, (JsonSerializer<?>) typeAdapter);
|
registerSerializerForTypeHierarchy(baseType, (JsonSerializer<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
if (typeAdapter instanceof JsonDeserializer<?>) {
|
if (typeAdapter instanceof JsonDeserializer<?>) {
|
||||||
registerDeserializerForTypeHierarchy(baseType, (JsonDeserializer<?>) typeAdapter);
|
registerDeserializerForTypeHierarchy(baseType, (JsonDeserializer<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> GsonBuilder registerInstanceCreatorForTypeHierarchy(Class<?> classOfT,
|
private <T> GsonBuilder registerInstanceCreatorForTypeHierarchy(Class<?> classOfT,
|
||||||
InstanceCreator<? extends T> instanceCreator) {
|
InstanceCreator<? extends T> instanceCreator, boolean isSystem) {
|
||||||
instanceCreators.registerForTypeHierarchy(classOfT, instanceCreator);
|
instanceCreators.registerForTypeHierarchy(classOfT, instanceCreator, isSystem);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> GsonBuilder registerSerializerForTypeHierarchy(Class<?> classOfT,
|
private <T> GsonBuilder registerSerializerForTypeHierarchy(Class<?> classOfT,
|
||||||
final JsonSerializer<T> serializer) {
|
JsonSerializer<T> serializer, boolean isSystem) {
|
||||||
serializers.registerForTypeHierarchy(classOfT, serializer);
|
serializers.registerForTypeHierarchy(classOfT, serializer, isSystem);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> GsonBuilder registerDeserializerForTypeHierarchy(Class<?> classOfT,
|
private <T> GsonBuilder registerDeserializerForTypeHierarchy(Class<?> classOfT,
|
||||||
JsonDeserializer<T> deserializer) {
|
JsonDeserializer<T> deserializer, boolean isSystem) {
|
||||||
deserializers.registerForTypeHierarchy(classOfT,
|
deserializers.registerForTypeHierarchy(classOfT,
|
||||||
new JsonDeserializerExceptionWrapper<T>(deserializer));
|
new JsonDeserializerExceptionWrapper<T>(deserializer), isSystem);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,7 +721,7 @@ public final class GsonBuilder {
|
|||||||
private static <T> void registerIfAbsent(Class<?> type,
|
private static <T> void registerIfAbsent(Class<?> type,
|
||||||
ParameterizedTypeHandlerMap<T> adapters, T adapter) {
|
ParameterizedTypeHandlerMap<T> adapters, T adapter) {
|
||||||
if (!adapters.hasSpecificHandlerFor(type)) {
|
if (!adapters.hasSpecificHandlerFor(type)) {
|
||||||
adapters.register(type, adapter);
|
adapters.register(type, adapter, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,25 +38,34 @@ import java.util.logging.Logger;
|
|||||||
final class ParameterizedTypeHandlerMap<T> {
|
final class ParameterizedTypeHandlerMap<T> {
|
||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
Logger.getLogger(ParameterizedTypeHandlerMap.class.getName());
|
Logger.getLogger(ParameterizedTypeHandlerMap.class.getName());
|
||||||
private final Map<Type, T> map = new HashMap<Type, T>();
|
/**
|
||||||
private final List<Pair<Class<?>, T>> typeHierarchyList = new ArrayList<Pair<Class<?>, T>>();
|
* Map that is meant for storing default type adapters
|
||||||
|
*/
|
||||||
|
private final Map<Type, T> systemMap = new HashMap<Type, T>();
|
||||||
|
private final Map<Type, T> userMap = new HashMap<Type, T>();
|
||||||
|
/**
|
||||||
|
* List of default type hierarchy adapters
|
||||||
|
*/
|
||||||
|
private final List<Pair<Class<?>, T>> systemTypeHierarchyList = new ArrayList<Pair<Class<?>, T>>();
|
||||||
|
private final List<Pair<Class<?>, T>> userTypeHierarchyList = new ArrayList<Pair<Class<?>, T>>();
|
||||||
private boolean modifiable = true;
|
private boolean modifiable = true;
|
||||||
|
|
||||||
public synchronized void registerForTypeHierarchy(Class<?> typeOfT, T value) {
|
public synchronized void registerForTypeHierarchy(Class<?> typeOfT, T value, boolean isSystem) {
|
||||||
Pair<Class<?>, T> pair = new Pair<Class<?>, T>(typeOfT, value);
|
Pair<Class<?>, T> pair = new Pair<Class<?>, T>(typeOfT, value);
|
||||||
registerForTypeHierarchy(pair);
|
registerForTypeHierarchy(pair, isSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void registerForTypeHierarchy(Pair<Class<?>, T> pair) {
|
public synchronized void registerForTypeHierarchy(Pair<Class<?>, T> pair, boolean isSystem) {
|
||||||
if (!modifiable) {
|
if (!modifiable) {
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
||||||
}
|
}
|
||||||
int index = getIndexOfSpecificHandlerForTypeHierarchy(pair.first);
|
List<Pair<Class<?>, T>> typeHierarchyList = isSystem ? systemTypeHierarchyList : userTypeHierarchyList;
|
||||||
|
int index = getIndexOfSpecificHandlerForTypeHierarchy(pair.first, typeHierarchyList);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
logger.log(Level.WARNING, "Overriding the existing type handler for {0}", pair.first);
|
logger.log(Level.WARNING, "Overriding the existing type handler for {0}", pair.first);
|
||||||
typeHierarchyList.remove(index);
|
typeHierarchyList.remove(index);
|
||||||
}
|
}
|
||||||
index = getIndexOfAnOverriddenHandler(pair.first);
|
index = getIndexOfAnOverriddenHandler(pair.first, typeHierarchyList);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
throw new IllegalArgumentException("The specified type handler for type " + pair.first
|
throw new IllegalArgumentException("The specified type handler for type " + pair.first
|
||||||
+ " hides the previously registered type hierarchy handler for "
|
+ " hides the previously registered type hierarchy handler for "
|
||||||
@ -67,7 +76,7 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
typeHierarchyList.add(0, pair);
|
typeHierarchyList.add(0, pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getIndexOfAnOverriddenHandler(Class<?> type) {
|
private static <T> int getIndexOfAnOverriddenHandler(Class<?> type, List<Pair<Class<?>, T>> typeHierarchyList) {
|
||||||
for (int i = typeHierarchyList.size()-1; i >= 0; --i) {
|
for (int i = typeHierarchyList.size()-1; i >= 0; --i) {
|
||||||
Pair<Class<?>, T> entry = typeHierarchyList.get(i);
|
Pair<Class<?>, T> entry = typeHierarchyList.get(i);
|
||||||
if (type.isAssignableFrom(entry.first)) {
|
if (type.isAssignableFrom(entry.first)) {
|
||||||
@ -77,13 +86,14 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void register(Type typeOfT, T value) {
|
public synchronized void register(Type typeOfT, T value, boolean isSystem) {
|
||||||
if (!modifiable) {
|
if (!modifiable) {
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
||||||
}
|
}
|
||||||
if (hasSpecificHandlerFor(typeOfT)) {
|
if (hasSpecificHandlerFor(typeOfT)) {
|
||||||
logger.log(Level.WARNING, "Overriding the existing type handler for {0}", typeOfT);
|
logger.log(Level.WARNING, "Overriding the existing type handler for {0}", typeOfT);
|
||||||
}
|
}
|
||||||
|
Map<Type, T> map = isSystem ? systemMap : userMap;
|
||||||
map.put(typeOfT, value);
|
map.put(typeOfT, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,18 +101,30 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
if (!modifiable) {
|
if (!modifiable) {
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
||||||
}
|
}
|
||||||
for (Map.Entry<Type, T> entry : other.map.entrySet()) {
|
for (Map.Entry<Type, T> entry : other.userMap.entrySet()) {
|
||||||
if (!map.containsKey(entry.getKey())) {
|
if (!userMap.containsKey(entry.getKey())) {
|
||||||
register(entry.getKey(), entry.getValue());
|
register(entry.getKey(), entry.getValue(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Map.Entry<Type, T> entry : other.systemMap.entrySet()) {
|
||||||
|
if (!systemMap.containsKey(entry.getKey())) {
|
||||||
|
register(entry.getKey(), entry.getValue(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Quite important to traverse the typeHierarchyList from stack bottom first since
|
// Quite important to traverse the typeHierarchyList from stack bottom first since
|
||||||
// we want to register the handlers in the same order to preserve priority order
|
// we want to register the handlers in the same order to preserve priority order
|
||||||
for (int i = other.typeHierarchyList.size()-1; i >= 0; --i) {
|
for (int i = other.userTypeHierarchyList.size()-1; i >= 0; --i) {
|
||||||
Pair<Class<?>, T> entry = other.typeHierarchyList.get(i);
|
Pair<Class<?>, T> entry = other.userTypeHierarchyList.get(i);
|
||||||
int index = getIndexOfSpecificHandlerForTypeHierarchy(entry.first);
|
int index = getIndexOfSpecificHandlerForTypeHierarchy(entry.first, userTypeHierarchyList);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
registerForTypeHierarchy(entry);
|
registerForTypeHierarchy(entry, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = other.systemTypeHierarchyList.size()-1; i >= 0; --i) {
|
||||||
|
Pair<Class<?>, T> entry = other.systemTypeHierarchyList.get(i);
|
||||||
|
int index = getIndexOfSpecificHandlerForTypeHierarchy(entry.first, systemTypeHierarchyList);
|
||||||
|
if (index < 0) {
|
||||||
|
registerForTypeHierarchy(entry, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,14 +133,21 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
if (!modifiable) {
|
if (!modifiable) {
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
||||||
}
|
}
|
||||||
for (Map.Entry<Type, T> entry : other.map.entrySet()) {
|
for (Map.Entry<Type, T> entry : other.userMap.entrySet()) {
|
||||||
register(entry.getKey(), entry.getValue());
|
register(entry.getKey(), entry.getValue(), false);
|
||||||
|
}
|
||||||
|
for (Map.Entry<Type, T> entry : other.systemMap.entrySet()) {
|
||||||
|
register(entry.getKey(), entry.getValue(), true);
|
||||||
}
|
}
|
||||||
// Quite important to traverse the typeHierarchyList from stack bottom first since
|
// Quite important to traverse the typeHierarchyList from stack bottom first since
|
||||||
// we want to register the handlers in the same order to preserve priority order
|
// we want to register the handlers in the same order to preserve priority order
|
||||||
for (int i = other.typeHierarchyList.size()-1; i >= 0; --i) {
|
for (int i = other.userTypeHierarchyList.size()-1; i >= 0; --i) {
|
||||||
Pair<Class<?>, T> entry = other.typeHierarchyList.get(i);
|
Pair<Class<?>, T> entry = other.userTypeHierarchyList.get(i);
|
||||||
registerForTypeHierarchy(entry);
|
registerForTypeHierarchy(entry, false);
|
||||||
|
}
|
||||||
|
for (int i = other.systemTypeHierarchyList.size()-1; i >= 0; --i) {
|
||||||
|
Pair<Class<?>, T> entry = other.systemTypeHierarchyList.get(i);
|
||||||
|
registerForTypeHierarchy(entry, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +155,8 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
if (!modifiable) {
|
if (!modifiable) {
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
||||||
}
|
}
|
||||||
if (!map.containsKey(typeOfT)) {
|
if (!userMap.containsKey(typeOfT)) {
|
||||||
register(typeOfT, value);
|
register(typeOfT, value, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,22 +165,33 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized T getHandlerFor(Type type) {
|
public synchronized T getHandlerFor(Type type) {
|
||||||
T handler = map.get(type);
|
T handler = userMap.get(type);
|
||||||
if (handler == null) {
|
if (handler != null) {
|
||||||
Class<?> rawClass = $Gson$Types.getRawType(type);
|
return handler;
|
||||||
if (rawClass != type) {
|
}
|
||||||
handler = getHandlerFor(rawClass);
|
handler = systemMap.get(type);
|
||||||
}
|
if (handler != null) {
|
||||||
if (handler == null) {
|
return handler;
|
||||||
// check if something registered for type hierarchy
|
}
|
||||||
handler = getHandlerForTypeHierarchy(rawClass);
|
Class<?> rawClass = $Gson$Types.getRawType(type);
|
||||||
|
if (rawClass != type) {
|
||||||
|
handler = getHandlerFor(rawClass);
|
||||||
|
if (handler != null) {
|
||||||
|
return handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check if something registered for type hierarchy
|
||||||
|
handler = getHandlerForTypeHierarchy(rawClass);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private T getHandlerForTypeHierarchy(Class<?> type) {
|
private T getHandlerForTypeHierarchy(Class<?> type) {
|
||||||
for (Pair<Class<?>, T> entry : typeHierarchyList) {
|
for (Pair<Class<?>, T> entry : userTypeHierarchyList) {
|
||||||
|
if (entry.first.isAssignableFrom(type)) {
|
||||||
|
return entry.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Pair<Class<?>, T> entry : systemTypeHierarchyList) {
|
||||||
if (entry.first.isAssignableFrom(type)) {
|
if (entry.first.isAssignableFrom(type)) {
|
||||||
return entry.second;
|
return entry.second;
|
||||||
}
|
}
|
||||||
@ -160,10 +200,11 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean hasSpecificHandlerFor(Type type) {
|
public synchronized boolean hasSpecificHandlerFor(Type type) {
|
||||||
return map.containsKey(type);
|
return userMap.containsKey(type) || systemMap.containsKey(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized int getIndexOfSpecificHandlerForTypeHierarchy(Class<?> type) {
|
private static <T> int getIndexOfSpecificHandlerForTypeHierarchy(
|
||||||
|
Class<?> type, List<Pair<Class<?>, T>> typeHierarchyList) {
|
||||||
for (int i = typeHierarchyList.size()-1; i >= 0; --i) {
|
for (int i = typeHierarchyList.size()-1; i >= 0; --i) {
|
||||||
if (type.equals(typeHierarchyList.get(i).first)) {
|
if (type.equals(typeHierarchyList.get(i).first)) {
|
||||||
return i;
|
return i;
|
||||||
@ -176,16 +217,33 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
ParameterizedTypeHandlerMap<T> copy = new ParameterizedTypeHandlerMap<T>();
|
ParameterizedTypeHandlerMap<T> copy = new ParameterizedTypeHandlerMap<T>();
|
||||||
// Instead of individually registering entries in the map, make an efficient copy
|
// Instead of individually registering entries in the map, make an efficient copy
|
||||||
// of the list and map
|
// of the list and map
|
||||||
copy.map.putAll(map);
|
|
||||||
copy.typeHierarchyList.addAll(typeHierarchyList);
|
// TODO (inder): Performance optimization. We can probably just share the
|
||||||
|
// systemMap and systemTypeHierarchyList instead of making copies
|
||||||
|
copy.systemMap.putAll(systemMap);
|
||||||
|
copy.userMap.putAll(userMap);
|
||||||
|
copy.systemTypeHierarchyList.addAll(systemTypeHierarchyList);
|
||||||
|
copy.userTypeHierarchyList.addAll(userTypeHierarchyList);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder("{mapForTypeHierarchy:{");
|
StringBuilder sb = new StringBuilder("{userTypeHierarchyList:{");
|
||||||
|
appendList(sb, userTypeHierarchyList);
|
||||||
|
sb.append("},systemTypeHierarchyList:{");
|
||||||
|
appendList(sb, systemTypeHierarchyList);
|
||||||
|
sb.append("},userMap:{");
|
||||||
|
appendMap(sb, userMap);
|
||||||
|
sb.append("},systemMap:{");
|
||||||
|
appendMap(sb, systemMap);
|
||||||
|
sb.append("}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendList(StringBuilder sb, List<Pair<Class<?>,T>> list) {
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (Pair<Class<?>, T> entry : typeHierarchyList) {
|
for (Pair<Class<?>, T> entry : list) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
@ -194,8 +252,10 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
sb.append(typeToString(entry.first)).append(':');
|
sb.append(typeToString(entry.first)).append(':');
|
||||||
sb.append(entry.second);
|
sb.append(entry.second);
|
||||||
}
|
}
|
||||||
sb.append("},map:{");
|
}
|
||||||
first = true;
|
|
||||||
|
private void appendMap(StringBuilder sb, Map<Type, T> map) {
|
||||||
|
boolean first = true;
|
||||||
for (Map.Entry<Type, T> entry : map.entrySet()) {
|
for (Map.Entry<Type, T> entry : map.entrySet()) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
@ -205,8 +265,6 @@ final class ParameterizedTypeHandlerMap<T> {
|
|||||||
sb.append(typeToString(entry.getKey())).append(':');
|
sb.append(typeToString(entry.getKey())).append(':');
|
||||||
sb.append(entry.getValue());
|
sb.append(entry.getValue());
|
||||||
}
|
}
|
||||||
sb.append("}");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String typeToString(Type type) {
|
private String typeToString(Type type) {
|
||||||
|
@ -37,7 +37,7 @@ public class MappedObjectConstructorTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testInstanceCreatorTakesTopPrecedence() throws Exception {
|
public void testInstanceCreatorTakesTopPrecedence() throws Exception {
|
||||||
creatorMap.register(ObjectWithDefaultConstructor.class, new MyInstanceCreator());
|
creatorMap.register(ObjectWithDefaultConstructor.class, new MyInstanceCreator(), false);
|
||||||
ObjectWithDefaultConstructor obj =
|
ObjectWithDefaultConstructor obj =
|
||||||
constructor.construct(ObjectWithDefaultConstructor.class);
|
constructor.construct(ObjectWithDefaultConstructor.class);
|
||||||
assertEquals("instanceCreator", obj.stringValue);
|
assertEquals("instanceCreator", obj.stringValue);
|
||||||
|
@ -48,7 +48,7 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
|||||||
public void testHasGenericButNotSpecific() throws Exception {
|
public void testHasGenericButNotSpecific() throws Exception {
|
||||||
Type specificType = new TypeToken<List<String>>() {}.getType();
|
Type specificType = new TypeToken<List<String>>() {}.getType();
|
||||||
String handler = "blah";
|
String handler = "blah";
|
||||||
paramMap.register(List.class, handler);
|
paramMap.register(List.class, handler, false);
|
||||||
|
|
||||||
assertFalse(paramMap.hasSpecificHandlerFor(specificType));
|
assertFalse(paramMap.hasSpecificHandlerFor(specificType));
|
||||||
assertTrue(paramMap.hasSpecificHandlerFor(List.class));
|
assertTrue(paramMap.hasSpecificHandlerFor(List.class));
|
||||||
@ -60,7 +60,7 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
|||||||
public void testHasSpecificType() throws Exception {
|
public void testHasSpecificType() throws Exception {
|
||||||
Type specificType = new TypeToken<List<String>>() {}.getType();
|
Type specificType = new TypeToken<List<String>>() {}.getType();
|
||||||
String handler = "blah";
|
String handler = "blah";
|
||||||
paramMap.register(specificType, handler);
|
paramMap.register(specificType, handler, false);
|
||||||
|
|
||||||
assertTrue(paramMap.hasSpecificHandlerFor(specificType));
|
assertTrue(paramMap.hasSpecificHandlerFor(specificType));
|
||||||
assertFalse(paramMap.hasSpecificHandlerFor(List.class));
|
assertFalse(paramMap.hasSpecificHandlerFor(List.class));
|
||||||
@ -72,8 +72,8 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
|||||||
public void testTypeOverridding() throws Exception {
|
public void testTypeOverridding() throws Exception {
|
||||||
String handler1 = "blah1";
|
String handler1 = "blah1";
|
||||||
String handler2 = "blah2";
|
String handler2 = "blah2";
|
||||||
paramMap.register(String.class, handler1);
|
paramMap.register(String.class, handler1, false);
|
||||||
paramMap.register(String.class, handler2);
|
paramMap.register(String.class, handler2, false);
|
||||||
|
|
||||||
assertTrue(paramMap.hasSpecificHandlerFor(String.class));
|
assertTrue(paramMap.hasSpecificHandlerFor(String.class));
|
||||||
assertEquals(handler2, paramMap.getHandlerFor(String.class));
|
assertEquals(handler2, paramMap.getHandlerFor(String.class));
|
||||||
@ -82,44 +82,44 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
|||||||
public void testMakeUnmodifiable() throws Exception {
|
public void testMakeUnmodifiable() throws Exception {
|
||||||
paramMap.makeUnmodifiable();
|
paramMap.makeUnmodifiable();
|
||||||
try {
|
try {
|
||||||
paramMap.register(String.class, "blah");
|
paramMap.register(String.class, "blah", false);
|
||||||
fail("Can not register handlers when map is unmodifiable");
|
fail("Can not register handlers when map is unmodifiable");
|
||||||
} catch (IllegalStateException expected) { }
|
} catch (IllegalStateException expected) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTypeHierarchy() {
|
public void testTypeHierarchy() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler");
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
String handler = paramMap.getHandlerFor(Sub.class);
|
String handler = paramMap.getHandlerFor(Sub.class);
|
||||||
assertEquals("baseHandler", handler);
|
assertEquals("baseHandler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTypeHierarchyMultipleHandlers() {
|
public void testTypeHierarchyMultipleHandlers() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler");
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
paramMap.registerForTypeHierarchy(Sub.class, "subHandler");
|
paramMap.registerForTypeHierarchy(Sub.class, "subHandler", false);
|
||||||
String handler = paramMap.getHandlerFor(SubOfSub.class);
|
String handler = paramMap.getHandlerFor(SubOfSub.class);
|
||||||
assertEquals("subHandler", handler);
|
assertEquals("subHandler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTypeHierarchyRegisterIfAbsent() {
|
public void testTypeHierarchyRegisterIfAbsent() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler");
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
ParameterizedTypeHandlerMap<String> otherMap = new ParameterizedTypeHandlerMap<String>();
|
ParameterizedTypeHandlerMap<String> otherMap = new ParameterizedTypeHandlerMap<String>();
|
||||||
otherMap.registerForTypeHierarchy(Base.class, "baseHandler2");
|
otherMap.registerForTypeHierarchy(Base.class, "baseHandler2", false);
|
||||||
paramMap.registerIfAbsent(otherMap);
|
paramMap.registerIfAbsent(otherMap);
|
||||||
String handler = paramMap.getHandlerFor(Base.class);
|
String handler = paramMap.getHandlerFor(Base.class);
|
||||||
assertEquals("baseHandler", handler);
|
assertEquals("baseHandler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceExistingTypeHierarchyHandler() {
|
public void testReplaceExistingTypeHierarchyHandler() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler");
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "base2Handler");
|
paramMap.registerForTypeHierarchy(Base.class, "base2Handler", false);
|
||||||
String handler = paramMap.getHandlerFor(Base.class);
|
String handler = paramMap.getHandlerFor(Base.class);
|
||||||
assertEquals("base2Handler", handler);
|
assertEquals("base2Handler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHidingExistingTypeHierarchyHandlerIsDisallowed() {
|
public void testHidingExistingTypeHierarchyHandlerIsDisallowed() {
|
||||||
paramMap.registerForTypeHierarchy(Sub.class, "subHandler");
|
paramMap.registerForTypeHierarchy(Sub.class, "subHandler", false);
|
||||||
try {
|
try {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler");
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
fail("A handler that hides an existing type hierarchy handler is not allowed");
|
fail("A handler that hides an existing type hierarchy handler is not allowed");
|
||||||
} catch (IllegalArgumentException expected) {
|
} catch (IllegalArgumentException expected) {
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user