@author pavlo
| 37 | * @author pavlo |
| 38 | */ |
| 39 | public abstract class JSONUtil { |
| 40 | private static final Logger LOG = LoggerFactory.getLogger(JSONUtil.class.getName()); |
| 41 | |
| 42 | private static final String JSON_CLASS_SUFFIX = "_class"; |
| 43 | private static final Map<Class<?>, Field[]> SERIALIZABLE_FIELDS = new HashMap<>(); |
| 44 | |
| 45 | /** |
| 46 | * @param clazz |
| 47 | * @return |
| 48 | */ |
| 49 | public static Field[] getSerializableFields(Class<?> clazz, String... fieldsToExclude) { |
| 50 | Field[] ret = SERIALIZABLE_FIELDS.get(clazz); |
| 51 | if (ret == null) { |
| 52 | Collection<String> exclude = CollectionUtil.addAll(new HashSet<>(), fieldsToExclude); |
| 53 | synchronized (SERIALIZABLE_FIELDS) { |
| 54 | ret = SERIALIZABLE_FIELDS.get(clazz); |
| 55 | if (ret == null) { |
| 56 | List<Field> fields = new ArrayList<>(); |
| 57 | for (Field f : clazz.getFields()) { |
| 58 | int modifiers = f.getModifiers(); |
| 59 | if (!Modifier.isTransient(modifiers) |
| 60 | && Modifier.isPublic(modifiers) |
| 61 | && !Modifier.isStatic(modifiers) |
| 62 | && !exclude.contains(f.getName())) { |
| 63 | fields.add(f); |
| 64 | } |
| 65 | } |
| 66 | ret = fields.toArray(new Field[0]); |
| 67 | SERIALIZABLE_FIELDS.put(clazz, ret); |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | return (ret); |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * JSON Pretty Print |
| 76 | * |
| 77 | * @param json |
| 78 | * @return |
| 79 | * @throws JSONException |
| 80 | */ |
| 81 | public static String format(String json) { |
| 82 | try { |
| 83 | return (JSONUtil.format( |
| 84 | new JSONObject(json) { |
| 85 | /** |
| 86 | * changes the value of JSONObject.map to a LinkedHashMap in order to maintain order of |
| 87 | * keys. See Also: https://stackoverflow.com/a/62476486 |
| 88 | */ |
| 89 | @Override |
| 90 | public JSONObject put(String key, Object value) throws JSONException { |
| 91 | try { |
| 92 | Field map = JSONObject.class.getDeclaredField("map"); |
| 93 | map.setAccessible(true); |
| 94 | Object mapValue = map.get(this); |
| 95 | if (!(mapValue instanceof LinkedHashMap)) { |
| 96 | map.set(this, new LinkedHashMap<>()); |