diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java b/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java index 1aa286799..3193bcf49 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java @@ -220,16 +220,18 @@ public void readSignificantChar(char c) { incrementPosition(1); } - public void readSignificantSubSequence(CharSequence s) { + // true if successful, false if invalid path + public boolean readSignificantSubSequence(CharSequence s) { skipBlanks(); if (! inBounds(position + s.length() - 1)) { - throw new InvalidPathException(String.format("End of string reached while expecting: %s", s)); + return false; } if (! subSequence(position, position + s.length()).equals(s)) { - throw new InvalidPathException(String.format("Expected: %s", s)); + return false; } incrementPosition(s.length()); + return true; } public int indexOfPreviousSignificantChar(int startPosition){ @@ -314,4 +316,4 @@ public CharacterIndex trim() { skipBlanksAtEnd(); return this; } -} \ No newline at end of file +} diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java b/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java index 731473348..ad93e747e 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java @@ -216,7 +216,7 @@ public DocumentContext put(JsonPath path, String key, Object value) { private JsonPath pathFromCache(String path, Predicate[] filters) { Cache cache = CacheProvider.getCache(); - String cacheKey = Utils.concat(path, new LinkedList(asList(filters)).toString()); + String cacheKey = path + new LinkedList(asList(filters)).toString(); JsonPath jsonPath = cache.get(cacheKey); if (jsonPath == null) { jsonPath = compile(path, filters); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java index ac47274a7..5dedc54c1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java @@ -91,7 +91,13 @@ public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateCont private static class LessThanEvaluator implements Evaluator { @Override public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { - if(left.isNumberNode() && right.isNumberNode()){ + if(left.isStringNode() && right.isNumberNode()) { + return Double.parseDouble(left.asStringNode().getString()) < right.asNumberNode().getNumber().doubleValue(); + } + else if(left.isNumberNode() && right.isStringNode()) { + return left.asNumberNode().getNumber().doubleValue() < Double.parseDouble(right.asStringNode().getString()); + } + else if(left.isNumberNode() && right.isNumberNode()){ return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) < 0; } if(left.isStringNode() && right.isStringNode()){ return left.asStringNode().getString().compareTo(right.asStringNode().getString()) < 0; @@ -103,7 +109,13 @@ public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateCont private static class LessThanEqualsEvaluator implements Evaluator { @Override public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { - if(left.isNumberNode() && right.isNumberNode()){ + if(left.isStringNode() && right.isNumberNode()) { + return Double.parseDouble(left.asStringNode().getString()) <= right.asNumberNode().getNumber().doubleValue(); + } + else if(left.isNumberNode() && right.isStringNode()) { + return left.asNumberNode().getNumber().doubleValue() <= Double.parseDouble(right.asStringNode().getString()); + } + else if(left.isNumberNode() && right.isNumberNode()){ return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) <= 0; } if(left.isStringNode() && right.isStringNode()){ return left.asStringNode().getString().compareTo(right.asStringNode().getString()) <= 0; @@ -115,9 +127,16 @@ public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateCont private static class GreaterThanEvaluator implements Evaluator { @Override public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { - if(left.isNumberNode() && right.isNumberNode()){ + if(left.isStringNode() && right.isNumberNode()) { + return Double.parseDouble(left.asStringNode().getString()) > right.asNumberNode().getNumber().doubleValue(); + } + else if(left.isNumberNode() && right.isStringNode()) { + return left.asNumberNode().getNumber().doubleValue() > Double.parseDouble(right.asStringNode().getString()); + } + else if(left.isNumberNode() && right.isNumberNode()){ return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) > 0; - } else if(left.isStringNode() && right.isStringNode()){ + } + else if(left.isStringNode() && right.isStringNode()){ return left.asStringNode().getString().compareTo(right.asStringNode().getString()) > 0; } return false; @@ -127,7 +146,13 @@ public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateCont private static class GreaterThanEqualsEvaluator implements Evaluator { @Override public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { - if(left.isNumberNode() && right.isNumberNode()){ + if(left.isStringNode() && right.isNumberNode()) { + return Double.parseDouble(left.asStringNode().getString()) >= right.asNumberNode().getNumber().doubleValue(); + } + else if(left.isNumberNode() && right.isStringNode()) { + return left.asNumberNode().getNumber().doubleValue() >= Double.parseDouble(right.asStringNode().getString()); + } + else if(left.isNumberNode() && right.isNumberNode()){ return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) >= 0; } else if(left.isStringNode() && right.isStringNode()){ return left.asStringNode().getString().compareTo(right.asStringNode().getString()) >= 0; diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java index 67b512e41..bfdc0e473 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java @@ -132,6 +132,13 @@ private ExpressionNode readLogicalOR() { while (true) { int savepoint = filter.position(); + if (filter.readSignificantSubSequence(LogicalOperator.OR.getOperatorString())) + ops.add(readLogicalAND()); + else { + filter.setPosition(savepoint); + break; + } +/* try { filter.readSignificantSubSequence(LogicalOperator.OR.getOperatorString()); ops.add(readLogicalAND()); @@ -140,6 +147,7 @@ private ExpressionNode readLogicalOR() { filter.setPosition(savepoint); break; } + */ } return 1 == ops.size() ? ops.get(0) : LogicalExpressionNode.createLogicalOr(ops); @@ -152,6 +160,13 @@ private ExpressionNode readLogicalAND() { while (true) { int savepoint = filter.position(); + if (filter.readSignificantSubSequence(LogicalOperator.AND.getOperatorString())) + ops.add(readLogicalANDOperand()); + else { + filter.setPosition(savepoint); + break; + } +/* try { filter.readSignificantSubSequence(LogicalOperator.AND.getOperatorString()); ops.add(readLogicalANDOperand()); @@ -160,6 +175,7 @@ private ExpressionNode readLogicalAND() { filter.setPosition(savepoint); break; } + */ } return 1 == ops.size() ? ops.get(0) : LogicalExpressionNode.createLogicalAnd(ops); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java index d1619c453..0dc7418bd 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java @@ -814,7 +814,7 @@ public PathNode asExistsCheck(boolean shouldExist) { @Override public String toString() { - return existsCheck && ! shouldExist ? Utils.concat("!" , path.toString()) : path.toString(); + return existsCheck && ! shouldExist ? ('!' + path.toString()) : path.toString(); } public ValueNode evaluate(Predicate.PredicateContext ctx) { diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java index 5a5046d84..b9c515a28 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/PathToken.java @@ -40,7 +40,7 @@ void handleObjectProperty(String currentPath, Object model, EvaluationContextImp if(properties.size() == 1) { String property = properties.get(0); - String evalPath = Utils.concat(currentPath, "['", property, "']"); + String evalPath = currentPath + "['" + property + "']"; Object propertyVal = readObjectProperty(property, model, ctx); if(propertyVal == JsonProvider.UNDEFINED){ // Conditions below heavily depend on current token type (and its logic) and are not "universal", @@ -123,7 +123,7 @@ private static Object readObjectProperty(String property, Object model, Evaluati protected void handleArrayIndex(int index, String currentPath, Object model, EvaluationContextImpl ctx) { - String evalPath = Utils.concat(currentPath, "[", String.valueOf(index), "]"); + String evalPath = currentPath + "[" + index + "]"; PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, index) : PathRef.NO_OP; int effectiveIndex = index < 0 ? ctx.jsonProvider().length(model) + index : index; try {