package somehussar.gui.field; import somehussar.gui.FieldConstraints; import java.lang.invoke.MethodHandle; public final class EditableField { private final String name; private final Class type; private final MethodHandle getter; private final MethodHandle setter; private final FieldConstraints constraints; public String getName() { return name; } public Class getType() { return type; } @SuppressWarnings({"unchecked"}) public T read(T instance) { try { return (T) getter.invoke(instance); } catch (Throwable t) { throw new RuntimeException("Failed to read field " + name, t); } } public void write(T instance, T value) { constraints.validate(value); try { setter.invoke(instance, value); } catch (Throwable t) { throw new RuntimeException("Failed to write field " + name, t); } } public FieldConstraints getConstraints() { return this.constraints; } EditableField(Builder b) { this.name = b.name; this.type = b.type; this.getter = b.getter; this.setter = b.setter; this.constraints = b.constraints; } public static class Builder { private String name; private Class type; private MethodHandle getter; private MethodHandle setter; private FieldConstraints constraints; public Builder name(String v) { this.name = v; return this; } public Builder type(Class v) { this.type = v; return this; } public Builder getter(MethodHandle v) { this.getter = v; return this; } public Builder setter(MethodHandle v) { this.setter = v; return this; } public Builder constraints(FieldConstraints v) { this.constraints = v; return this; } public EditableField build() { return new EditableField(this); } } }