// HACK: reflection private void updateScenarioParameters() { for (ConfigurableObject configObj : this.scenarioParameters.values()) { String beanName = configObj.getId(); Object bean = this.context.getBean(beanName); Class<?> clazz = bean.getClass(); HashMap<String, java.lang.reflect.Field> declaredFields = new HashMap<String, java.lang.reflect.Field>(); do { for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { declaredFields.put(field.getName(), field); } clazz = clazz.getSuperclass(); } while (clazz != null); clazz = bean.getClass(); for (ScenarioParameter parameter : configObj.getParameters()) { String field = this.capitalize(parameter.getField()); Object value = parameter.getValue(); Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.getName().equals("set" + field)) { try { method.invoke(bean, value); } catch (Exception e) { throw new RuntimeException(e); } ((NodeBacked) bean).persist(); break; } } } } }
@RequestMapping(value = "/save", method = RequestMethod.POST) @ResponseBody public JsonResponse save( @RequestParam("ids") String[] ids, @RequestParam("counts") int[] counts, @RequestParam("fields") String[] fields, @RequestParam("values") String[] values) { Map<String, Map<String, ScenarioParameter>> params = new HashMap<String, Map<String, ScenarioParameter>>(); Map<String, ConfigurableObject> oldParams = this.engineService.getScenarioParameters(); int countsum = 0; String error = null; for (int i = 0; i < ids.length; i++) { Map<String, ScenarioParameter> p = new HashMap<String, ScenarioParameter>(); for (int j = countsum; j < countsum + counts[i]; j++) { Object value; ConfigurableObject obj = oldParams.get(ids[i]); ScenarioParameter param = obj.getParameter(fields[j]); try { value = this.parseValue(param.getValue(), values[j]); } catch (IllegalArgumentException e) { error = "Incorrect value for '" + ids[i] + "' field '" + fields[j] + "' (" + e.getMessage() + ")"; break; } p.put(fields[j], new ScenarioParameter(fields[j], value)); } if (error != null) break; params.put(ids[i], p); countsum += counts[i]; } if (error == null) { this.engineService.setScenarioParameters(params); return new JsonResponse(true); } else { JsonResponse response = new JsonResponse(false); response.setError(error); return response; } }
@Override public synchronized void setScenarioParameters( Map<String, Map<String, ScenarioParameter>> parameters) { // perform sanity check first to avoid exploitation by hackers for (String obj : parameters.keySet()) { if (!this.scenarioParameters.containsKey(obj)) { throw new RuntimeException("Object with id '" + obj + "' can not be configured"); } ConfigurableObject oldObj = this.scenarioParameters.get(obj); Map<String, ScenarioParameter> newParams = parameters.get(obj); for (String field : newParams.keySet()) { if (!oldObj.containsParam(field)) { throw new RuntimeException( "'" + obj + "'" + " has no configurable field '" + field + "'"); } ScenarioParameter newParam = newParams.get(field); oldObj.setParamValue(field, newParam.getValue()); } } this.updateScenarioParameters(); }
private synchronized void loadScenario(Scenario scenario) { if (this.simulation.getState() != EngineState.STOPPED && this.simulation.getState() != EngineState.CRASHED) return; boolean found = false; for (Scenario scen : this.scenarios) { if (scenario.equals(scen)) { found = true; break; } } if (!found) throw new RuntimeException("Scenario " + scenario.getName() + " does not exist"); if (this.context != null) { this.context.close(); } try { this.graph.clear(); } catch (Exception err) { logger.error("Error clearing graph", err); } String[] configs = {SCENARIO_FOLDER + "/" + scenario.getName()}; this.context = new ClassPathXmlApplicationContext(configs, this.applicationContext); if (!this.currentScenario.equals(found) || this.scenarioParameters.isEmpty()) { this.scenarioParameters.clear(); String[] names = this.context.getBeanNamesForType(Object.class); for (String beanName : names) { Object bean = this.context.getBean(beanName); ArrayList<java.lang.reflect.Field> fields = new ArrayList<java.lang.reflect.Field>(); Class<?> clazz = bean.getClass(); do { for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { fields.add(field); } clazz = clazz.getSuperclass(); } while (clazz != null); clazz = bean.getClass(); for (java.lang.reflect.Field field : fields) { String name = field.getName(); SimulationParameter annotation = field.getAnnotation(SimulationParameter.class); if (annotation != null) { Object value = null; try { Method getter; Class<?> fieldType = field.getType(); if (fieldType.equals(Boolean.class) || fieldType.equals(boolean.class)) { getter = bean.getClass().getMethod("is" + this.capitalize(name)); } else { getter = bean.getClass().getMethod("get" + this.capitalize(name)); } value = getter.invoke(bean); } catch (Exception e) { throw new RuntimeException(e); } ConfigurableObject cfgObj = this.scenarioParameters.get(beanName); if (cfgObj == null) { cfgObj = new ConfigurableObject(beanName, clazz.getName()); this.scenarioParameters.put(beanName, cfgObj); } ScenarioParameter parameter = new ScenarioParameter(name, value, annotation.label()); if (!Double.isNaN(annotation.from()) && !Double.isNaN(annotation.to())) { parameter.setFrom(annotation.from()); parameter.setTo(annotation.to()); } if (!Double.isNaN(annotation.step())) { parameter.setStep(annotation.step()); } cfgObj.addParameter(parameter); } } } } this.currentScenario = scenario; this.scenarioLoaded = true; }