package xapi.ui.api; import xapi.collect.X_Collect; import xapi.collect.api.ClassTo; import xapi.collect.api.StringTo; import xapi.fu.In1Out1; import xapi.fu.In2; import xapi.fu.X_Fu; import xapi.ui.service.UiService; /** * @author James X. Nelson (james@wetheinter.net) * Created on 4/19/16. */ public class UiWithAttributes <Node, E extends UiElement<Node, ? extends Node, E>> implements UiFeature<Node, E> { private In1Out1<String, String> getter; private In2<String, String> setter; private ClassTo<In1Out1<String, Object>> deserializers; private ClassTo<In1Out1<Object, String>> serializers; public UiWithAttributes() { final StringTo<String> values = X_Collect.newStringMap(String.class); getter = values::get; setter = values::put; } protected In2<String, String> findSetter(E element) { return null; } protected In1Out1<String,String> findGetter(E element) { return null; } @Override public void initialize(E element, UiService service) { deserializers = service.getDeserializers(); serializers = service.getSerializers(); getter = findGetter(element); if (getter != null) { setter = findSetter(element); } if (setter == null) { final StringTo<String> values = X_Collect.newStringMap(String.class); getter = values::get; setter = values::put; } } public String getAttribute(String key) { return getter.io(key); } public <T, Generic extends T> T getAttributeAsType(String key, Class<Generic> cls) { String serialized = getAttribute(key); if (serialized == null) { return null; } final In1Out1<String, Object> deserializer = deserializers.get(cls); if (deserializer == null) { throw new IllegalStateException("Cannot deserialize unregistered type " + cls + ";" + "\nRegistered types: " + X_Fu.reduceToString(deserializers.keys(), Class::getCanonicalName, ", ") ); } final Object value = deserializer.io(serialized); assert value == null || cls.isInstance(value) : "Registered deserializer " + deserializer +" for type " + cls +" did not produce an instance of " + cls+";\n Instead, received an object of type " + value.getClass()+":\n"+value; return (T) value; } public <T, Generic extends T> void setAttributeAsType(String key, Class<Generic> cls, T value) { if (value == null) { setAttribute(key, null); return; } final In1Out1<Object, String> serializer = serializers.get(cls); if (serializer == null) { throw new IllegalStateException("Cannot serialize unregistered type " + cls + ";" + "\nRegistered types: " + X_Fu.reduceToString(serializers.keys(), Class::getCanonicalName, ", ") ); } final String serialized = serializer.io(value); setAttribute(key, serialized); } public void setAttribute(String key, String value) { setter.in(key, value); } }