Browse Source

Multi prop restored to 0.9.

pull/57/head
Kalle Stenflo 10 years ago
parent
commit
631533e048
  1. 7
      json-path-web-test/src/main/java/com/jayway/jsonpath/web/bench/Bench.java
  2. 5
      json-path-web-test/src/main/java/com/jayway/jsonpath/web/resource/ApiResource.java
  3. 9
      json-path-web-test/src/main/resources/webapp/index.html
  4. 6
      json-path/src/main/java/com/jayway/jsonpath/Option.java
  5. 5
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/GsonJsonProvider.java
  6. 6
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JacksonJsonProvider.java
  7. 5
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JsonSmartJsonProvider.java
  8. 23
      json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java
  9. 2
      json-path/src/main/java/com/jayway/jsonpath/internal/token/PropertyPathToken.java
  10. 2
      json-path/src/main/java/com/jayway/jsonpath/internal/token/WildcardPathToken.java
  11. 6
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
  12. 60
      json-path/src/test/java/com/jayway/jsonpath/MultiPropTest.java
  13. 15
      json-path/src/test/java/com/jayway/jsonpath/OptionsTest.java
  14. 2
      json-path/src/test/java/com/jayway/jsonpath/old/JsonPathTest.java

7
json-path-web-test/src/main/java/com/jayway/jsonpath/web/bench/Bench.java

@ -24,14 +24,16 @@ public class Bench {
private final boolean flagWrap; private final boolean flagWrap;
private final boolean flagSuppress; private final boolean flagSuppress;
private final boolean flagNullLeaf; private final boolean flagNullLeaf;
private final boolean flagRequireProps;
public Bench(String json, String path, boolean optionAsValues, boolean flagWrap, boolean flagSuppress, boolean flagNullLeaf) { public Bench(String json, String path, boolean optionAsValues, boolean flagWrap, boolean flagSuppress, boolean flagNullLeaf, boolean flagRequireProps) {
this.json = json; this.json = json;
this.path = path; this.path = path;
this.optionAsValues = optionAsValues; this.optionAsValues = optionAsValues;
this.flagWrap = flagWrap; this.flagWrap = flagWrap;
this.flagSuppress = flagSuppress; this.flagSuppress = flagSuppress;
this.flagNullLeaf = flagNullLeaf; this.flagNullLeaf = flagNullLeaf;
this.flagRequireProps = flagRequireProps;
} }
public Result runJayway() { public Result runJayway() {
@ -54,6 +56,9 @@ public class Bench {
if(flagNullLeaf){ if(flagNullLeaf){
configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL); configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
} }
if(flagRequireProps){
configuration = configuration.addOptions(Option.REQUIRE_PROPERTIES);
}
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
try { try {

5
json-path-web-test/src/main/java/com/jayway/jsonpath/web/resource/ApiResource.java

@ -49,11 +49,12 @@ public class ApiResource {
@FormParam("type") String type, @FormParam("type") String type,
@FormParam("flagWrap") boolean flagWrap, @FormParam("flagWrap") boolean flagWrap,
@FormParam("flagNullLeaf") boolean flagNullLeaf, @FormParam("flagNullLeaf") boolean flagNullLeaf,
@FormParam("flagSuppress") boolean flagSuppress ){ @FormParam("flagSuppress") boolean flagSuppress,
@FormParam("flagRequireProps") boolean flagRequireProps){
boolean value = "VALUE".equalsIgnoreCase(type); boolean value = "VALUE".equalsIgnoreCase(type);
Map<String, Result> resultMap = new Bench(json, path, value, flagWrap, flagSuppress, flagNullLeaf).runAll(); Map<String, Result> resultMap = new Bench(json, path, value, flagWrap, flagSuppress, flagNullLeaf, flagRequireProps).runAll();
return Response.ok(resultMap).build(); return Response.ok(resultMap).build();
} }

9
json-path-web-test/src/main/resources/webapp/index.html

@ -121,6 +121,12 @@
Return null for missing leaf Return null for missing leaf
</label> </label>
</div> </div>
<div class="checkbox">
<label>
<input type="checkbox" name="flagRequireProps" id="cbFlagRequireProps" />
Require all properties
</label>
</div>
</fieldset> </fieldset>
</div> </div>
</div> </div>
@ -271,7 +277,8 @@
type: $('input[name=rbType]:checked').val(), type: $('input[name=rbType]:checked').val(),
flagWrap: $('#cbFlagWrap').prop('checked'), flagWrap: $('#cbFlagWrap').prop('checked'),
flagNullLeaf: $('#cbFlagNullLeaf').prop('checked'), flagNullLeaf: $('#cbFlagNullLeaf').prop('checked'),
flagSuppress: $('#cbFlagSuppress').prop('checked') flagSuppress: $('#cbFlagSuppress').prop('checked'),
flagRequireProps: $('#cbFlagRequireProps').prop('checked')
} }
$.ajax({ $.ajax({
url: "/api/eval", url: "/api/eval",

6
json-path/src/main/java/com/jayway/jsonpath/Option.java

@ -80,9 +80,9 @@ public enum Option {
* *
* evaluating the path "$[*].b" * evaluating the path "$[*].b"
* *
* If REQUIRE_PATH_PROPERTIES option is present PathNotFoundException is thrown. * If REQUIRE_PROPERTIES option is present PathNotFoundException is thrown.
* If REQUIRE_PATH_PROPERTIES option is not present ["b-val"] is returned. * If REQUIRE_PROPERTIES option is not present ["b-val"] is returned.
*/ */
REQUIRE_PATH_PROPERTIES REQUIRE_PROPERTIES
} }

5
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/GsonJsonProvider.java

@ -117,6 +117,11 @@ public class GsonJsonProvider extends AbstractJsonProvider {
return new JsonArray(); return new JsonArray();
} }
@Override
public Object createMap() {
return new JsonObject();
}
@Override @Override
public boolean isArray(Object obj) { public boolean isArray(Object obj) {
return (obj instanceof JsonArray || obj instanceof List); return (obj instanceof JsonArray || obj instanceof List);

6
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JacksonJsonProvider.java

@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -106,5 +107,8 @@ public class JacksonJsonProvider extends AbstractJsonProvider {
return new LinkedList<Object>(); return new LinkedList<Object>();
} }
@Override
public Object createMap() {
return new LinkedHashMap<String, Object>();
}
} }

5
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JsonSmartJsonProvider.java

@ -14,6 +14,7 @@
*/ */
package com.jayway.jsonpath.internal.spi.json; package com.jayway.jsonpath.internal.spi.json;
import com.google.gson.internal.LinkedTreeMap;
import com.jayway.jsonpath.InvalidJsonException; import com.jayway.jsonpath.InvalidJsonException;
import com.jayway.jsonpath.JsonPathException; import com.jayway.jsonpath.JsonPathException;
import com.jayway.jsonpath.spi.json.Mode; import com.jayway.jsonpath.spi.json.Mode;
@ -48,6 +49,10 @@ public class JsonSmartJsonProvider extends AbstractJsonProvider {
return orderedMapper.createArray(); return orderedMapper.createArray();
} }
public Object createMap() {
return orderedMapper.createObject();
}
public Object parse(String json) { public Object parse(String json) {
try { try {
return createParser().parse(json, orderedMapper); return createParser().parse(json, orderedMapper);

23
json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java

@ -46,7 +46,7 @@ public abstract class PathToken {
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
propertyVal = null; propertyVal = null;
} else { } else {
if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) && !ctx.options().contains(Option.REQUIRE_PATH_PROPERTIES)){ if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) && !ctx.options().contains(Option.REQUIRE_PROPERTIES)){
return; return;
} else { } else {
throw new PathNotFoundException("No results for path: " + evalPath); throw new PathNotFoundException("No results for path: " + evalPath);
@ -55,11 +55,11 @@ public abstract class PathToken {
} }
} else { } else {
if(!isUpstreamDefinite() && if(!isUpstreamDefinite() &&
!ctx.options().contains(Option.REQUIRE_PATH_PROPERTIES) && !ctx.options().contains(Option.REQUIRE_PROPERTIES) &&
!ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){ !ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){
return; return;
} else { } else {
throw new PathNotFoundException(evalPath); throw new PathNotFoundException("Missing property in path " + evalPath);
} }
} }
} }
@ -74,24 +74,31 @@ public abstract class PathToken {
if (!isLeaf()) { if (!isLeaf()) {
throw new InvalidPathException("Multi properties can only be used as path leafs: " + evalPath); throw new InvalidPathException("Multi properties can only be used as path leafs: " + evalPath);
} }
Object merged = ctx.jsonProvider().createMap();
for (String property : properties) { for (String property : properties) {
evalPath = currentPath + "['" + property + "']"; Object propertyVal = null;
if(hasProperty(property, model, ctx)) { if(hasProperty(property, model, ctx)) {
Object propertyVal = readObjectProperty(property, model, ctx); propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){ if(propertyVal == JsonProvider.UNDEFINED){
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) {
propertyVal = null; propertyVal = null;
} else { } else {
continue; continue;
} }
} }
ctx.addResult(evalPath, propertyVal);
} else { } else {
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
ctx.addResult(evalPath, null); propertyVal = null;
} else if (ctx.options().contains(Option.REQUIRE_PROPERTIES)) {
throw new PathNotFoundException("Missing property in path " + evalPath);
} else {
continue;
} }
} }
ctx.jsonProvider().setProperty(merged, property, propertyVal);
} }
ctx.addResult(evalPath, merged);
} }
} }

2
json-path/src/main/java/com/jayway/jsonpath/internal/token/PropertyPathToken.java

@ -45,7 +45,7 @@ public class PropertyPathToken extends PathToken {
@Override @Override
boolean isTokenDefinite() { boolean isTokenDefinite() {
return properties.size() == 1; return true;
} }
@Override @Override

2
json-path/src/main/java/com/jayway/jsonpath/internal/token/WildcardPathToken.java

@ -35,7 +35,7 @@ public class WildcardPathToken extends PathToken {
try { try {
handleArrayIndex(idx, currentPath, model, ctx); handleArrayIndex(idx, currentPath, model, ctx);
} catch (PathNotFoundException p){ } catch (PathNotFoundException p){
if(ctx.options().contains(Option.REQUIRE_PATH_PROPERTIES)){ if(ctx.options().contains(Option.REQUIRE_PROPERTIES)){
throw p; throw p;
} }
} }

6
json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java

@ -53,6 +53,12 @@ public interface JsonProvider {
*/ */
Object createArray(); Object createArray();
/**
* Creates a provider specific json object
* @return new object
*/
Object createMap();
/** /**
* checks if object is an array * checks if object is an array
* *

60
json-path/src/test/java/com/jayway/jsonpath/MultiPropTest.java

@ -0,0 +1,60 @@
package com.jayway.jsonpath;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static com.jayway.jsonpath.JsonPath.using;
import static org.assertj.core.api.Assertions.assertThat;
public class MultiPropTest {
@Test
public void multi_prop_can_be_read_from_root() {
Map<String, Object> model = new HashMap<String, Object>(){{
put("a", "a-val");
put("b", "b-val");
put("c", "c-val");
}};
Configuration conf = Configuration.defaultConfiguration();
assertThat(using(conf).parse(model).read("$['a', 'b']", Map.class))
.containsEntry("a", "a-val")
.containsEntry("b", "b-val");
}
@Test
public void multi_props_can_be_defaulted_to_null() {
Map<String, Object> model = new HashMap<String, Object>(){{
put("a", "a-val");
put("b", "b-val");
put("c", "c-val");
}};
Configuration conf = Configuration.defaultConfiguration().addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
assertThat(using(conf).parse(model).read("$['a', 'd']", Map.class))
.containsEntry("a", "a-val")
.containsEntry("d", null);
}
@Test(expected = PathNotFoundException.class)
public void multi_props_can_be_required() {
Map<String, Object> model = new HashMap<String, Object>(){{
put("a", "a-val");
put("b", "b-val");
put("c", "c-val");
}};
Configuration conf = Configuration.defaultConfiguration().addOptions(Option.REQUIRE_PROPERTIES);
using(conf).parse(model).read("$['a', 'x']", Map.class);
}
}

15
json-path/src/test/java/com/jayway/jsonpath/OptionsTest.java

@ -2,7 +2,6 @@ package com.jayway.jsonpath;
import org.junit.Test; import org.junit.Test;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -65,7 +64,7 @@ public class OptionsTest extends BaseTest {
} }
@Test @Test
public void multi_properties_are_not_merged_by_default() { public void multi_properties_are_merged_by_default() {
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();
model.put("a", "a"); model.put("a", "a");
@ -74,10 +73,14 @@ public class OptionsTest extends BaseTest {
Configuration conf = Configuration.defaultConfiguration(); Configuration conf = Configuration.defaultConfiguration();
Object result = using(conf).parse(model).read("$.['a', 'b']"); Map<String, Object> result = using(conf).parse(model).read("$.['a', 'b']");
assertThat(result).isInstanceOf(List.class); //assertThat(result).isInstanceOf(List.class);
assertThat((List)result).containsOnly("a", "b"); //assertThat((List)result).containsOnly("a", "b");
assertThat(result)
.containsEntry("a", "a")
.containsEntry("b", "b");
} }
@Test @Test
@ -89,7 +92,7 @@ public class OptionsTest extends BaseTest {
assertThat(using(conf).parse(model).read("$[*].a", List.class)).containsExactly("a-val"); assertThat(using(conf).parse(model).read("$[*].a", List.class)).containsExactly("a-val");
conf = conf.addOptions(Option.REQUIRE_PATH_PROPERTIES); conf = conf.addOptions(Option.REQUIRE_PROPERTIES);
try{ try{
using(conf).parse(model).read("$[*].a", List.class); using(conf).parse(model).read("$[*].a", List.class);

2
json-path/src/test/java/com/jayway/jsonpath/old/JsonPathTest.java

@ -85,7 +85,7 @@ public class JsonPathTest extends BaseTest {
//Object read = JsonPath.using(Configuration.defaultConfiguration().setOptions(Option.THROW_ON_MISSING_PROPERTY)).parse(DOCUMENT).read("$.store.book[*].fooBar"); //Object read = JsonPath.using(Configuration.defaultConfiguration().setOptions(Option.THROW_ON_MISSING_PROPERTY)).parse(DOCUMENT).read("$.store.book[*].fooBar");
//Object read = JsonPath.using(Configuration.defaultConfiguration()).parse(DOCUMENT).read("$.store.book[*].fooBar"); //Object read = JsonPath.using(Configuration.defaultConfiguration()).parse(DOCUMENT).read("$.store.book[*].fooBar");
Object read2 = JsonPath.using(Configuration.defaultConfiguration().addOptions(Option.REQUIRE_PATH_PROPERTIES)).parse(DOCUMENT).read("$.store.book[*].fooBar.not"); Object read2 = JsonPath.using(Configuration.defaultConfiguration().addOptions(Option.REQUIRE_PROPERTIES)).parse(DOCUMENT).read("$.store.book[*].fooBar.not");
} }

Loading…
Cancel
Save