aQute.lib.json.RecordHandler Maven / Gradle / Ivy
The newest version!
package aQute.lib.json;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import aQute.bnd.exceptions.Exceptions;
public class RecordHandler extends Handler {
final static Lookup lookup = MethodHandles.lookup();
final Map accessors = new TreeMap<>();
final JSONCodec codec;
final MethodHandle constructor;
class Accessor {
final MethodHandle getter;
final String name;
final Type type;
final int index;
public Accessor(RecordComponent component, int index) throws IllegalAccessException {
Method m = component.getAccessor();
getter = lookup.unreflect(m);
this.name = JSONCodec.keyword(component.getName());
this.type = component.getGenericType();
this.index = index;
}
public Object get(Object object) {
try {
return getter.invoke(object);
} catch (Throwable e) {
throw Exceptions.duck(e);
}
}
}
RecordHandler(JSONCodec codec, Class> c) throws Exception {
this.codec = codec;
assert c.getSuperclass() == Record.class;
assert c.isRecord();
MethodType constructorType = MethodType.methodType(void.class);
int index = 0;
for (RecordComponent component : c.getRecordComponents()) {
constructorType = constructorType.appendParameterTypes(component.getType());
Accessor accessor = new Accessor(component, index++);
accessors.put(accessor.name, accessor);
}
this.constructor = lookup.findConstructor(c, constructorType);
}
@Override
public void encode(Encoder enc, Object object, Map
© 2015 - 2024 Weber Informatics LLC | Privacy Policy