package org.quaere.alias; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.IdentityHashMap; import java.util.List; public class FieldMapping<T> { private final Class clazz; private final List<T> list; private final IdentityHashMap<Object, Field> fieldMap = new IdentityHashMap<Object, Field>(); /* * This is a special field. It could be any, but it must be one that is not used by the application */ private static final Field FIELD_ITSELF; static { try { FIELD_ITSELF = System.class.getField("out"); } catch (Exception e) { throw new Error("Field System.out not found: " + e); } } public FieldMapping(Class clazz, List<T> list, Object instance) { this.clazz = clazz; this.list = list; boolean basic = Utils.isBasicClass(instance.getClass()); if (basic) { fieldMap.put(instance, FIELD_ITSELF); } else { Field[] fields = instance.getClass().getFields(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; Class type = f.getType(); try { Object obj = Utils.createNew(type); fieldMap.put(obj, f); f.set(instance, obj); } catch (IllegalAccessException e) { throw new Error("IllegalAccessException setting " + instance.getClass().getName()+"."+ f.getName()); } } if (Utils.MAP_NON_PUBLIC_FIELDS) { // TODO only new fields fields = instance.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; if ((f.getModifiers() & Modifier.PUBLIC) != 0) { continue; } f.setAccessible(true); Class type = f.getType(); try { Object obj = Utils.createNew(type); fieldMap.put(obj, f); f.set(instance, obj); } catch (IllegalAccessException e) { throw new Error("IllegalAccessException setting " + instance.getClass().getName()+"."+ f.getName()); } } } } } public List<T> getList() { return list; } Object getValue(Object o, T t) { Field field = fieldMap.get(o); if (field == null) { return o; } else if (FieldMapping.FIELD_ITSELF == field) { return t; } else { try { return field.get(t); } catch (Exception e) { throw new Error("Error accessing field " + field.getName()); } } } public T convert(Object object) { if (clazz == null) { return (T) object; } else { return (T) convert(object, clazz); } } @SuppressWarnings("unchecked") public <U> U convert(Object object, Class<U> clazz) { if (clazz == Operation.class) { return (U) convert(object, this.clazz); } else if (clazz == Get.class) { return (U) object; } if (clazz.isAssignableFrom(object.getClass())) { return (U) object; } if (clazz == Integer.class) { if (object instanceof Number) { return (U) Integer.valueOf(((Number) object).intValue()); } } else if (clazz == String.class) { return (U) object.toString(); } throw new Error("Can not convert " + object.getClass() + " to " + clazz); } Class<T> getObjectClass() { return clazz; } Field getField(Object field) { return fieldMap.get(field); } }