Created
July 19, 2022 19:42
-
-
Save nithril/b55d6ab32db253dfe24995f87c899685 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
private final BeanIdResolver resolver = new BeanIdResolver(); | |
private final String propertyName = resolver.getMechanism().getDefaultPropertyName(); | |
@Override | |
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { | |
var mapper = (ObjectMapper) p.getCodec(); | |
var treeNode = mapper.readTree(p); | |
// Primitive | |
if (treeNode instanceof NumericNode n) { | |
return switch (n.numberType()) { | |
case INT, LONG -> n.asLong(); | |
case BIG_INTEGER -> n.bigIntegerValue(); | |
case FLOAT, DOUBLE -> n.asDouble(); | |
case BIG_DECIMAL -> n.decimalValue(); | |
}; | |
} else if (treeNode instanceof TextNode t) { | |
return t.asText(); | |
} else if (treeNode instanceof BooleanNode b) { | |
return b.asBoolean(); | |
} else if (treeNode instanceof ArrayNode a) { | |
if (a.isEmpty()) { | |
return List.of(); | |
} | |
if (a.get(0).isValueNode() || a.get(0).isArray()) { | |
// collection of primitive or collection of collection of all but pojo | |
return mapper.treeToValue(treeNode, List.class); | |
} else { | |
// Get the type | |
var type = Streams.stream(a) | |
.map(o -> ((ObjectNode) o).remove(propertyName).asText()) | |
.reduce((l, r) -> l) | |
.get(); // Array cannot be empty | |
var javaType = resolver.typeFromId(ctxt, type); | |
var collectionType = ctxt.getTypeFactory().constructCollectionType(List.class, javaType); | |
return mapper.treeToValue(treeNode, collectionType); | |
} | |
} else if (treeNode instanceof ObjectNode o) { | |
// Pojo, map is not supported (yet) | |
var javaType = resolver.typeFromId(ctxt, o.get(propertyName).textValue()); | |
o.remove(propertyName); | |
return mapper.treeToValue(treeNode, javaType); | |
} else { | |
throw new RuntimeException("Unsupported node %s".formatted(treeNode)); | |
} | |
} |
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
private final BeanIdResolver idResolver = new BeanIdResolver(); | |
private final String propertyName = idResolver.getMechanism().getDefaultPropertyName(); | |
public AsPropertyTypeSerializer asPropertyTypeSerializer = new AsPropertyTypeSerializer(idResolver, null, propertyName); | |
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { | |
var map = (Map<String, Object>) value; | |
for (var e : map.entrySet()) { | |
gen.writeFieldName(e.getKey()); | |
if (isPrimitive(e.getValue())) { | |
gen.getCodec().writeValue(gen, e.getValue()); | |
} else if (e.getValue() instanceof Collection c) { | |
serializeCollection(gen, provider, c); | |
} else { | |
provider.findValueSerializer(e.getValue().getClass()).serializeWithType(e.getValue(), gen, provider, asPropertyTypeSerializer); | |
} | |
} | |
} | |
private void serializeCollection(JsonGenerator gen, SerializerProvider provider, Collection col) throws IOException { | |
var firstValue = firstNonNullValue(col); | |
if (col.isEmpty() || firstValue.isEmpty()) { | |
gen.writeStartArray(); | |
gen.writeEndArray(); | |
} else { | |
if (isPrimitive(firstValue.get()) || firstValue.get() instanceof Collection) { | |
// collection of primitive or collection of collection of all but pojo | |
gen.getCodec().writeValue(gen, col); | |
} else { | |
// Collection of pojo | |
// Assuming consistent type over the collection, any type for pojo is not supported and not desired | |
// Polymorphism is not supported | |
var javaType = provider.getTypeFactory().constructType(firstValue.get().getClass()); | |
var valueSerializer = provider.findValueSerializer(javaType); | |
if (col instanceof List) { | |
new IndexedListSerializer(javaType, false, asPropertyTypeSerializer, valueSerializer) | |
.serialize((List) col, gen, provider); | |
} else { | |
new CollectionSerializer(javaType, false, asPropertyTypeSerializer, valueSerializer) | |
.serialize(col, gen, provider); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment