diff --git a/build.gradle b/build.gradle index a4c9decb8..4589914c1 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,7 @@ allprojects { ext.displayName = null ext.buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss') + apply plugin: 'maven' group = 'com.jayway.jsonpath' version = '2.0.1' + (snapshotVersion ? "-SNAPSHOT" : "") @@ -75,4 +76,4 @@ task wrapper(type: Wrapper) { //Task used by Heroku for staging task stage(dependsOn: [':json-path-web-test:clean', 'json-path-web-test:jar', 'json-path-web-test:shadowJar']) {} -apply from: "$rootDir/gradle/binaryCompatibility.gradle" \ No newline at end of file +apply from: "$rootDir/gradle/binaryCompatibility.gradle" 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 720728a26..0ed13df8f 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 @@ void handleArrayIndex(int index, String currentPath, Object model, EvaluationCon } } + 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 f7824036d..db3a00b5a 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 List getProperties() { @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 9c80e56b9..bb7504dc9 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 void test_type_ref() throws IOException { 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;