Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.gateway.util; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeType; import org.junit.Assert; import org.junit.Test; import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.CoreMatchers.sameInstance; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; public class JsonPathTest { @Test public void testCompileInvalidExpressions() { String[] paths = { null, "", "$.", "$[", "$[]", ".", "[", "$.[one]", "$.['one']", "(", ")", "@", "$?", "$(", "$)", "$@", "$?" }; for (String path : paths) { try { JsonPath.compile(path); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException e) { } } } @Test public void testCompileUnsupportedExpressions() { String[] paths = { "$..book[-1:]", "$..book[,1]", "$..book[0,1]", "$..book[:2]", "$..book[0:7:2]", "$..book[(@.length-1)]", "$..book[?(@.isbn)]", "$..book[?(@.price<10)]" }; for (String path : paths) { try { JsonPath.compile(path); fail("Expected IllegalArgumentException for " + path); } catch (IllegalArgumentException e) { // Expected. } } } @Test public void testCompileValidExpressions() { JsonPath.Expression expression; JsonPath.Segment[] segments; expression = JsonPath.compile("$"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(1)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[0].getIndex(), is(-1)); expression = JsonPath.compile("$.one"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getField(), is("one")); expression = JsonPath.compile("$.'one'"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getField(), is("one")); expression = JsonPath.compile("$[one]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getField(), is("one")); expression = JsonPath.compile("$['one']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("one")); assertThat(segments[1].getIndex(), is(-1)); expression = JsonPath.compile("$[7]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.INDEX)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[1].getIndex(), is(7)); expression = JsonPath.compile("$.7"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.INDEX)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[1].getIndex(), is(7)); expression = JsonPath.compile("$['7']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("7")); assertThat(segments[1].getIndex(), is(-1)); expression = JsonPath.compile("$.'7'"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("7")); assertThat(segments[1].getIndex(), is(-1)); expression = JsonPath.compile("$.*.field"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.WILD)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("field")); expression = JsonPath.compile("$.**.field"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.GLOB)); assertThat(segments[1].getField(), is(nullValue())); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("field")); expression = JsonPath.compile("$[*][field]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.WILD)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("field")); expression = JsonPath.compile("$[**]['field']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.GLOB)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("field")); expression = JsonPath.compile("$..field"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.GLOB)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("field")); expression = JsonPath.compile("$[one].two"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("one")); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("two")); expression = JsonPath.compile("$.one[two]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("one")); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[2].getField(), is("two")); expression = JsonPath.compile("$..*"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(3)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[0].getField(), nullValue()); assertThat(segments[0].getIndex(), is(-1)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.GLOB)); assertThat(segments[1].getField(), nullValue()); assertThat(segments[1].getIndex(), is(-1)); assertThat(segments[2].getType(), is(JsonPath.Segment.Type.WILD)); assertThat(segments[2].getField(), nullValue()); assertThat(segments[2].getIndex(), is(-1)); } @Test public void testCompileQuotedExpressions() { JsonPath.Expression expression; JsonPath.Segment[] segments; expression = JsonPath.compile("$.fieldName"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("fieldName")); expression = JsonPath.compile("$[fieldName]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("fieldName")); expression = JsonPath.compile("$['fieldName']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("fieldName")); expression = JsonPath.compile("$.field_name"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field_name")); expression = JsonPath.compile("$['field_name']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field_name")); expression = JsonPath.compile("$[field_name]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field_name")); expression = JsonPath.compile("$['field-name']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field-name")); expression = JsonPath.compile("$[field-name]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field-name")); expression = JsonPath.compile("$.field-name"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field-name")); expression = JsonPath.compile("$['field.name']"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field.name")); expression = JsonPath.compile("$[field.name]"); assertThat(expression, notNullValue()); segments = expression.getSegments(); assertThat(segments, notNullValue()); assertThat(segments.length, is(2)); assertThat(segments[0].getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(segments[1].getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(segments[1].getField(), is("field.name")); } @Test public void testEvaluateObjects() throws IOException { String json; JsonPath.Segment seg; List<JsonPath.Match> matches; JsonPath.Match match; JsonPath.Match parent; JsonNode root; JsonNode node; JsonPath.Expression expression; JsonFactory factory = new JsonFactory(); ObjectMapper mapper = new ObjectMapper(factory); json = "{ \"field\" : \"value\" }"; root = mapper.readTree(json); assertThat(root, notNullValue()); expression = JsonPath.compile("$.field"); matches = expression.evaluate(root); assertThat(matches, notNullValue()); assertThat(matches.size(), is(1)); match = matches.get(0); assertThat(matches, notNullValue()); seg = matches.get(0).getSegment(); assertThat(seg, notNullValue()); assertThat(seg.getType(), is(JsonPath.Segment.Type.FIELD)); assertThat(seg.getField(), is("field")); node = match.getNode(); assertThat(node, notNullValue()); assertThat(node.getNodeType(), is(JsonNodeType.STRING)); assertThat(node.asText(), is("value")); parent = match.getParent(); assertThat(parent, notNullValue()); assertThat(parent.getNode(), sameInstance(root)); assertThat(parent.getParent(), nullValue()); assertThat(parent.getSegment().getType(), is(JsonPath.Segment.Type.ROOT)); json = "{ \"outer\" : { \"inner\" : \"value\"} }"; root = mapper.readTree(json); assertThat(root, notNullValue()); expression = JsonPath.compile("$.outer.inner"); matches = expression.evaluate(root); match = matches.get(0); assertThat(match, notNullValue()); assertThat(match.getField(), is("inner")); seg = match.getSegment(); assertThat(seg, notNullValue()); assertThat(seg.getField(), is("inner")); assertThat(seg.getType(), is(JsonPath.Segment.Type.FIELD)); node = match.getNode(); assertThat(node, notNullValue()); assertThat(node.asText(), is("value")); parent = match.getParent(); assertThat(parent, notNullValue()); assertThat(parent.getField(), is("outer")); assertThat(parent.getNode().getNodeType(), is(JsonNodeType.OBJECT)); parent = parent.getParent(); assertThat(parent.getSegment().getType(), is(JsonPath.Segment.Type.ROOT)); assertThat(parent.getNode().getNodeType(), is(JsonNodeType.OBJECT)); json = "{ \"outer\" : { \"inner\" : \"value\"} }"; root = mapper.readTree(json); assertThat(root, notNullValue()); expression = JsonPath.compile("$.*.inner"); matches = expression.evaluate(root); assertThat(matches.size(), is(1)); match = matches.get(0); assertThat(match.getField(), is("inner")); assertThat(match.getNode().asText(), is("value")); } @Test public void testEvaluateArrays() throws IOException { String json; JsonPath.Segment seg; List<JsonPath.Match> matches; JsonPath.Match match; JsonPath.Match parent; JsonNode root; JsonNode node; JsonPath.Expression expression; JsonFactory factory = new JsonFactory(); ObjectMapper mapper = new ObjectMapper(factory); json = "[ \"outer-array\", { \"nested-field\" : \"nested-object\" }, [ \"nested-array\" ] ]"; root = mapper.readTree(json); assertThat(root, notNullValue()); expression = JsonPath.compile("$[0]"); matches = expression.evaluate(root); assertThat(matches.size(), is(1)); match = matches.get(0); assertThat(match.getIndex(), is(0)); assertThat(match.getSegment().getIndex(), is(0)); assertThat(match.getNode().asText(), is("outer-array")); expression = JsonPath.compile("$[1][nested-field]"); matches = expression.evaluate(root); assertThat(matches.size(), is(1)); match = matches.get(0); assertThat(match.getField(), is("nested-field")); assertThat(match.getNode().asText(), is("nested-object")); expression = JsonPath.compile("$[*][nested-field]"); matches = expression.evaluate(root); assertThat(matches.size(), is(1)); match = matches.get(0); assertThat(match.getField(), is("nested-field")); assertThat(match.getNode().asText(), is("nested-object")); json = "{ \"array\" : [ { \"name\" : \"value-1\" }, { \"name\" : \"value-2 \"}, { \"name\" : \"value-3\" } ] }"; root = mapper.readTree(json); expression = JsonPath.compile("$.array.*.name"); matches = expression.evaluate(root); assertThat(matches.size(), is(3)); expression = JsonPath.compile("$.array[*].name"); matches = expression.evaluate(root); assertThat(matches.size(), is(3)); expression = JsonPath.compile("$.array[*][name]"); matches = expression.evaluate(root); assertThat(matches.size(), is(3)); expression = JsonPath.compile("$.array"); matches = expression.evaluate(root); match = matches.get(0); expression = JsonPath.compile("$.*.name"); matches = expression.evaluate(match.getNode()); Assert.assertThat(matches.size(), is(3)); } @Test public void testGlobMatching() throws IOException { String json; JsonPath.Segment seg; List<JsonPath.Match> matches; JsonPath.Match parent; JsonNode root; JsonNode node; JsonPath.Expression expression; Set<String> matchValues; JsonFactory factory = new JsonFactory(); ObjectMapper mapper = new ObjectMapper(factory); json = "{ \"field\" : \"value\" }"; root = mapper.readTree(json); assertThat(root, notNullValue()); expression = JsonPath.compile("$..field"); matches = expression.evaluate(root); matchValues = new HashSet<String>(); assertThat(matches.size(), is(1)); for (JsonPath.Match match : matches) { matchValues.add(match.getNode().asText()); } assertThat(matchValues, hasItem("value")); json = "{ \"field-1\" : { \"field-1-1\" : { \"field-1-1-1\" : \"value-1-1-1\", \"field\" : \"value-A\" }, \"field\" : \"value-B\"}, \"field-2\" : { \"field-2-1\" : { \"field-2-1-1\" : \"value-2-1-1\", \"field\" : \"value-C\" }, \"field\" : \"value-D\" }, \"field\" : \"value-E\" }"; root = mapper.readTree(json); assertThat(root, notNullValue()); expression = JsonPath.compile("$..field"); matches = expression.evaluate(root); assertThat(matches.size(), is(5)); matchValues = new HashSet<String>(); for (JsonPath.Match match : matches) { matchValues.add(match.getNode().asText()); } assertThat(matchValues, hasItem("value-A")); assertThat(matchValues, hasItem("value-B")); assertThat(matchValues, hasItem("value-C")); assertThat(matchValues, hasItem("value-D")); assertThat(matchValues, hasItem("value-E")); } }