|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|