diff --git a/src/main/java/eu/midnightdust/yaytris/util/NightJson.java b/src/main/java/eu/midnightdust/yaytris/util/NightJson.java index d840ab5..ddaa48c 100644 --- a/src/main/java/eu/midnightdust/yaytris/util/NightJson.java +++ b/src/main/java/eu/midnightdust/yaytris/util/NightJson.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; import java.util.*; import java.util.concurrent.atomic.AtomicReference; @@ -36,7 +37,8 @@ public class NightJson { jsonFile.write(String.format("// %s\n", ((Comment) field.get(null)).commentString)); continue; } - jsonFile.write(String.format(field.getType() == String.class || field.getType().isEnum() ? "\"%s\": \"%s\"" : "\"%s\": %s", field.getName(), field.get(null))); + jsonFile.write(String.format("\"%s\": ", field.getName())); + jsonFile.write(objToString(field.get(null), field.getType())); jsonFile.write(it.hasNext() ? ",\n" : "\n"); } jsonFile.write("}"); @@ -65,9 +67,13 @@ public class NightJson { lastKey.set(s.replaceAll("([\":])", "")); jsonKeyValuePairs.put(lastKey.get(), ""); } - else jsonKeyValuePairs.put(lastKey.get(), (jsonKeyValuePairs.get( - lastKey.get()).isEmpty() ? "" : jsonKeyValuePairs.get(lastKey.get()) + " " - ) + s.replaceAll("([\",])", "")); + else { + String val = s.replaceAll("(\")", ""); + if (val.endsWith(",")) val = val.substring(0, val.length()-1); + jsonKeyValuePairs.put(lastKey.get(), (jsonKeyValuePairs.get( + lastKey.get()).isEmpty() ? "" : jsonKeyValuePairs.get(lastKey.get()) + " " + ) + val); + } } }); @@ -78,7 +84,7 @@ public class NightJson { try { field = jsonClass.getField(key); } catch (NoSuchFieldException e) {continue;} - field.set(field, stringToObj(field, currentString)); + field.set(field, stringToFieldObj(currentString, field)); } jsonFile.close(); } catch (IOException | IllegalAccessException | NoSuchElementException e) { @@ -87,8 +93,44 @@ public class NightJson { } } - private Object stringToObj(Field field, String currentString) { - switch (field.getType().getName()) { + private String objToString(Object value, Class type) throws IllegalAccessException { + if (type == Map.class) { + StringBuilder mapPairs = new StringBuilder(); + Map map = (Map) value; + Iterator it = map.keySet().iterator(); + if (it.hasNext()) mapPairs.append("{"); + while (it.hasNext()) { + Object key = it.next(); + Object val = map.get(key); + mapPairs.append(String.format("%s: %s", objToString(key, key.getClass()), objToString(val, val.getClass()))); + if (it.hasNext()) mapPairs.append(","); + else mapPairs.append("}"); + } + return mapPairs.toString(); + } + return String.format(type == String.class || type.isEnum() ? "\"%s\"" : "%s", value); + } + + private Object stringToFieldObj(String currentString, Field field) { + if (field.getType() == Map.class) { + Map map = new HashMap<>(); + Iterator it = Arrays.stream(currentString.substring(1, currentString.length()-1).split(",")).iterator(); + while (it.hasNext()) { + String pair = it.next(); + System.out.println(pair); + int semicolonPos = pair.indexOf(":"); + Class keyType = getPrimitiveType((Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]); + Class valType = getPrimitiveType((Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[1]); + map.put(stringToObj(pair.substring(0, semicolonPos), keyType), + stringToObj(pair.substring(semicolonPos+2), valType)); + } + return map; + } + return stringToObj(currentString, field.getType()); + } + + private Object stringToObj(String currentString, Class type) { + switch (type.getName()) { case "byte": return Byte.parseByte(currentString); case "int": return Integer.parseInt(currentString); case "long": return Long.parseLong(currentString); @@ -96,11 +138,16 @@ public class NightJson { case "double": return Double.parseDouble(currentString); case "boolean": return Boolean.parseBoolean(currentString); } - if (field.getType().isEnum()) return Arrays.stream(field.getType().getEnumConstants()) + if (type.isEnum()) return Arrays.stream(type.getEnumConstants()) .filter(enumConstant -> Objects.equals(enumConstant.toString(), currentString)).findFirst().orElseThrow(); else return currentString; } + public static Class getPrimitiveType(Class rawType) { + try { return (Class) rawType.getField("TYPE").get(null); // Tries to get primitive types from non-primitives (e.g. Boolean -> boolean) + } catch (NoSuchFieldException | IllegalAccessException ignored) { return rawType; } + } + public static class Comment { final String commentString; public Comment(String commentString) {