From 5026ea0e78a700445bfe6678f2259dbefb4c27f8 Mon Sep 17 00:00:00 2001 From: Nicholas Rahn Date: Thu, 25 Jun 2015 15:13:10 +0200 Subject: [PATCH] Support for getting the length of an array. --- .../com/jayway/jsonpath/internal/token/PathToken.java | 11 +++++++++++ .../jsonpath/internal/token/PropertyPathToken.java | 5 +++++ .../java/com/jayway/jsonpath/JsonProviderTest.java | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java index 720728a2..0ed13df8 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java @@ -128,6 +128,17 @@ public abstract class PathToken { } } + void handleArrayLength(String currentPath, Object model, EvaluationContextImpl ctx) { + String evalPath = currentPath + ".length"; + PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, "length") : PathRef.NO_OP; + Object evalHit = ctx.jsonProvider().length(model); + if (isLeaf()) { + ctx.addResult(evalPath, pathRef, evalHit); + } else { + next().evaluate(evalPath, pathRef, evalHit, ctx); + } + } + PathToken prev(){ return prev; } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/token/PropertyPathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/token/PropertyPathToken.java index f7824036..db3a00b5 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/token/PropertyPathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/token/PropertyPathToken.java @@ -38,6 +38,11 @@ public class PropertyPathToken extends PathToken { @Override public void evaluate(String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx) { if (!ctx.jsonProvider().isMap(model)) { + // Special case handling of the 'length' property of arrays. + if (isLeaf() && ctx.jsonProvider().isArray(model) && properties.size() == 1 && properties.get(0).equals("length")) { + handleArrayLength(currentPath, model, ctx); + return; + } throw new PathNotFoundException("Property " + getPathFragment() + " not found in path " + currentPath); } diff --git a/json-path/src/test/java/com/jayway/jsonpath/JsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/JsonProviderTest.java index 9c80e56b..bb7504dc 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/JsonProviderTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/JsonProviderTest.java @@ -75,6 +75,13 @@ public class JsonProviderTest extends BaseTest { assertThat(using(GSON_CONFIGURATION).parse(JSON).read("$", typeRef)).extracting("foo").containsExactly("foo0", "foo1", "foo2"); } + @Test + public void length_of_array() { + assertThat(using(JACKSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book.length", Integer.class)).isEqualTo(4); + assertThat(using(JACKSON_JSON_NODE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book.length", Integer.class)).isEqualTo(4); + assertThat(using(JSON_SMART_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book.length", Integer.class)).isEqualTo(4); + assertThat(using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book.length", Integer.class)).isEqualTo(4); + } public static class FooBarBaz { public T gen;