- Timestamp:
- 07/02/13 16:20:07 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
java/main/src/main/java/com/framsticks/params/ReflectionAccess.java
r88 r90 4 4 import java.lang.reflect.InvocationTargetException; 5 5 import java.lang.reflect.Method; 6 import java.util.ArrayList; 6 7 import java.util.Collections; 8 import java.util.Comparator; 7 9 import java.util.HashMap; 8 import java.util.LinkedList;9 10 import java.util.List; 10 11 import java.util.Map; … … 15 16 16 17 import com.framsticks.params.annotations.AutoAppendAnnotation; 18 import com.framsticks.params.types.ProcedureParam; 17 19 import com.framsticks.util.FramsticksException; 18 20 import com.framsticks.util.lang.Pair; … … 31 33 private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName()); 32 34 33 protected final Class<?> reflectedClass;35 protected final Class<?> javaClass; 34 36 protected final Backend backend; 35 37 … … 41 43 protected static final Map<Pair<Class<?>, FramsClass>, Backend> synchronizedCache = Collections.synchronizedMap(new HashMap<Pair<Class<?>, FramsClass>, Backend>()); 42 44 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; 46 48 } 47 49 … … 50 52 } 51 53 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<>(); 58 62 59 63 /** 60 64 * @param params 61 65 */ 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() { 66 67 } 67 68 … … 75 76 76 77 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 82 101 for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) { 83 102 if (!candidates.containsKey(vp.getId())) { … … 92 111 } 93 112 94 ReflectedValueParam rvp = new ReflectedValueParam();95 params.put(vp, rvp);96 113 final boolean primitive = pc.isPrimitive(); 97 114 if (pc.getField() != null) { 98 115 final Field f = pc.getField(); 99 rvp.getter =new ReflectedGetter() {116 backend.getters.put(vp, new ReflectedGetter() { 100 117 @Override 101 118 public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException { 102 119 return type.cast(f.get(object)); 103 120 } 104 } ;121 }); 105 122 if (!pc.isFinal()) { 106 rvp.setter =new ReflectedSetter() {123 backend.setters.put(vp, new ReflectedSetter() { 107 124 @Override 108 125 public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException { … … 112 129 f.set(object, value); 113 130 } 114 } ;131 }); 115 132 } 116 133 } else { 117 134 final Method g = pc.getGetter(); 118 135 119 rvp.getter =new ReflectedGetter() {136 backend.getters.put(vp, new ReflectedGetter() { 120 137 @Override 121 138 public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { 122 139 return type.cast(g.invoke(object)); 123 140 } 124 } ;141 }); 125 142 126 143 if (!pc.isFinal()) { 127 144 final Method s = pc.getSetter(); 128 rvp.setter =new ReflectedSetter() {145 backend.setters.put(vp, new ReflectedSetter() { 129 146 @Override 130 147 public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { … … 134 151 s.invoke(object, value); 135 152 } 136 } ;153 }); 137 154 } 138 155 } … … 141 158 throw e.arg("java class", reflectedClass).arg("framsClass", framsClass); 142 159 } 143 144 List<Method> autoAppendMethods = new LinkedList<>();145 160 146 161 Class<?> javaClass = reflectedClass; … … 156 171 throw new ConstructionException().msg("invalid number of arguments in AutoAppend marked method").arg("method", m).arg("arguments", args.length); 157 172 } 158 autoAppendMethods.add(m);173 backend.autoAppendMethods.add(m); 159 174 } 160 175 … … 162 177 } 163 178 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 165 195 synchronizedCache.put(id, backend); 166 196 return backend; … … 194 224 public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException { 195 225 super(framsClass); 196 this. reflectedClass = reflectedClass;226 this.javaClass = reflectedClass; 197 227 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 204 230 205 231 @Override … … 211 237 } 212 238 213 return backend. params.get(param).getter.get(object, type);239 return backend.getters.get(param).get(object, type); 214 240 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 215 241 throw new FramsticksException().msg("failed to get").cause(e); … … 231 257 throw new FramsticksException().msg("no object set"); 232 258 } 233 Backend.ReflectedSetter s = backend. params.get(param).setter;259 Backend.ReflectedSetter s = backend.setters.get(param); 234 260 if (s == null) { 235 throw new FramsticksException().msg("trying to set final");261 throw new FramsticksException().msg("trying to set unsettable"); 236 262 } 237 263 s.set(object, value); … … 241 267 } catch (FramsticksException e) { 242 268 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); 243 294 } 244 295 } … … 273 324 @Override 274 325 public ReflectionAccess select(Object object) { 275 assert object == null || reflectedClass.isInstance(object);326 assert object == null || javaClass.isInstance(object); 276 327 this.object = object; 277 328 return this; … … 302 353 @Override 303 354 public ReflectionAccess cloneAccess() throws ConstructionException { 304 return new ReflectionAccess( reflectedClass, framsClass);355 return new ReflectionAccess(javaClass, framsClass); 305 356 } 306 357 … … 308 359 public Object createAccessee() { 309 360 try { 310 return reflectedClass.newInstance();361 return javaClass.newInstance(); 311 362 } catch (InstantiationException | IllegalAccessException e) { 312 363 e.printStackTrace(); 313 364 } 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()); 315 366 return null; 316 367 } … … 332 383 if (m.getParameterTypes()[0].isAssignableFrom(value.getClass())) { 333 384 try { 385 log.trace("auto appending with value " + value + " with method " + m); 334 386 m.invoke(object, value); 335 387 return true; … … 341 393 return false; 342 394 } 395 343 396 } 344 397
Note: See TracChangeset
for help on using the changeset viewer.