package novoda.android.typewriter.introspection; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import novoda.android.typewriter.annotation.Mapper; import novoda.android.typewriter.util.StringUtil; public class RichClass<T> { private final Class<T> klass; private final List<Method> methods; private final Map<String, String> fieldMapper; private final Map<String, Method> methodMapper; public RichClass(Class<T> klass) { this.klass = klass; methods = Arrays.asList(klass.getMethods()); fieldMapper = new HashMap<String, String>(); for (Field f : klass.getDeclaredFields()) { Mapper s = f.getAnnotation(Mapper.class); if (s != null) { fieldMapper.put(s.value(), f.getName()); } } methodMapper = new HashMap<String, Method>(); for (Method m : methods) { Mapper mm = m.getAnnotation(Mapper.class); if (mm != null) { methodMapper.put(mm.value(), m); } } } public Method setter(String what) { if (methodMapper.containsKey(what)) { return methodMapper.get(what); } String methodName = StringUtil.asCamelifySetMethod(what); if (fieldMapper.containsKey(what)) { methodName = StringUtil.asCamelifySetMethod(fieldMapper.get(what)); } for (Method m : methods) { if (m.getName().equals(methodName)) { return m; } } throw new RichClassException("can not find method " + what + " " + fieldMapper); } public boolean hasMethod(String method) { try { return setter(method) != null; } catch (Exception e) { return false; } } public T newInstance() { try { return klass.newInstance(); } catch (Exception e) { throw new RichClassException(e); } } public static class RichClassException extends RuntimeException { public RichClassException(String reason) { super(reason); } public RichClassException(Exception reason) { super(reason); } } }