content: package org.allaymc.server.utils;
  
  import com.google.gson.*;
  import com.google.gson.reflect.TypeToken;
  import com.google.gson.stream.JsonReader;
  import com.google.gson.stream.JsonWriter;
  import lombok.Getter;
  import lombok.Setter;
  import lombok.experimental.UtilityClass;
  import org.allaymc.api.utils.SemVersion;
  import org.apache.commons.lang3.BooleanUtils;
  import org.apache.commons.lang3.StringUtils;
  import org.apache.commons.lang3.math.NumberUtils;
  
  import java.io.*;
  import java.lang.reflect.Type;
  import java.math.BigDecimal;
  import java.math.BigInteger;
  import java.util.*;
  import java.util.function.Consumer;
  
  /**
   * Gson Utilities.
   * <p>
   * Advantage:
   * <li>When the data volume is less than 10,000, the speed has an absolute advantage</li>
   * <li>API and annotation support is relatively complete, and loose parsing is supported</li>
   * <li>Supports a wide range of data sources (strings, objects, files, streams, readers)</li>
   *
   * @author duanxinyuan | CoolLoong
   */
  @UtilityClass
  public class JSONUtils {
  
      private static final Gson GSON;
  
      static {
          GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss");
          // Prevent escaping some special characters to Unicode encoding
          gsonBuilder.disableHtmlEscaping();
          registerTypeAdapter(gsonBuilder);
          GSON = gsonBuilder.create();
      }
  
      private static void registerTypeAdapter(GsonBuilder gsonBuilder) {
          gsonBuilder.registerTypeAdapter(short.class, new NumberTypeAdapter<>(short.class));
          gsonBuilder.registerTypeAdapter(Short.class, new NumberTypeAdapter<>(Short.class));
          gsonBuilder.registerTypeAdapter(int.class, new NumberTypeAdapter<>(int.class));
          gsonBuilder.registerTypeAdapter(Integer.class, new NumberTypeAdapter<>(Integer.class));
          gsonBuilder.registerTypeAdapter(long.class, new NumberTypeAdapter<>(long.class));
          gsonBuilder.registerTypeAdapter(Long.class, new NumberTypeAdapter<>(Long.class));
          gsonBuilder.registerTypeAdapter(float.class, new NumberTypeAdapter<>(float.class));
          gsonBuilder.registerTypeAdapter(Float.class, new NumberTypeAdapter<>(Float.class));
          gsonBuilder.registerTypeAdapter(double.class, new NumberTypeAdapter<>(double.class));
          gsonBuilder.registerTypeAdapter(Double.class, new NumberTypeAdapter<>(Double.class));
          gsonBuilder.registerTypeAdapter(BigDecimal.class, new NumberTypeAdapter<>(BigDecimal.class));
          gsonBuilder.registerTypeAdapter(SemVersion.class, new SemVersion.Serializer());
          gsonBuilder.registerTypeAdapter(SemVersion.class, new SemVersion.Deserializer());
      }
  
      /**
       * Parse a JSON string (from reader) to an object.
       *
       * @param reader the reader
       * @param type   the type of the object
       * @return the object
       */
      public static <V> V from(Reader reader, Class<V> type) {
          JsonReader jsonReader = new JsonReader(Objects.requireNonNull(reader));
          return GSON.fromJson(jsonReader, type);
      }
  
      /**
       * Parse a JSON string (from reader) to an object.
       *
       * @param reader    the reader
       * @param typeToken the type of the object
       * @return the object
       */
      public static <V> V from(Reader reader, TypeToken<V> typeToken) {
          JsonReader jsonReader = new JsonReader(Objects.requireNonNull(reader));
          return GSON.fromJson(jsonReader, typeToken);
      }
  
      /**
       * Parse a JSON string (from input stream) to an object.
       *
       * @param inputStream the input stream
       * @param type        the type of the object
       * @return the object
       */
      public static <V> V from(InputStream inputStream, Class<V> type) {
          JsonReader reader = new JsonReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
          return GSON.fromJson(reader, type);
      }
  
      /**
       * Parse a JSON string (from input stream) to an object.
       *
       * @param inputStream the input stream
       * @param typeToken   the type of the object
       * @return the object
       */
      public static <V> V from(InputStream inputStream, TypeToken<V> typeToken) {
          JsonReader reader = new JsonReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
          return GSON.fromJson(reader, typeToken.getType());
      }
  
      /**
       * Parse a JSON string (from input stream) to a list.
       *
       * @param inputStream the input stream
       * @param type        the type of elements in the list
       * @return the list
       */
      public static <V> List<V> fromList(InputStream inputStream, Class<V> type) {
          JsonReader reader = new JsonReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
          TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
          return GSON.fromJson(reader, typeToken.getType());
      }
  
      /**
       * Parse a JSON string (in file) to an object.
       *
       * @param file the file
       * @param type the type of the object
       * @return the object
       */
      public static <V> V from(File file, Class<V> type) {
          try {
              JsonReader reader = new JsonReader(new FileReader(file));
              return GSON.fromJson(reader, type);
          } catch (FileNotFoundException e) {
              throw new GsonException("gson from error, file path: {}, type: {}", file.getPath(), type, e);
          }
      }
  
      /**
       * Parse a JSON string (in file) to an object.
       *
       * @param file      the file
       * @param typeToken the type of the object
       * @return the object
       */
      public static <V> V from(File file, TypeToken<V> typeToken) {
          try {
              JsonReader reader = new JsonReader(new FileReader(file));
              return GSON.fromJson(reader, typeToken.getType());
          } catch (FileNotFoundException e) {
              throw new GsonException("gson from error, file path: {}, type: {}", file.getPath(), typeToken.getType(), e);
          }
      }
  
      /**
       * Parse a JSON string (in file) to a list.
       *
       * @param file the file
       * @param type the type of elements in the list
       * @return the list
       */
      public static <V> List<V> fromList(File file, Class<V> type) {
          try {
              JsonReader reader = new JsonReader(new FileReader(file));
              TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
              return GSON.fromJson(reader, typeToken.getType());
          } catch (FileNotFoundException e) {
              throw new GsonException("gson from error, file path: {}, type: {}", file.getPath(), type, e);
          }
      }
  
      /**
       * Parse a JSON string to an object.
       *
       * @param json the JSON string
       * @param type the type of the object
       * @return the object
       */
      public static <V> V from(String json, Class<V> type) {
          return GSON.fromJson(json, type);
      }
  
      /**
       * Parse a JSON string to an object.
       *
       * @param json the JSON string
       * @param type the type of the object
       * @return the object
       */
      public static <V> V from(String json, Type type) {
          return GSON.fromJson(json, type);
      }
  
      /**
       * Parse a JSON string to an object.
       *
       * @param json      the JSON string
       * @param typeToken the type of the object
       * @return the object
       */
      public static <V> V from(String json, TypeToken<V> typeToken) {
          return GSON.fromJson(json, typeToken.getType());
      }
  
      /**
       * Parse a JSON string to a list.
       *
       * @param json the JSON string
       * @param type the type of elements in the list
       * @return the list
       */
      public static <V> List<V> fromList(String json, Class<V> type) {
          TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
          return GSON.fromJson(json, typeToken.getType());
      }
  
      /**
       * Parse a JSON string to a map.
       *
       * @param json the JSON string
       * @return the map
       */
      public static Map<String, Object> fromMap(String json) {
          return GSON.fromJson(json, new TypeToken<HashMap<String, Object>>() {
          }.getType());
      }
  
      /**
       * Parse a JSON string (from input stream) to an object leniently.
       *
       * @param inputStream the input stream
       * @param type        the type of the object
       * @return the object
       */
      public static <V> V fromLenient(InputStream inputStream, Class<V> type) {
          JsonReader reader = new JsonReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
          reader.setStrictness(Strictness.LENIENT);
          return GSON.fromJson(reader, type);
      }
  
      /**
       * Parse a JSON string to an object leniently.
       *
       * @param inputStream the input stream
       * @param type        the type of the object
       * @return the object
       */
      public static <V> V fromLenient(InputStream inputStream, TypeToken<V> type) {
          JsonReader reader = new JsonReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
          reader.setStrictness(Strictness.LENIENT);
          return GSON.fromJson(reader, type);
      }
  
      /**
       * Parse a JSON string to a list leniently.
       *
       * @param inputStream the input stream
       * @param type        the type of elements in the list
       * @return the list
       */
      public static <V> List<V> fromListLenient(InputStream inputStream, Class<V> type) {
          JsonReader reader = new JsonReader(new InputStreamReader(Objects.requireNonNull(inputStream)));
          reader.setStrictness(Strictness.LENIENT);
          TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
          return GSON.fromJson(reader, typeToken.getType());
      }
  
      /**
       * Parse a JSON string (in file) to an object leniently.
       *
       * @param file the file
       * @param type the type of the object
       * @return the object
       */
      public static <V> V fromLenient(File file, Class<V> type) {
          try {
              JsonReader reader = new JsonReader(new FileReader(file));
              reader.setStrictness(Strictness.LENIENT);
              return GSON.fromJson(reader, type);
          } catch (FileNotFoundException e) {
              throw new GsonException("gson lenient from error, file path: {}, type: {}", file.getPath(), type, e);
          }
      }
  
      /**
       * Parse a JSON string (in file) to a list leniently.
       *
       * @param file the file
       * @param type the type of elements in the list
       * @return the list
       */
      public static <V> List<V> fromListLenient(File file, Class<V> type) {
          try {
              JsonReader reader = new JsonReader(new FileReader(file));
              reader.setStrictness(Strictness.LENIENT);
              TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
              return GSON.fromJson(reader, typeToken.getType());
          } catch (FileNotFoundException e) {
              throw new GsonException("gson lenient from error, file path: {}, type: {}", file.getPath(), type, e);
          }
      }
  
      /**
       * Parse a JSON string to an object leniently.
       *
       * @param json the JSON string
       * @param type the type of the object
       * @return the object
       */
      public static <V> V fromLenient(String json, Class<V> type) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          JsonReader reader = new JsonReader(new StringReader(json));
          reader.setStrictness(Strictness.LENIENT);
          return GSON.fromJson(reader, type);
      }
  
      /**
       * Parse a JSON string to an object leniently.
       *
       * @param json the JSON string
       * @param type the type of the object
       * @return the object
       */
      public static <V> V fromLenient(String json, Type type) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          JsonReader reader = new JsonReader(new StringReader(json));
          reader.setStrictness(Strictness.LENIENT);
          return GSON.fromJson(reader, type);
      }
  
      /**
       * Parse a JSON string to an object leniently.
       *
       * @param json      the JSON string
       * @param typeToken the type of the object
       * @return the object
       */
      public static <V> V fromLenient(String json, TypeToken<V> typeToken) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          JsonReader reader = new JsonReader(new StringReader(json));
          reader.setStrictness(Strictness.LENIENT);
          return GSON.fromJson(reader, typeToken.getType());
      }
  
      /**
       * Read a list from a JSON string leniently.
       *
       * @param json the JSON string
       * @param type the type of elements in the list
       * @return the list
       */
      public static <V> List<V> fromListLenient(String json, Class<V> type) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          JsonReader reader = new JsonReader(new StringReader(json));
          reader.setStrictness(Strictness.LENIENT);
          TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
          return GSON.fromJson(reader, typeToken.getType());
      }
  
      /**
       * Convert a list to a JSON string.
       *
       * @param list the list
       * @return the JSON string
       */
      public static <V> String to(List<V> list) {
          return GSON.toJson(list);
      }
  
      /**
       * Convert an object to a JSON string.
       *
       * @param v the object
       * @return the JSON string
       */
      public static <V> String to(V v) {
          return GSON.toJson(v);
      }
  
      /**
       * Write an object to a file.
       *
       * @param path the file path
       * @param list the list
       */
      public static <V> void toFile(String path, List<V> list) {
          try (JsonWriter jsonWriter = new JsonWriter(new FileWriter(path, true))) {
              GSON.toJson(list, new TypeToken<List<V>>() {
              }.getType(), jsonWriter);
              jsonWriter.flush();
          } catch (Exception e) {
              throw new GsonException("gson to file error, path: {}, list: {}", path, list, e);
          }
      }
  
      /**
       * Write an object to a file.
       *
       * @param path the file path
       * @param v    the object
       */
      public static <V> void toFile(String path, V v) {
          toFile(path, v, null);
      }
  
      /**
       * Write an object to a file.
       *
       * @param path                   the file path
       * @param v                      the object
       * @param jsonWriterConfigurator the JSON writer configurator
       */
      public static <V> void toFile(String path, V v, Consumer<JsonWriter> jsonWriterConfigurator) {
          try (JsonWriter jsonWriter = new JsonWriter(new FileWriter(path, true))) {
              if (jsonWriterConfigurator != null) jsonWriterConfigurator.accept(jsonWriter);
              GSON.toJson(v, v.getClass(), jsonWriter);
              jsonWriter.flush();
          } catch (Exception e) {
              throw new GsonException("gson to file error, path: {}, obj: {}", path, v, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or {@code null} if the field does not exist
       */
      public static String getAsString(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          String propertyValue;
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return null;
          }
          try {
              propertyValue = jsonByKey.getAsString();
          } catch (Exception e) {
              propertyValue = jsonByKey.toString();
          }
          return propertyValue;
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or zero if the field does not exist
       */
      public static int getAsInt(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return 0;
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return 0;
          }
          try {
              return jsonByKey.getAsInt();
          } catch (Exception e) {
              throw new GsonException("gson get int error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or zero if the field does not exist
       */
      public static long getAsLong(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return 0L;
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return 0L;
          }
          try {
              return jsonByKey.getAsLong();
          } catch (Exception e) {
              throw new GsonException("gson get long error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or zero if the field does not exist
       */
      public static double getAsDouble(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return 0.0;
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return 0.0;
          }
          try {
              return jsonByKey.getAsDouble();
          } catch (Exception e) {
              throw new GsonException("gson get double error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or zero if the field does not exist
       */
      public static BigInteger getAsBigInteger(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return new BigInteger(String.valueOf(0.00));
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return new BigInteger(String.valueOf(0.00));
          }
          try {
              return jsonByKey.getAsBigInteger();
          } catch (Exception e) {
              throw new GsonException("gson get big integer error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or zero if the field does not exist
       */
      public static BigDecimal getAsBigDecimal(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return new BigDecimal("0.0");
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return new BigDecimal("0.0");
          }
          try {
              return jsonByKey.getAsBigDecimal();
          } catch (Exception e) {
              throw new GsonException("gson get big decimal error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or {@code false} if the field does not exist
       */
      public static boolean getAsBoolean(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return false;
          }
          JsonPrimitive jsonByKey = (JsonPrimitive) getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return false;
          }
          try {
              if (jsonByKey.isBoolean()) {
                  return jsonByKey.getAsBoolean();
              } else {
                  if (jsonByKey.isString()) {
                      String string = jsonByKey.getAsString();
                      if ("1".equals(string)) {
                          return true;
                      } else {
                          return BooleanUtils.toBoolean(string);
                      }
                  } else {// number
                      return BooleanUtils.toBoolean(jsonByKey.getAsInt());
                  }
              }
          } catch (Exception e) {
              throw new GsonException("gson get boolean error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or zero if the field does not exist
       */
      public static byte getAsByte(String json, String key) {
          if (StringUtils.isEmpty(json)) {
              return 0;
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return 0;
          }
          try {
              return jsonByKey.getAsByte();
          } catch (Exception e) {
              throw new GsonException("gson get byte error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or {@code null} if the field does not exist
       */
      public static <V> V getAsObject(String json, String key, Class<V> type) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return null;
          }
          try {
              return from(jsonByKey.getAsString(), type);
          } catch (Exception e) {
              throw new GsonException("gson get list error, json: {}, key: {}, type: {}", json, key, type, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the value of the field, or {@code null} if the field does not exist
       */
      public static <V> List<V> getAsList(String json, String key, Class<V> type) {
          if (StringUtils.isEmpty(json)) {
              return null;
          }
          JsonElement jsonByKey = getAsJsonObject(json, key);
          if (null == jsonByKey) {
              return null;
          }
          try {
              JsonArray jsonArray = jsonByKey.getAsJsonArray();
              TypeToken<List<V>> typeToken = (TypeToken<List<V>>) TypeToken.getParameterized(ArrayList.class, type);
              return from(jsonArray.toString(), typeToken);
          } catch (Exception e) {
              throw new GsonException("gson get list error, json: {}, key: {}, type: {}", json, key, type, e);
          }
      }
  
      /**
       * Get the value of a field from a JSON string.
       *
       * @return the field
       */
      public static JsonElement getAsJsonObject(String json, String key) {
          try {
              JsonElement element = JsonParser.parseString(json);
              JsonObject jsonObj = element.getAsJsonObject();
              return jsonObj.get(key);
          } catch (JsonSyntaxException e) {
              throw new GsonException("gson get object from json error, json: {}, key: {}", json, key, e);
          }
      }
  
      /**
       * Add a field to a JSON string.
       *
       * @return the JSON string with the field added
       */
      public static <V> String add(String json, String key, V value) {
          JsonElement element = JsonParser.parseString(json);
          JsonObject jsonObject = element.getAsJsonObject();
          add(jsonObject, key, value);
          return jsonObject.toString();
      }
  
      /**
       * Add a field to a JSON string.
       */
      private static <V> void add(JsonObject jsonObject, String key, V value) {
          if (value instanceof String) {
              jsonObject.addProperty(key, (String) value);
          } else if (value instanceof Number) {
              jsonObject.addProperty(key, (Number) value);
          } else {
              jsonObject.addProperty(key, to(value));
          }
      }
  
      /**
       * Remove a field from a JSON string.
       *
       * @return the JSON string with the field removed
       */
      public static String remove(String json, String key) {
          JsonElement element = JsonParser.parseString(json);
          JsonObject jsonObj = element.getAsJsonObject();
          jsonObj.remove(key);
          return jsonObj.toString();
      }
  
      /**
       * Update a field in a JSON string.
       *
       * @return the JSON string with the field updated
       */
      public static <V> String update(String json, String key, V value) {
          JsonElement element = JsonParser.parseString(json);
          JsonObject jsonObject = element.getAsJsonObject();
          jsonObject.remove(key);
          add(jsonObject, key, value);
          return jsonObject.toString();
      }
  
      /**
       * Format a JSON string.
       *
       * @return the formatted JSON string
       */
      public static String format(String json) {
          Gson gson = new GsonBuilder().setPrettyPrinting().create();
          JsonElement jsonElement = JsonParser.parseString(json);
          return gson.toJson(jsonElement);
      }
  
      /**
       * Check if a string is a JSON string.
       *
       * @return {@code true} if the string is a JSON string, otherwise {@code false}.
       */
      public static boolean isJson(String json) {
          try {
              return JsonParser.parseString(json).isJsonObject();
          } catch (Exception e) {
              return false;
          }
      }
  
      /**
       * @author duanxinyuan
       */
      private static class NumberTypeAdapter<T> extends TypeAdapter<Number> {
  
          private final Class<T> c;
  
          public NumberTypeAdapter(Class<T> c) {
              this.c = c;
          }
  
          @Override
          public void write(JsonWriter jsonWriter, Number number) throws IOException {
              if (number != null) {
                  jsonWriter.value(number);
              } else {
                  jsonWriter.nullValue();
              }
          }
  
          @Override
          public Number read(JsonReader jsonReader) {
              try {
                  if (jsonReader.peek() == null) {
                      return null;
                  }
                  String json = jsonReader.nextString();
                  if (c == short.class) {
                      return NumberUtils.toShort(json);
                  } else if (c == Short.class) {
                      if (StringUtils.isEmpty(json)) {
                          return null;
                      }
                      return Short.parseShort(json);
                  } else if (c == int.class) {
                      return NumberUtils.toInt(json);
                  } else if (c == Integer.class) {
                      if (StringUtils.isEmpty(json)) {
                          return null;
                      }
                      return Integer.parseInt(json);
                  } else if (c == long.class) {
                      return NumberUtils.toLong(json);
                  } else if (c == Long.class) {
                      if (StringUtils.isEmpty(json)) {
                          return null;
                      }
                      return Long.parseLong(json);
                  } else if (c == float.class) {
                      return Float.parseFloat(json);
                  } else if (c == Float.class) {
                      if (StringUtils.isEmpty(json)) {
                          return null;
                      }
                      return NumberUtils.toFloat(json);
                  } else if (c == double.class) {
                      return NumberUtils.toDouble(json);
                  } else if (c == Double.class) {
                      if (StringUtils.isEmpty(json)) {
                          return null;
                      }
                      return Double.parseDouble(json);
                  } else if (c == BigDecimal.class) {
                      if (StringUtils.isEmpty(json)) {
                          return null;
                      }
                      return new BigDecimal(json);
                  } else {
                      return Integer.parseInt(json);
                  }
              } catch (Exception e) {
                  return null;
              }
          }
      }
  
      /**
       * @author duanxinyuan
       */
      @Setter
      @Getter
      public static class GsonException extends FormativeException {
  
          public GsonException() {
              super();
          }
  
          public GsonException(String message) {
              super(message);
          }
  
          public GsonException(Throwable cause) {
              super(cause);
          }
  
          public GsonException(String format, Object... arguments) {
              super(format, arguments);
          }
      }
  }