diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/Accessor.java b/src/main/java/com/massivecraft/massivecore/store/accessor/Accessor.java index 65fe423a..5d4d5fb5 100644 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/Accessor.java +++ b/src/main/java/com/massivecraft/massivecore/store/accessor/Accessor.java @@ -1,20 +1,154 @@ package com.massivecraft.massivecore.store.accessor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; -public final class Accessor +public class Accessor { - private static Map, EntityAccessor> class2EntityAccessor = new HashMap, EntityAccessor>(); - - public static EntityAccessor get(Class clazz) + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + private final Class clazz; + public Class getClazz() { return this.clazz; } + + private Map fieldToAccessor = new LinkedHashMap(); + public Map getFieldToAccessor() { return this.fieldToAccessor; } + + public FieldAccessor getFieldAccessor(String fieldName) { - EntityAccessor ret = class2EntityAccessor.get(clazz); - if (ret == null) + FieldAccessor ret = this.fieldToAccessor.get(fieldName); + if (ret == null) throw new IllegalArgumentException("The field \""+fieldName+"\" is not supported."); + return ret; + } + + public void setFieldAccessor(String fieldName, FieldAccessor fieldAccessor) + { + this.fieldToAccessor.put(fieldName, fieldAccessor); + } + + public Collection getFieldNames() + { + return this.fieldToAccessor.keySet(); + } + + // -------------------------------------------- // + // CONSTRUCT / FACTORY + // -------------------------------------------- // + + private static Map, Accessor> classToAccessor = new HashMap, Accessor>(); + + public static Accessor get(Class clazz) + { + Accessor ret = classToAccessor.get(clazz); + if (ret != null) return ret; + return new Accessor(clazz); + } + + private Accessor(Class clazz) + { + this.clazz = clazz; + this.populate(); + classToAccessor.put(clazz, this); + } + + // -------------------------------------------- // + // POPULATE: REFLECTION + // -------------------------------------------- // + + public void populate() + { + Map map = getFieldMap(this.clazz); + for (Entry entry : map.entrySet()) { - ret = new EntityAccessorPerProperty(clazz); - class2EntityAccessor.put(clazz, ret); + String fieldName = entry.getKey(); + Field field = entry.getValue(); + FieldAccessor fieldAccessor = new FieldAccessor(field); + this.setFieldAccessor(fieldName, fieldAccessor); } + } + + // -------------------------------------------- // + // GET & SET & COPY + // -------------------------------------------- // + + public Object get(Object object, String fieldName) + { + FieldAccessor fieldAccessor = this.getFieldAccessor(fieldName); + return fieldAccessor.get(object); + } + + public void set(Object object, String fieldName, Object val) + { + FieldAccessor fieldAccessor = this.getFieldAccessor(fieldName); + fieldAccessor.set(object, val); + } + + // Copy one only! + public void copy(Object from, Object to, String fieldName) + { + FieldAccessor fieldAccessor = this.getFieldAccessor(fieldName); + Object val = fieldAccessor.get(from); + fieldAccessor.set(to, val); + } + + // Copy a few! + public void copy(Object from, Object to, Collection fieldNames) + { + for (String fieldName : fieldNames) + { + this.copy(from, to, fieldName); + } + } + + // Copy them all! + public void copy(Object from, Object to) + { + for (FieldAccessor fieldAccessor : this.getFieldToAccessor().values()) + { + Object val = fieldAccessor.get(from); + fieldAccessor.set(to, val); + } + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + public static List getFieldList(Class clazz) + { + List fields = new ArrayList(); + + for (Class c = clazz; c != null; c = c.getSuperclass()) + { + fields.addAll(Arrays.asList(c.getDeclaredFields())); + } + + return fields; + } + + public static Map getFieldMap(Class clazz) + { + Map ret = new LinkedHashMap(); + + for (Field field : getFieldList(clazz)) + { + if (Modifier.isTransient(field.getModifiers())) continue; + if (Modifier.isFinal(field.getModifiers())) continue; + String fieldName = field.getName(); + if (ret.containsKey(fieldName)) continue; + field.setAccessible(true); + ret.put(fieldName, field); + } + return ret; } diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/AccessorUtil.java b/src/main/java/com/massivecraft/massivecore/store/accessor/AccessorUtil.java deleted file mode 100644 index 2d29b9de..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/AccessorUtil.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class AccessorUtil -{ - // -------------------------------------------- // - // MAKE ACCESSIBLE - // -------------------------------------------- // - - public static void makeAccessible(Field field) - { - if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) - { - field.setAccessible(true); - } - } - - public static void makeAccessible(Method method) - { - if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) - { - method.setAccessible(true); - } - } - - // -------------------------------------------- // - // FIND - // -------------------------------------------- // - - public static List findMethod(Class clazz, String name) - { - List ret = new ArrayList(); - for (Class c = clazz; c != null; c = c.getSuperclass()) - { - Method[] methods = (c.isInterface() ? c.getMethods() : c.getDeclaredMethods()); - for (Method method : methods) - { - if (name.equals(method.getName())) ret.add(method); - } - } - return ret; - } - - public static Field findField(Class clazz, String name) - { - for (Class c = clazz; c != null && !Object.class.equals(c); c = c.getSuperclass()) - { - Field[] fields = c.getDeclaredFields(); - for (Field field : fields) - { - if (name.equals(field.getName())) return field; - } - } - return null; - } - - public static List findAllFields(Class clazz) - { - List fields = new ArrayList(); - for (Class c = clazz; c != null; c = c.getSuperclass()) - { - fields.addAll(Arrays.asList(c.getDeclaredFields())); - } - return fields; - } - - /** - * Must be non-transient. - * Must be non-final. - * Will be set accessible if possible. - */ - public static Map getFieldMap(Class clazz) - { - Map ret = new HashMap(); - - for (Field field : findAllFields(clazz)) - { - if (Modifier.isTransient(field.getModifiers())) continue; - if (Modifier.isFinal(field.getModifiers())) continue; - makeAccessible(field); - ret.put(field.getName(), field); - } - - return ret; - } - - // -------------------------------------------- // - // FIND GETTERS AND SETTERS - // -------------------------------------------- // - - public static String ucfirst(String str) - { - return Character.toUpperCase(str.charAt(0))+str.substring(1); - } - public static String calcGetterNameBool(String fieldName) { return "is"+ucfirst(fieldName); } - public static String calcGetterName(String fieldName) { return "get"+ucfirst(fieldName); } - public static String calcSetterName(String fieldName) { return "set"+ucfirst(fieldName); } - - // TODO: Use a predictate? - public static Method findGetter(Class clazz, String fieldName) - { - for (Method method : findMethod(clazz, calcGetterName(fieldName))) - { - if (method.getParameterTypes().length == 0 && method.getReturnType() != null) return method; - } - - for (Method method : findMethod(clazz, calcGetterNameBool(fieldName))) - { - if (method.getParameterTypes().length == 0 && method.getReturnType() == Boolean.class) return method; - } - - return null; - } - - public static Method findSetter(Class clazz, String fieldName) - { - List methods = findMethod(clazz, calcSetterName(fieldName)); - methods.addAll(findMethod(clazz, fieldName)); - - for (Method method : methods) - { - if (method != null && method.getParameterTypes().length == 1) return method; - } - - return null; - } - - // -------------------------------------------- // - // CREATE PROPERTY ACCESS - // -------------------------------------------- // - - public static PropertyGetter createPropertyGetter(Class clazz, String name) - { - Method method = findGetter(clazz, name); - if (method != null) return new PropertyGetterMethodReflection(method); - - Field field = findField(clazz, name); - if (field != null) return new PropertyGetterFieldReflection(field); - - return null; - } - - public static PropertySetter createPropertySetter(Class clazz, String name) - { - Method method = findSetter(clazz, name); - if (method != null) return new PropertySetterMethodReflection(method); - - Field field = findField(clazz, name); - if (field != null) return new PropertySetterFieldReflection(field); - - return null; - } - - public static PropertyAccessor createPropertyAccessor(Class clazz, String name) - { - PropertyGetter getter = createPropertyGetter(clazz, name); - if (getter == null) return null; - - PropertySetter setter = createPropertySetter(clazz, name); - if (setter == null) return null; - - return new PropertyAccessorComposite(getter, setter); - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessor.java b/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessor.java deleted file mode 100644 index 48fd78a3..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessor.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public interface EntityAccessor extends EntitySetter, EntityGetter, EntityGlue -{ - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessorAbstract.java b/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessorAbstract.java deleted file mode 100644 index c092a0b6..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessorAbstract.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.util.Collection; - -public abstract class EntityAccessorAbstract implements EntityAccessor -{ - protected final Class clazz; - public Class getClazz() { return this.clazz; } - - public EntityAccessorAbstract(Class clazz) - { - this.clazz = clazz; - } - - private static final boolean DEFAULT_TRANSPARENT = false; - @Override - public void copy(Object from, Object to, String property, boolean transparent) - { - Object val = this.get(from, property); - if (transparent && val == null) return; - this.set(to, property, val); - } - @Override - public void copy(Object from, Object to, String property) - { - this.copy(from, to, property, DEFAULT_TRANSPARENT); - } - @Override - public void copy(Object from, Object to, Collection properties, boolean transparent) - { - for (String property : properties) - { - this.copy(from, to, property, transparent); - } - } - @Override - public void copy(Object from, Object to, Collection properties) - { - this.copy(from, to, properties, DEFAULT_TRANSPARENT); - } - @Override - public void copy(Object from, Object to, boolean transparent) - { - this.copy(from, to, this.getPropertyNames(), transparent); - } - @Override - public void copy(Object from, Object to) - { - this.copy(from, to, DEFAULT_TRANSPARENT); - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessorPerProperty.java b/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessorPerProperty.java deleted file mode 100644 index e096a125..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityAccessorPerProperty.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class EntityAccessorPerProperty extends EntityAccessorAbstract -{ - protected Map propertyAccessors; - public Map getPropertyAccessors() { return this.propertyAccessors; } - public PropertyAccessor getPropertyAccessor(String name) - { - PropertyAccessor ret = this.propertyAccessors.get(name); - if (ret == null) - { - throw new IllegalArgumentException("The property \""+name+"\" is not supported."); - } - return ret; - } - public void setPropertyAccessor(String name, PropertyAccessor val) - { - this.propertyAccessors.put(name, val); - } - - - //----------------------------------------------// - // CONSTRUCTORS - //----------------------------------------------// - - public EntityAccessorPerProperty(Class clazz) - { - super(clazz); - this.propertyAccessors = new HashMap(); - this.populateAI1(); - } - - //----------------------------------------------// - // AI - //----------------------------------------------// - - public void populateAI1() - { - this.propertyAccessorAI(AccessorUtil.getFieldMap(this.clazz).keySet()); - } - - public void propertyAccessorAI(String name) - { - this.propertyAccessors.put(name, AccessorUtil.createPropertyAccessor(this.clazz, name)); - } - public void propertyAccessorAI(String... names) - { - for (String name : names) - { - this.propertyAccessorAI(name); - } - } - public void propertyAccessorAI(Collection names) - { - this.propertyAccessorAI(names.toArray(new String[0])); - } - - //----------------------------------------------// - // IMPLEMENTATION - //----------------------------------------------// - - @Override - public void set(Object entity, String property, Object val) - { - PropertyAccessor pa = this.getPropertyAccessor(property); - pa.set(entity, val); - } - - @Override - public Object get(Object entity, String property) - { - PropertyAccessor pa = this.getPropertyAccessor(property); - return pa.get(entity); - } - - @Override - public Collection getPropertyNames() - { - return this.propertyAccessors.keySet(); - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityGetter.java b/src/main/java/com/massivecraft/massivecore/store/accessor/EntityGetter.java deleted file mode 100644 index 9d42f7d2..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityGetter.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public interface EntityGetter -{ - public Object get(Object entity, String property); -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityGlue.java b/src/main/java/com/massivecraft/massivecore/store/accessor/EntityGlue.java deleted file mode 100644 index 8a8953da..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/EntityGlue.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.util.Collection; - -public interface EntityGlue -{ - public void copy(Object from, Object to, String property, boolean transparent); - public void copy(Object from, Object to, String property); - - public void copy(Object from, Object to, Collection properties, boolean transparent); - public void copy(Object from, Object to, Collection properties); - - public void copy(Object from, Object to, boolean transparent); - public void copy(Object from, Object to); - - public Collection getPropertyNames(); -} \ No newline at end of file diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/EntitySetter.java b/src/main/java/com/massivecraft/massivecore/store/accessor/EntitySetter.java deleted file mode 100644 index 8f1194e7..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/EntitySetter.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public interface EntitySetter -{ - public void set(Object entity, String property, Object val); -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/FieldAccessor.java b/src/main/java/com/massivecraft/massivecore/store/accessor/FieldAccessor.java new file mode 100644 index 00000000..4f47fdac --- /dev/null +++ b/src/main/java/com/massivecraft/massivecore/store/accessor/FieldAccessor.java @@ -0,0 +1,52 @@ +package com.massivecraft.massivecore.store.accessor; + +import java.lang.reflect.Field; + +public class FieldAccessor +{ + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + private final Field field; + + // -------------------------------------------- // + // CONSTRUCT + // -------------------------------------------- // + + public FieldAccessor(Field field) + { + field.setAccessible(true); + this.field = field; + } + + // -------------------------------------------- // + // CORE + // -------------------------------------------- // + + public Object get(Object entity) + { + try + { + return this.field.get(entity); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + + public void set(Object entity, Object val) + { + try + { + this.field.set(entity, val); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyAccessor.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyAccessor.java deleted file mode 100644 index c28440b9..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyAccessor.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public interface PropertyAccessor extends PropertySetter, PropertyGetter -{ - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyAccessorComposite.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyAccessorComposite.java deleted file mode 100644 index 5168bc5a..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyAccessorComposite.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public class PropertyAccessorComposite implements PropertyAccessor -{ - private final PropertyGetter getter; - private final PropertySetter setter; - - public PropertyAccessorComposite(PropertyGetter getter, PropertySetter setter) - { - this.getter = getter; - this.setter = setter; - } - - @Override - public void set(Object entity, Object val) - { - this.setter.set(entity, val); - } - - @Override - public Object get(Object entity) - { - return this.getter.get(entity); - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetter.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetter.java deleted file mode 100644 index b9bd34cf..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetter.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public interface PropertyGetter -{ - public Object get(Object entity); -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetterFieldReflection.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetterFieldReflection.java deleted file mode 100644 index 7f9d6749..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetterFieldReflection.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.lang.reflect.Field; - -public class PropertyGetterFieldReflection implements PropertyGetter -{ - private final Field field; - - public PropertyGetterFieldReflection(Field field) - { - AccessorUtil.makeAccessible(field); - this.field = field; - } - - @Override - public Object get(Object entity) - { - try - { - return this.field.get(entity); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetterMethodReflection.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetterMethodReflection.java deleted file mode 100644 index 8678987e..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertyGetterMethodReflection.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.lang.reflect.Method; - -public class PropertyGetterMethodReflection implements PropertyGetter -{ - private final Method method; - - public PropertyGetterMethodReflection(Method method) - { - AccessorUtil.makeAccessible(method); - this.method = method; - } - - @Override - public Object get(Object entity) - { - try - { - return this.method.invoke(entity, new Object[0]); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetter.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetter.java deleted file mode 100644 index 073cfca0..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetter.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -public interface PropertySetter -{ - public void set(Object entity, Object val); -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetterFieldReflection.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetterFieldReflection.java deleted file mode 100644 index 561ae218..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetterFieldReflection.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.lang.reflect.Field; - -public class PropertySetterFieldReflection implements PropertySetter -{ - private final Field field; - - public PropertySetterFieldReflection(Field field) - { - AccessorUtil.makeAccessible(field); - this.field = field; - } - - @Override - public void set(Object entity, Object val) - { - try - { - this.field.set(entity, val); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - -} diff --git a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetterMethodReflection.java b/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetterMethodReflection.java deleted file mode 100644 index 081a08cf..00000000 --- a/src/main/java/com/massivecraft/massivecore/store/accessor/PropertySetterMethodReflection.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.massivecraft.massivecore.store.accessor; - -import java.lang.reflect.Method; - -public class PropertySetterMethodReflection implements PropertySetter -{ - private final Method method; - - public PropertySetterMethodReflection(Method method) - { - AccessorUtil.makeAccessible(method); - this.method = method; - } - - @Override - public void set(Object entity, Object val) - { - try - { - this.method.invoke(entity, val); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - -}