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; } }