diff --git a/aQute.libg/src/aQute/lib/json/EnumHandler.java b/aQute.libg/src/aQute/lib/json/EnumHandler.java index 1e6837bd97..507f825105 100644 --- a/aQute.libg/src/aQute/lib/json/EnumHandler.java +++ b/aQute.libg/src/aQute/lib/json/EnumHandler.java @@ -2,25 +2,40 @@ import java.io.IOException; import java.lang.reflect.Type; +import java.util.HashMap; import java.util.Map; public class EnumHandler extends Handler { @SuppressWarnings("rawtypes") final Class type; + final Map mapping = new HashMap<>(); public EnumHandler(Class type) { this.type = type; + for ( Object constant : type.getEnumConstants()) { + String s = JSONCodec.keyword(constant.toString().toLowerCase()); + mapping.put(s, constant); + } } @Override public void encode(Encoder app, Object object, Map visited) throws IOException, Exception { - StringHandler.string(app, object.toString()); + StringHandler.string(app, JSONCodec.keyword(object.toString())); } @Override @SuppressWarnings("unchecked") public Object decode(Decoder dec, String s) throws Exception { - return Enum.valueOf(type, s); + try { + return Enum.valueOf(type, s); + } catch (IllegalArgumentException e) { + Object result = mapping.get(s); + if (result != null) { + throw new IllegalArgumentException( + "enum constant " + s + " not found for " + type.getSimpleName() + " " + mapping.values()); + } + return result; + } } } diff --git a/aQute.libg/src/aQute/lib/json/JSONCodec.java b/aQute.libg/src/aQute/lib/json/JSONCodec.java index fc9345811c..b3af7e1100 100644 --- a/aQute.libg/src/aQute/lib/json/JSONCodec.java +++ b/aQute.libg/src/aQute/lib/json/JSONCodec.java @@ -570,4 +570,11 @@ public static String keyword(String name) { return name; } + public static String name(String key) { + if (keywords.contains(key)) { + return key + KEYWORD_SUFFIX; + } + return key; + } + } diff --git a/aQute.libg/src/aQute/lib/json/ObjectHandler.java b/aQute.libg/src/aQute/lib/json/ObjectHandler.java index 00b4739e33..cc5c66ac7f 100644 --- a/aQute.libg/src/aQute/lib/json/ObjectHandler.java +++ b/aQute.libg/src/aQute/lib/json/ObjectHandler.java @@ -168,14 +168,14 @@ public Object decodeObject(Decoder r) throws Exception { } private Field getField(String key) { - if (JSONCodec.keywords.contains(key)) - key = key + JSONCodec.KEYWORD_SUFFIX; for (Field field : fields) { - int n = key.compareTo(field.getName()); - if (n == 0) + if (key.equals(field.getName())) + return field; + } + String fixup = JSONCodec.name(key); + for (Field field : fields) { + if (fixup.equals(field.getName())) return field; - if (n < 0) - return null; } return null; } diff --git a/aQute.libg/src/aQute/lib/json/RecordHandler.java b/aQute.libg/src/aQute/lib/json/RecordHandler.java index a8f523c229..eae9b98853 100644 --- a/aQute.libg/src/aQute/lib/json/RecordHandler.java +++ b/aQute.libg/src/aQute/lib/json/RecordHandler.java @@ -74,7 +74,7 @@ public void encode(Encoder enc, Object object, Map visited) throws if (!del.isEmpty()) enc.linebreak(); - StringHandler.string(enc, a.name); + StringHandler.string(enc, JSONCodec.keyword(a.name)); enc.append(":"); enc.encode(value, a.type, visited); del = ",";