package com.fasterxml.jackson.datatype.pcollections.deser;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.LogicalType;
import org.pcollections.PCollection;
public abstract class PCollectionsCollectionDeserializer<T extends PCollection<Object>>
extends StdDeserializer<T>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1L;
protected final CollectionType _containerType;
protected final JsonDeserializer<?> _valueDeserializer;
protected final TypeDeserializer _typeDeserializerForValue;
protected PCollectionsCollectionDeserializer(CollectionType type,
TypeDeserializer typeDeser, JsonDeserializer<?> deser)
{
super(type);
_containerType = type;
_typeDeserializerForValue = typeDeser;
_valueDeserializer = deser;
}
protected abstract T createEmptyCollection();
public abstract PCollectionsCollectionDeserializer<T> withResolved(
TypeDeserializer typeDeser, JsonDeserializer<?> valueDeser);
@Override
public LogicalType logicalType() {
return LogicalType.Collection;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _valueDeserializer;
TypeDeserializer typeDeser = _typeDeserializerForValue;
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(_containerType.getContentType(), property);
}
if (typeDeser != null) {
typeDeser = typeDeser.forProperty(property);
}
if (deser == _valueDeserializer && typeDeser == _typeDeserializerForValue) {
return this;
}
return withResolved(typeDeser, deser);
}
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException
{
return typeDeserializer.deserializeTypedFromArray(p, ctxt);
}
@SuppressWarnings("unchecked")
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (p.isExpectedStartArrayToken()) {
return _deserializeContents(p, ctxt);
}
if (ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
return _deserializeFromSingleValue(p, ctxt);
}
return (T) ctxt.handleUnexpectedToken(handledType(), p);
}
protected T _deserializeContents(JsonParser p, DeserializationContext ctxt)
throws IOException {
JsonDeserializer<?> valueDes = _valueDeserializer;
JsonToken t;
final TypeDeserializer typeDeser = _typeDeserializerForValue;
T collection = createEmptyCollection();
while ((t = p.nextToken()) != JsonToken.END_ARRAY) {
Object value;
if (t == JsonToken.VALUE_NULL) {
value = null;
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
@SuppressWarnings("unchecked")
T newCollection = (T) collection.plus(value);
collection = newCollection;
}
return collection;
}
protected T _deserializeFromSingleValue(JsonParser p, DeserializationContext ctxt)
throws IOException
{
JsonDeserializer<?> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _typeDeserializerForValue;
JsonToken t = p.getCurrentToken();
Object value;
if (t == JsonToken.VALUE_NULL) {
value = null;
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
@SuppressWarnings("unchecked")
T result = (T) createEmptyCollection().plus(value);
return result;
}
}