package trikita.anvil; import android.view.View; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; final class PropertySetter implements Anvil.AttributeSetter { private final Map<Class, Class> WRAP = new HashMap<Class, Class>() {{ put(int.class, Integer.class); put(long.class, Long.class); put(double.class, Double.class); put(float.class, Float.class); put(boolean.class, Boolean.class); put(char.class, Character.class); put(byte.class, Byte.class); put(void.class, Void.class); put(short.class, Short.class); put(Integer.class, int.class); put(Long.class, long.class); put(Double.class, double.class); put(Float.class, float.class); put(Boolean.class, boolean.class); put(Character.class, char.class); put(Byte.class, byte.class); put(Void.class, void.class); put(Short.class, short.class); }}; private boolean assignable(Class<?> a, Class<?> b) { if (a == null) { return false; } if (b == null) { return !(a.isPrimitive()); } if (b.isPrimitive() && !a.isPrimitive()) { b = WRAP.get(b); if (b == null) { return false; } } if (a.isPrimitive() && !b.isPrimitive()) { b = WRAP.get(b); if (b == null) { return false; } } if (b.equals(a)) { return true; } if (b.isPrimitive()) { if (a.isPrimitive() == false) { return false; } if (Integer.TYPE.equals(b)) { return Long.TYPE.equals(a) || Float.TYPE.equals(a) || Double.TYPE.equals(a); } if (Long.TYPE.equals(b)) { return Float.TYPE.equals(a) || Double.TYPE.equals(a); } if (Boolean.TYPE.equals(b)) { return false; } if (Double.TYPE.equals(b)) { return false; } if (Float.TYPE.equals(b)) { return Double.TYPE.equals(a); } if (Character.TYPE.equals(b)) { return Integer.TYPE.equals(a) || Long.TYPE.equals(a) || Float.TYPE.equals(a) || Double.TYPE.equals(a); } if (Short.TYPE.equals(b)) { return Integer.TYPE.equals(a) || Long.TYPE.equals(a) || Float.TYPE.equals(a) || Double.TYPE.equals(a); } if (Byte.TYPE.equals(b)) { return Short.TYPE.equals(a) || Integer.TYPE.equals(a) || Long.TYPE.equals(a) || Float.TYPE.equals(a) || Double.TYPE.equals(a); } return false; } return a.isAssignableFrom(b); } @Override public boolean set(View v, String name, Object value, Object prevValue) { name = Character.toUpperCase(name.charAt(0)) + name.substring(1); String setter = "set" + name; String listener = "set" + name + "Listener"; Class<?> cls = v.getClass(); while (cls != null) { try { for (Method m : cls.getDeclaredMethods()) { if ((m.getName().equals(setter) || m.getName().equals(listener)) && m.getParameterTypes().length == 1) { Class arg = m.getParameterTypes()[0]; if ((value == null && !arg.isPrimitive()) || (value != null && assignable(arg, value.getClass()))) { m.invoke(v, value); return true; } } } cls = cls.getSuperclass(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return false; } }