Ignore:
Timestamp:
07/02/13 16:20:07 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

CHANGELOG:
Make ProcedureParam? hold only ValueParams?.

Use id instead of names when naming gui components internally.

Basic procedure calling in GUI.

The actual procedure call is currently only backed
by the ObjectInstance?.

Add UnimplementedException?.

Improve naming of various gui elements.

Allow easy navigating in FEST Swing testing.

Add optional explicit order attribute to FramsClassAnnotation?.

That's because java reflection does return declared members
in any specific order. That ordering is needed only for
classes that have no representation in framsticks and need
a deterministic ordering of params.

Add ControlOwner? interface.

Add test for procedure calling in Browser.

First version of ParamAnnotation? for procedures.

Development of ProcedureParam?.

Add draft version of ProcedureParam? implementation in ReflectionAccess?.

Allow viewing FramsClasses? in gui Browser.

Extract ResourceBuilder? from ModelBuilder?.

Remove internalId from Param.

It was currently completely not utilised. Whether it is still needed
after introduction of ParamAnnotation? is arguable.

Add remaining param attributes to ParamAnnotation?.

Change AutoBuilder? semantics.

AutoBuilder? returns list of objects that are to be appended
with methods @AutoAppendAnnotation?.

This allows to omit explicit addition of ModelPackage? to instance
if the instance uses ModelBuilder? (registration of ModelPackage? comes
from schema).

Fix params ordering problem in auto created FramsClasses?.

Improve ObjectInstance?.

Several fixes to ModelBuilder?.

Improve test for ObjectInstance? in Browser.

Make initialization of robot static.

With robot recreated for second browser test, the test hanged
deep in AWT.

Add base convenience base test for Browser tests.

More tests to ObjectInstance?.

Rename Dispatcher.invokeLater() to dispatch().

Add assertDispatch.

It allows assertions in other threads, than TestNGInvoker.
Assertions are gathered after each method invocation and rethrown.

Use timeOut annotation attribute for tests involving some waiting.

Remove firstTask method (merge with joinableStart).

Clean up leftovers.

Remove unused FavouritesXMLFactory (the reading part is already
completely done with generic XmlLoader?, and writing part will be done
based on the same approach if needed).
Move UserFavourite? to the com.framsticks.gui.configuration package.

Remove GenotypeBrowser? as to specific.

This functionality will be available in ObjectInstance?.

Add interface ParamsPackage?.

Package containing registration of Java classes meant to use with
ReflectionAccess? may be in Instance using configuration.

Minor changes.

Make Group immutable.

Add AutoBuilder? interface extending Builder - only those would
be used to automatically build from XML.

Fix groups in FramsClass?.

Minor naming cleanup in Registry.

Add ModelComponent? interface.

All class creating the Model are implementing that interface.

Extract Model.build into ModelBuilder?.

ModelBuilder? will be compatible with other builders
and allow using it from configuration.

Fix NeuroConnection?.

Add synchronous get operation for dispatchers.

Rename JoinableMonitor? to Monitor.

Add ObjectInstance?.

This class is mainly for demonstration
and testing purposes.

Improve FramsServer? runner.

  • improve ExternalProcess? runner,
  • runner can kill the server but also react properly, when the server exists on it's own,
  • set default path to search for framsticks server installation,
  • add LoggingOutputListener?.
File:
1 edited

Legend:

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

    r88 r90  
    44import java.lang.reflect.InvocationTargetException;
    55import java.lang.reflect.Method;
     6import java.util.ArrayList;
    67import java.util.Collections;
     8import java.util.Comparator;
    79import java.util.HashMap;
    8 import java.util.LinkedList;
    910import java.util.List;
    1011import java.util.Map;
     
    1516
    1617import com.framsticks.params.annotations.AutoAppendAnnotation;
     18import com.framsticks.params.types.ProcedureParam;
    1719import com.framsticks.util.FramsticksException;
    1820import com.framsticks.util.lang.Pair;
     
    3133        private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
    3234
    33         protected final Class<?> reflectedClass;
     35        protected final Class<?> javaClass;
    3436        protected final Backend backend;
    3537
     
    4143                protected static final Map<Pair<Class<?>, FramsClass>, Backend> synchronizedCache = Collections.synchronizedMap(new HashMap<Pair<Class<?>, FramsClass>, Backend>());
    4244
    43                 public static class ReflectedValueParam {
    44                         public ReflectedSetter setter;
    45                         public ReflectedGetter getter;
     45
     46                public interface ReflectedGetter {
     47                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
    4648                }
    4749
     
    5052                }
    5153
    52                 public interface ReflectedGetter {
    53                         public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
    54                 }
    55 
    56                 protected final Map<ValueParam, ReflectedValueParam> params;
    57                 protected final List<Method> autoAppendMethods;
     54                public interface ReflectedCaller {
     55                        public Object call(Object object, Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
     56                }
     57
     58                protected final Map<ValueParam, ReflectedSetter> setters = new HashMap<>();
     59                protected final Map<ValueParam, ReflectedGetter> getters = new HashMap<>();
     60                protected final Map<ProcedureParam, ReflectedCaller> callers = new HashMap<>();
     61                protected final List<Method> autoAppendMethods = new ArrayList<>();
    5862
    5963                /**
    6064                 * @param params
    6165                 */
    62                 public Backend(Map<ValueParam, ReflectedValueParam> params, List<Method> autoAppendMethods) {
    63                         // this.params = Collections.unmodifiableMap(params);
    64                         this.params = params;
    65                         this.autoAppendMethods = autoAppendMethods;
     66                public Backend() {
    6667                }
    6768
     
    7576
    7677                        log.debug("constructing backend for " + id);
    77                         final Map<ValueParam, ReflectedValueParam> params = new HashMap<>();
    78 
    79                         Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
    80 
    81                         try {
     78                        backend = new Backend();
     79
     80                        Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass).getCandidates();
     81
     82                        try {
     83                                for (final ProcedureParam pp : filterInstanceof(framsClass.getParamEntries(), ProcedureParam.class)) {
     84                                        if (!candidates.containsKey(pp.getId())) {
     85                                                log.trace("java class does implement method " + pp);
     86                                                continue;
     87                                        }
     88                                        ParamCandidate pc = candidates.get(pp.getId());
     89                                        final Method method = pc.getCaller();
     90
     91                                        backend.callers.put(pp, new ReflectedCaller() {
     92
     93                                                @Override
     94                                                public Object call(Object object, Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     95                                                        return method.invoke(object, arguments);
     96                                                }
     97                                        });
     98
     99                                }
     100
    82101                                for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
    83102                                        if (!candidates.containsKey(vp.getId())) {
     
    92111                                        }
    93112
    94                                         ReflectedValueParam rvp = new ReflectedValueParam();
    95                                         params.put(vp, rvp);
    96113                                        final boolean primitive = pc.isPrimitive();
    97114                                        if (pc.getField() != null) {
    98115                                                final Field f = pc.getField();
    99                                                 rvp.getter = new ReflectedGetter() {
     116                                                backend.getters.put(vp, new ReflectedGetter() {
    100117                                                        @Override
    101118                                                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
    102119                                                                return type.cast(f.get(object));
    103120                                                        }
    104                                                 };
     121                                                });
    105122                                                if (!pc.isFinal()) {
    106                                                         rvp.setter = new ReflectedSetter() {
     123                                                        backend.setters.put(vp, new ReflectedSetter() {
    107124                                                                @Override
    108125                                                                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
     
    112129                                                                        f.set(object, value);
    113130                                                                }
    114                                                         };
     131                                                        });
    115132                                                }
    116133                                        } else {
    117134                                                final Method g = pc.getGetter();
    118135
    119                                                 rvp.getter = new ReflectedGetter() {
     136                                                backend.getters.put(vp, new ReflectedGetter() {
    120137                                                        @Override
    121138                                                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    122139                                                                return type.cast(g.invoke(object));
    123140                                                        }
    124                                                 };
     141                                                });
    125142
    126143                                                if (!pc.isFinal()) {
    127144                                                        final Method s = pc.getSetter();
    128                                                         rvp.setter = new ReflectedSetter() {
     145                                                        backend.setters.put(vp, new ReflectedSetter() {
    129146                                                                @Override
    130147                                                                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     
    134151                                                                        s.invoke(object, value);
    135152                                                                }
    136                                                         };
     153                                                        });
    137154                                                }
    138155                                        }
     
    141158                                throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
    142159                        }
    143 
    144                         List<Method> autoAppendMethods = new LinkedList<>();
    145160
    146161                        Class<?> javaClass = reflectedClass;
     
    156171                                                throw new ConstructionException().msg("invalid number of arguments in AutoAppend marked method").arg("method", m).arg("arguments", args.length);
    157172                                        }
    158                                         autoAppendMethods.add(m);
     173                                        backend.autoAppendMethods.add(m);
    159174                                }
    160175
     
    162177                        }
    163178
    164                         backend = new Backend(params, autoAppendMethods);
     179                        Collections.sort(backend.autoAppendMethods, new Comparator<Method>() {
     180
     181                                @Override
     182                                public int compare(Method m0, Method m1) {
     183                                        Class<?> arg0 = m0.getParameterTypes()[0];
     184                                        Class<?> arg1 = m1.getParameterTypes()[0];
     185                                        if (arg0.isAssignableFrom(arg1)) {
     186                                                return 1;
     187                                        }
     188                                        if (arg1.isAssignableFrom(arg0)) {
     189                                                return -1;
     190                                        }
     191                                        return 0;
     192                                }
     193                        });
     194
    165195                        synchronizedCache.put(id, backend);
    166196                        return backend;
     
    194224        public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException {
    195225                super(framsClass);
    196                 this.reflectedClass = reflectedClass;
     226                this.javaClass = reflectedClass;
    197227                this.backend = Backend.getOrCreateFor(reflectedClass, framsClass);
    198                 // log.info("created ReflectionAccess " + this);
    199         }
    200 
    201         // private static String accessorName(boolean get, String id) {
    202         //      return (get ? "get" : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
    203         // }
     228        }
     229
    204230
    205231        @Override
     
    211237                                }
    212238
    213                                 return backend.params.get(param).getter.get(object, type);
     239                                return backend.getters.get(param).get(object, type);
    214240                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    215241                                throw new FramsticksException().msg("failed to get").cause(e);
     
    231257                                        throw new FramsticksException().msg("no object set");
    232258                                }
    233                                 Backend.ReflectedSetter s = backend.params.get(param).setter;
     259                                Backend.ReflectedSetter s = backend.setters.get(param);
    234260                                if (s == null) {
    235                                         throw new FramsticksException().msg("trying to set final");
     261                                        throw new FramsticksException().msg("trying to set unsettable");
    236262                                }
    237263                                s.set(object, value);
     
    241267                } catch (FramsticksException e) {
    242268                        throw e.arg("param", param).arg("value", value).arg("access", this);
     269                }
     270        }
     271
     272        @Override
     273        public Object call(String id, Object[] arguments) {
     274                return call(framsClass.getParamEntry(id, ProcedureParam.class), arguments);
     275        }
     276
     277        @Override
     278        public Object call(ProcedureParam param, Object[] arguments) {
     279                try {
     280                        try {
     281                                if (object == null) {
     282                                        throw new FramsticksException().msg("no object set");
     283                                }
     284                                Backend.ReflectedCaller c = backend.callers.get(param);
     285                                if (c == null) {
     286                                        throw new FramsticksException().msg("method is not bound");
     287                                }
     288                                return c.call(object, arguments);
     289                        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
     290                                throw new FramsticksException().msg("failed to call").cause(e);
     291                        }
     292                } catch (FramsticksException e) {
     293                        throw e.arg("param", param).arg("access", this);
    243294                }
    244295        }
     
    273324        @Override
    274325        public ReflectionAccess select(Object object) {
    275                 assert object == null || reflectedClass.isInstance(object);
     326                assert object == null || javaClass.isInstance(object);
    276327                this.object = object;
    277328                return this;
     
    302353        @Override
    303354        public ReflectionAccess cloneAccess() throws ConstructionException {
    304                 return new ReflectionAccess(reflectedClass, framsClass);
     355                return new ReflectionAccess(javaClass, framsClass);
    305356        }
    306357
     
    308359        public Object createAccessee() {
    309360                try {
    310                         return reflectedClass.newInstance();
     361                        return javaClass.newInstance();
    311362                } catch (InstantiationException | IllegalAccessException e) {
    312363                        e.printStackTrace();
    313364                }
    314                 log.fatal("failed to create reflected object of class " + reflectedClass.getCanonicalName() + " for frams type " + framsClass.getId());
     365                log.fatal("failed to create reflected object of class " + javaClass.getCanonicalName() + " for frams type " + framsClass.getId());
    315366                return null;
    316367        }
     
    332383                        if (m.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
    333384                                try {
     385                                        log.trace("auto appending with value " + value + " with method " + m);
    334386                                        m.invoke(object, value);
    335387                                        return true;
     
    341393                return false;
    342394        }
     395
    343396}
    344397
Note: See TracChangeset for help on using the changeset viewer.