Browse Source

Removed pipes around custom operators.

pull/183/merge
Kalle Stenflo 9 years ago
parent
commit
efcd01ddae
  1. 56
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java
  2. 1
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalExpressionNode.java
  3. 24
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/RelationalOperator.java
  4. 13
      json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java
  5. 20
      json-path/src/test/java/com/jayway/jsonpath/FilterParseTest.java

56
json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java

@ -20,7 +20,6 @@ public class FilterCompiler {
private static final char MINUS = '-'; private static final char MINUS = '-';
private static final char TICK = '\''; private static final char TICK = '\'';
private static final char FUNCTION = '%'; private static final char FUNCTION = '%';
private static final char OPERATOR_PIPE = '¦';
private static final char LT = '<'; private static final char LT = '<';
private static final char GT = '>'; private static final char GT = '>';
private static final char EQ = '='; private static final char EQ = '=';
@ -134,17 +133,18 @@ public class FilterCompiler {
private RelationalExpressionNode readExpression() { private RelationalExpressionNode readExpression() {
ValueNode left = readValueNode(); ValueNode left = readValueNode();
if (left.isPathNode()) { if(expressionIsTerminated()) {
final PathNode pathNode = left.asPathNode(); PathNode pathNode = left.asPathNode();
if (pathNode.isExistsCheck()) { left = pathNode.asExistsCheck(pathNode.shouldExists());
return new RelationalExpressionNode(pathNode, RelationalOperator.EXISTS, pathNode.shouldExists() ? ValueNode.TRUE : ValueNode.FALSE); RelationalOperator operator = RelationalOperator.EXISTS;
} ValueNode right = left.asPathNode().shouldExists() ? ValueNode.TRUE : ValueNode.FALSE;
} return new RelationalExpressionNode(left, operator, right);
} else {
RelationalOperator operator = readRelationalOperator(); RelationalOperator operator = readRelationalOperator();
ValueNode right = readValueNode(); ValueNode right = readValueNode();
return new RelationalExpressionNode(left, operator, right); return new RelationalExpressionNode(left, operator, right);
} }
}
private LogicalOperator readLogicalOperator(){ private LogicalOperator readLogicalOperator(){
int begin = filter.skipBlanks().position(); int begin = filter.skipBlanks().position();
@ -166,18 +166,16 @@ public class FilterCompiler {
private RelationalOperator readRelationalOperator() { private RelationalOperator readRelationalOperator() {
int begin = filter.skipBlanks().position(); int begin = filter.skipBlanks().position();
if (filter.currentChar() == OPERATOR_PIPE) { if(isRelationalOperatorChar(filter.currentChar())){
int closingOperatorIndex = filter.nextIndexOf(OPERATOR_PIPE); while (filter.inBounds() && isRelationalOperatorChar(filter.currentChar())) {
if (closingOperatorIndex == -1) { filter.incrementPosition(1);
throw new InvalidPathException("Operator not closed. Expected " + OPERATOR_PIPE + " in " + filter);
} else {
filter.setPosition(closingOperatorIndex + 1);
} }
} else { } else {
while (filter.inBounds() && isRelationalOperatorChar(filter.currentChar())) { while (filter.inBounds() && filter.currentChar() != SPACE) {
filter.incrementPosition(1); filter.incrementPosition(1);
} }
} }
CharSequence operator = filter.subSequence(begin, filter.position()); CharSequence operator = filter.subSequence(begin, filter.position());
logger.trace("Operator from {} to {} -> [{}]", begin, filter.position()-1, operator); logger.trace("Operator from {} to {} -> [{}]", begin, filter.position()-1, operator);
return RelationalOperator.fromString(operator.toString()); return RelationalOperator.fromString(operator.toString());
@ -277,7 +275,6 @@ public class FilterCompiler {
private PathNode readPath() { private PathNode readPath() {
char previousSignificantChar = filter.previousSignificantChar(); char previousSignificantChar = filter.previousSignificantChar();
boolean operatorOnLeft = isRelationalOperatorChar(previousSignificantChar) && previousSignificantChar != BANG;
int begin = filter.position(); int begin = filter.position();
filter.incrementPosition(1); //skip $ and @ filter.incrementPosition(1); //skip $ and @
@ -297,14 +294,22 @@ public class FilterCompiler {
filter.incrementPosition(1); filter.incrementPosition(1);
} }
} }
boolean operatorOnRight = isRelationalOperatorChar(filter.currentChar()) || isRelationalOperatorChar(filter.nextSignificantChar());
boolean existsCheck = !operatorOnLeft && !operatorOnRight; boolean shouldExists = !(previousSignificantChar == BANG);
boolean shouldExists = true;
if(existsCheck){
shouldExists = !(previousSignificantChar == BANG);
}
CharSequence path = filter.subSequence(begin, filter.position()); CharSequence path = filter.subSequence(begin, filter.position());
return new PathNode(path, existsCheck, shouldExists); return new PathNode(path, false, shouldExists);
}
private boolean expressionIsTerminated(){
char c = filter.currentChar();
if(c == CLOSE_BRACKET || isLogicalOperatorChar(c)){
return true;
}
c = filter.nextSignificantChar();
if(c == CLOSE_BRACKET || isLogicalOperatorChar(c)){
return true;
}
return false;
} }
private boolean currentCharIsClosingFunctionBracket(int lowerBound){ private boolean currentCharIsClosingFunctionBracket(int lowerBound){
@ -325,7 +330,10 @@ public class FilterCompiler {
return false; return false;
} }
private boolean isLogicalOperatorChar(char c) {
return c == AND || c == OR;
}
private boolean isRelationalOperatorChar(char c) { private boolean isRelationalOperatorChar(char c) {
return c == OPERATOR_PIPE || c == LT || c == GT || c == EQ || c == TILDE || c == BANG; return c == LT || c == GT || c == EQ || c == TILDE || c == BANG;
} }
} }

1
json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalExpressionNode.java

@ -42,7 +42,6 @@ public class LogicalExpressionNode extends ExpressionNode {
@Override @Override
public String toString() { public String toString() {
//return "(" + Utils.join(" " + operator.getOperatorString() + " ", Utils.reverse(chain)) + ")";
return "(" + Utils.join(" " + operator.getOperatorString() + " ", chain) + ")"; return "(" + Utils.join(" " + operator.getOperatorString() + " ", chain) + ")";
} }

24
json-path/src/main/java/com/jayway/jsonpath/internal/filter/RelationalOperator.java

@ -11,15 +11,15 @@ public enum RelationalOperator {
LT("<"), LT("<"),
GT(">"), GT(">"),
REGEX("=~"), REGEX("=~"),
NIN("¦NIN¦"), NIN("NIN"),
IN("¦IN¦"), IN("IN"),
CONTAINS("¦CONTAINS¦"), CONTAINS("CONTAINS"),
ALL("¦ALL¦"), ALL("ALL"),
SIZE("¦SIZE¦"), SIZE("SIZE"),
EXISTS("¦EXISTS¦"), EXISTS("EXISTS"),
TYPE("¦TYPE¦"), TYPE("TYPE"),
MATCHES("¦MATCHES¦"), MATCHES("MATCHES"),
EMPTY("¦EMPTY¦"); EMPTY("EMPTY");
private final String operatorString; private final String operatorString;
@ -27,13 +27,9 @@ public enum RelationalOperator {
this.operatorString = operatorString; this.operatorString = operatorString;
} }
public String getOperatorString() {
return operatorString;
}
public static RelationalOperator fromString(String operatorString){ public static RelationalOperator fromString(String operatorString){
for (RelationalOperator operator : RelationalOperator.values()) { for (RelationalOperator operator : RelationalOperator.values()) {
if(operator.operatorString.equals(operatorString) ){ if(operator.operatorString.equals(operatorString.toUpperCase()) ){
return operator; return operator;
} }
} }

13
json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java

@ -5,10 +5,9 @@ import org.junit.Test;
public class FilterCompilerTest { public class FilterCompilerTest {
@Test @Test
public void filter_compiler_test() { public void filter_compiler_test() {
/*
FilterCompiler.compile("[?(@)]"); FilterCompiler.compile("[?(@)]");
FilterCompiler.compile("[?($)]"); FilterCompiler.compile("[?($)]");
@ -28,7 +27,6 @@ public class FilterCompilerTest {
FilterCompiler.compile("[?($['firstname']['num_gt'] > 1.1)]"); FilterCompiler.compile("[?($['firstname']['num_gt'] > 1.1)]");
FilterCompiler.compile("[?($['firstname']['num_lt'] < 11.11)]"); FilterCompiler.compile("[?($['firstname']['num_lt'] < 11.11)]");
FilterCompiler.compile("[?($['firstname']['num_in'] ¦IN¦ 0.1)]");
FilterCompiler.compile("[?($['firstname']['str_eq'] == 'hej')]"); FilterCompiler.compile("[?($['firstname']['str_eq'] == 'hej')]");
FilterCompiler.compile("[?($['firstname']['str_eq'] == '')]"); FilterCompiler.compile("[?($['firstname']['str_eq'] == '')]");
@ -47,15 +45,10 @@ public class FilterCompilerTest {
FilterCompiler.compile("[?((@.a && @.b) || (@.c && @.d))]"); FilterCompiler.compile("[?((@.a && @.b) || (@.c && @.d))]");
FilterCompiler.compile("[?(@.a ¦IN¦ [1,2,3])]"); FilterCompiler.compile("[?(@.a IN [1,2,3])]");
FilterCompiler.compile("[?(@.a ¦IN¦ {'foo':'bar'})]"); FilterCompiler.compile("[?(@.a IN {'foo':'bar'})]");
FilterCompiler.compile("[?(@.value<'7')]"); FilterCompiler.compile("[?(@.value<'7')]");
*/
//FilterCompiler.compile("[?(@.message == 'it\\'s here')]");
FilterCompiler.compile("[?(@.message == 'it\\\\')]"); FilterCompiler.compile("[?(@.message == 'it\\\\')]");
} }
} }

20
json-path/src/test/java/com/jayway/jsonpath/FilterParseTest.java

@ -102,7 +102,7 @@ public class FilterParseTest {
@Test @Test
public void a_nin_filter_can_be_serialized() { public void a_nin_filter_can_be_serialized() {
String filter = filter(where("a").nin(1)).toString(); String filter = filter(where("a").nin(1)).toString();
String parsed = parse("[?(@['a'] ¦NIN¦ [1])]").toString(); String parsed = parse("[?(@['a'] NIN [1])]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -111,7 +111,7 @@ public class FilterParseTest {
public void a_in_filter_can_be_serialized() { public void a_in_filter_can_be_serialized() {
String filter = filter(where("a").in("a")).toString(); String filter = filter(where("a").in("a")).toString();
String parsed = parse("[?(@['a'] ¦IN¦ ['a'])]").toString(); String parsed = parse("[?(@['a'] IN ['a'])]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -119,7 +119,7 @@ public class FilterParseTest {
@Test @Test
public void a_contains_filter_can_be_serialized() { public void a_contains_filter_can_be_serialized() {
String filter = filter(where("a").contains("a")).toString(); String filter = filter(where("a").contains("a")).toString();
String parsed = parse("[?(@['a'] ¦CONTAINS¦ 'a')]").toString(); String parsed = parse("[?(@['a'] CONTAINS 'a')]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -128,7 +128,7 @@ public class FilterParseTest {
public void a_all_filter_can_be_serialized() { public void a_all_filter_can_be_serialized() {
String filter = filter(where("a").all("a", "b")).toString(); String filter = filter(where("a").all("a", "b")).toString();
String parsed = parse("[?(@['a'] ¦ALL¦ ['a','b'])]").toString(); String parsed = parse("[?(@['a'] ALL ['a','b'])]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -137,7 +137,7 @@ public class FilterParseTest {
public void a_size_filter_can_be_serialized() { public void a_size_filter_can_be_serialized() {
String filter = filter(where("a").size(5)).toString(); String filter = filter(where("a").size(5)).toString();
String parsed = parse("[?(@['a'] ¦SIZE¦ 5)]").toString(); String parsed = parse("[?(@['a'] SIZE 5)]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -163,21 +163,21 @@ public class FilterParseTest {
@Test @Test
public void a_type_filter_can_be_serialized() { public void a_type_filter_can_be_serialized() {
assertThat(filter(where("a").type(String.class)).toString()).isEqualTo("[?(@['a'] ¦TYPE¦ java.lang.String)]"); assertThat(filter(where("a").type(String.class)).toString()).isEqualTo("[?(@['a'] TYPE java.lang.String)]");
} }
@Test @Test
public void a_matches_filter_can_be_serialized() { public void a_matches_filter_can_be_serialized() {
Filter a = filter(where("x").eq(1000)); Filter a = filter(where("x").eq(1000));
assertThat(filter(where("a").matches(a)).toString()).isEqualTo("[?(@['a'] ¦MATCHES¦ [?(@['x'] == 1000)])]"); assertThat(filter(where("a").matches(a)).toString()).isEqualTo("[?(@['a'] MATCHES [?(@['x'] == 1000)])]");
} }
@Test @Test
public void a_not_empty_filter_can_be_serialized() { public void a_not_empty_filter_can_be_serialized() {
String filter = filter(where("a").empty(false)).toString(); String filter = filter(where("a").empty(false)).toString();
String parsed = parse("[?(@['a'] ¦EMPTY¦ false)]").toString(); String parsed = parse("[?(@['a'] EMPTY false)]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -195,7 +195,7 @@ public class FilterParseTest {
public void in_string_filter_can_be_serialized() { public void in_string_filter_can_be_serialized() {
String filter = filter(where("a").in("1","2")).toString(); String filter = filter(where("a").in("1","2")).toString();
String parsed = parse("[?(@['a'] ¦IN¦ ['1','2'])]").toString(); String parsed = parse("[?(@['a'] IN ['1','2'])]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@ -204,7 +204,7 @@ public class FilterParseTest {
public void a_deep_path_filter_can_be_serialized() { public void a_deep_path_filter_can_be_serialized() {
String filter = filter(where("a.b.c").in("1", "2")).toString(); String filter = filter(where("a.b.c").in("1", "2")).toString();
String parsed = parse("[?(@['a']['b']['c'] ¦IN¦ ['1','2'])]").toString(); String parsed = parse("[?(@['a']['b']['c'] IN ['1','2'])]").toString();
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }

Loading…
Cancel
Save