Advertisement
Guest User

Untitled

a guest
Feb 20th, 2020
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.13 KB | None | 0 0
  1. package me.catcoder.plugins.ubans.util;
  2.  
  3. import com.google.common.collect.Iterators;
  4. import com.google.gson.JsonArray;
  5. import com.google.gson.JsonElement;
  6. import com.google.gson.JsonObject;
  7. import com.google.gson.JsonPrimitive;
  8.  
  9. import java.util.Iterator;
  10. import java.util.Objects;
  11. import java.util.Optional;
  12. import java.util.function.Function;
  13. import java.util.function.Predicate;
  14. import java.util.regex.Pattern;
  15.  
  16. /**
  17.  * Wrapper for JsonObject with recursive path walking and null safety.
  18.  *
  19.  * @author CatCoder
  20.  */
  21. public class JsonWrapper {
  22.  
  23.     private static final Pattern PATH_REGEX = Pattern.compile("\\.");
  24.  
  25.     private final JsonObject root;
  26.  
  27.     public JsonWrapper(JsonObject root) {
  28.         this.root = Objects.requireNonNull(root, "object");
  29.     }
  30.  
  31.     public JsonObject root() {
  32.         return root;
  33.     }
  34.  
  35.     // PRIMITIVES
  36.     public <T> JsonValueTransformer<T> primitives(
  37.             Function<JsonPrimitive, T> func,
  38.             Predicate<JsonPrimitive> filter,
  39.             Function<T, JsonElement> valueExtractor) {
  40.         return new SimpleJsonValueTransformer<>((path) -> element(path)
  41.                 .filter(JsonElement::isJsonPrimitive)
  42.                 .map(JsonElement::getAsJsonPrimitive)
  43.                 .filter(filter).map(func), valueExtractor);
  44.     }
  45.  
  46.     public JsonValueTransformer<String> strings() {
  47.         return primitives(JsonPrimitive::getAsString, JsonPrimitive::isString, JsonPrimitive::new);
  48.     }
  49.  
  50.     public JsonValueTransformer<Number> numbers() {
  51.         return primitives(JsonPrimitive::getAsNumber, JsonPrimitive::isNumber, JsonPrimitive::new);
  52.     }
  53.  
  54.     public JsonValueTransformer<Boolean> booleans() {
  55.         return primitives(JsonPrimitive::getAsBoolean, JsonPrimitive::isBoolean, JsonPrimitive::new);
  56.     }
  57.  
  58.     // PRIMITIVES
  59.  
  60.     public JsonValueTransformer<JsonObject> objects() {
  61.         return new SimpleJsonValueTransformer<>((path) -> element(path)
  62.                 .filter(JsonElement::isJsonObject)
  63.                 .map(JsonElement::getAsJsonObject), (v) -> v);
  64.     }
  65.  
  66.     public JsonValueTransformer<JsonArray> arrays() {
  67.         return new SimpleJsonValueTransformer<>((path) -> element(path)
  68.                 .filter(JsonElement::isJsonArray)
  69.                 .map(JsonElement::getAsJsonArray), (v) -> v);
  70.     }
  71.  
  72.     public Optional<JsonWrapper> sub(String path) {
  73.         return element(path)
  74.                 .filter(JsonElement::isJsonObject)
  75.                 .map(JsonElement::getAsJsonObject)
  76.                 .map(JsonWrapper::new);
  77.     }
  78.  
  79.     public int set(String path, JsonElement value) {
  80.         Objects.requireNonNull(path, "path");
  81.  
  82.         Iterator<String> pathIterator = Iterators.forArray(PATH_REGEX.split(path));
  83.         JsonObject currentObject = root;
  84.         String lastPath = null;
  85.         int depth = 0;
  86.  
  87.         // Build tree
  88.         while (pathIterator.hasNext()) {
  89.             if (lastPath != null) {
  90.                 JsonElement next = currentObject.get(lastPath);
  91.                 if (next == null) {
  92.                     next = new JsonObject();
  93.                     currentObject.add(lastPath, next);
  94.                 }
  95.                 currentObject = (JsonObject) next;
  96.                 depth++;
  97.             }
  98.  
  99.             lastPath = pathIterator.next();
  100.         }
  101.  
  102.         if (lastPath != null) {
  103.             currentObject.add(lastPath, value);
  104.         }
  105.  
  106.         return depth;
  107.     }
  108.  
  109.     public Optional<JsonElement> element(String path) {
  110.         Iterator<String> pathIterator = Iterators.forArray(PATH_REGEX.split(path));
  111.  
  112.         // Iterator cannot be empty, so we allowed to do this
  113.         String prevPath = pathIterator.next();
  114.         JsonElement lastElement = root.get(prevPath);
  115.  
  116.         if (lastElement == null) {
  117.             return Optional.empty();
  118.         }
  119.  
  120.         while (pathIterator.hasNext()) {
  121.             if (lastElement == null) {
  122.                 break;
  123.             }
  124.             prevPath = pathIterator.next();
  125.             lastElement = lastElement.getAsJsonObject().get(prevPath);
  126.         }
  127.  
  128.         return Optional.ofNullable(lastElement);
  129.     }
  130.  
  131.     private class SimpleJsonValueTransformer<T> implements JsonValueTransformer<T> {
  132.  
  133.         private final Function<String, Optional<T>> getter;
  134.         private final Function<T, JsonElement> valueExtractor;
  135.  
  136.         public SimpleJsonValueTransformer(Function<String, Optional<T>> getter,
  137.                                           Function<T, JsonElement> valueExtractor) {
  138.             this.getter = getter;
  139.             this.valueExtractor = valueExtractor;
  140.         }
  141.  
  142.         @Override
  143.         public Optional<T> transform(String path) {
  144.             return getter.apply(path);
  145.         }
  146.  
  147.         @Override
  148.         public int set(String path, T value) {
  149.             return JsonWrapper.this.set(path, valueExtractor.apply(value));
  150.         }
  151.     }
  152.  
  153.     public interface JsonValueTransformer<T> {
  154.  
  155.         Optional<T> transform(String path);
  156.  
  157.         @SuppressWarnings("OptionalGetWithoutIsPresent")
  158.         default T unwrap(String path) {
  159.             return transform(path).get();
  160.         }
  161.  
  162.         int set(String path, T value);
  163.     }
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement