|
7 | 7 | import com.fasterxml.jackson.core.JsonProcessingException;
|
8 | 8 | import com.fasterxml.jackson.databind.JsonNode;
|
9 | 9 | import com.fasterxml.jackson.databind.ObjectMapper;
|
| 10 | +import com.jayway.jsonpath.Configuration; |
| 11 | +import com.jayway.jsonpath.DocumentContext; |
| 12 | +import com.jayway.jsonpath.InvalidJsonException; |
| 13 | +import com.jayway.jsonpath.JsonPath; |
| 14 | + |
| 15 | +import java.io.ObjectInputFilter; |
10 | 16 | import java.util.LinkedHashMap;
|
11 | 17 | import java.util.LinkedList;
|
12 | 18 | import java.util.List;
|
13 | 19 | import java.util.Map;
|
| 20 | +import java.util.stream.Collectors; |
| 21 | + |
| 22 | +import com.jayway.jsonpath.Option; |
| 23 | +import com.jayway.jsonpath.PathNotFoundException; |
| 24 | +import com.jayway.jsonpath.spi.json.JacksonJsonProvider; |
| 25 | +import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; |
14 | 26 | import lombok.experimental.UtilityClass;
|
15 | 27 | import org.opensearch.sql.data.model.ExprCollectionValue;
|
16 | 28 | import org.opensearch.sql.data.model.ExprDoubleValue;
|
@@ -46,16 +58,59 @@ public static ExprValue isValidJson(ExprValue jsonExprValue) {
|
46 | 58 |
|
47 | 59 | /** Converts a JSON encoded string to an Expression object. */
|
48 | 60 | public static ExprValue castJson(ExprValue json) {
|
| 61 | + JsonNode jsonNode = jsonToNode(json); |
| 62 | + return processJsonNode(jsonNode); |
| 63 | + } |
| 64 | + |
| 65 | + public static ExprValue extractJson(ExprValue json, ExprValue path) { |
| 66 | + String jsonString = json.stringValue(); |
| 67 | + String jsonPath = path.stringValue(); |
| 68 | + |
| 69 | + try { |
| 70 | + Configuration config = Configuration.builder() |
| 71 | + .options(Option.AS_PATH_LIST) |
| 72 | + .build(); |
| 73 | + List<String> resultPaths = JsonPath.using(config).parse(jsonString).read(jsonPath); |
| 74 | + |
| 75 | + List<ExprValue> elements = new LinkedList<>(); |
| 76 | + |
| 77 | + for (String resultPath : resultPaths) { |
| 78 | + Object result = JsonPath.parse(jsonString).read(resultPath); |
| 79 | + String resultJsonString = new ObjectMapper().writeValueAsString(result); |
| 80 | + try { |
| 81 | + elements.add(processJsonNode(jsonStringToNode(resultJsonString))); |
| 82 | + } catch (SemanticCheckException e) { |
| 83 | + elements.add(new ExprStringValue(resultJsonString)); |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + if (elements.size() == 1) { |
| 88 | + return elements.get(0); |
| 89 | + } else { |
| 90 | + return new ExprCollectionValue(elements); |
| 91 | + } |
| 92 | + } catch (PathNotFoundException e) { |
| 93 | + return LITERAL_NULL; |
| 94 | + } catch (InvalidJsonException | JsonProcessingException e) { |
| 95 | + final String errorFormat = "JSON string '%s' is not valid. Error details: %s"; |
| 96 | + throw new SemanticCheckException(String.format(errorFormat, json, e.getMessage()), e); |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + private static JsonNode jsonToNode(ExprValue json) { |
| 101 | + return jsonStringToNode(json.stringValue()); |
| 102 | + } |
| 103 | + |
| 104 | + private static JsonNode jsonStringToNode(String jsonString) { |
49 | 105 | ObjectMapper objectMapper = new ObjectMapper();
|
50 | 106 | JsonNode jsonNode;
|
51 | 107 | try {
|
52 |
| - jsonNode = objectMapper.readTree(json.stringValue()); |
| 108 | + jsonNode = objectMapper.readTree(jsonString); |
53 | 109 | } catch (JsonProcessingException e) {
|
54 | 110 | final String errorFormat = "JSON string '%s' is not valid. Error details: %s";
|
55 |
| - throw new SemanticCheckException(String.format(errorFormat, json, e.getMessage()), e); |
| 111 | + throw new SemanticCheckException(String.format(errorFormat, jsonString, e.getMessage()), e); |
56 | 112 | }
|
57 |
| - |
58 |
| - return processJsonNode(jsonNode); |
| 113 | + return jsonNode; |
59 | 114 | }
|
60 | 115 |
|
61 | 116 | private static ExprValue processJsonNode(JsonNode jsonNode) {
|
|
0 commit comments