fix(serialize-databind): prevent returning superclass from hierarchical adapter

This commit is contained in:
Johannes Frohnmeyer 2024-04-13 13:56:38 +02:00
parent aca5f104ec
commit 4f3f1caf2d
Signed by: Johannes
GPG Key ID: E76429612C2929F4
2 changed files with 34 additions and 1 deletions

View File

@ -8,6 +8,7 @@ import io.gitlab.jfronny.commons.serialize.databind.api.TypeToken;
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
import io.gitlab.jfronny.commons.serialize.SerializeReader;
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
import io.gitlab.jfronny.commons.serialize.databind.impl.HierarchyAdapter;
import java.lang.reflect.Type;
import java.util.*;
@ -68,7 +69,8 @@ public class ObjectMapper implements WithScopedValue<ObjectMapper> {
}
for (TypeToken<?> token : hierarchyAdapters.keySet()) {
if (token.isAssignableFrom(type)) {
TypeAdapter<T> adapter = (TypeAdapter<T>) hierarchyAdapters.get(token);
// We know the adapters type is a superclass of the requested type
TypeAdapter<T> adapter = new HierarchyAdapter<>((TypeAdapter) hierarchyAdapters.get(token), type.getRawType());
explicitAdapters.put(type, adapter);
return adapter;
}

View File

@ -0,0 +1,31 @@
package io.gitlab.jfronny.commons.serialize.databind.impl;
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
import io.gitlab.jfronny.commons.serialize.SerializeReader;
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
import io.gitlab.jfronny.commons.serialize.databind.api.TypeAdapter;
public class HierarchyAdapter<T> extends TypeAdapter<T> {
private final TypeAdapter<? super T> baseAdapter;
private final Class<T> type;
public HierarchyAdapter(TypeAdapter<? super T> baseAdapter, Class<T> type) {
this.baseAdapter = baseAdapter;
this.type = type;
}
@Override
public <TEx extends Throwable, Writer extends SerializeWriter<TEx, Writer>> void serialize(T value, Writer writer) throws TEx, MalformedDataException {
baseAdapter.serialize(value, writer);
}
@Override
public <TEx extends Throwable, Reader extends SerializeReader<TEx, Reader>> T deserialize(Reader reader) throws TEx, MalformedDataException {
var result = baseAdapter.deserialize(reader);
if (result == null) return null;
if (!type.isInstance(result)) {
throw new MalformedDataException("Expected " + type.getName() + " but got " + result.getClass().getName() + " at path " + reader.getPath());
}
return type.cast(result);
}
}