Created
March 13, 2015 11:15
-
-
Save dhke/27879e948c3925fee356 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CollectionsGenericAbstractTypeResolver | |
extends AbstractTypeResolver { | |
public CollectionsGenericAbstractTypeResolver() | |
{ | |
} | |
@Override | |
public JavaType resolveAbstractType(DeserializationConfig config, JavaType type) | |
{ | |
if (MultiMap.class.isAssignableFrom(type.getRawClass())) { | |
JavaType keyType = type.getKeyType(); | |
if (keyType == null) { | |
keyType = TypeFactory.unknownType(); | |
} | |
JavaType valueType = type.getContentType(); | |
if (valueType == null) { | |
valueType = TypeFactory.unknownType(); | |
} | |
return config.getTypeFactory().constructMapLikeType(MultiHashMap.class, keyType, valueType); | |
} else { | |
return null; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CollectionsGenericDeserializers | |
extends SimpleDeserializers { | |
private static final long serialVersionUID = 9185735258872784781L; | |
@Override | |
public JsonDeserializer<?> findMapLikeDeserializer(MapLikeType type, DeserializationConfig config, | |
BeanDescription beanDesc, KeyDeserializer keyDeserializer, | |
TypeDeserializer elementTypeDeserializer, | |
JsonDeserializer<?> elementDeserializer) throws JsonMappingException | |
{ | |
if (MultiMap.class.isAssignableFrom(type.getRawClass())) { | |
return new MultiMapDeserializer(type, keyDeserializer, elementTypeDeserializer, elementDeserializer); | |
} else { | |
return super.findMapLikeDeserializer(type, config, beanDesc, keyDeserializer, elementTypeDeserializer, | |
elementDeserializer); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CollectionsGenericModule | |
extends SimpleModule { | |
@Override | |
public void setupModule(SetupContext context) | |
{ | |
context.addAbstractTypeResolver(new CollectionsGenericAbstractTypeResolver()); | |
context.addTypeModifier(new CollectionsGenericTypeModifier()); | |
context.addSerializers(new CollectionsGenericSerializers()); | |
context.addDeserializers(new CollectionsGenericDeserializers()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CollectionsGenericSerializers | |
extends SimpleSerializers { | |
private static final long serialVersionUID = -1167031439656909741L; | |
@Override | |
public JsonSerializer<?> findMapLikeSerializer(SerializationConfig config, MapLikeType type, | |
BeanDescription beanDesc, JsonSerializer<Object> keySerializer, | |
TypeSerializer elementTypeSerializer, | |
JsonSerializer<Object> elementValueSerializer) | |
{ | |
if (MultiMap.class.isAssignableFrom(type.getRawClass())) { | |
return new MultiMapSerializer(); | |
} else { | |
return super.findMapLikeSerializer(config, type, beanDesc, keySerializer, elementTypeSerializer, | |
elementValueSerializer); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CollectionsGenericTypeModifier | |
extends TypeModifier { | |
@Override | |
public JavaType modifyType(JavaType type, Type jdkType, TypeBindings context, TypeFactory typeFactory) | |
{ | |
final Class<?> rawClass = type.getRawClass(); | |
if (MultiMap.class.isAssignableFrom(rawClass)) { | |
JavaType keyType = type.containedType(0); | |
JavaType valueType = type.containedType(1); | |
if (keyType == null) { | |
keyType = TypeFactory.unknownType(); | |
} | |
if (valueType == null) { | |
valueType = TypeFactory.unknownType(); | |
} | |
return typeFactory.constructMapLikeType(rawClass, keyType, valueType); | |
} | |
return type; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MultiMapDeserializer | |
extends JsonDeserializer<MultiMap<Object, Object>> | |
implements ContextualDeserializer { | |
private final MapLikeType _type; | |
private final KeyDeserializer _keyDeserializer; | |
private final TypeDeserializer _elementTypeDeserializer; | |
private final JsonDeserializer<?> _elementDeserializer; | |
public MultiMapDeserializer(MapLikeType type, KeyDeserializer keyDeserializer, | |
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) | |
{ | |
_type = type; | |
_keyDeserializer = keyDeserializer; | |
_elementTypeDeserializer = elementTypeDeserializer; | |
_elementDeserializer = elementDeserializer; | |
} | |
protected MultiMap<Object, Object> createMultiMap(DeserializationContext ctxt) | |
throws JsonProcessingException | |
{ | |
Class<?> rawClass = _type.getRawClass(); | |
if (Modifier.isAbstract(rawClass.getModifiers())) { | |
/* XXX - default to MultiHashMap, make this configurable */ | |
rawClass = MultiHashMap.class; | |
} | |
try { | |
return (MultiMap<Object, Object>) rawClass.newInstance(); | |
} catch (IllegalAccessException ex) { | |
throw ctxt.instantiationException(rawClass, ex); | |
} catch (InstantiationException ex) { | |
throw ctxt.instantiationException(rawClass, ex); | |
} | |
} | |
@Override | |
public MultiMap<Object, Object> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException | |
{ | |
final MultiMap<Object, Object> multiMap = createMultiMap(ctxt); | |
expect(p, JsonToken.START_OBJECT, "Multimaps must be JSON objectsf"); | |
while (p.nextToken() != JsonToken.END_OBJECT) { | |
final Object key; | |
if (_keyDeserializer != null) { | |
key = _keyDeserializer.deserializeKey(p.getCurrentName(), ctxt); | |
} else { | |
key = p.getCurrentName(); | |
} | |
p.nextToken(); | |
expect(p, JsonToken.START_ARRAY, "Multimap values should be arrays"); | |
while (p.nextToken() != JsonToken.END_ARRAY) { | |
final Object value; | |
if (p.getCurrentToken() == JsonToken.VALUE_NULL) { | |
value = null; | |
} else if (_elementTypeDeserializer != null) { | |
value = _elementDeserializer.deserializeWithType(p, ctxt, _elementTypeDeserializer); | |
} else { | |
value = _elementDeserializer.deserialize(p, ctxt); | |
} | |
multiMap.put(key, value); | |
} | |
} | |
return multiMap; | |
} | |
private void expect(JsonParser jp, JsonToken token, final String messageIfIncorrect) throws IOException | |
{ | |
if (jp.getCurrentToken() != token) { | |
throw new JsonMappingException( | |
"Expecting " + token + ", found " + jp.getCurrentToken() + ": " + messageIfIncorrect, | |
jp.getCurrentLocation()); | |
} | |
} | |
@Override | |
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException | |
{ | |
KeyDeserializer keyDeser = _keyDeserializer; | |
if (keyDeser == null) { | |
keyDeser = ctxt.findKeyDeserializer(_type.getKeyType(), property); | |
} | |
JsonDeserializer<?> elementDeser = _elementDeserializer; | |
if (elementDeser == null) { | |
elementDeser = ctxt.findContextualValueDeserializer(_type.getContentType(), property); | |
} | |
TypeDeserializer typeDeser = _elementTypeDeserializer; | |
if ((typeDeser != null) && (property != null)) { | |
typeDeser = typeDeser.forProperty(property); | |
} | |
return new MultiMapDeserializer(_type, keyDeser, typeDeser, elementDeser); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MultiMapSerializer | |
extends JsonSerializer<MultiMap> { | |
@Override | |
public void serialize(MultiMap value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException | |
{ | |
serializers.defaultSerializeValue(value.map(), gen); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment