Ignore:
Timestamp:
06/26/13 13:27:31 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

  • use java annotations to mark classes and fields to be used when:
    • using java classes with ReflectionAccess? to represent remote objects with FramsClass? description found by "info ..." requests
    • to build up FramsClass? representation of objects not present at remote server
  • allow using primitive types (instead of wraping counterparts) in reflected classes
  • rework FramsClass? creation process (add FramsClassBuilder?)
  • add more tests

CHANGELOG:
Prepare model.World class.

Minor change.

Use primitive types for Genotype and Creature classes.

Use primitive types in model.Neuro* classes.

Use primitive types in model.Joint* classes.

Use primitive types in model.Part* classes.

Fix primitive values.

Extract FramsClassBuilder?.

Add tests of Model classes.

More fixes.

Refactorize out ParamCandidate?.

Several fixes.

Fix all regressions after introducing annotations.

Use annotations throughout the project.

Add exception classes.

Improve creation of FramsClass?.

More changes.

Many changes regarding annotations.

Annotate classes in com.framsticks.model package.

Remove manual FramsClass? constructor.

Construct FramsClass? for Creature. Add test.

Add default values to the ParamAnnotation?.

Add ParamBuilderTest? and ParamAnnotation?.

Add FramsClassAnnotation?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • java/main/src/main/java/com/framsticks/params/ReflectionAccess.java

    r85 r86  
    33import java.lang.reflect.Field;
    44import java.lang.reflect.InvocationTargetException;
    5 import java.lang.reflect.Modifier;
     5import java.lang.reflect.Method;
     6import java.util.HashMap;
     7import java.util.Map;
    68
    79import org.apache.log4j.Logger;
    810
    9 import com.framsticks.util.lang.Containers;
    10 
     11import com.framsticks.util.FramsticksException;
     12
     13import static com.framsticks.util.lang.Containers.*;
    1114
    1215/**
     
    1922 */
    2023public class ReflectionAccess extends SimpleAbstractAccess {
    21         private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
     24        private final static Logger log = Logger.getLogger(ReflectionAccess.class
     25                        .getName());
    2226
    2327        protected final Class<?> reflectedClass;
    2428        private Object object;
    2529
    26         public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) {
     30
     31        protected interface ReflectedSetter {
     32                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
     33        }
     34
     35        protected interface ReflectedGetter {
     36                public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
     37        }
     38
     39        protected static class ReflectedValueParam {
     40                public ReflectedSetter setter;
     41                public ReflectedGetter getter;
     42        }
     43
     44        protected final Map<ValueParam, ReflectedValueParam> reflectedValueParams = new HashMap<>();
     45
     46        public ReflectionAccess(Class<?> reflectedClass) throws ConstructionException {
     47                this(reflectedClass, FramsClassBuilder.buildForClass(reflectedClass));
     48        }
     49
     50        public static boolean typeMatch(Class<?> a, Class<?> b) {
     51                assert !b.isPrimitive();
     52                if (!a.isPrimitive()) {
     53                        return a.equals(b);
     54                }
     55
     56                if (a.equals(int.class)) {
     57                        return b.equals(Integer.class);
     58                }
     59                if (a.equals(double.class)) {
     60                        return b.equals(Double.class);
     61                }
     62                if (a.equals(boolean.class)) {
     63                        return b.equals(Boolean.class);
     64                }
     65                assert false;
     66                return false;
     67        }
     68
     69        public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException {
    2770                this.reflectedClass = reflectedClass;
    2871                setFramsClass(framsClass);
    29         }
    30 
    31         private static String accessorName(boolean get, String id) {
    32                 return (get ? "get"  : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
    33         }
     72
     73                Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
     74
     75                try {
     76                        for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
     77                                if (!candidates.containsKey(vp.getId())) {
     78                                        throw new ConstructionException().msg("missing candidate for param").arg("param", vp);
     79                                }
     80                                ParamCandidate pc = candidates.get(vp.getId());
     81                                if (pc.isReadOnly() && !vp.hasFlag(Flags.READONLY)) {
     82                                        throw new ConstructionException().msg("readonly state conflict").arg("param", vp);
     83                                }
     84                                if (!typeMatch(pc.getRawType(), vp.getStorageType())) {
     85                                        throw new ConstructionException().msg("types mismatch for param").arg("param", vp).arg("candidate", pc.getType()).arg("storage", vp.getStorageType());
     86                                }
     87
     88                                ReflectedValueParam rvp = new ReflectedValueParam();
     89                                reflectedValueParams.put(vp, rvp);
     90                                final boolean primitive = pc.isPrimitive();
     91                                if (pc.getField() != null) {
     92                                        final Field f = pc.getField();
     93                                        rvp.getter = new ReflectedGetter() {
     94                                                @Override
     95                                                public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
     96                                                        return type.cast(f.get(object));
     97                                                }
     98                                        };
     99                                        if (!pc.isFinal()) {
     100                                                rvp.setter = new ReflectedSetter() {
     101                                                        @Override
     102                                                        public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
     103                                                                if (value == null && primitive) {
     104                                                                        throw new FramsticksException().msg("setting null to primitive value");
     105                                                                }
     106                                                                f.set(object, value);
     107                                                        }
     108                                                };
     109                                        }
     110                                } else {
     111                                        final Method g = pc.getGetter();
     112
     113                                        rvp.getter = new ReflectedGetter() {
     114                                                @Override
     115                                                public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     116                                                        return type.cast(g.invoke(object));
     117                                                }
     118                                        };
     119
     120                                        if (!pc.isFinal()) {
     121                                                final Method s = pc.getSetter();
     122                                                rvp.setter = new ReflectedSetter() {
     123                                                        @Override
     124                                                        public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     125                                                                if (value == null && primitive) {
     126                                                                        throw new FramsticksException().msg("setting null to primitive value");
     127                                                                }
     128                                                                s.invoke(object, value);
     129                                                        }
     130                                                };
     131                                        }
     132                                }
     133                        }
     134                } catch (ConstructionException e) {
     135                        throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
     136                }
     137        }
     138
     139        // private static String accessorName(boolean get, String id) {
     140        //      return (get ? "get" : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
     141        // }
    34142
    35143        @Override
    36144        public <T> T get(ValueParam param, Class<T> type) {
    37                 if (object == null) {
    38                         return null;
    39                 }
    40                 try {
    41                         //TODO: use internal id, if present
    42                         String id = param.getId();
     145                try {
    43146                        try {
    44                                 return type.cast(reflectedClass.getField(id).get(object));
    45                         } catch (NoSuchFieldException ignored) {
    46                         }
    47                         try {
    48                                 return type.cast(reflectedClass.getMethod(accessorName(true, id)).invoke(object));
    49                         } catch (NoSuchMethodException | InvocationTargetException ex) {
    50                                 //e.printStackTrace();
    51                         }
    52                         try {
    53                                 return type.cast(reflectedClass.getMethod(id).invoke(object));
    54                         } catch (NoSuchMethodException | InvocationTargetException ex) {
    55                                 //e.printStackTrace();
    56                         }
    57 
    58                 } catch (IllegalAccessException e) {
    59                         log.warn("illegal access error occurred while trying to access returnedObject");
    60                         e.printStackTrace();
    61                 } catch (ClassCastException ignored) {
    62 
    63                 }
    64                 return null;
     147                                if (object == null) {
     148                                        throw new FramsticksException().msg("no object set");
     149                                }
     150
     151                                return reflectedValueParams.get(param).getter.get(object, type);
     152                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
     153                                throw new FramsticksException().msg("failed to get").cause(e);
     154                        }
     155                } catch (FramsticksException e) {
     156                        throw e.arg("param", param).arg("type", type).arg("access", this);
     157                }
    65158        }
    66159
     
    71164
    72165        private <T> void setValue(ValueParam param, T value) {
    73                 if (object == null) {
    74                         return;
    75                 }
    76                 try {
    77                         String id = param.getId();
     166                try {
    78167                        try {
    79                                 Field f = reflectedClass.getField(id);
    80                                 Class<?> t = f.getType();
    81                                 if (Modifier.isFinal(f.getModifiers())) {
    82                                         return;
    83                                 }
    84                                 if (value != null || (!t.isPrimitive())) {
    85                                         f.set(object, value);
    86                                 }
    87                                 return;
    88                         } catch (NoSuchFieldException ignored) {
    89                         }
    90                         try {
    91                                 reflectedClass.getMethod(accessorName(false, id), new Class[]{param.getStorageType()}).invoke(object, value);
    92                         } catch (InvocationTargetException | NoSuchMethodException ignored) {
    93                         }
    94                         try {
    95                                 reflectedClass.getMethod(id, new Class[]{param.getStorageType()}).invoke(object, value);
    96                         } catch (InvocationTargetException | NoSuchMethodException ignored) {
    97                         }
    98                 } catch (Exception ex) {
    99                         ex.printStackTrace();
     168                                if (object == null) {
     169                                        throw new FramsticksException().msg("no object set");
     170                                }
     171                                ReflectedSetter s = reflectedValueParams.get(param).setter;
     172                                if (s == null) {
     173                                        throw new FramsticksException().msg("trying to set final");
     174                                }
     175                                s.set(object, value);
     176                        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
     177                                throw new FramsticksException().msg("failed to set").cause(e);
     178                        }
     179                } catch (FramsticksException e) {
     180                        throw e.arg("param", param).arg("value", value).arg("access", this);
    100181                }
    101182        }
     
    114195
    115196                try {
    116                         for (ValueParam p : Containers.filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
     197                        for (ValueParam p : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
    117198                                setValue(p, p.getDef(Object.class));
    118199                        }
     
    159240
    160241        @Override
    161         public ReflectionAccess cloneAccess() {
     242        public ReflectionAccess cloneAccess() throws ConstructionException {
    162243                return new ReflectionAccess(reflectedClass, framsClass);
    163244        }
     
    173254                return null;
    174255        }
     256
     257        @Override
     258        public String toString() {
     259                StringBuilder b = new StringBuilder();
     260                b.append(framsClass);
     261                if (object != null) {
     262                        b.append("(").append(object).append(")");
     263                }
     264                return b.toString();
     265        }
     266
    175267}
     268
Note: See TracChangeset for help on using the changeset viewer.