JsonSummarizer.java
package com.github.dakusui.json;
import com.github.dakusui.valid8j_cliche.core.All;
import com.github.dakusui.valid8j_cliche.core.Transform;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import static com.github.dakusui.valid8j.Assertions.that;
import static com.github.dakusui.valid8j_cliche.core.Cliche.statement;
import static com.github.dakusui.valid8j_cliche.json.JsonObjectTo.keyList;
import static com.github.dakusui.valid8j_pcond.forms.Predicates.*;
import static com.github.dakusui.valid8j_pcond.forms.Printables.predicate;
public class JsonSummarizer {
public static JsonElement summaryObject(JsonObject root, List<Object> pathToParent, Object focus) {
JsonElement previousElement = parentElement(focus, JsonUtils.asJsonElement(root, pathToParent.toArray()));
JsonElement ret = focus instanceof String ? new JsonObject() : new JsonArray();
for (int i = pathToParent.size() - 1; i >= 0; i--) {
Object currentKey = pathToParent.get(i);
if (currentKey instanceof String) {
ret = new JsonObject();
((JsonObject) ret).add((String) currentKey, previousElement);
} else if (currentKey instanceof Integer) {
ret = new JsonArray();
((JsonArray) ret).add(previousElement);
} else
assert false;
previousElement = ret;
}
return ret;
}
public static JsonElement collapseForObjectValue(JsonElement element) {
JsonElement ret = collapseJsonElement(element);
if (ret != null) return ret;
return new JsonPrimitive("...");
}
private static JsonElement collapseJsonElement(JsonElement element) {
if (element.isJsonArray()) {
JsonArray ret = new JsonArray();
if (!((JsonArray) element).isEmpty())
ret.add("...");
return ret;
} else if (element.isJsonObject()) {
JsonObject ret = new JsonObject();
if (!((JsonObject) element).keySet().isEmpty())
ret.add("...", new JsonPrimitive("..."));
return ret;
}
return null;
}
public static JsonElement collapseForArrayElement(JsonElement element) {
JsonElement ret = collapseJsonElement(element);
if (ret != null) return ret;
return element;
}
/**
* <pre>
*
* </pre>
*
* @param object input JSON object.
* @return A summarized JSON object.
*/
public static JsonObject focusedObject(JsonObject object) {
JsonObject ret = new JsonObject();
object.keySet().forEach(k -> ret.add(k, collapseForObjectValue(object.get(k))));
return ret;
}
public static JsonElement parentElement(Object focus, JsonElement parent) {
Predicate<Object> focusIsInstanceOfString = predicate("focusIsInstanceOfString", v -> focus instanceof String);
Predicate<Object> focusIsInstanceOfInteger = predicate("focusIsInstanceOfInteger", v -> focus instanceof Integer);
assert All.$(
statement(focus, isNotNull()),
statement(parent, allOf(isNotNull(), or(
callp("isJsonObject").and(focusIsInstanceOfString),
callp("isJsonArray").and(focusIsInstanceOfInteger)))));
if (parent.isJsonObject())
return parentObject((String) focus, (JsonObject) parent);
if (parent.isJsonArray())
return parentArray((Integer) focus, (JsonArray) parent);
throw new RuntimeException();
}
public static JsonObject parentObject(String focusedChildKey, JsonObject object) {
assert All.$(
statement(focusedChildKey, isNotNull()),
statement(object, allOf(
isNotNull(),
Transform.$(keyList()).check(contains(focusedChildKey)))));
JsonObject ret = new JsonObject();
object
.keySet()
.forEach(k -> ret.add(k, Objects.equals(k, focusedChildKey) ?
focusedElement(object.get(k)) :
collapseForObjectValue(object.get(k))));
return ret;
}
public static JsonArray focusedArray(JsonArray array) {
JsonArray ret = new JsonArray();
array.forEach(each -> ret.add(collapseForArrayElement(each)));
return ret;
}
public static JsonArray parentArray(int focusedChildIndex, JsonArray array) {
assert All.$(
statement(array, isNotNull()),
statement(focusedChildIndex, greaterThanOrEqualTo(0).and(lessThan(array.size()))));
JsonArray ret = new JsonArray();
JsonElement focusedChild = array.get(focusedChildIndex);
array.forEach(i -> ret.add(Objects.equals(i, focusedChild) ?
focusedElement(i) :
collapseForArrayElement(i)));
return ret;
}
public static JsonElement focusedElement(JsonElement element) {
assert that(element, isNotNull());
JsonElement ret;
if (element.isJsonObject()) {
ret = focusedObject((JsonObject) element);
} else if (element.isJsonArray()) {
ret = focusedArray((JsonArray) element);
} else {
ret = element;
}
return ret;
}
static JsonPrimitive compactJsonPrimitive(JsonPrimitive primitive, int headLength, int tailLength) {
if (primitive.isString()) {
String dots = "...";
String s = primitive.getAsString();
if (headLength + dots.length() + tailLength >= s.length())
return primitive;
return new JsonPrimitive(s.substring(0, headLength) + dots + s.substring(s.length() - tailLength));
}
return primitive;
}
static JsonArray compactJsonArray(JsonArray array, int headLength, int tailLength) {
if (headLength + 1 + tailLength >= array.size())
return array;
JsonArray ret = new JsonArray();
for (int i = 0; i < headLength; i++)
ret.add(array.get(i));
ret.add("...");
for (int i = array.size() - tailLength; i < array.size(); i++)
ret.add(array.get(i));
return ret;
}
static JsonObject compactJsonObject(JsonObject object, int headLength, int tailLength) {
if (headLength + 1 + tailLength >= object.size())
return object;
JsonObject ret = new JsonObject();
List<String> keys = object.keySet().stream().sorted().toList();
for (int i = 0; i < headLength; i++)
ret.add(keys.get(i), object.get(keys.get(i)));
ret.add(keys.get(headLength) + "...", new JsonPrimitive("..."));
for (int i = keys.size() - tailLength; i < keys.size(); i++)
ret.add(keys.get(i), object.get(keys.get(i)));
return ret;
}
static JsonElement compactJsonElement(JsonElement element, int headLength, int tailLength) {
if (element.isJsonArray())
return compactJsonArray((JsonArray) element, headLength, tailLength);
if (element.isJsonObject())
return compactJsonObject((JsonObject) element, headLength, tailLength);
if (element.isJsonPrimitive())
return compactJsonPrimitive((JsonPrimitive) element, headLength, tailLength);
return element;
}
}