package io.ebeaninternal.server.dto;
import io.ebeaninternal.server.type.DataReader;
import io.ebeaninternal.server.type.ScalarType;
import io.ebeaninternal.server.type.TypeManager;
import java.beans.PropertyDescriptor;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.sql.SQLException;
class DtoMetaProperty implements DtoReadSet {
private final Class<?> dtoType;
private final String name;
private final MethodHandle setter;
private final ScalarType<?> scalarType;
DtoMetaProperty(TypeManager typeManager, PropertyDescriptor descriptor, Class<?> dtoType) throws IllegalAccessException, NoSuchMethodException {
this.dtoType = dtoType;
this.name = descriptor.getName();
Method writeMethod = descriptor.getWriteMethod();
if (writeMethod != null) {
Class<?> propertyType = descriptor.getPropertyType();
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
this.setter = lookup.findVirtual(dtoType, writeMethod.getName(), MethodType.methodType(void.class, propertyType));
this.scalarType = typeManager.getScalarType(propertyType);
} else {
this.scalarType = null;
this.setter = null;
}
}
String getName() {
return name;
}
@Override
public boolean isReadOnly() {
return scalarType == null;
}
@Override
public void readSet(Object bean, DataReader dataReader) throws SQLException {
Object value = scalarType.read(dataReader);
invoke(bean, value);
}
private void invoke(Object instance, Object arg) {
try {
setter.invoke(instance, arg);
} catch (Throwable e) {
throw new RuntimeException("Error calling setter for property " + fullname() + " with arg: " + arg, e);
}
}
private String fullname() {
return dtoType.getName() + "." + name;
}
}