Browse Source

Clean up.

pull/46/head
Kalle Stenflo 10 years ago
parent
commit
4194ac3e7e
  1. 1
      json-path-assert/src/main/java/com/jayway/jsonassert/impl/JsonAsserterImpl.java
  2. 1
      json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java
  3. 7
      json-path-web-test/src/main/java/com/jayway/jsonpath/web/bench/Bench.java
  4. 3
      json-path-web-test/src/main/java/com/jayway/jsonpath/web/resource/ApiResource.java
  5. 7
      json-path-web-test/src/main/resources/html/index.html
  6. 32
      json-path/src/main/java/com/jayway/jsonpath/Configuration.java
  7. 59
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  8. 6
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  9. 3
      json-path/src/main/java/com/jayway/jsonpath/Option.java
  10. 7
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/EvaluationContextImpl.java
  11. 37
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/PathToken.java
  12. 16
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/RootPathToken.java
  13. 6
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/WildcardPathToken.java
  14. 3
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/AbstractJsonProvider.java
  15. 1
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JsonSmartJsonProvider.java
  16. 6
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProviderFactory.java
  17. 29
      json-path/src/test/java/com/jayway/jsonpath/IssuesTest.java
  18. 3
      json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java
  19. 29
      json-path/src/test/java/com/jayway/jsonpath/NullHandlingTest.java
  20. 5
      json-path/src/test/java/com/jayway/jsonpath/internal/PropertyPathTokenTest.java
  21. 4
      json-path/src/test/java/com/jayway/jsonpath/reader/ReadConfigurationTest.java
  22. 9
      pom.xml

1
json-path-assert/src/main/java/com/jayway/jsonassert/impl/JsonAsserterImpl.java

@ -4,7 +4,6 @@ package com.jayway.jsonassert.impl;
import com.jayway.jsonassert.JsonAsserter; import com.jayway.jsonassert.JsonAsserter;
import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.PathNotFoundException;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;

1
json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java

@ -1,6 +1,5 @@
package com.jayway.jsonassert; package com.jayway.jsonassert;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.io.InputStream; import java.io.InputStream;

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

@ -25,14 +25,16 @@ public class Bench {
private final boolean flagWrap; private final boolean flagWrap;
private final boolean flagMerge; private final boolean flagMerge;
private final boolean flagSuppress; private final boolean flagSuppress;
private final boolean flagNullLeaf;
public Bench(String json, String path, boolean optionAsValues, boolean flagWrap, boolean flagMerge, boolean flagSuppress) { public Bench(String json, String path, boolean optionAsValues, boolean flagWrap, boolean flagMerge, boolean flagSuppress, boolean flagNullLeaf) {
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.flagMerge = flagMerge; this.flagMerge = flagMerge;
this.flagSuppress = flagSuppress; this.flagSuppress = flagSuppress;
this.flagNullLeaf = flagNullLeaf;
} }
public Result runJayway() { public Result runJayway() {
@ -55,6 +57,9 @@ public class Bench {
if (!optionAsValues) { if (!optionAsValues) {
configuration = configuration.addOptions(Option.AS_PATH_LIST); configuration = configuration.addOptions(Option.AS_PATH_LIST);
} }
if(flagNullLeaf){
configuration = configuration.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
}
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
try { try {

3
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("flagMerge") boolean flagMerge, @FormParam("flagMerge") boolean flagMerge,
@FormParam("flagNullLeaf") boolean flagNullLeaf,
@FormParam("flagSuppress") boolean flagSuppress ){ @FormParam("flagSuppress") boolean flagSuppress ){
boolean value = "VALUE".equalsIgnoreCase(type); boolean value = "VALUE".equalsIgnoreCase(type);
Map<String, Result> resultMap = new Bench(json, path, value, flagWrap, flagMerge, flagSuppress).runAll(); Map<String, Result> resultMap = new Bench(json, path, value, flagWrap, flagMerge, flagSuppress, flagNullLeaf).runAll();
return Response.ok(resultMap).build(); return Response.ok(resultMap).build();
} }

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

@ -82,6 +82,12 @@
Merge multi props to new object Merge multi props to new object
</label> </label>
</div> </div>
<div class="checkbox">
<label>
<input type="checkbox" name="flagNullLeaf" id="cbFlagNullLeaf" />
Return null for missing leaf
</label>
</div>
</fieldset> </fieldset>
</div> </div>
</div> </div>
@ -222,6 +228,7 @@
type: $('input[name=rbType]:checked').val(), type: $('input[name=rbType]:checked').val(),
flagWrap: $('#cbFlagWrap').prop('checked'), flagWrap: $('#cbFlagWrap').prop('checked'),
flagMerge: $('#cbFlagMerge').prop('checked'), flagMerge: $('#cbFlagMerge').prop('checked'),
flagNullLeaf: $('#cbFlagNullLeaf').prop('checked'),
flagSuppress: $('#cbFlagSuppress').prop('checked') flagSuppress: $('#cbFlagSuppress').prop('checked')
} }
console.log(data); console.log(data);

32
json-path/src/main/java/com/jayway/jsonpath/Configuration.java

@ -26,6 +26,22 @@ import static java.util.Arrays.asList;
public class Configuration { public class Configuration {
private static Defaults DEFAULTS = new Defaults() {
@Override
public JsonProvider provider() {
return JsonProviderFactory.createProvider();
}
@Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
};
public static synchronized void setDefaults(Defaults defaults){
DEFAULTS = defaults;
}
private final JsonProvider provider; private final JsonProvider provider;
private final Set<Option> options; private final Set<Option> options;
@ -64,7 +80,7 @@ public class Configuration {
public static Configuration defaultConfiguration() { public static Configuration defaultConfiguration() {
return new Configuration(JsonProviderFactory.createProvider(), EnumSet.noneOf(Option.class)); return Configuration.builder().jsonProvider(DEFAULTS.provider()).options(DEFAULTS.options()).build();
} }
public static ConfigurationBuilder builder() { public static ConfigurationBuilder builder() {
@ -82,7 +98,9 @@ public class Configuration {
} }
public ConfigurationBuilder options(Option... flags) { public ConfigurationBuilder options(Option... flags) {
this.options.addAll(asList(flags)); if(flags.length > 0) {
this.options.addAll(asList(flags));
}
return this; return this;
} }
@ -93,9 +111,17 @@ public class Configuration {
public Configuration build() { public Configuration build() {
if (provider == null) { if (provider == null) {
provider = JsonProviderFactory.createProvider(); provider = DEFAULTS.provider();
} }
return new Configuration(provider, options); return new Configuration(provider, options);
} }
} }
public interface Defaults {
JsonProvider provider();
Set<Option> options();
}
} }

59
json-path/src/main/java/com/jayway/jsonpath/Criteria.java

@ -19,6 +19,7 @@ import static com.jayway.jsonpath.internal.Utils.notNull;
/** /**
* *
*/ */
@SuppressWarnings("unchecked")
public class Criteria implements Predicate { public class Criteria implements Predicate {
private static final Logger logger = LoggerFactory.getLogger(Criteria.class); private static final Logger logger = LoggerFactory.getLogger(Criteria.class);
@ -173,10 +174,8 @@ public class Criteria implements Predicate {
boolean eval(Object expected, Object actual, Configuration configuration) { boolean eval(Object expected, Object actual, Configuration configuration) {
final Class<?> expType = (Class<?>) expected; final Class<?> expType = (Class<?>) expected;
final Class<?> actType = actual == null ? null : actual.getClass(); final Class<?> actType = actual == null ? null : actual.getClass();
if (actType != null) {
return expType.isAssignableFrom(actType); return actType != null && expType.isAssignableFrom(actType);
}
return false;
} }
}, },
REGEX { REGEX {
@ -272,10 +271,17 @@ public class Criteria implements Predicate {
if (CriteriaType.EXISTS == criteriaType) { if (CriteriaType.EXISTS == criteriaType) {
boolean exists = ((Boolean) expected); boolean exists = ((Boolean) expected);
try { try {
path.evaluate(model, configuration.options(Option.THROW_ON_MISSING_PROPERTY)).getValue(); //path.evaluate(model, configuration.options(Option.THROW_ON_MISSING_PROPERTY)).getValue();
return exists == true;
Configuration c = configuration;
if(c.containsOption(Option.ALWAYS_RETURN_LIST) || c.containsOption(Option.SUPPRESS_EXCEPTIONS)){
c = c.options();
}
path.evaluate(model, c).getValue();
return exists;
} catch (PathNotFoundException e) { } catch (PathNotFoundException e) {
return exists == false; return !exists;
} }
} else { } else {
@ -326,7 +332,7 @@ public class Criteria implements Predicate {
* Creates a criterion using equality * Creates a criterion using equality
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria is(Object o) { public Criteria is(Object o) {
this.criteriaType = CriteriaType.EQ; this.criteriaType = CriteriaType.EQ;
@ -338,7 +344,7 @@ public class Criteria implements Predicate {
* Creates a criterion using equality * Creates a criterion using equality
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria eq(Object o) { public Criteria eq(Object o) {
return is(o); return is(o);
@ -348,7 +354,7 @@ public class Criteria implements Predicate {
* Creates a criterion using the <b>!=</b> operator * Creates a criterion using the <b>!=</b> operator
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria ne(Object o) { public Criteria ne(Object o) {
this.criteriaType = CriteriaType.NE; this.criteriaType = CriteriaType.NE;
@ -360,7 +366,7 @@ public class Criteria implements Predicate {
* Creates a criterion using the <b>&lt;</b> operator * Creates a criterion using the <b>&lt;</b> operator
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria lt(Object o) { public Criteria lt(Object o) {
this.criteriaType = CriteriaType.LT; this.criteriaType = CriteriaType.LT;
@ -372,7 +378,7 @@ public class Criteria implements Predicate {
* Creates a criterion using the <b>&lt;=</b> operator * Creates a criterion using the <b>&lt;=</b> operator
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria lte(Object o) { public Criteria lte(Object o) {
this.criteriaType = CriteriaType.LTE; this.criteriaType = CriteriaType.LTE;
@ -384,7 +390,7 @@ public class Criteria implements Predicate {
* Creates a criterion using the <b>&gt;</b> operator * Creates a criterion using the <b>&gt;</b> operator
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria gt(Object o) { public Criteria gt(Object o) {
this.criteriaType = CriteriaType.GT; this.criteriaType = CriteriaType.GT;
@ -396,7 +402,7 @@ public class Criteria implements Predicate {
* Creates a criterion using the <b>&gt;=</b> operator * Creates a criterion using the <b>&gt;=</b> operator
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria gte(Object o) { public Criteria gte(Object o) {
this.criteriaType = CriteriaType.GTE; this.criteriaType = CriteriaType.GTE;
@ -408,7 +414,7 @@ public class Criteria implements Predicate {
* Creates a criterion using a Regex * Creates a criterion using a Regex
* *
* @param pattern * @param pattern
* @return * @return the criteria
*/ */
public Criteria regex(Pattern pattern) { public Criteria regex(Pattern pattern) {
notNull(pattern, "pattern can not be null"); notNull(pattern, "pattern can not be null");
@ -422,7 +428,7 @@ public class Criteria implements Predicate {
* to specify an array of possible matches. * to specify an array of possible matches.
* *
* @param o the values to match against * @param o the values to match against
* @return * @return the criteria
*/ */
public Criteria in(Object... o) { public Criteria in(Object... o) {
return in(Arrays.asList(o)); return in(Arrays.asList(o));
@ -433,7 +439,7 @@ public class Criteria implements Predicate {
* to specify an array of possible matches. * to specify an array of possible matches.
* *
* @param c the collection containing the values to match against * @param c the collection containing the values to match against
* @return * @return the criteria
*/ */
public Criteria in(Collection<?> c) { public Criteria in(Collection<?> c) {
notNull(c, "collection can not be null"); notNull(c, "collection can not be null");
@ -447,7 +453,7 @@ public class Criteria implements Predicate {
* which the specified field does not have any value in the specified array. * which the specified field does not have any value in the specified array.
* *
* @param o the values to match against * @param o the values to match against
* @return * @return the criteria
*/ */
public Criteria nin(Object... o) { public Criteria nin(Object... o) {
return nin(Arrays.asList(o)); return nin(Arrays.asList(o));
@ -458,7 +464,7 @@ public class Criteria implements Predicate {
* which the specified field does not have any value in the specified array. * which the specified field does not have any value in the specified array.
* *
* @param c the values to match against * @param c the values to match against
* @return * @return the criteria
*/ */
public Criteria nin(Collection<?> c) { public Criteria nin(Collection<?> c) {
notNull(c, "collection can not be null"); notNull(c, "collection can not be null");
@ -472,7 +478,7 @@ public class Criteria implements Predicate {
* in the specified array all values in the array must be matched. * in the specified array all values in the array must be matched.
* *
* @param o * @param o
* @return * @return the criteria
*/ */
public Criteria all(Object... o) { public Criteria all(Object... o) {
return all(Arrays.asList(o)); return all(Arrays.asList(o));
@ -483,7 +489,7 @@ public class Criteria implements Predicate {
* in the specified array all values in the array must be matched. * in the specified array all values in the array must be matched.
* *
* @param c * @param c
* @return * @return the criteria
*/ */
public Criteria all(Collection<?> c) { public Criteria all(Collection<?> c) {
notNull(c, "collection can not be null"); notNull(c, "collection can not be null");
@ -501,7 +507,7 @@ public class Criteria implements Predicate {
* </ol> * </ol>
* *
* @param size * @param size
* @return * @return the criteria
*/ */
public Criteria size(int size) { public Criteria size(int size) {
this.criteriaType = CriteriaType.SIZE; this.criteriaType = CriteriaType.SIZE;
@ -514,7 +520,7 @@ public class Criteria implements Predicate {
* Check for existence (or lack thereof) of a field. * Check for existence (or lack thereof) of a field.
* *
* @param b * @param b
* @return * @return the criteria
*/ */
public Criteria exists(boolean b) { public Criteria exists(boolean b) {
this.criteriaType = CriteriaType.EXISTS; this.criteriaType = CriteriaType.EXISTS;
@ -526,7 +532,7 @@ public class Criteria implements Predicate {
* The $type operator matches values based on their Java type. * The $type operator matches values based on their Java type.
* *
* @param t * @param t
* @return * @return the criteria
*/ */
public Criteria type(Class<?> t) { public Criteria type(Class<?> t) {
notNull(t, "type can not be null"); notNull(t, "type can not be null");
@ -538,7 +544,7 @@ public class Criteria implements Predicate {
/** /**
* The <code>notEmpty</code> operator checks that an array or String is not empty. * The <code>notEmpty</code> operator checks that an array or String is not empty.
* *
* @return * @return the criteria
*/ */
public Criteria notEmpty() { public Criteria notEmpty() {
this.criteriaType = CriteriaType.NOT_EMPTY; this.criteriaType = CriteriaType.NOT_EMPTY;
@ -549,7 +555,8 @@ public class Criteria implements Predicate {
/** /**
* The <code>matches</code> operator checks that an object matches the given predicate. * The <code>matches</code> operator checks that an object matches the given predicate.
* *
* @return * @param p
* @return the criteria
*/ */
public Criteria matches(Predicate p) { public Criteria matches(Predicate p) {
this.criteriaType = CriteriaType.MATCHES; this.criteriaType = CriteriaType.MATCHES;

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

@ -165,11 +165,12 @@ public class JsonPath {
* @param <T> expected return type * @param <T> expected return type
* @return object(s) matched by the given path * @return object(s) matched by the given path
*/ */
@SuppressWarnings("unchecked")
public <T> T read(Object jsonObject, Configuration configuration) { public <T> T read(Object jsonObject, Configuration configuration) {
boolean optAsPathList = configuration.containsOption(Option.AS_PATH_LIST); boolean optAsPathList = configuration.containsOption(Option.AS_PATH_LIST);
boolean optAlwaysReturnList = configuration.containsOption(Option.ALWAYS_RETURN_LIST); boolean optAlwaysReturnList = configuration.containsOption(Option.ALWAYS_RETURN_LIST);
boolean optSuppressExceptions = configuration.containsOption(Option.SUPPRESS_EXCEPTIONS); boolean optSuppressExceptions = configuration.containsOption(Option.SUPPRESS_EXCEPTIONS);
boolean optThrowOnMissingProperty = configuration.containsOption(Option.THROW_ON_MISSING_PROPERTY); //boolean optThrowOnMissingProperty = configuration.containsOption(Option.THROW_ON_MISSING_PROPERTY);
try { try {
if(optAsPathList){ if(optAsPathList){
@ -185,7 +186,8 @@ public class JsonPath {
} }
} }
} catch (RuntimeException e){ } catch (RuntimeException e){
if(optThrowOnMissingProperty || !optSuppressExceptions){ //if(optThrowOnMissingProperty || !optSuppressExceptions){
if(!optSuppressExceptions){
throw e; throw e;
} }
} }

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

@ -19,7 +19,8 @@ public enum Option {
/** /**
* Throw {@link PathNotFoundException} when JsonPath tries to read a property that does not exists. * Throw {@link PathNotFoundException} when JsonPath tries to read a property that does not exists.
*/ */
THROW_ON_MISSING_PROPERTY, //THROW_ON_MISSING_PROPERTY,
DEFAULT_PATH_LEAF_TO_NULL,
/** /**
* Makes this implementation more compliant to the Goessner spec. All results are returned as Lists. * Makes this implementation more compliant to the Goessner spec. All results are returned as Lists.

7
json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/EvaluationContextImpl.java

@ -8,10 +8,11 @@ import com.jayway.jsonpath.spi.compiler.Path;
import com.jayway.jsonpath.spi.json.JsonProvider; import com.jayway.jsonpath.spi.json.JsonProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static com.jayway.jsonpath.internal.Utils.notNull;
/** /**
* *
*/ */
@ -24,6 +25,8 @@ class EvaluationContextImpl implements EvaluationContext {
private int resultIndex = 0; private int resultIndex = 0;
EvaluationContextImpl(Path path, Configuration configuration) { EvaluationContextImpl(Path path, Configuration configuration) {
notNull(path, "path can not be null");
notNull(configuration, "configuration can not be null");
this.path = path; this.path = path;
this.configuration = configuration; this.configuration = configuration;
this.valueResult = configuration.getProvider().createArray(); this.valueResult = configuration.getProvider().createArray();
@ -50,6 +53,7 @@ class EvaluationContextImpl implements EvaluationContext {
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T> T getValue() { public <T> T getValue() {
if (path.isDefinite()) { if (path.isDefinite()) {
@ -61,6 +65,7 @@ class EvaluationContextImpl implements EvaluationContext {
return (T) valueResult; return (T) valueResult;
} }
@SuppressWarnings("unchecked")
@Override @Override
public <T> T getPath() { public <T> T getPath() {
if(resultIndex == 0){ if(resultIndex == 0){

37
json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/PathToken.java

@ -25,7 +25,20 @@ abstract class PathToken {
String evalPath = currentPath + "['" + property + "']"; String evalPath = currentPath + "['" + property + "']";
Object propertyVal = readObjectProperty(property, model, ctx); Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){ if(propertyVal == JsonProvider.UNDEFINED){
return; if(isLeaf()) {
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
propertyVal = null;
} else {
if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){
return;
} else {
throw new PathNotFoundException("No results for path: " + evalPath);
}
}
} else {
return;
}
} }
if (isLeaf()) { if (isLeaf()) {
ctx.addResult(evalPath, propertyVal); ctx.addResult(evalPath, propertyVal);
@ -44,7 +57,11 @@ abstract class PathToken {
for (String property : properties) { for (String property : properties) {
Object propertyVal = readObjectProperty(property, model, ctx); Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){ if(propertyVal == JsonProvider.UNDEFINED){
continue; if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
propertyVal = null;
} else {
continue;
}
} }
ctx.jsonProvider().setProperty(map, property, propertyVal); ctx.jsonProvider().setProperty(map, property, propertyVal);
} }
@ -56,7 +73,11 @@ abstract class PathToken {
if(hasProperty(property, model, ctx)) { if(hasProperty(property, model, ctx)) {
Object propertyVal = readObjectProperty(property, model, ctx); Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){ if(propertyVal == JsonProvider.UNDEFINED){
continue; if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){
propertyVal = null;
} else {
continue;
}
} }
ctx.addResult(evalPath, propertyVal); ctx.addResult(evalPath, propertyVal);
} }
@ -70,13 +91,7 @@ abstract class PathToken {
} }
private Object readObjectProperty(String property, Object model, EvaluationContextImpl ctx) { private Object readObjectProperty(String property, Object model, EvaluationContextImpl ctx) {
Object val = ctx.jsonProvider().getMapValue(model, property, true); return ctx.jsonProvider().getMapValue(model, property, true);
if(val == JsonProvider.UNDEFINED){
if(ctx.options().contains(Option.THROW_ON_MISSING_PROPERTY)) {
throw new PathNotFoundException("Property ['" + property + "'] not found in the current context");
}
}
return val;
} }
void handleArrayIndex(int index, String currentPath, Object json, EvaluationContextImpl ctx) { void handleArrayIndex(int index, String currentPath, Object json, EvaluationContextImpl ctx) {
@ -89,7 +104,7 @@ abstract class PathToken {
next().evaluate(evalPath, evalHit, ctx); next().evaluate(evalPath, evalHit, ctx);
} }
} catch (IndexOutOfBoundsException e) { } catch (IndexOutOfBoundsException e) {
throw new PathNotFoundException("Index out of bounds when evaluating path " + currentPath + "[" + index + "]"); throw new PathNotFoundException("Index out of bounds when evaluating path " + evalPath);
} }
} }

16
json-path/src/main/java/com/jayway/jsonpath/internal/spi/compiler/RootPathToken.java

@ -28,23 +28,7 @@ class RootPathToken extends PathToken /*implements Path*/ {
this.tokenCount++; this.tokenCount++;
return this; return this;
} }
/*
@Override
public EvaluationContextImpl evaluate(Object model, Configuration configuration) {
if(logger.isDebugEnabled()) {
logger.debug("Evaluating path: {}", toString());
}
EvaluationContextImpl ctx = new EvaluationContextImpl(configuration, isDefinite());
evaluate("", model, ctx);
if(logger.isDebugEnabled()) {
logger.debug("Found:\n{}", JsonFormatter.prettyPrint(ctx.configuration().getProvider().toJson(ctx.getPathList())));
}
return ctx;
}
*/
@Override @Override
void evaluate(String currentPath, Object model, EvaluationContextImpl ctx) { void evaluate(String currentPath, Object model, EvaluationContextImpl ctx) {
if (isLeaf()) { if (isLeaf()) {

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

@ -1,5 +1,7 @@
package com.jayway.jsonpath.internal.spi.compiler; package com.jayway.jsonpath.internal.spi.compiler;
import com.jayway.jsonpath.PathNotFoundException;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
/** /**
@ -15,7 +17,9 @@ class WildcardPathToken extends PathToken {
} }
} else if (ctx.jsonProvider().isArray(model)) { } else if (ctx.jsonProvider().isArray(model)) {
for (int idx = 0; idx < ctx.jsonProvider().length(model); idx++) { for (int idx = 0; idx < ctx.jsonProvider().length(model); idx++) {
handleArrayIndex(idx, currentPath, model, ctx); try {
handleArrayIndex(idx, currentPath, model, ctx);
} catch (PathNotFoundException p){}
} }
} }
} }

3
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/AbstractJsonProvider.java

@ -114,6 +114,7 @@ public abstract class AbstractJsonProvider implements JsonProvider {
* @param key a String key or a numerical index * @param key a String key or a numerical index
* @param value the value to set * @param value the value to set
*/ */
@SuppressWarnings("unchecked")
public void setProperty(Object obj, Object key, Object value) { public void setProperty(Object obj, Object key, Object value) {
if (isMap(obj)) if (isMap(obj))
((Map) obj).put(key.toString(), value); ((Map) obj).put(key.toString(), value);
@ -146,6 +147,7 @@ public abstract class AbstractJsonProvider implements JsonProvider {
* @param obj an array or an object * @param obj an array or an object
* @return the keys for an object or the indexes for an array * @return the keys for an object or the indexes for an array
*/ */
@SuppressWarnings("unchecked")
public Collection<String> getPropertyKeys(Object obj) { public Collection<String> getPropertyKeys(Object obj) {
if (isArray(obj)) { if (isArray(obj)) {
List l = (List) obj; List l = (List) obj;
@ -178,6 +180,7 @@ public abstract class AbstractJsonProvider implements JsonProvider {
* @param obj an array or an object * @param obj an array or an object
* @return the entries for an array or the values for a map * @return the entries for an array or the values for a map
*/ */
@SuppressWarnings("unchecked")
public Iterable<Object> toIterable(Object obj) { public Iterable<Object> toIterable(Object obj) {
if (isArray(obj)) if (isArray(obj))
return ((Iterable) obj); return ((Iterable) obj);

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

@ -16,7 +16,6 @@ package com.jayway.jsonpath.internal.spi.json;
import com.jayway.jsonpath.InvalidJsonException; import com.jayway.jsonpath.InvalidJsonException;
import com.jayway.jsonpath.spi.json.Mode; import com.jayway.jsonpath.spi.json.Mode;
import net.minidev.json.JSONArray; import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject; import net.minidev.json.JSONObject;
import net.minidev.json.mapper.AMapper; import net.minidev.json.mapper.AMapper;

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

@ -14,12 +14,12 @@
*/ */
package com.jayway.jsonpath.spi.json; package com.jayway.jsonpath.spi.json;
import com.jayway.jsonpath.internal.spi.json.JacksonProvider; import com.jayway.jsonpath.internal.spi.json.JsonSmartJsonProvider;
public abstract class JsonProviderFactory { public abstract class JsonProviderFactory {
//private static JsonProvider provider = new JsonSmartJsonProvider(); private static JsonProvider provider = new JsonSmartJsonProvider();
private static JsonProvider provider = new JacksonProvider(); //private static JsonProvider provider = new JacksonProvider();
public static JsonProvider createProvider() { public static JsonProvider createProvider() {
return provider; return provider;

29
json-path/src/test/java/com/jayway/jsonpath/IssuesTest.java

@ -4,7 +4,6 @@ import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.spi.json.JsonProvider; import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.json.JsonProviderFactory; import com.jayway.jsonpath.spi.json.JsonProviderFactory;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.assertj.core.data.MapEntry;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Test; import org.junit.Test;
@ -13,15 +12,30 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static junit.framework.Assert.*; import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
public class IssuesTest { public class IssuesTest {
private static final JsonProvider jp = JsonProviderFactory.createProvider(); private static final JsonProvider jp = JsonProviderFactory.createProvider();
@Test
public void full_ones_can_be_filtered() {
String json = "[\n" +
" {\"kind\" : \"full\"},\n" +
" {\"kind\" : \"empty\"}\n" +
"]";
List<Map<String, String>> fullOnes = JsonPath.read(json, "$[?(@.kind == full)]");
assertEquals(1, fullOnes.size());
assertEquals("full", fullOnes.get(0).get("kind"));
}
@Test @Test
public void issue_36() { public void issue_36() {
String json = "{\n" + String json = "{\n" +
@ -210,8 +224,8 @@ public class IssuesTest {
@Test(expected = PathNotFoundException.class) @Test(expected = PathNotFoundException.class)
public void issue_22() throws Exception { public void issue_22() throws Exception {
Configuration configuration = Configuration.builder().options(Option.THROW_ON_MISSING_PROPERTY).build(); //Configuration configuration = Configuration.builder().options(Option.THROW_ON_MISSING_PROPERTY).build();
//Configuration configuration = Configuration.defaultConfiguration(); Configuration configuration = Configuration.defaultConfiguration();
String json = "{\"a\":{\"b\":1,\"c\":2}}"; String json = "{\"a\":{\"b\":1,\"c\":2}}";
System.out.println(JsonPath.parse(json, configuration).read("a.d")); System.out.println(JsonPath.parse(json, configuration).read("a.d"));
@ -230,8 +244,8 @@ public class IssuesTest {
@Test @Test
public void issue_22b() throws Exception { public void issue_22b() throws Exception {
String json = "{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}"; String json = "{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}";
System.out.println(JsonPath.read(json, "a[?(@.b==5)].d")); List<Object> res = JsonPath.using(Configuration.defaultConfiguration().options(Option.DEFAULT_PATH_LEAF_TO_NULL)).parse(json).read("a[?(@.b==5)].d");
System.out.println(JsonPath.read(json, "a[?(@.b==5)].d")); Assertions.assertThat(res).hasSize(1).containsNull();
} }
@Test(expected = PathNotFoundException.class) @Test(expected = PathNotFoundException.class)
@ -369,7 +383,7 @@ public class IssuesTest {
failBecauseExceptionWasNotThrown(PathNotFoundException.class); failBecauseExceptionWasNotThrown(PathNotFoundException.class);
} catch (PathNotFoundException e){ } catch (PathNotFoundException e){
Assertions.assertThat(e).hasMessage("No results for path: $['nonExistingProperty']");
} }
@ -378,7 +392,6 @@ public class IssuesTest {
failBecauseExceptionWasNotThrown(PathNotFoundException.class); failBecauseExceptionWasNotThrown(PathNotFoundException.class);
} catch (PathNotFoundException e){ } catch (PathNotFoundException e){
Assertions.assertThat(e).hasMessage("No results for path: $['nonExisting']['property']");
} }
} }

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

@ -80,7 +80,8 @@ public class JsonPathTest {
@Test(expected = PathNotFoundException.class) @Test(expected = PathNotFoundException.class)
public void missing_prop() { public void missing_prop() {
Object read = JsonPath.using(Configuration.defaultConfiguration().options(Option.THROW_ON_MISSING_PROPERTY)).parse(DOCUMENT).read("$.store.book[*].fooBar"); //Object read = JsonPath.using(Configuration.defaultConfiguration().options(Option.THROW_ON_MISSING_PROPERTY)).parse(DOCUMENT).read("$.store.book[*].fooBar");
Object read = JsonPath.using(Configuration.defaultConfiguration()).parse(DOCUMENT).read("$.store.book[*].fooBar");
System.out.println(read); System.out.println(read);

29
json-path/src/test/java/com/jayway/jsonpath/NullHandlingTest.java

@ -1,14 +1,12 @@
package com.jayway.jsonpath; package com.jayway.jsonpath;
import org.hamcrest.Matchers; import org.assertj.core.api.Assertions;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.util.List; import java.util.List;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertNull;
import static org.hamcrest.MatcherAssert.assertThat;
public class NullHandlingTest { public class NullHandlingTest {
@ -41,18 +39,16 @@ public class NullHandlingTest {
@Test @Test
@Ignore
public void last_token_defaults_to_null() { public void last_token_defaults_to_null() {
//FIXME //FIXME
//Configuration configuration = Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).build(); Configuration configuration = Configuration.builder().options(Option.DEFAULT_PATH_LEAF_TO_NULL).build();
//assertNull(JsonPath.parse(DOCUMENT, configuration).read("$.children[2].age")); assertNull(JsonPath.parse(DOCUMENT, configuration).read("$.children[2].age"));
assertNull(JsonPath.read(DOCUMENT, "$.children[2].age")); //assertNull(JsonPath.read(DOCUMENT, "$.children[2].age"));
} }
@ -64,18 +60,27 @@ public class NullHandlingTest {
@Test @Test
public void the_age_of_all_with_age_defined() { public void the_age_of_all_with_age_defined() {
List<Integer> result = JsonPath.read(DOCUMENT, "$.children[*].age"); //List<Integer> result = JsonPath.read(DOCUMENT, "$.children[*].age");
List<Integer> result = JsonPath.using(Configuration.defaultConfiguration().options(Option.SUPPRESS_EXCEPTIONS)).parse(DOCUMENT).read("$.children[*].age");
Assertions.assertThat(result).containsSequence(0, null);
assertThat(result, Matchers.hasItems(0, null));
} }
@Test @Test
public void path2() { public void path2() {
System.out.println(JsonPath.read("{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}", "a[?(@.b==4)].c")); List<Object> result = JsonPath.read("{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}", "a[?(@.b==4)].c");
Assertions.assertThat(result).isEmpty();
} }
@Test
public void path() { public void path() {
System.out.println(JsonPath.read("{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}", "a[?(@.b==5)].d")); String json = "{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}";
List<Object> result = JsonPath.using(Configuration.defaultConfiguration().options(Option.DEFAULT_PATH_LEAF_TO_NULL)).parse(json).read("a[?(@.b==5)].d");
System.out.println(result);
} }

5
json-path/src/test/java/com/jayway/jsonpath/internal/PropertyPathTokenTest.java

@ -8,9 +8,7 @@ import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertNull;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -65,7 +63,8 @@ public class PropertyPathTokenTest {
@Test(expected = PathNotFoundException.class) @Test(expected = PathNotFoundException.class)
public void property_not_found_option_throw() { public void property_not_found_option_throw() {
String result = JsonPath.using(Configuration.defaultConfiguration().options(Option.THROW_ON_MISSING_PROPERTY)).parse(SIMPLE_MAP).read("$.not-found"); //String result = JsonPath.using(Configuration.defaultConfiguration().options(Option.THROW_ON_MISSING_PROPERTY)).parse(SIMPLE_MAP).read("$.not-found");
String result = JsonPath.using(Configuration.defaultConfiguration()).parse(SIMPLE_MAP).read("$.not-found");
assertThat(result).isNull(); assertThat(result).isNull();
} }

4
json-path/src/test/java/com/jayway/jsonpath/reader/ReadConfigurationTest.java

@ -2,7 +2,6 @@ package com.jayway.jsonpath.reader;
import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.JsonProvider; import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.json.JsonProviderFactory; import com.jayway.jsonpath.spi.json.JsonProviderFactory;
import org.junit.Test; import org.junit.Test;
@ -19,7 +18,8 @@ public class ReadConfigurationTest {
Configuration configuration2 = Configuration.builder() Configuration configuration2 = Configuration.builder()
.jsonProvider(JsonProviderFactory.createProvider()) .jsonProvider(JsonProviderFactory.createProvider())
.options(Option.THROW_ON_MISSING_PROPERTY).build(); .build();
//.options(Option.THROW_ON_MISSING_PROPERTY).build();
JsonProvider jsonProvider = JsonProviderFactory.createProvider(); JsonProvider jsonProvider = JsonProviderFactory.createProvider();

9
pom.xml

@ -56,12 +56,13 @@
<scm.branch>master</scm.branch> <scm.branch>master</scm.branch>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.7.5</slf4j.version> <slf4j.version>1.7.7</slf4j.version>
<junit.version>4.10</junit.version> <junit.version>4.10</junit.version>
<commons-io.version>2.4</commons-io.version> <commons-io.version>2.4</commons-io.version>
<hamcrest.version>1.3</hamcrest.version> <hamcrest.version>1.3</hamcrest.version>
<jackson.version>2.4.0</jackson.version> <jackson.version>2.4.1.3</jackson.version>
<json-smart.version>2.0</json-smart.version> <json-smart.version>2.0</json-smart.version>
<assertj.version>1.6.1</assertj.version>
</properties> </properties>
<scm> <scm>
<url>http://github.com/jayway/JsonPath/tree/${scm.branch}</url> <url>http://github.com/jayway/JsonPath/tree/${scm.branch}</url>
@ -184,12 +185,12 @@
<dependency> <dependency>
<groupId>io.fastjson</groupId> <groupId>io.fastjson</groupId>
<artifactId>boon</artifactId> <artifactId>boon</artifactId>
<version>0.13</version> <version>0.23</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.assertj</groupId> <groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId> <artifactId>assertj-core</artifactId>
<version>1.6.0</version> <version>${assertj.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>

Loading…
Cancel
Save