package com.team254.lib.util; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.*; /** * ConstantsBase * <p> * Base class for storing robot constants. Anything stored as a public static * field will be reflected and be able to set externally * * @author Tom Bottiglieri */ public abstract class ConstantsBase { HashMap<String, Boolean> modifiedKeys = new HashMap<String, Boolean>(); public abstract String getFileLocation(); public static class Constant { public String name; public Class type; public Object value; public Constant(String name, Class type, Object value) { this.name = name; this.type = type; this.value = value; } public boolean equals(Object o) { String itsName = ((Constant) o).name; Class itsType = ((Constant) o).type; Object itsValue = ((Constant) o).value; return o instanceof Constant && this.name.equals(itsName) && this.type.equals(itsType) && this.value.equals(itsValue); } } public File getFile() { String filePath = getFileLocation(); filePath = filePath.replaceFirst("^~", System.getProperty("user.home")); return new File(filePath); } public boolean setConstant(String name, Double value) { return setConstantRaw(name, value); } public boolean setConstant(String name, Integer value) { return setConstantRaw(name, value); } public boolean setConstant(String name, String value) { return setConstantRaw(name, value); } private boolean setConstantRaw(String name, Object value) { boolean success = false; Field[] declaredFields = this.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) && field.getName().equals(name)) { try { Object current = field.get(this); field.set(this, value); success = true; if (!value.equals(current)) { modifiedKeys.put(name, true); } } catch (IllegalArgumentException | IllegalAccessException e) { System.out.println("Could not set field: " + name); } } } return success; } public Object getValueForConstant(String name) throws Exception { Field[] declaredFields = this.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) && field.getName().equals(name)) { try { return field.get(this); } catch (IllegalArgumentException | IllegalAccessException e) { throw new Exception("Constant not found"); } } } throw new Exception("Constant not found"); } public Constant getConstant(String name) { Field[] declaredFields = this.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) && field.getName().equals(name)) { try { return new Constant(field.getName(), field.getType(), field.get(this)); } catch (IllegalArgumentException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return new Constant("", Object.class, 0); } public Collection<Constant> getConstants() { List<Constant> constants = (List<Constant>) getAllConstants(); int stop = constants.size() - 1; for (int i = 0; i < constants.size(); ++i) { Constant c = constants.get(i); if ("kEndEditableArea".equals(c.name)) { stop = i; } } return constants.subList(0, stop); } private Collection<Constant> getAllConstants() { Field[] declaredFields = this.getClass().getDeclaredFields(); List<Constant> constants = new ArrayList<Constant>( declaredFields.length); for (Field field : declaredFields) { if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) { Constant c; try { c = new Constant(field.getName(), field.getType(), field.get(this)); constants.add(c); } catch (IllegalArgumentException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return constants; } public JSONObject getJSONObjectFromFile() throws IOException, ParseException { File file = getFile(); if (file == null || !file.exists()) { return new JSONObject(); } FileReader reader; reader = new FileReader(file); JSONParser jsonParser = new JSONParser(); return (JSONObject) jsonParser.parse(reader); } public void loadFromFile() { try { JSONObject jsonObject = getJSONObjectFromFile(); Set keys = jsonObject.keySet(); for (Object o : keys) { String key = (String) o; Object value = jsonObject.get(o); if (value instanceof Long && getConstant(key).type.equals(int.class)) { value = new BigDecimal((Long) value).intValueExact(); } setConstantRaw(key, value); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void saveToFile() { File file = getFile(); if (file == null) { return; } try { JSONObject json = getJSONObjectFromFile(); FileWriter writer = new FileWriter(file); for (String key : modifiedKeys.keySet()) { try { Object value = getValueForConstant(key); json.put(key, value); } catch (Exception e) { e.printStackTrace(); } } writer.write(json.toJSONString()); writer.close(); } catch (IOException | ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }