This repository was archived by the owner on Oct 31, 2024. It is now read-only.
Description May or may not work, too lazy to raise a PR, sorry - it's here in case someone wants it.
package io.atlassian.rps.util;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonArray;
import com.google.gson.JsonSyntaxException;
import io.burt.jmespath.BaseRuntime;
import io.burt.jmespath.JmesPathType;
import static io.burt.jmespath.JmesPathType.NULL;
import static io.burt.jmespath.JmesPathType.STRING;
import static io.burt.jmespath.JmesPathType.BOOLEAN;
import static io.burt.jmespath.JmesPathType.OBJECT;
import static io.burt.jmespath.JmesPathType.ARRAY;
import static io.burt.jmespath.JmesPathType.NUMBER;
import io.burt.jmespath.function.FunctionRegistry;
/**
* Unfortunately, Jmespath supports only Jackson in the default library, so we have to
* write our own adapter for Gson (cribbed off the Jackson one).
*/
public class JmespathGsonRuntime extends BaseRuntime<JsonElement> {
private final Gson jsonParser;
public JmespathGsonRuntime() {
this(null);
}
public JmespathGsonRuntime(FunctionRegistry functionRegistry) {
super(functionRegistry);
this.jsonParser = new Gson();
}
@Override
public JsonElement parseString(String string) {
try {
return jsonParser.fromJson(string, JsonElement.class);
} catch (JsonSyntaxException e) {
throw new IllegalStateException(e);
}
}
@Override
public List<JsonElement> toList(JsonElement value) {
if (value.isJsonArray()) {
return StreamSupport.stream(value.getAsJsonArray().spliterator(), false)
.collect(Collectors.toList());
} else if (value.isJsonObject()) {
return value.getAsJsonObject().entrySet().stream()
.map(Map.Entry::getValue)
.collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
@Override
public String toString(JsonElement str) {
if (str.isJsonPrimitive()) {
return str.getAsString();
} else {
return str.toString();
}
}
@Override
public Number toNumber(JsonElement n) {
return n.getAsNumber();
}
@Override
public boolean isTruthy(JsonElement value) {
switch (typeOf(value)) {
case NULL:
return false;
case BOOLEAN:
return value.getAsBoolean();
case STRING:
return value.getAsString().length() > 0;
case NUMBER:
return value.getAsFloat() > 0;
case ARRAY:
return value.getAsJsonArray().size() > 0;
case OBJECT:
return value.getAsJsonObject().size() > 0;
}
throw new IllegalStateException(String.format("Unknown node type encountered: %s", value.getClass()));
}
@Override
public JmesPathType typeOf(JsonElement value) {
if (value.isJsonNull()) {
return JmesPathType.NULL;
} else if (value.isJsonArray()) {
return JmesPathType.ARRAY;
} else if (value.isJsonObject()) {
return JmesPathType.OBJECT;
} else if (value.isJsonPrimitive()) {
JsonPrimitive primValue = value.getAsJsonPrimitive();
if (primValue.isBoolean()) {
return JmesPathType.BOOLEAN;
} else if (primValue.isNumber()) {
return JmesPathType.NUMBER;
} else if (primValue.isString()) {
return JmesPathType.STRING;
}
}
throw new IllegalStateException(String.format("Unknown node type encountered: %s", value.getClass()));
}
@Override
public JsonElement getProperty(JsonElement value, JsonElement name) {
return nodeOrNullNode(
value.isJsonObject() ? value.getAsJsonObject().get(name.getAsString()) : null
);
}
@Override
public Collection<JsonElement> getPropertyNames(JsonElement value) {
if (value.isJsonObject()) {
return value.getAsJsonObject().entrySet().stream()
.map(entry -> new JsonPrimitive(entry.getKey()))
.collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
@Override
public JsonElement createNull() {
return nodeOrNullNode(null);
}
@Override
public JsonElement createArray(Collection<JsonElement> elements) {
JsonArray array = new JsonArray();
elements.forEach(array::add);
return array;
}
@Override
public JsonElement createString(String str) {
return new JsonPrimitive(str);
}
@Override
public JsonElement createBoolean(boolean b) {
return new JsonPrimitive(b);
}
@Override
public JsonElement createObject(Map<JsonElement, JsonElement> obj) {
JsonObject result = new JsonObject();
obj.entrySet().forEach(entry -> result.add(entry.getKey().getAsString(), entry.getValue()));
return result;
}
@Override
public JsonElement createNumber(double n) {
return new JsonPrimitive(n);
}
@Override
public JsonElement createNumber(long n) {
return new JsonPrimitive(n);
}
private JsonElement nodeOrNullNode(JsonElement node) {
if (node == null) {
return JsonNull.INSTANCE;
} else {
return node;
}
}
}
Reactions are currently unavailable
May or may not work, too lazy to raise a PR, sorry - it's here in case someone wants it.