Browse Source

Removed deprecated classes and some minor fixes.

pull/71/head
Kalle Stenflo 10 years ago
parent
commit
1735bc7a87
  1. 9
      changelog.md
  2. 267
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  3. 24
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  4. 3
      json-path/src/main/java/com/jayway/jsonpath/ParseContext.java
  5. 7
      json-path/src/main/java/com/jayway/jsonpath/ReadContext.java
  6. 7
      json-path/src/main/java/com/jayway/jsonpath/WriteContext.java
  7. 14
      json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java
  8. 26
      json-path/src/main/java/com/jayway/jsonpath/spi/http/HttpProvider.java
  9. 45
      json-path/src/main/java/com/jayway/jsonpath/spi/http/HttpProviderFactory.java
  10. 2
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java
  11. 5
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonSmartJsonProvider.java
  12. 44
      json-path/src/main/java/com/jayway/jsonpath/spi/json/Mode.java
  13. 7
      json-path/src/test/java/com/jayway/jsonpath/BaseTest.java
  14. 26
      json-path/src/test/java/com/jayway/jsonpath/ReadContextTest.java
  15. 4
      json-path/src/test/java/com/jayway/jsonpath/old/ComplianceTest.java
  16. 76
      json-path/src/test/java/com/jayway/jsonpath/old/FilterTest.java
  17. 99
      json-path/src/test/java/com/jayway/jsonpath/old/IssuesTest.java
  18. 1
      json-path/src/test/resources/simplelogger.properties

9
changelog.md

@ -1,11 +1,16 @@
In The Pipe
In the Pipe
===========
2.0.0 (2015-03-)
================
* Upgraded dependency versions
* Moved JsonProvider and MappingProvider implementations out of the interal package **OSGi**
* Deprecated HTTP provider and methods
* Removed HTTP provider and methods
* Add an unwrap(Object) method to JsonProvider, use it when extracting values for Criteria evaluation **breaks JsonProvider SPI**
* Fixed issue #71 - esacpe character in inline predicates
`JsonPath.read(json, "$.logs[?(@.message == 'it\\'s here')].message");`
* New method `jsonString()` added to `ReadContext` and `WriteContext` to extract json model as a string
* Path does not have to be definite in filter API `filter(where("authors[*].lastName").contains("Waugh"))`
1.2.0 (2014-11-11)
==================

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

@ -58,9 +58,9 @@ public class Criteria implements Predicate {
private static enum CriteriaType {
EQ {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean res = (0 == safeCompare(left, right));
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), left, res);
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = (0 == safeCompare(expected, model));
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
@ -71,9 +71,9 @@ public class Criteria implements Predicate {
},
NE {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean res = (0 != safeCompare(left, right));
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), left, res);
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = (0 != safeCompare(expected, model));
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
@ -84,14 +84,15 @@ public class Criteria implements Predicate {
},
GT {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
if ((left == null) ^ (right == null)) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
if ((expected == null) ^ (model == null)) {
return false;
}
boolean res = (0 > safeCompare(left, right));
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), left, res);
boolean res = (0 > safeCompare(expected, model));
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
@Override
public String toString() {
return ">";
@ -99,14 +100,15 @@ public class Criteria implements Predicate {
},
GTE {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
if ((left == null) ^ (right == null)) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
if ((expected == null) ^ (model == null)) {
return false;
}
boolean res = (0 >= safeCompare(left, right));
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), left, res);
boolean res = (0 >= safeCompare(expected, model));
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
@Override
public String toString() {
return ">=";
@ -114,14 +116,15 @@ public class Criteria implements Predicate {
},
LT {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
if ((left == null) ^ (right == null)) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
if ((expected == null) ^ (model == null)) {
return false;
}
boolean res = (0 < safeCompare(left, right));
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), left, res);
boolean res = (0 < safeCompare(expected, model));
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
@Override
public String toString() {
return "<";
@ -129,14 +132,15 @@ public class Criteria implements Predicate {
},
LTE {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
if ((left == null) ^ (right == null)) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
if ((expected == null) ^ (model == null)) {
return false;
}
boolean res = (0 <= safeCompare(left, right));
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), left, res);
boolean res = (0 <= safeCompare(expected, model));
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
@Override
public String toString() {
return "<=";
@ -144,37 +148,59 @@ public class Criteria implements Predicate {
},
IN {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = false;
Collection exps = (Collection) left;
Collection exps = (Collection) expected;
for (Object exp : exps) {
if (0 == safeCompare(exp, right)) {
if (0 == safeCompare(exp, model)) {
res = true;
break;
}
}
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), join(", ", exps), res);
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), join(", ", exps), res);
return res;
}
},
NIN {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
Collection nexps = (Collection) left;
boolean res = !nexps.contains(right);
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right, name(), join(", ", nexps), res);
boolean eval(Object expected, Object model, PredicateContext ctx) {
Collection nexps = (Collection) expected;
boolean res = !nexps.contains(model);
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), join(", ", nexps), res);
return res;
}
},
CONTAINS {
@Override
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = false;
if (ctx.configuration().jsonProvider().isArray(model)) {
for (Object o : ctx.configuration().jsonProvider().toIterable(model)) {
if (expected.equals(o)) {
res = true;
break;
}
}
} else if(model instanceof String){
if(isNullish(expected) || !(expected instanceof String)){
res = false;
} else {
res = ((String) model).contains((String)expected);
}
}
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", model, name(), expected, res);
return res;
}
},
ALL {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = true;
Collection exps = (Collection) left;
if (ctx.configuration().jsonProvider().isArray(right)) {
Collection exps = (Collection) expected;
if (ctx.configuration().jsonProvider().isArray(model)) {
for (Object exp : exps) {
boolean found = false;
for (Object check : ctx.configuration().jsonProvider().toIterable(right)) {
for (Object check : ctx.configuration().jsonProvider().toIterable(model)) {
if (0 == safeCompare(exp, check)) {
found = true;
break;
@ -185,71 +211,75 @@ public class Criteria implements Predicate {
break;
}
}
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", join(", ", ctx.configuration().jsonProvider().toIterable(right)), name(), join(", ", exps), res);
if (logger.isDebugEnabled())
logger.debug("[{}] {} [{}] => {}", join(", ", ctx.configuration().jsonProvider().toIterable(model)), name(), join(", ", exps), res);
} else {
res = false;
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", "<NOT AN ARRAY>", name(), join(", ", exps), res);
if (logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", "<NOT AN ARRAY>", name(), join(", ", exps), res);
}
return res;
}
},
SIZE {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
int size = (Integer) left;
boolean eval(Object expected, Object model, PredicateContext ctx) {
int size = (Integer) expected;
boolean res;
if (ctx.configuration().jsonProvider().isArray(right)) {
int length = ctx.configuration().jsonProvider().length(right);
if (ctx.configuration().jsonProvider().isArray(model)) {
int length = ctx.configuration().jsonProvider().length(model);
res = (length == size);
if(logger.isDebugEnabled()) logger.debug("Array with size {} {} {} => {}", length, name(), size, res);
} else if (right instanceof String) {
int length = ((String) right).length();
if (logger.isDebugEnabled()) logger.debug("Array with size {} {} {} => {}", length, name(), size, res);
} else if (model instanceof String) {
int length = ((String) model).length();
res = length == size;
if(logger.isDebugEnabled()) logger.debug("String with length {} {} {} => {}", length, name(), size, res);
if (logger.isDebugEnabled()) logger.debug("String with length {} {} {} => {}", length, name(), size, res);
} else {
res = false;
if(logger.isDebugEnabled()) logger.debug("{} {} {} => {}", right == null ? "null" : right.getClass().getName(), name(), size, res);
if (logger.isDebugEnabled())
logger.debug("{} {} {} => {}", model == null ? "null" : model.getClass().getName(), name(), size, res);
}
return res;
}
},
EXISTS {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
//This must be handled outside
throw new UnsupportedOperationException();
}
},
TYPE {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
final Class<?> expType = (Class<?>) left;
final Class<?> actType = right == null ? null : right.getClass();
boolean eval(Object expected, Object model, PredicateContext ctx) {
final Class<?> expType = (Class<?>) expected;
final Class<?> actType = model == null ? null : model.getClass();
return actType != null && expType.isAssignableFrom(actType);
}
},
REGEX {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = false;
Pattern pattern;
Object target;
Object target;
if(right instanceof Pattern){
pattern = (Pattern) right;
target = left;
if (model instanceof Pattern) {
pattern = (Pattern) model;
target = expected;
} else {
pattern = (Pattern) left;
target = right;
pattern = (Pattern) expected;
target = model;
}
if(target != null){
if (target != null) {
res = pattern.matcher(target.toString()).matches();
}
if(logger.isDebugEnabled()) logger.debug("[{}] {} [{}] => {}", right == null?"null":right.toString(), name(), left==null?"null":left.toString(), res);
if (logger.isDebugEnabled())
logger.debug("[{}] {} [{}] => {}", model == null ? "null" : model.toString(), name(), expected == null ? "null" : expected.toString(), res);
return res;
}
@Override
public String toString() {
return "=~";
@ -257,32 +287,32 @@ public class Criteria implements Predicate {
},
MATCHES {
@Override
boolean eval(Object left, final Object right, final PredicateContext ctx) {
boolean eval(Object expected, final Object model, final PredicateContext ctx) {
PredicateContextImpl pci = (PredicateContextImpl) ctx;
Predicate exp = (Predicate) left;
return exp.apply(new PredicateContextImpl(right, ctx.root(), ctx.configuration(), pci.documentPathCache()));
Predicate exp = (Predicate) expected;
return exp.apply(new PredicateContextImpl(model, ctx.root(), ctx.configuration(), pci.documentPathCache()));
}
},
NOT_EMPTY {
@Override
boolean eval(Object left, Object right, PredicateContext ctx) {
boolean eval(Object expected, Object model, PredicateContext ctx) {
boolean res = false;
if (right != null) {
if (ctx.configuration().jsonProvider().isArray(right)) {
int len = ctx.configuration().jsonProvider().length(right);
if (model != null) {
if (ctx.configuration().jsonProvider().isArray(model)) {
int len = ctx.configuration().jsonProvider().length(model);
res = (0 != len);
if(logger.isDebugEnabled()) logger.debug("array length = {} {} => {}", len, name(), res);
} else if (right instanceof String) {
int len = ((String) right).length();
if (logger.isDebugEnabled()) logger.debug("array length = {} {} => {}", len, name(), res);
} else if (model instanceof String) {
int len = ((String) model).length();
res = (0 != len);
if(logger.isDebugEnabled()) logger.debug("string length = {} {} => {}", len, name(), res);
if (logger.isDebugEnabled()) logger.debug("string length = {} {} => {}", len, name(), res);
}
}
return res;
}
};
abstract boolean eval(Object left, Object right, PredicateContext ctx);
abstract boolean eval(Object expected, Object model, PredicateContext ctx);
public static CriteriaType parse(String str) {
if ("==".equals(str)) {
@ -306,12 +336,12 @@ public class Criteria implements Predicate {
}
private Criteria(List<Criteria> criteriaChain, Object left) {
/*
if(left instanceof Path) {
if (!((Path)left).isDefinite()) {
throw new InvalidCriteriaException("A criteria path must be definite. The path " + left.toString() + " is not!");
}
}
}*/
this.left = left;
this.criteriaChain = criteriaChain;
this.criteriaChain.add(this);
@ -338,17 +368,17 @@ public class Criteria implements Predicate {
return true;
}
private Object evaluateIfPath(Object target, PredicateContext ctx){
private Object evaluateIfPath(Object target, PredicateContext ctx) {
Object res = target;
if(res instanceof Path){
if (res instanceof Path) {
Path leftPath = (Path) target;
if(ctx instanceof PredicateContextImpl){
if (ctx instanceof PredicateContextImpl) {
//This will use cache for document ($) queries
PredicateContextImpl ctxi = (PredicateContextImpl) ctx;
res = ctxi.evaluate(leftPath);
} else {
Object doc = leftPath.isRootPath()?ctx.root():ctx.item();
Object doc = leftPath.isRootPath() ? ctx.root() : ctx.item();
res = leftPath.evaluate(doc, ctx.root(), ctx.configuration()).getValue();
}
}
@ -361,8 +391,8 @@ public class Criteria implements Predicate {
try {
Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build();
Object value = ((Path) left).evaluate(ctx.item(), ctx.root(), c).getValue();
if(exists){
return (value != null);
if (exists) {
return (value != null);
} else {
return (value == null);
}
@ -403,7 +433,7 @@ public class Criteria implements Predicate {
*/
public static Criteria where(String key) {
if(!key.startsWith("$") && !key.startsWith("@")){
if (!key.startsWith("$") && !key.startsWith("@")) {
key = "@." + key;
}
return where(PathCompiler.compile(key));
@ -416,7 +446,7 @@ public class Criteria implements Predicate {
* @return the criteria builder
*/
public Criteria and(String key) {
if(!key.startsWith("$") && !key.startsWith("@")){
if (!key.startsWith("$") && !key.startsWith("@")) {
key = "@." + key;
}
return new Criteria(this.criteriaChain, PathCompiler.compile(key));
@ -542,6 +572,19 @@ public class Criteria implements Predicate {
return this;
}
/**
* The <code>contains</code> operator asserts that the provided object is contained
* in the result. The object that should contain the input can be either an object or a String.
*
* @param o that should exists in given collection or
* @return the criteria
*/
public Criteria contains(Object o) {
this.criteriaType = CriteriaType.CONTAINS;
this.right = o;
return this;
}
/**
* The <code>nin</code> operator is similar to $in except that it selects objects for
* which the specified field does not have any value in the specified array.
@ -658,15 +701,16 @@ public class Criteria implements Predicate {
return this;
}
private static boolean isPath(String string){
return (string != null
&& (string.startsWith("$") || string.startsWith("@") || string.startsWith("!@")));
private static boolean isPath(String string) {
return (string != null
&& (string.startsWith("$") || string.startsWith("@") || string.startsWith("!@")));
}
private static boolean isString(String string){
private static boolean isString(String string) {
return (string != null && !string.isEmpty() && string.charAt(0) == '\'' && string.charAt(string.length() - 1) == '\'');
}
private static boolean isPattern(String string){
private static boolean isPattern(String string) {
return (string != null
&& !string.isEmpty()
&& string.charAt(0) == '/'
@ -684,13 +728,13 @@ public class Criteria implements Predicate {
}
/**
* Parse the provided criteria
*
* @param criteria
* @return a criteria
*/
public static Criteria parse(String criteria){
public static Criteria parse(String criteria) {
int operatorIndex = -1;
String left = "";
String operator = "";
@ -713,9 +757,10 @@ public class Criteria implements Predicate {
/**
* Creates a new criteria
* @param left path to evaluate in criteria
*
* @param left path to evaluate in criteria
* @param operator operator
* @param right expected value
* @param right expected value
* @return a new Criteria
*/
public static Criteria create(String left, String operator, String right) {
@ -725,38 +770,38 @@ public class Criteria implements Predicate {
Path rightPath = null;
boolean existsCheck = true;
if(isPath(left)){
if(left.charAt(0) == '!'){
if (isPath(left)) {
if (left.charAt(0) == '!') {
existsCheck = false;
left = left.substring(1);
}
leftPath = PathCompiler.compile(left);
if(!leftPath.isDefinite()){
if (!leftPath.isDefinite()) {
throw new InvalidPathException("the predicate path: " + left + " is not definite");
}
leftPrepared = leftPath;
} else if(isString(left)) {
} else if (isString(left)) {
leftPrepared = left.substring(1, left.length() - 1);
} else if(isPattern(left)){
} else if (isPattern(left)) {
leftPrepared = compilePattern(left);
}
if(isPath(right)){
if(right.charAt(0) == '!'){
if (isPath(right)) {
if (right.charAt(0) == '!') {
throw new InvalidPathException("Invalid negation! Can only be used for existence check e.g [?(!@.foo)]");
}
rightPath = PathCompiler.compile(right);
if(!rightPath.isDefinite()){
if (!rightPath.isDefinite()) {
throw new InvalidPathException("the predicate path: " + right + " is not definite");
}
rightPrepared = rightPath;
} else if(isString(right)) {
} else if (isString(right)) {
rightPrepared = right.substring(1, right.length() - 1);
} else if(isPattern(right)){
} else if (isPattern(right)) {
rightPrepared = compilePattern(right);
}
if(leftPath != null && operator.isEmpty()){
if (leftPath != null && operator.isEmpty()) {
return Criteria.where(leftPath).exists(existsCheck);
} else {
return new Criteria(leftPrepared, CriteriaType.parse(operator), rightPrepared);
@ -765,7 +810,7 @@ public class Criteria implements Predicate {
private static int safeCompare(Object left, Object right) throws ValueCompareException {
if(left == right){
if (left == right) {
return 0;
}
@ -779,10 +824,10 @@ public class Criteria implements Predicate {
} else if (leftNullish && rightNullish) {
return 0;
} else if (left instanceof String && right instanceof String) {
String exp = (String)left;
if(exp.contains("\'")){
exp = exp.replace("\\'", "'");
}
String exp = (String) left;
if (exp.contains("\'")) {
exp = exp.replace("\\'", "'");
}
return exp.compareTo((String) right);
} else if (left instanceof Number && right instanceof Number) {
return new BigDecimal(left.toString()).compareTo(new BigDecimal(right.toString()));
@ -807,24 +852,20 @@ public class Criteria implements Predicate {
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(left.toString())
//.append("|")
.append(criteriaType.toString())
//.append("|")
.append(wrapString(right));
//.append("|");
return sb.toString();
}
private static String wrapString(Object o){
if(o == null){
private static String wrapString(Object o) {
if (o == null) {
return "null";
}
if(o instanceof String){
if (o instanceof String) {
return "'" + o.toString() + "'";
} else {
return o.toString();
@ -832,6 +873,4 @@ public class Criteria implements Predicate {
}
}

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

@ -21,7 +21,6 @@ import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.PathCompiler;
import com.jayway.jsonpath.internal.PathRef;
import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
import com.jayway.jsonpath.spi.json.JsonProvider;
import java.io.File;
@ -318,29 +317,6 @@ public class JsonPath {
return read(jsonURL, Configuration.defaultConfiguration());
}
/**
* Applies this JsonPath to the provided json URL
*
* @param jsonURL url to read from
* @param configuration configuration to use
* @param <T> expected return type
* @return list of objects matched by the given path
* @throws IOException
*/
@SuppressWarnings({"unchecked"})
public <T> T read(URL jsonURL, Configuration configuration) throws IOException {
notNull(jsonURL, "json URL can not be null");
notNull(configuration, "jsonProvider can not be null");
InputStream in = null;
try {
in = HttpProviderFactory.getProvider().get(jsonURL);
return read(in, "UTF-8", configuration);
} finally {
Utils.closeQuietly(in);
}
}
/**
* Applies this JsonPath to the provided json file
*

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

@ -30,7 +30,4 @@ public interface ParseContext {
DocumentContext parse(InputStream json, String charset);
DocumentContext parse(File json) throws IOException;
@Deprecated
DocumentContext parse(URL json) throws IOException;
}

7
json-path/src/main/java/com/jayway/jsonpath/ReadContext.java

@ -30,6 +30,13 @@ public interface ReadContext {
*/
<T> T json();
/**
* Returns the JSON model that this context is operating on as a JSON string
*
* @return json model as string
*/
String jsonString();
/**
* Reads the given path from this context
*

7
json-path/src/main/java/com/jayway/jsonpath/WriteContext.java

@ -30,6 +30,13 @@ public interface WriteContext {
*/
<T> T json();
/**
* Returns the JSON model that this context is operating on as a JSON string
*
* @return json model as string
*/
String jsonString();
/**
* Set the value a the given path
*

14
json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java

@ -23,7 +23,6 @@ import com.jayway.jsonpath.ParseContext;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.ReadContext;
import com.jayway.jsonpath.TypeRef;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,7 +30,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import static com.jayway.jsonpath.JsonPath.compile;
@ -111,13 +109,6 @@ public class JsonReader implements ParseContext, DocumentContext {
return this;
}
@Override
public DocumentContext parse(URL json) throws IOException {
notNull(json, "json url can not be null");
InputStream is = HttpProviderFactory.getProvider().get(json);
return parse(is);
}
@Override
public Configuration configuration() {
return configuration;
@ -133,6 +124,11 @@ public class JsonReader implements ParseContext, DocumentContext {
return json;
}
@Override
public String jsonString() {
return configuration.jsonProvider().toJson(json);
}
@Override
public <T> T read(String path, Predicate... filters) {
notEmpty(path, "path can not be null or empty");

26
json-path/src/main/java/com/jayway/jsonpath/spi/http/HttpProvider.java

@ -1,26 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed 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 com.jayway.jsonpath.spi.http;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@Deprecated
public interface HttpProvider {
InputStream get(URL url) throws IOException;
}

45
json-path/src/main/java/com/jayway/jsonpath/spi/http/HttpProviderFactory.java

@ -1,45 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed 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 com.jayway.jsonpath.spi.http;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
@Deprecated
public abstract class HttpProviderFactory {
public static HttpProviderFactory factory = new HttpProviderFactory() {
@Override
protected HttpProvider create() {
return new HttpProvider() {
@Override
public InputStream get(URL url) throws IOException {
URLConnection connection = url.openConnection();
connection.setRequestProperty("Accept", "application/json");
return connection.getInputStream();
}
};
}
};
public static HttpProvider getProvider() {
return factory.create();
}
protected abstract HttpProvider create();
}

2
json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java

@ -71,7 +71,7 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider {
if (!(obj instanceof JsonNode)) {
throw new JsonPathException("Not a JSON Node");
}
return toString();
return obj.toString();
}
@Override

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

@ -49,11 +49,6 @@ public class JsonSmartJsonProvider extends AbstractJsonProvider {
this.mapper = mapper;
}
@Deprecated
public JsonSmartJsonProvider(Mode mode) {
this(mode.intValue(), JSONValue.defaultReader.DEFAULT_ORDERED);
}
public Object createArray() {
return mapper.createArray();
}

44
json-path/src/main/java/com/jayway/jsonpath/spi/json/Mode.java

@ -1,44 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed 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 com.jayway.jsonpath.spi.json;
@Deprecated
public enum Mode {
SLACK(-1),
STRICT(1);
private final int mode;
Mode(int mode) {
this.mode = mode;
}
public int intValue() {
return mode;
}
public Mode parse(int mode) {
if (mode == -1) {
return SLACK;
} else if (mode == 1) {
return STRICT;
} else {
throw new IllegalArgumentException("Mode " + mode + " not supported");
}
}
}

7
json-path/src/test/java/com/jayway/jsonpath/BaseTest.java

@ -32,6 +32,13 @@ public class BaseTest {
public static final Configuration JSON_SMART_CONFIGURATION = Configuration.defaultConfiguration();
public static final String JSON_BOOK_DOCUMENT =
"{ " +
" \"category\" : \"reference\",\n" +
" \"author\" : \"Nigel Rees\",\n" +
" \"title\" : \"Sayings of the Century\",\n" +
" \"display-price\" : 8.95\n" +
"}";
public static final String JSON_DOCUMENT = "{\n" +
" \"string-property\" : \"string-value\", \n" +
" \"int-max-property\" : " + Integer.MAX_VALUE + ", \n" +

26
json-path/src/test/java/com/jayway/jsonpath/ReadContextTest.java

@ -0,0 +1,26 @@
package com.jayway.jsonpath;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import static com.jayway.jsonpath.JsonPath.using;
public class ReadContextTest extends BaseTest {
@Test
public void json_can_be_fetched_as_string() {
String expected = "{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"display-price\":8.95}";
String jsonString1 = using(JSON_SMART_CONFIGURATION).parse(JSON_BOOK_DOCUMENT).jsonString();
String jsonString2 = using(JACKSON_CONFIGURATION).parse(JSON_BOOK_DOCUMENT).jsonString();
String jsonString3 = using(JACKSON_JSON_NODE_CONFIGURATION).parse(JSON_BOOK_DOCUMENT).jsonString();
String jsonString4 = using(GSON_CONFIGURATION).parse(JSON_BOOK_DOCUMENT).jsonString();
Assertions.assertThat(jsonString1).isEqualTo(expected);
Assertions.assertThat(jsonString2).isEqualTo(expected);
Assertions.assertThat(jsonString3).isEqualTo(expected);
Assertions.assertThat(jsonString4).isEqualTo(expected);
}
}

4
json-path/src/test/java/com/jayway/jsonpath/old/ComplianceTest.java

@ -107,10 +107,10 @@ public class ComplianceTest {
" }\n" +
" }";
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@)]"), Matchers.is(notNullValue()));
assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@)]"), Matchers.is(notNullValue()));
assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.id == 'ViewSVG')].id"), hasItems("ViewSVG"));
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.id && !@.label)].id"), hasItems("?")); //low
assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.id && !@.label)].id"), hasItems("Open", "Quality", "Pause", "Mute", "Copy", "Help")); //low
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(@ && @.label && /SVG/.test(@.label))].id"), hasItems("?")); //low
//assertThat(JsonPath.<List<String>>read(json, "$.menu.items[?(!@)]"), hasItems("?")); //low
//assertThat(JsonPath.<List<String>>read(json, "$..[0]"), hasItems("?")); //low

76
json-path/src/test/java/com/jayway/jsonpath/old/FilterTest.java

@ -2,11 +2,13 @@ package com.jayway.jsonpath.old;
import com.jayway.jsonpath.BaseTest;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Criteria;
import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.InvalidCriteriaException;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.spi.json.JsonProvider;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import java.util.Collections;
@ -412,10 +414,78 @@ public class FilterTest extends BaseTest {
assertEquals(2, result2.size());
}
@Test(expected = InvalidCriteriaException.class)
public void filter_path_must_be_absolute() {
@Test
public void contains_filter_evaluates_on_array() {
where("$.store.*").size(4);
String json = "{\n" +
"\"store\": {\n" +
" \"book\": [\n" +
" {\n" +
" \"category\": \"reference\",\n" +
" \"authors\" : [\n" +
" {\n" +
" \"firstName\" : \"Nigel\",\n" +
" \"lastName\" : \"Rees\"\n" +
" }\n" +
" ],\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"authors\": [\n" +
" {\n" +
" \"firstName\" : \"Evelyn\",\n" +
" \"lastName\" : \"Waugh\"\n" +
" },\n" +
" {\n" +
" \"firstName\" : \"Another\",\n" +
" \"lastName\" : \"Author\"\n" +
" }\n" +
" ],\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
Filter filter = filter(where("authors[*].lastName").contains("Waugh"));
List<String> result = JsonPath.parse(json).read("$.store.book[?].title", filter);
Assertions.assertThat(result).containsExactly("Sword of Honour");
}
@Test
public void contains_filter_evaluates_on_string() {
String json = "{\n" +
"\"store\": {\n" +
" \"book\": [\n" +
" {\n" +
" \"category\": \"reference\",\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
Filter filter = filter(where("category").contains("fic"));
List<String> result = JsonPath.parse(json).read("$.store.book[?].title", filter);
Assertions.assertThat(result).containsExactly("Sword of Honour");
}
}

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

@ -6,6 +6,7 @@ import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.spi.json.JsonProvider;
import org.assertj.core.api.Assertions;
@ -21,6 +22,7 @@ import static com.jayway.jsonpath.JsonPath.read;
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.filter;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@ -233,6 +235,7 @@ public class IssuesTest {
String json = "{\"a\":{\"b\":1,\"c\":2}}";
JsonPath.parse(json, configuration).read("a.d");
}
@Test
public void issue_22c() throws Exception {
//Configuration configuration = Configuration.builder().build();
@ -243,7 +246,6 @@ public class IssuesTest {
}
@Test
public void issue_22b() throws Exception {
String json = "{\"a\":[{\"b\":1,\"c\":2},{\"b\":5,\"c\":2}]}";
@ -280,6 +282,7 @@ public class IssuesTest {
assertTrue(result.size() == 1);
}
@Test
public void issue_30() throws Exception {
String json = "{\"foo\" : {\"@id\" : \"123\", \"$\" : \"hello\"}}";
@ -289,13 +292,13 @@ public class IssuesTest {
}
@Test
public void issue_32(){
public void issue_32() {
String json = "{\"text\" : \"skill: \\\"Heuristic Evaluation\\\"\", \"country\" : \"\"}";
assertEquals("skill: \"Heuristic Evaluation\"", read(json, "$.text"));
}
@Test
public void issue_33(){
public void issue_33() {
String json = "{ \"store\": {\n" +
" \"book\": [ \n" +
" { \"category\": \"reference\",\n" +
@ -343,7 +346,7 @@ public class IssuesTest {
@Test(expected = PathNotFoundException.class)
public void a_test() {
String json ="{\n" +
String json = "{\n" +
" \"success\": true,\n" +
" \"data\": {\n" +
" \"user\": 3,\n" +
@ -385,7 +388,7 @@ public class IssuesTest {
read(json, "nonExistingProperty");
failBecauseExceptionWasNotThrown(PathNotFoundException.class);
} catch (PathNotFoundException e){
} catch (PathNotFoundException e) {
}
@ -394,7 +397,7 @@ public class IssuesTest {
read(json, "nonExisting.property");
failBecauseExceptionWasNotThrown(PathNotFoundException.class);
} catch (PathNotFoundException e){
} catch (PathNotFoundException e) {
}
}
@ -411,8 +414,6 @@ public class IssuesTest {
public void issue_46() {
String json = "{\"a\": {}}";
Configuration configuration = Configuration.defaultConfiguration().setOptions(Option.SUPPRESS_EXCEPTIONS);
@ -422,7 +423,7 @@ public class IssuesTest {
read(json, "a.x");
failBecauseExceptionWasNotThrown(PathNotFoundException.class);
} catch (PathNotFoundException e){
} catch (PathNotFoundException e) {
Assertions.assertThat(e).hasMessage("No results for path: $['a']['x']");
}
}
@ -437,7 +438,7 @@ public class IssuesTest {
" ]\n" +
"}\n";
List<String> result = JsonPath.read(json, "$.a.*.b.*.c");
List<String> result = JsonPath.read(json, "$.a.*.b.*.c");
Assertions.assertThat(result).containsExactly("foo");
@ -447,7 +448,7 @@ public class IssuesTest {
public void issue_60() {
String json ="[\n" +
String json = "[\n" +
"{\n" +
" \"mpTransactionId\": \"542986eae4b001fd500fdc5b-coreDisc_50-title\",\n" +
" \"resultType\": \"FAIL\",\n" +
@ -498,19 +499,65 @@ public class IssuesTest {
Assertions.assertThat(problems).containsExactly("Chain does not have a discovery event. Possible it was cut by the date that was picked", "No start transcoding events found");
}
@Test
public void issue_71() {
String json = "{\n"
+ " \"logs\": [\n"
+ " {\n"
+ " \"message\": \"it's here\",\n"
+ " \"id\": 2\n"
+ " }\n"
+ " ]\n"
+ "}";
List<String> result = JsonPath.read(json, "$.logs[?(@.message == 'it\\'s here')].message");
Assertions.assertThat(result).containsExactly("it's here");
}
//http://stackoverflow.com/questions/28596324/jsonpath-filtering-api
@Test
public void stack_overflow_question_1() {
String json = "{\n" +
"\"store\": {\n" +
" \"book\": [\n" +
" {\n" +
" \"category\": \"reference\",\n" +
" \"authors\" : [\n" +
" {\n" +
" \"firstName\" : \"Nigel\",\n" +
" \"lastName\" : \"Rees\"\n" +
" }\n" +
" ],\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"authors\": [\n" +
" {\n" +
" \"firstName\" : \"Evelyn\",\n" +
" \"lastName\" : \"Waugh\"\n" +
" },\n" +
" {\n" +
" \"firstName\" : \"Another\",\n" +
" \"lastName\" : \"Author\"\n" +
" }\n" +
" ],\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
Filter filter = Filter.filter(Criteria.where("authors[*].lastName").contains("Waugh"));
Object read = JsonPath.parse(json).read("$.store.book[?]", filter);
System.out.println(read);
}
@Test
public void issue_71() {
String json = "{\n"
+ " \"logs\": [\n"
+ " {\n"
+ " \"message\": \"it's here\",\n"
+ " \"id\": 2\n"
+ " }\n"
+ " ]\n"
+ "}";
List<String> result = JsonPath.read(json, "$.logs[?(@.message == 'it\\'s here')].message");
Assertions.assertThat(result).containsExactly("it's here");
}
}

1
json-path/src/test/resources/simplelogger.properties

@ -1,2 +1,3 @@
org.slf4j.simpleLogger.log.com.jayway=debug

Loading…
Cancel
Save