package com.fasterxml.jackson.dataformat.avro.deser;
import java.io.IOException;
import java.util.LinkedHashMap;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
public class AvroUntypedDeserializer
extends UntypedObjectDeserializer
implements ResolvableDeserializer
{
private static final long serialVersionUID = 1L;
protected JavaType _typeObject;
protected TypeDeserializer _typeDeserializer;
public AvroUntypedDeserializer() { super(); }
@Override
public void resolve(DeserializationContext ctxt)
throws JsonMappingException
{
_typeObject = ctxt.constructType(Object.class);
_typeDeserializer = ctxt.getConfig().findTypeDeserializer(_typeObject);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (p.canReadTypeId()) {
Object typeId = p.getTypeId();
if (typeId != null) {
if (_typeDeserializer != null) {
TypeIdResolver resolver = _typeDeserializer.getTypeIdResolver();
if (resolver != null && resolver.typeFromId(ctxt, typeId.toString()) != null) {
return _typeDeserializer.deserializeTypedFromAny(p, ctxt);
}
}
}
}
return super.deserialize(p, ctxt);
}
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer) throws IOException {
if (p.canReadTypeId() && p.getTypeId() != null && typeDeserializer != null) {
TypeIdResolver resolver = typeDeserializer.getTypeIdResolver();
if (resolver != null && resolver.typeFromId(ctxt, p.getTypeId().toString()) != null) {
return typeDeserializer.deserializeTypedFromAny(p, ctxt);
}
}
return super.deserializeWithType(p, ctxt, typeDeserializer);
}
@Override
protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException {
Object key1;
JsonToken t = p.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
key1 = p.nextFieldName();
} else if (t == JsonToken.FIELD_NAME) {
key1 = p.getCurrentName();
} else {
if (t != JsonToken.END_OBJECT) {
return ctxt.handleUnexpectedToken(handledType(), p);
}
key1 = null;
}
if (key1 == null) {
return new LinkedHashMap<>(2);
}
KeyDeserializer deserializer = null;
if (p.getTypeId() != null) {
if (_typeDeserializer != null) {
TypeIdResolver idResolver = _typeDeserializer.getTypeIdResolver();
JavaType keyType = idResolver.typeFromId(ctxt, p.getTypeId().toString());
if (keyType != null) {
deserializer = ctxt.findKeyDeserializer(keyType, null);
}
}
}
if (deserializer != null) {
key1 = deserializer.deserializeKey(key1.toString(), ctxt);
}
p.nextToken();
Object value1 = deserialize(p, ctxt);
Object key2 = p.nextFieldName();
if (key2 == null) {
LinkedHashMap<Object, Object> result = new LinkedHashMap<>(2);
result.put(key1, value1);
return result;
}
if (deserializer != null) {
key2 = deserializer.deserializeKey(key2.toString(), ctxt);
}
p.nextToken();
Object value2 = deserialize(p, ctxt);
Object key = p.nextFieldName();
if (key == null) {
LinkedHashMap<Object, Object> result = new LinkedHashMap<>(4);
result.put(key1, value1);
result.put(key2, value2);
return result;
}
LinkedHashMap<Object, Object> result = new LinkedHashMap<>();
result.put(key1, value1);
result.put(key2, value2);
do {
if (deserializer != null) {
key = deserializer.deserializeKey(key.toString(), ctxt);
}
p.nextToken();
result.put(key, deserialize(p, ctxt));
} while ((key = p.nextFieldName()) != null);
return result;
}
}