package io.burt.jmespath.vertx; import io.burt.jmespath.JmesPathType; import io.burt.jmespath.RuntimeConfiguration; import io.burt.jmespath.jcf.JcfRuntime; import io.vertx.core.json.Json; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import static io.burt.jmespath.JmesPathType.ARRAY; import static io.burt.jmespath.JmesPathType.OBJECT; public class VertxRuntime extends JcfRuntime { public VertxRuntime() { this(RuntimeConfiguration.defaultConfiguration()); } public VertxRuntime(RuntimeConfiguration configuration) { super(configuration); } @Override public Object parseString(String str) { return Json.decodeValue(str); } @Override @SuppressWarnings("unchecked") public List<Object> toList(final Object value) { if (value instanceof JsonArray) { final JsonArray ja = (JsonArray) value; return new AbstractList<Object>() { @Override public int size() { return ja.size(); } @Override public Object get(int i) { return ja.getValue(i); } }; } if (value instanceof JsonObject) { return new AbstractList<Object>() { private List<Object> cache = null; @Override public int size() { return ((JsonObject) value).size(); } @Override public Object get(int i) { if (cache == null) { List<Object> list = new ArrayList<>(size()); for (Map.Entry<String, Object> entry : (JsonObject) value) { list.add(entry.getValue()); } cache = list; } return cache.get(i); } }; } return Collections.EMPTY_LIST; } @Override public String toString(Object value) { if (value instanceof JsonArray || value instanceof JsonObject) { return value.toString(); } else { return super.toString(value); } } @Override public boolean isTruthy(Object value) { switch (typeOf(value)) { case OBJECT: return !((JsonObject) value).isEmpty(); case ARRAY: return !((JsonArray) value).isEmpty(); default: return super.isTruthy(value); } } @Override public JmesPathType typeOf(Object value) { if (value instanceof JsonObject) { return OBJECT; } else if (value instanceof JsonArray) { return ARRAY; } else if (value instanceof Collection || value instanceof Map) { throw new IllegalStateException(String.format("Unknown node type encountered: %s", value.getClass().getName())); } else { return super.typeOf(value); } } @Override public Object getProperty(Object value, Object name) { if ((value instanceof JsonObject) && (name instanceof String)) { return ((JsonObject) value).getValue((String) name); } else { return null; } } @Override @SuppressWarnings("unchecked") public Collection<Object> getPropertyNames(Object value) { if (value instanceof JsonObject) { JsonObject jo = (JsonObject) value; return (Collection) jo.getMap().keySet(); } else { return Collections.EMPTY_LIST; } } @Override public Object createArray(Collection<Object> elements) { JsonArray ja = new JsonArray(); for (Object element : elements) { ja.add(element); } return ja; } @Override public Object createObject(Map<Object, Object> obj) { JsonObject jo = new JsonObject(); for (Map.Entry<Object, Object> entry : obj.entrySet()) { jo.put((String) entry.getKey(), entry.getValue()); } return jo; } @Override public int compare(Object value1, Object value2) { switch (typeOf(value1)) { case ARRAY: case OBJECT: return value1.equals(value2) ? 0 : -1; default: return super.compare(value1, value2); } } }