From ea78bcc4596f669fca3cb56d551daffed4712ec5 Mon Sep 17 00:00:00 2001 From: dakirily Date: Tue, 3 Dec 2024 10:35:55 +0100 Subject: [PATCH] QPID-8674 - [Broker-J] Jms Selector Parsing - multiple AND's --- .../src/main/grammar/SelectorParser.jj | 273 +++--- .../filter/selector/SelectorParser.java | 907 ++++++++++-------- .../filter/JMSSelectorFilterSyntaxTest.java | 278 +++++- 3 files changed, 865 insertions(+), 593 deletions(-) diff --git a/broker-core/src/main/grammar/SelectorParser.jj b/broker-core/src/main/grammar/SelectorParser.jj index 4271907cd9..63f369a1dc 100644 --- a/broker-core/src/main/grammar/SelectorParser.jj +++ b/broker-core/src/main/grammar/SelectorParser.jj @@ -114,8 +114,6 @@ public class SelectorParser } throw new ParseException("Expression will not result in a boolean value: " + value); } - - } PARSER_END(SelectorParser) @@ -202,37 +200,31 @@ Expression orExpression() : Expression right; } { + left = andExpression() ( - left = andExpression() - ( - right = andExpression() - { - left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right)); - } - )* - ) + right = andExpression() + { + left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right)); + } + )* { return left; } - } - Expression andExpression() : { Expression left; Expression right; } { + left = equalityExpression() ( - left = equalityExpression() - ( - right = equalityExpression() - { - left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right)); - } - )* - ) + right = equalityExpression() + { + left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right)); + } + )* { return left; } @@ -244,32 +236,28 @@ Expression equalityExpression() : Expression right; } { + left = comparisonExpression() ( - left = comparisonExpression() - ( - - "=" right = comparisonExpression() - { - left = ComparisonExpression.createEqual(left, right); - } - | - "<>" right = comparisonExpression() - { - left = ComparisonExpression.createNotEqual(left, right); - } - | - LOOKAHEAD(2) - - { - left = ComparisonExpression.createIsNull(left); - } - | - - { - left = ComparisonExpression.createIsNotNull(left); - } - )* - ) + LOOKAHEAD(2) "=" right = comparisonExpression() + { + left = ComparisonExpression.createEqual(left, right); + } + | + "<>" right = comparisonExpression() + { + left = ComparisonExpression.createNotEqual(left, right); + } + | + LOOKAHEAD(2) + { + left = ComparisonExpression.createIsNull(left); + } + | + + { + left = ComparisonExpression.createIsNotNull(left); + } + )* { return left; } @@ -286,102 +274,83 @@ Expression comparisonExpression() : ArrayList list; } { + left = addExpression() ( - left = addExpression() - ( - - ">" right = addExpression() - { - left = ComparisonExpression.createGreaterThan(left, right); - } - | - ">=" right = addExpression() - { - left = ComparisonExpression.createGreaterThanEqual(left, right); - } - | - "<" right = addExpression() - { - left = ComparisonExpression.createLessThan(left, right); - } - | - "<=" right = addExpression() - { - left = ComparisonExpression.createLessThanEqual(left, right); - } - | - { - u=null; - } - t = stringLiteral() - [ u = stringLiteral() ] - { - left = ComparisonExpression.createLike(left, t, u); - } - | - LOOKAHEAD(2) - { - u=null; - } - t = stringLiteral() [ u = stringLiteral() ] - { - left = ComparisonExpression.createNotLike(left, t, u); - } - | - low = addExpression() high = addExpression() - { - left = ComparisonExpression.createBetween(left, low, high); - } - | - LOOKAHEAD(2) - low = addExpression() high = addExpression() - { - left = ComparisonExpression.createNotBetween(left, low, high); - } - | - - "(" - t = stringLiteral() - { - list = new ArrayList(); - list.add( t ); - } - ( - "," - t = stringLiteral() - { - list.add( t ); - } - - )* - ")" - { - left = ComparisonExpression.createInFilter(left, list, false ); - } - | - LOOKAHEAD(2) - - "(" - t = stringLiteral() - { - list = new ArrayList(); - list.add( t ); - } - ( - "," - t = stringLiteral() - { - list.add( t ); - } - - )* - ")" - { - left = ComparisonExpression.createNotInFilter(left, list, false); - } - - )* - ) + LOOKAHEAD(2) ">" right = addExpression() + { + left = ComparisonExpression.createGreaterThan(left, right); + } + | + ">=" right = addExpression() + { + left = ComparisonExpression.createGreaterThanEqual(left, right); + } + | + "<" right = addExpression() + { + left = ComparisonExpression.createLessThan(left, right); + } + | + "<=" right = addExpression() + { + left = ComparisonExpression.createLessThanEqual(left, right); + } + | + { + u=null; + } + t = stringLiteral() [ u = stringLiteral() ] + { + left = ComparisonExpression.createLike(left, t, u); + } + | + LOOKAHEAD(2) + { + u=null; + } + t = stringLiteral() [ u = stringLiteral() ] + { + left = ComparisonExpression.createNotLike(left, t, u); + } + | + low = addExpression() high = addExpression() + { + left = ComparisonExpression.createBetween(left, low, high); + } + | + LOOKAHEAD(2) low = addExpression() high = addExpression() + { + left = ComparisonExpression.createNotBetween(left, low, high); + } + | + "(" t = stringLiteral() + { + list = new ArrayList(); + list.add( t ); + } + ( "," t = stringLiteral() + { + list.add( t ); + } + )* ")" + { + left = ComparisonExpression.createInFilter(left, list, false ); + } + | + LOOKAHEAD(2) "(" t = stringLiteral() + { + list = new ArrayList(); + list.add( t ); + } + ( "," t = stringLiteral() + { + list.add( t ); + } + )* ")" + { + left = ComparisonExpression.createNotInFilter(left, list, false); + } + )* { return left; } @@ -407,7 +376,6 @@ Expression addExpression() : left = ArithmeticExpression.createMinus(left, right); } ) - )* { return left; @@ -422,7 +390,7 @@ Expression multExpr() : { left = unaryExpr() ( - "*" right = unaryExpr() + LOOKAHEAD(2) "*" right = unaryExpr() { left = ArithmeticExpression.createMultiply(left, right); } @@ -436,14 +404,12 @@ Expression multExpr() : { left = ArithmeticExpression.createMod(left, right); } - )* { return left; } } - Expression unaryExpr() : { String s=null; @@ -451,15 +417,19 @@ Expression unaryExpr() : } { ( - LOOKAHEAD( "+" unaryExpr() ) - "+" left=unaryExpr() + LOOKAHEAD("+" unaryExpr()) "+" left = unaryExpr() | - "-" left=unaryExpr() + "-" left = unaryExpr() { left = UnaryExpression.createNegate(left); } | - left=orExpression() + LOOKAHEAD( equalityExpression()) left = equalityExpression() + { + left = UnaryExpression.createNOT( asBooleanExpression(left) ); + } + | + LOOKAHEAD( unaryExpr()) left = unaryExpr() { left = UnaryExpression.createNOT( asBooleanExpression(left) ); } @@ -469,7 +439,6 @@ Expression unaryExpr() : { return left; } - } Expression primaryExpr() : @@ -482,15 +451,13 @@ Expression primaryExpr() : | left = variable() | - "(" left = orExpression() ")" + LOOKAHEAD(2) "(" left = orExpression() ")" ) { return left; } } - - ConstantExpression literal() : { Token t; @@ -610,8 +577,6 @@ PropertyExpression variable() : } return _factory.createPropertyExpression(rc.toString()); } - - ) { return left; diff --git a/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java b/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java index 80082f52c8..009b6ecb8a 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java +++ b/broker-core/src/main/java/org/apache/qpid/server/filter/selector/SelectorParser.java @@ -100,7 +100,7 @@ final public Expression orExpression() throws ParseException { } jj_consume_token(OR); right = andExpression(); - left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right)); + left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right)); } {if (true) return left;} throw new Error("Missing return statement in function"); @@ -121,7 +121,7 @@ final public Expression andExpression() throws ParseException { } jj_consume_token(AND); right = equalityExpression(); - left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right)); + left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right)); } {if (true) return left;} throw new Error("Missing return statement in function"); @@ -142,33 +142,34 @@ final public Expression equalityExpression() throws ParseException { default: break label_3; } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case 27: + if (jj_2_1(2)) { jj_consume_token(27); right = comparisonExpression(); - left = ComparisonExpression.createEqual(left, right); - break; - case 28: - jj_consume_token(28); - right = comparisonExpression(); - left = ComparisonExpression.createNotEqual(left, right); - break; - default: - if (jj_2_1(2)) { - jj_consume_token(IS); - jj_consume_token(NULL); - left = ComparisonExpression.createIsNull(left); - } else { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case IS: + left = ComparisonExpression.createEqual(left, right); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 28: + jj_consume_token(28); + right = comparisonExpression(); + left = ComparisonExpression.createNotEqual(left, right); + break; + default: + if (jj_2_2(2)) { jj_consume_token(IS); - jj_consume_token(NOT); jj_consume_token(NULL); - left = ComparisonExpression.createIsNotNull(left); - break; - default: - jj_consume_token(-1); - throw new ParseException(); + left = ComparisonExpression.createIsNull(left); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IS: + jj_consume_token(IS); + jj_consume_token(NOT); + jj_consume_token(NULL); + left = ComparisonExpression.createIsNotNull(left); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } } } } @@ -202,45 +203,29 @@ final public Expression comparisonExpression() throws ParseException { default: break label_4; } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case 29: + if (jj_2_3(2)) { jj_consume_token(29); right = addExpression(); - left = ComparisonExpression.createGreaterThan(left, right); - break; - case 30: - jj_consume_token(30); - right = addExpression(); - left = ComparisonExpression.createGreaterThanEqual(left, right); - break; - case 31: - jj_consume_token(31); - right = addExpression(); - left = ComparisonExpression.createLessThan(left, right); - break; - case 32: - jj_consume_token(32); - right = addExpression(); - left = ComparisonExpression.createLessThanEqual(left, right); - break; - case LIKE: - u=null; - jj_consume_token(LIKE); - t = stringLiteral(); + left = ComparisonExpression.createGreaterThan(left, right); + } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case ESCAPE: - jj_consume_token(ESCAPE); - u = stringLiteral(); + case 30: + jj_consume_token(30); + right = addExpression(); + left = ComparisonExpression.createGreaterThanEqual(left, right); break; - default: - ; - } - left = ComparisonExpression.createLike(left, t, u); - break; - default: - if (jj_2_2(2)) { - u=null; - jj_consume_token(NOT); + case 31: + jj_consume_token(31); + right = addExpression(); + left = ComparisonExpression.createLessThan(left, right); + break; + case 32: + jj_consume_token(32); + right = addExpression(); + left = ComparisonExpression.createLessThanEqual(left, right); + break; + case LIKE: + u=null; jj_consume_token(LIKE); t = stringLiteral(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -251,74 +236,91 @@ final public Expression comparisonExpression() throws ParseException { default: ; } - left = ComparisonExpression.createNotLike(left, t, u); - } else { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case BETWEEN: - jj_consume_token(BETWEEN); - low = addExpression(); - jj_consume_token(AND); - high = addExpression(); - left = ComparisonExpression.createBetween(left, low, high); - break; - default: - if (jj_2_3(2)) { - jj_consume_token(NOT); + left = ComparisonExpression.createLike(left, t, u); + break; + default: + if (jj_2_4(2)) { + u=null; + jj_consume_token(NOT); + jj_consume_token(LIKE); + t = stringLiteral(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case ESCAPE: + jj_consume_token(ESCAPE); + u = stringLiteral(); + break; + default: + ; + } + left = ComparisonExpression.createNotLike(left, t, u); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case BETWEEN: jj_consume_token(BETWEEN); low = addExpression(); jj_consume_token(AND); high = addExpression(); - left = ComparisonExpression.createNotBetween(left, low, high); - } else { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case IN: - jj_consume_token(IN); - jj_consume_token(33); - t = stringLiteral(); - list = new ArrayList(); - list.add( t ); - label_5: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case 34: - ; - break; - default: - break label_5; - } - jj_consume_token(34); - t = stringLiteral(); - list.add( t ); - } - jj_consume_token(35); - left = ComparisonExpression.createInFilter(left, list, false ); - break; - default: - if (jj_2_4(2)) { - jj_consume_token(NOT); + left = ComparisonExpression.createBetween(left, low, high); + break; + default: + if (jj_2_5(2)) { + jj_consume_token(NOT); + jj_consume_token(BETWEEN); + low = addExpression(); + jj_consume_token(AND); + high = addExpression(); + left = ComparisonExpression.createNotBetween(left, low, high); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IN: jj_consume_token(IN); jj_consume_token(33); t = stringLiteral(); - list = new ArrayList(); - list.add( t ); - label_6: + list = new ArrayList(); + list.add( t ); + label_5: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case 34: ; break; default: - break label_6; + break label_5; } jj_consume_token(34); t = stringLiteral(); - list.add( t ); + list.add( t ); } jj_consume_token(35); - left = ComparisonExpression.createNotInFilter(left, list, false); - } else { - jj_consume_token(-1); - throw new ParseException(); + left = ComparisonExpression.createInFilter(left, list, false ); + break; + default: + if (jj_2_6(2)) { + jj_consume_token(NOT); + jj_consume_token(IN); + jj_consume_token(33); + t = stringLiteral(); + list = new ArrayList(); + list.add( t ); + label_6: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 34: + ; + break; + default: + break label_6; + } + jj_consume_token(34); + t = stringLiteral(); + list.add( t ); + } + jj_consume_token(35); + left = ComparisonExpression.createNotInFilter(left, list, false); + } else { + jj_consume_token(-1); + throw new ParseException(); + } } } } @@ -336,7 +338,7 @@ final public Expression addExpression() throws ParseException { left = multExpr(); label_7: while (true) { - if (jj_2_5(2147483647)) { + if (jj_2_7(2147483647)) { ; } else { break label_7; @@ -376,25 +378,26 @@ final public Expression multExpr() throws ParseException { default: break label_8; } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case 38: + if (jj_2_8(2)) { jj_consume_token(38); right = unaryExpr(); left = ArithmeticExpression.createMultiply(left, right); - break; - case 39: - jj_consume_token(39); - right = unaryExpr(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 39: + jj_consume_token(39); + right = unaryExpr(); left = ArithmeticExpression.createDivide(left, right); - break; - case 40: - jj_consume_token(40); - right = unaryExpr(); + break; + case 40: + jj_consume_token(40); + right = unaryExpr(); left = ArithmeticExpression.createMod(left, right); - break; - default: - jj_consume_token(-1); - throw new ParseException(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } } } {if (true) return left;} @@ -404,7 +407,7 @@ final public Expression multExpr() throws ParseException { final public Expression unaryExpr() throws ParseException { String s=null; Expression left=null; - if (jj_2_6(2147483647)) { + if (jj_2_9(2147483647)) { jj_consume_token(36); left = unaryExpr(); } else { @@ -414,27 +417,35 @@ final public Expression unaryExpr() throws ParseException { left = unaryExpr(); left = UnaryExpression.createNegate(left); break; - case NOT: - jj_consume_token(NOT); - left = orExpression(); - left = UnaryExpression.createNOT( asBooleanExpression(left) ); - break; - case TRUE: - case FALSE: - case NULL: - case DECIMAL_LITERAL: - case HEX_LITERAL: - case OCTAL_LITERAL: - case FLOATING_POINT_LITERAL: - case STRING_LITERAL: - case ID: - case QUOTED_ID: - case 33: - left = primaryExpr(); - break; default: - jj_consume_token(-1); - throw new ParseException(); + if (jj_2_10(2147483647)) { + jj_consume_token(NOT); + left = equalityExpression(); + left = UnaryExpression.createNOT( asBooleanExpression(left) ); + } else if (jj_2_11(2147483647)) { + jj_consume_token(NOT); + left = unaryExpr(); + left = UnaryExpression.createNOT( asBooleanExpression(left) ); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case TRUE: + case FALSE: + case NULL: + case DECIMAL_LITERAL: + case HEX_LITERAL: + case OCTAL_LITERAL: + case FLOATING_POINT_LITERAL: + case STRING_LITERAL: + case ID: + case QUOTED_ID: + case 33: + left = primaryExpr(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } } } {if (true) return left;} @@ -458,14 +469,15 @@ final public Expression primaryExpr() throws ParseException { case QUOTED_ID: left = variable(); break; - case 33: - jj_consume_token(33); - left = orExpression(); - jj_consume_token(35); - break; default: - jj_consume_token(-1); - throw new ParseException(); + if (jj_2_12(2)) { + jj_consume_token(33); + left = orExpression(); + jj_consume_token(35); + } else { + jj_consume_token(-1); + throw new ParseException(); + } } {if (true) return left;} throw new Error("Missing return statement in function"); @@ -602,493 +614,550 @@ private boolean jj_2_6(int xla) { catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3R_12() { - if (jj_scan_token(36)) return true; - if (jj_3R_10()) return true; - return false; + private boolean jj_2_7(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_7(); } + catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3R_55() { - if (jj_scan_token(IN)) return true; - if (jj_scan_token(33)) return true; - if (jj_3R_47()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_60()) { jj_scanpos = xsp; break; } - } - if (jj_scan_token(35)) return true; - return false; + private boolean jj_2_8(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_8(); } + catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3R_46() { - if (jj_scan_token(IS)) return true; - if (jj_scan_token(NOT)) return true; - if (jj_scan_token(NULL)) return true; - return false; + private boolean jj_2_9(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_9(); } + catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3R_13() { - if (jj_scan_token(37)) return true; - if (jj_3R_10()) return true; - return false; + private boolean jj_2_10(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_10(); } + catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3R_39() { - if (jj_scan_token(NULL)) return true; - return false; + private boolean jj_2_11(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_11(); } + catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3_1() { - if (jj_scan_token(IS)) return true; - if (jj_scan_token(NULL)) return true; - return false; + private boolean jj_2_12(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_12(); } + catch(LookaheadSuccess ls) { return true; } } - private boolean jj_3R_10() { + private boolean jj_3R_38() { Token xsp; xsp = jj_scanpos; - if (jj_3R_12()) { + if (jj_3R_47()) { + jj_scanpos = xsp; + if (jj_3R_48()) { jj_scanpos = xsp; - if (jj_3R_13()) { + if (jj_3R_49()) { + jj_scanpos = xsp; + if (jj_3R_50()) { + jj_scanpos = xsp; + if (jj_3R_51()) { + jj_scanpos = xsp; + if (jj_3R_52()) { jj_scanpos = xsp; - if (jj_3R_14()) { + if (jj_3R_53()) { jj_scanpos = xsp; - if (jj_3R_15()) return true; + if (jj_3R_54()) return true; + } + } + } + } } } } return false; } - private boolean jj_3R_45() { - if (jj_scan_token(28)) return true; - if (jj_3R_30()) return true; + private boolean jj_3R_9() { + if (jj_3R_10()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_26()) { jj_scanpos = xsp; break; } + } return false; } - private boolean jj_3R_38() { - if (jj_scan_token(FALSE)) return true; + private boolean jj_3R_39() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_55()) { + jj_scanpos = xsp; + if (jj_3R_56()) return true; + } return false; } - private boolean jj_3_3() { + private boolean jj_3R_10() { + if (jj_3R_11()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_31()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3_12() { + if (jj_scan_token(33)) return true; + if (jj_3R_14()) return true; + if (jj_scan_token(35)) return true; + return false; + } + + private boolean jj_3R_30() { + if (jj_3R_39()) return true; + return false; + } + + private boolean jj_3R_29() { + if (jj_3R_38()) return true; + return false; + } + + private boolean jj_3R_28() { + if (jj_scan_token(IS)) return true; if (jj_scan_token(NOT)) return true; - if (jj_scan_token(BETWEEN)) return true; - if (jj_3R_42()) return true; - if (jj_scan_token(AND)) return true; - if (jj_3R_42()) return true; + if (jj_scan_token(NULL)) return true; return false; } - private boolean jj_3R_44() { - if (jj_scan_token(27)) return true; - if (jj_3R_30()) return true; + private boolean jj_3_11() { + if (jj_scan_token(NOT)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_31() { + private boolean jj_3R_25() { Token xsp; xsp = jj_scanpos; - if (jj_3R_44()) { + if (jj_3R_29()) { jj_scanpos = xsp; - if (jj_3R_45()) { + if (jj_3R_30()) { jj_scanpos = xsp; - if (jj_3_1()) { - jj_scanpos = xsp; - if (jj_3R_46()) return true; - } + if (jj_3_12()) return true; } } return false; } - private boolean jj_3R_54() { - if (jj_scan_token(BETWEEN)) return true; - if (jj_3R_42()) return true; - if (jj_scan_token(AND)) return true; + private boolean jj_3R_46() { + if (jj_scan_token(34)) return true; if (jj_3R_42()) return true; return false; } - private boolean jj_3R_37() { - if (jj_scan_token(TRUE)) return true; - return false; - } - - private boolean jj_3R_58() { + private boolean jj_3R_44() { if (jj_scan_token(ESCAPE)) return true; - if (jj_3R_47()) return true; + if (jj_3R_42()) return true; return false; } - private boolean jj_3R_18() { - if (jj_scan_token(40)) return true; - if (jj_3R_10()) return true; + private boolean jj_3_2() { + if (jj_scan_token(IS)) return true; + if (jj_scan_token(NULL)) return true; return false; } - private boolean jj_3R_36() { - if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; + private boolean jj_3R_20() { + if (jj_3R_25()) return true; return false; } - private boolean jj_3R_26() { - if (jj_3R_30()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_31()) { jj_scanpos = xsp; break; } - } + private boolean jj_3R_42() { + if (jj_scan_token(STRING_LITERAL)) return true; return false; } - private boolean jj_3_2() { + private boolean jj_3_10() { if (jj_scan_token(NOT)) return true; - if (jj_scan_token(LIKE)) return true; - if (jj_3R_47()) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_59()) jj_scanpos = xsp; + if (jj_3R_13()) return true; return false; } - private boolean jj_3R_53() { - if (jj_scan_token(LIKE)) return true; - if (jj_3R_47()) return true; - Token xsp; - xsp = jj_scanpos; - if (jj_3R_58()) jj_scanpos = xsp; + private boolean jj_3R_27() { + if (jj_scan_token(28)) return true; + if (jj_3R_9()) return true; return false; } - private boolean jj_3R_17() { - if (jj_scan_token(39)) return true; - if (jj_3R_10()) return true; + private boolean jj_3R_19() { + if (jj_scan_token(NOT)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_35() { - if (jj_scan_token(OCTAL_LITERAL)) return true; + private boolean jj_3_6() { + if (jj_scan_token(NOT)) return true; + if (jj_scan_token(IN)) return true; + if (jj_scan_token(33)) return true; + if (jj_3R_42()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_46()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(35)) return true; return false; } - private boolean jj_3R_16() { - if (jj_scan_token(38)) return true; - if (jj_3R_10()) return true; + private boolean jj_3_9() { + if (jj_scan_token(36)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_11() { + private boolean jj_3_1() { + if (jj_scan_token(27)) return true; + if (jj_3R_9()) return true; + return false; + } + + private boolean jj_3R_21() { Token xsp; xsp = jj_scanpos; - if (jj_3R_16()) { + if (jj_3_1()) { jj_scanpos = xsp; - if (jj_3R_17()) { + if (jj_3R_27()) { + jj_scanpos = xsp; + if (jj_3_2()) { jj_scanpos = xsp; - if (jj_3R_18()) return true; + if (jj_3R_28()) return true; + } } } return false; } - private boolean jj_3R_27() { - if (jj_scan_token(AND)) return true; - if (jj_3R_26()) return true; + private boolean jj_3R_45() { + if (jj_scan_token(34)) return true; + if (jj_3R_42()) return true; return false; } - private boolean jj_3R_34() { - if (jj_scan_token(HEX_LITERAL)) return true; + private boolean jj_3R_18() { + if (jj_scan_token(NOT)) return true; + if (jj_3R_13()) return true; return false; } - private boolean jj_3R_9() { - if (jj_3R_10()) return true; + private boolean jj_3R_43() { + if (jj_scan_token(ESCAPE)) return true; + if (jj_3R_42()) return true; + return false; + } + + private boolean jj_3R_17() { + if (jj_scan_token(37)) return true; + if (jj_3R_12()) return true; + return false; + } + + private boolean jj_3R_13() { + if (jj_3R_9()) return true; Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3R_11()) { jj_scanpos = xsp; break; } + if (jj_3R_21()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_33() { - if (jj_scan_token(DECIMAL_LITERAL)) return true; + private boolean jj_3R_16() { + if (jj_scan_token(36)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_57() { - if (jj_scan_token(37)) return true; - if (jj_3R_9()) return true; + private boolean jj_3R_54() { + if (jj_scan_token(NULL)) return true; return false; } - private boolean jj_3R_21() { - if (jj_3R_26()) return true; + private boolean jj_3R_37() { + if (jj_scan_token(IN)) return true; + if (jj_scan_token(33)) return true; + if (jj_3R_42()) return true; Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3R_27()) { jj_scanpos = xsp; break; } + if (jj_3R_45()) { jj_scanpos = xsp; break; } } + if (jj_scan_token(35)) return true; return false; } - private boolean jj_3_5() { + private boolean jj_3R_12() { Token xsp; xsp = jj_scanpos; - if (jj_scan_token(36)) { + if (jj_3R_16()) { jj_scanpos = xsp; - if (jj_scan_token(37)) return true; + if (jj_3R_17()) { + jj_scanpos = xsp; + if (jj_3R_18()) { + jj_scanpos = xsp; + if (jj_3R_19()) { + jj_scanpos = xsp; + if (jj_3R_20()) return true; + } + } + } } - if (jj_3R_9()) return true; return false; } - private boolean jj_3R_52() { - if (jj_scan_token(32)) return true; - if (jj_3R_42()) return true; + private boolean jj_3R_53() { + if (jj_scan_token(FALSE)) return true; return false; } - private boolean jj_3R_41() { - if (jj_scan_token(QUOTED_ID)) return true; + private boolean jj_3_5() { + if (jj_scan_token(NOT)) return true; + if (jj_scan_token(BETWEEN)) return true; + if (jj_3R_10()) return true; + if (jj_scan_token(AND)) return true; + if (jj_3R_10()) return true; return false; } - private boolean jj_3R_56() { - if (jj_scan_token(36)) return true; - if (jj_3R_9()) return true; + private boolean jj_3R_58() { + if (jj_scan_token(AND)) return true; + if (jj_3R_13()) return true; return false; } - private boolean jj_3R_32() { - if (jj_3R_47()) return true; + private boolean jj_3R_36() { + if (jj_scan_token(BETWEEN)) return true; + if (jj_3R_10()) return true; + if (jj_scan_token(AND)) return true; + if (jj_3R_10()) return true; return false; } - private boolean jj_3R_51() { - if (jj_scan_token(31)) return true; - if (jj_3R_42()) return true; + private boolean jj_3R_52() { + if (jj_scan_token(TRUE)) return true; return false; } - private boolean jj_3R_40() { - if (jj_scan_token(ID)) return true; + private boolean jj_3R_22() { + if (jj_3R_13()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_58()) { jj_scanpos = xsp; break; } + } return false; } - private boolean jj_3R_61() { - if (jj_scan_token(34)) return true; - if (jj_3R_47()) return true; + private boolean jj_3R_24() { + if (jj_scan_token(40)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_48() { + private boolean jj_3R_51() { + if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; + return false; + } + + private boolean jj_3_4() { + if (jj_scan_token(NOT)) return true; + if (jj_scan_token(LIKE)) return true; + if (jj_3R_42()) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_56()) { - jj_scanpos = xsp; - if (jj_3R_57()) return true; - } + if (jj_3R_44()) jj_scanpos = xsp; return false; } - private boolean jj_3R_22() { - if (jj_scan_token(OR)) return true; - if (jj_3R_21()) return true; + private boolean jj_3R_23() { + if (jj_scan_token(39)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_28() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_32()) { - jj_scanpos = xsp; - if (jj_3R_33()) { - jj_scanpos = xsp; - if (jj_3R_34()) { - jj_scanpos = xsp; - if (jj_3R_35()) { - jj_scanpos = xsp; - if (jj_3R_36()) { - jj_scanpos = xsp; - if (jj_3R_37()) { - jj_scanpos = xsp; - if (jj_3R_38()) { - jj_scanpos = xsp; - if (jj_3R_39()) return true; - } - } - } - } - } - } - } + private boolean jj_3R_57() { + if (jj_scan_token(OR)) return true; + if (jj_3R_22()) return true; return false; } private boolean jj_3R_50() { - if (jj_scan_token(30)) return true; - if (jj_3R_42()) return true; + if (jj_scan_token(OCTAL_LITERAL)) return true; return false; } - private boolean jj_3R_29() { + private boolean jj_3R_35() { + if (jj_scan_token(LIKE)) return true; + if (jj_3R_42()) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_40()) { - jj_scanpos = xsp; - if (jj_3R_41()) return true; - } + if (jj_3R_43()) jj_scanpos = xsp; return false; } - private boolean jj_3R_49() { - if (jj_scan_token(29)) return true; - if (jj_3R_42()) return true; + private boolean jj_3_8() { + if (jj_scan_token(38)) return true; + if (jj_3R_12()) return true; return false; } - private boolean jj_3R_43() { + private boolean jj_3R_15() { Token xsp; xsp = jj_scanpos; - if (jj_3R_49()) { - jj_scanpos = xsp; - if (jj_3R_50()) { - jj_scanpos = xsp; - if (jj_3R_51()) { - jj_scanpos = xsp; - if (jj_3R_52()) { - jj_scanpos = xsp; - if (jj_3R_53()) { - jj_scanpos = xsp; - if (jj_3_2()) { - jj_scanpos = xsp; - if (jj_3R_54()) { - jj_scanpos = xsp; - if (jj_3_3()) { + if (jj_3_8()) { jj_scanpos = xsp; - if (jj_3R_55()) { + if (jj_3R_23()) { jj_scanpos = xsp; - if (jj_3_4()) return true; - } - } - } - } - } - } - } + if (jj_3R_24()) return true; } } return false; } - private boolean jj_3R_42() { - if (jj_3R_9()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_48()) { jj_scanpos = xsp; break; } - } + private boolean jj_3R_34() { + if (jj_scan_token(32)) return true; + if (jj_3R_10()) return true; return false; } - private boolean jj_3R_19() { - if (jj_3R_21()) return true; + private boolean jj_3R_14() { + if (jj_3R_22()) return true; Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3R_22()) { jj_scanpos = xsp; break; } + if (jj_3R_57()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_25() { - if (jj_scan_token(33)) return true; - if (jj_3R_19()) return true; - if (jj_scan_token(35)) return true; + private boolean jj_3R_49() { + if (jj_scan_token(HEX_LITERAL)) return true; return false; } - private boolean jj_3R_24() { - if (jj_3R_29()) return true; + private boolean jj_3R_11() { + if (jj_3R_12()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_15()) { jj_scanpos = xsp; break; } + } return false; } - private boolean jj_3R_23() { - if (jj_3R_28()) return true; + private boolean jj_3R_33() { + if (jj_scan_token(31)) return true; + if (jj_3R_10()) return true; return false; } - private boolean jj_3R_60() { - if (jj_scan_token(34)) return true; - if (jj_3R_47()) return true; + private boolean jj_3R_41() { + if (jj_scan_token(37)) return true; + if (jj_3R_11()) return true; return false; } - private boolean jj_3R_20() { + private boolean jj_3_7() { Token xsp; xsp = jj_scanpos; - if (jj_3R_23()) { - jj_scanpos = xsp; - if (jj_3R_24()) { + if (jj_scan_token(36)) { jj_scanpos = xsp; - if (jj_3R_25()) return true; - } + if (jj_scan_token(37)) return true; } + if (jj_3R_11()) return true; return false; } - private boolean jj_3R_30() { - if (jj_3R_42()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_43()) { jj_scanpos = xsp; break; } - } + private boolean jj_3R_48() { + if (jj_scan_token(DECIMAL_LITERAL)) return true; return false; } - private boolean jj_3_4() { - if (jj_scan_token(NOT)) return true; - if (jj_scan_token(IN)) return true; - if (jj_scan_token(33)) return true; - if (jj_3R_47()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_61()) { jj_scanpos = xsp; break; } - } - if (jj_scan_token(35)) return true; + private boolean jj_3R_32() { + if (jj_scan_token(30)) return true; + if (jj_3R_10()) return true; return false; } - private boolean jj_3_6() { + private boolean jj_3R_40() { if (jj_scan_token(36)) return true; - if (jj_3R_10()) return true; + if (jj_3R_11()) return true; return false; } - private boolean jj_3R_59() { - if (jj_scan_token(ESCAPE)) return true; - if (jj_3R_47()) return true; + private boolean jj_3R_56() { + if (jj_scan_token(QUOTED_ID)) return true; return false; } private boolean jj_3R_47() { - if (jj_scan_token(STRING_LITERAL)) return true; + if (jj_3R_42()) return true; return false; } - private boolean jj_3R_15() { - if (jj_3R_20()) return true; + private boolean jj_3_3() { + if (jj_scan_token(29)) return true; + if (jj_3R_10()) return true; return false; } - private boolean jj_3R_14() { - if (jj_scan_token(NOT)) return true; - if (jj_3R_19()) return true; + private boolean jj_3R_26() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_3()) { + jj_scanpos = xsp; + if (jj_3R_32()) { + jj_scanpos = xsp; + if (jj_3R_33()) { + jj_scanpos = xsp; + if (jj_3R_34()) { + jj_scanpos = xsp; + if (jj_3R_35()) { + jj_scanpos = xsp; + if (jj_3_4()) { + jj_scanpos = xsp; + if (jj_3R_36()) { + jj_scanpos = xsp; + if (jj_3_5()) { + jj_scanpos = xsp; + if (jj_3R_37()) { + jj_scanpos = xsp; + if (jj_3_6()) return true; + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_55() { + if (jj_scan_token(ID)) return true; + return false; + } + + private boolean jj_3R_31() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_40()) { + jj_scanpos = xsp; + if (jj_3R_41()) return true; + } return false; } @@ -1169,7 +1238,7 @@ private Token jj_consume_token(int kind) throws ParseException { throw generateParseException(); } - static private final class LookaheadSuccess extends Error { } + static private final class LookaheadSuccess extends java.lang.Error { } final private LookaheadSuccess jj_ls = new LookaheadSuccess(); private boolean jj_scan_token(int kind) { if (jj_scanpos == jj_lastpos) { diff --git a/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java b/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java index 629b048a94..26545f5d81 100644 --- a/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java +++ b/broker-core/src/test/java/org/apache/qpid/server/filter/JMSSelectorFilterSyntaxTest.java @@ -25,36 +25,77 @@ import org.junit.jupiter.api.Test; -public class JMSSelectorFilterSyntaxTest +class JMSSelectorFilterSyntaxTest { @Test - public void equality() throws Exception + void equality() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("size")).thenReturn("small"); when(message.getHeader("price")).thenReturn(100); assertTrue(new JMSSelectorFilter("color = 'red'").matches(message)); + assertTrue(new JMSSelectorFilter("size = 'small'").matches(message)); assertTrue(new JMSSelectorFilter("price = 100").matches(message)); assertFalse(new JMSSelectorFilter("color = 'blue'").matches(message)); + assertFalse(new JMSSelectorFilter("size = 'big'").matches(message)); assertFalse(new JMSSelectorFilter("price = 200").matches(message)); } @Test - public void inequality() throws Exception + void notEquality() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("size")).thenReturn("small"); + when(message.getHeader("price")).thenReturn(100); + + assertFalse(new JMSSelectorFilter("not color = 'red'").matches(message)); + assertFalse(new JMSSelectorFilter("not size = 'small'").matches(message)); + assertFalse(new JMSSelectorFilter("not price = 100").matches(message)); + assertTrue(new JMSSelectorFilter("not color = 'blue'").matches(message)); + assertTrue(new JMSSelectorFilter("not size = 'big'").matches(message)); + assertTrue(new JMSSelectorFilter("not price = 200").matches(message)); + + assertFalse(new JMSSelectorFilter("not (color = 'red') and not (price = 100) and not (size = 'small')").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 100 and not size = 'small'").matches(message)); + assertTrue(new JMSSelectorFilter("not (color = 'blue') and not (price = 200) and not (size = 'big')").matches(message)); + assertTrue(new JMSSelectorFilter("not color = 'blue' and not price = 200 and not size = 'big'").matches(message)); + } + + @Test + void inequality() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("size")).thenReturn("small"); when(message.getHeader("price")).thenReturn(100); assertTrue(new JMSSelectorFilter("color <> 'blue'").matches(message)); + assertTrue(new JMSSelectorFilter("size <> 'big'").matches(message)); assertTrue(new JMSSelectorFilter("price <> 200").matches(message)); assertFalse(new JMSSelectorFilter("color <> 'red'").matches(message)); + assertFalse(new JMSSelectorFilter("size <> 'small'").matches(message)); assertFalse(new JMSSelectorFilter("price <> 100").matches(message)); } @Test - public void greaterThan() throws Exception + void notInequality() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("size")).thenReturn("small"); + when(message.getHeader("price")).thenReturn(100); + + assertTrue(new JMSSelectorFilter("not (color <> 'red') and not (price <> 100) and not (size <> 'small')").matches(message)); + assertTrue(new JMSSelectorFilter("not color <> 'red' and not price <> 100 and not size <> 'small'").matches(message)); + assertFalse(new JMSSelectorFilter("not (color <> 'blue') and not (price <> 200) and not (size <> 'big')").matches(message)); + assertFalse(new JMSSelectorFilter("not color <> 'blue' and not price <> 200 and not size <> 'big'").matches(message)); + } + + @Test + void greaterThan() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("price")).thenReturn(100); @@ -64,7 +105,17 @@ public void greaterThan() throws Exception } @Test - public void greaterThanOrEquals() throws Exception + void notGreaterThan() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("price")).thenReturn(100); + + assertFalse(new JMSSelectorFilter("not price > 10").matches(message)); + assertTrue(new JMSSelectorFilter("not price > 100").matches(message)); + } + + @Test + void greaterThanOrEquals() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("price")).thenReturn(100); @@ -75,7 +126,18 @@ public void greaterThanOrEquals() throws Exception } @Test - public void lessThan() throws Exception + void notGreaterThanOrEquals() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("price")).thenReturn(100); + + assertFalse(new JMSSelectorFilter("not price >= 10").matches(message)); + assertFalse(new JMSSelectorFilter("not price >= 100").matches(message)); + assertTrue(new JMSSelectorFilter("not price >= 200").matches(message)); + } + + @Test + void lessThan() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("price")).thenReturn(100); @@ -85,7 +147,17 @@ public void lessThan() throws Exception } @Test - public void lessThanOrEquals() throws Exception + void notLessThan() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("price")).thenReturn(100); + + assertFalse(new JMSSelectorFilter("not price < 110").matches(message)); + assertTrue(new JMSSelectorFilter("not price < 100").matches(message)); + } + + @Test + void lessThanOrEquals() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("price")).thenReturn(100); @@ -96,7 +168,18 @@ public void lessThanOrEquals() throws Exception } @Test - public void and() throws Exception + void notLessThanOrEquals() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("price")).thenReturn(100); + + assertFalse(new JMSSelectorFilter("not price <= 110").matches(message)); + assertFalse(new JMSSelectorFilter("not price <= 100").matches(message)); + assertTrue(new JMSSelectorFilter("not price <= 10").matches(message)); + } + + @Test + void and() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("color")).thenReturn("red"); @@ -109,7 +192,73 @@ public void and() throws Exception } @Test - public void or() throws Exception + void multipleAnd() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("price")).thenReturn(100); + when(message.getHeader("size")).thenReturn("large"); + when(message.getHeader("height")).thenReturn(10); + when(message.getHeader("width")).thenReturn(5); + when(message.getHeader("depth")).thenReturn(2); + when(message.getHeader("length")).thenReturn(8); + + assertTrue(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'large' and height = 10 and width = 5 and depth = 2 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'blue' and price = 100 and size = 'large' and height = 10 and width = 5 and depth = 2 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 200 and size = 'large' and height = 10 and width = 5 and depth = 2 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'small' and height = 10 and width = 5 and depth = 2 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'large' and height = 11 and width = 5 and depth = 2 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'large' and height = 10 and width = 4 and depth = 2 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'large' and height = 10 and width = 5 and depth = 3 and length = 8").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'large' and height = 10 and width = 5 and depth = 2 and length = 9").matches(message)); + + assertFalse(new JMSSelectorFilter("color = 'red' and not price = 100").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and price = 100").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 100").matches(message)); + assertFalse(new JMSSelectorFilter("not (color = 'red' and price = 100)").matches(message)); + assertTrue(new JMSSelectorFilter("not color <> 'red' and not price <> 100").matches(message)); + + assertTrue(new JMSSelectorFilter("color = 'red' and price = 100 and size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and price = 100 and not size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and not price = 100 and size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and price = 100 and size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 100 and size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and not price = 100 and not size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("not color = 'red' and price = 100 and not size = 'large'").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and not price = 100 and not size = 'large'").matches(message)); + + assertTrue(new JMSSelectorFilter("not color <> 'red' and not price <> 100 and not size <> 'large'").matches(message)); + } + + @Test + public void chainedNot() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("price")).thenReturn(100); + when(message.getHeader("size")).thenReturn("large"); + + assertFalse(new JMSSelectorFilter("not(true)").matches(message)); + assertTrue(new JMSSelectorFilter("not not(true)").matches(message)); + assertFalse(new JMSSelectorFilter("not not not(true)").matches(message)); + assertTrue(new JMSSelectorFilter("not not not not(true)").matches(message)); + + assertFalse(new JMSSelectorFilter("true and not (false) and not (true)").matches(message)); + assertFalse(new JMSSelectorFilter("true and (not false) and (not true)").matches(message)); + assertFalse(new JMSSelectorFilter("color = 'red' and not (price = 200) and not (size = 'large')").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'red' and not (price = 200) and not (size = 'small')").matches(message)); + + when(message.getHeader("entry")).thenReturn("bbb"); + when(message.getHeader("fruit")).thenReturn("apple"); + + assertTrue(new JMSSelectorFilter("not (((true and true) or (false or true)) and (not (price not between 90 and 110) and not (not (fruit in ('apple', 'banana', 'cherry')) or (entry NOT LIKE '%aaa%'))))").matches(message)); + + when(message.getHeader("entry")).thenReturn("aaa"); + assertFalse(new JMSSelectorFilter("not (((true and true) or (false or true)) and (not (price not between 90 and 110) and not (not (fruit in ('apple', 'banana', 'cherry')) or (entry NOT LIKE '%aaa%'))))").matches(message)); + } + + @Test + void or() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("color")).thenReturn("red"); @@ -122,7 +271,29 @@ public void or() throws Exception } @Test - public void in() throws Exception + void multipleOr() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("color")).thenReturn("red"); + when(message.getHeader("price")).thenReturn(100); + when(message.getHeader("size")).thenReturn("large"); + when(message.getHeader("height")).thenReturn(10); + when(message.getHeader("width")).thenReturn(5); + when(message.getHeader("depth")).thenReturn(2); + when(message.getHeader("length")).thenReturn(8); + + assertFalse(new JMSSelectorFilter("color = 'blue' or price = 200 or size = 'small' or height = 11 or width = 4 or depth = 1 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'red' or price = 200 or size = 'small' or height = 11 or width = 4 or depth = 1 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'blue' or price = 100 or size = 'small' or height = 11 or width = 4 or depth = 1 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or size = 'large' or height = 11 or width = 4 or depth = 1 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or size = 'small' or height = 10 or width = 4 or depth = 1 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or size = 'small' or height = 11 or width = 5 or depth = 1 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or size = 'small' or height = 11 or width = 4 or depth = 2 or length = 9").matches(message)); + assertTrue(new JMSSelectorFilter("color = 'blue' or price = 200 or size = 'small' or height = 11 or width = 4 or depth = 1 or length = 8").matches(message)); + } + + @Test + void in() throws Exception { final Filterable message = mock(Filterable.class); @@ -140,7 +311,7 @@ public void in() throws Exception } @Test - public void notIn() throws Exception + void notIn() throws Exception { final Filterable message = mock(Filterable.class); @@ -153,20 +324,23 @@ public void notIn() throws Exception assertFalse(new JMSSelectorFilter("fruit not in ('apple', 'banana', 'cherry')").matches(message)); assertFalse(new JMSSelectorFilter("not (fruit in ('apple', 'banana', 'cherry'))").matches(message)); assertFalse(new JMSSelectorFilter("not fruit in ('apple', 'banana', 'cherry')").matches(message)); + assertTrue(new JMSSelectorFilter("not fruit not in ('apple', 'banana', 'cherry')").matches(message)); when(message.getHeader("fruit")).thenReturn("cherry"); assertFalse(new JMSSelectorFilter("fruit not in ('apple', 'banana', 'cherry')").matches(message)); assertFalse(new JMSSelectorFilter("not (fruit in ('apple', 'banana', 'cherry'))").matches(message)); assertFalse(new JMSSelectorFilter("not fruit in ('apple', 'banana', 'cherry')").matches(message)); + assertTrue(new JMSSelectorFilter("not fruit not in ('apple', 'banana', 'cherry')").matches(message)); when(message.getHeader("fruit")).thenReturn("mango"); assertTrue(new JMSSelectorFilter("fruit not in ('apple', 'banana', 'cherry')").matches(message)); assertTrue(new JMSSelectorFilter("not (fruit in ('apple', 'banana', 'cherry'))").matches(message)); assertTrue(new JMSSelectorFilter("not fruit in ('apple', 'banana', 'cherry')").matches(message)); + assertFalse(new JMSSelectorFilter("not fruit not in ('apple', 'banana', 'cherry')").matches(message)); } @Test - public void between() throws Exception + void between() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("price")).thenReturn(100); @@ -178,7 +352,7 @@ public void between() throws Exception } @Test - public void notBetween() throws Exception + void notBetween() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("price")).thenReturn(100); @@ -187,11 +361,13 @@ public void notBetween() throws Exception assertFalse(new JMSSelectorFilter("price not between 100 and 110").matches(message)); assertFalse(new JMSSelectorFilter("price not between 90 and 100").matches(message)); assertTrue(new JMSSelectorFilter("price not between 110 and 120").matches(message)); + assertFalse(new JMSSelectorFilter("not price not between 110 and 120").matches(message)); assertFalse(new JMSSelectorFilter("not (price between 90 and 110)").matches(message)); assertFalse(new JMSSelectorFilter("not (price between 100 and 110)").matches(message)); assertFalse(new JMSSelectorFilter("not (price between 90 and 100)").matches(message)); assertTrue(new JMSSelectorFilter("not (price between 110 and 120)").matches(message)); + assertFalse(new JMSSelectorFilter("not (price not between 110 and 120)").matches(message)); assertFalse(new JMSSelectorFilter("not price between 90 and 110").matches(message)); assertFalse(new JMSSelectorFilter("not price between 100 and 110").matches(message)); @@ -200,7 +376,7 @@ public void notBetween() throws Exception } @Test - public void like() throws Exception + void like() throws Exception { final Filterable message = mock(Filterable.class); @@ -212,7 +388,7 @@ public void like() throws Exception } @Test - public void notLike() throws Exception + void notLike() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("entry")).thenReturn("bbb"); @@ -230,10 +406,12 @@ public void notLike() throws Exception assertFalse(new JMSSelectorFilter("NOT (entry LIKE '%aaa%')").matches(message)); assertFalse(new JMSSelectorFilter("NOT entry LIKE '%aaa%'").matches(message)); + assertTrue(new JMSSelectorFilter("NOT (entry NOT LIKE '%aaa%')").matches(message)); + assertTrue(new JMSSelectorFilter("NOT entry NOT LIKE '%aaa%'").matches(message)); } @Test - public void isNull() throws Exception + void isNull() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("entry")).thenReturn("aaa"); @@ -243,7 +421,7 @@ public void isNull() throws Exception } @Test - public void isNotNull() throws Exception + void isNotNull() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("entry")).thenReturn("aaa"); @@ -251,13 +429,16 @@ public void isNotNull() throws Exception assertTrue(new JMSSelectorFilter("entry is not null").matches(message)); assertTrue(new JMSSelectorFilter("not (entry is null)").matches(message)); assertTrue(new JMSSelectorFilter("not entry is null").matches(message)); + assertFalse(new JMSSelectorFilter("not entry is not null").matches(message)); + assertFalse(new JMSSelectorFilter("another_entry is not null").matches(message)); assertFalse(new JMSSelectorFilter("not (another_entry is null)").matches(message)); assertFalse(new JMSSelectorFilter("not another_entry is null").matches(message)); + assertTrue(new JMSSelectorFilter("not another_entry is not null").matches(message)); } @Test - public void arithmetic() throws Exception + void arithmetic() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("size")).thenReturn(10); @@ -276,7 +457,37 @@ public void arithmetic() throws Exception } @Test - public void arithmeticOperatorsPrecedence() throws Exception + void notArithmetic() throws Exception + { + final Filterable message = mock(Filterable.class); + when(message.getHeader("size")).thenReturn(10); + when(message.getHeader("price")).thenReturn(100); + + assertTrue(new JMSSelectorFilter("not (size + price = 111)").matches(message)); + assertTrue(new JMSSelectorFilter("not (price - size = 91)").matches(message)); + assertTrue(new JMSSelectorFilter("not (price / size = 11)").matches(message)); + assertTrue(new JMSSelectorFilter("not (price * size = 1001)").matches(message)); + + assertTrue(new JMSSelectorFilter("not size + price = 111").matches(message)); + assertTrue(new JMSSelectorFilter("not price - size = 91").matches(message)); + assertTrue(new JMSSelectorFilter("not price / size = 11").matches(message)); + assertTrue(new JMSSelectorFilter("not price * size = 1001").matches(message)); + + assertTrue(new JMSSelectorFilter("not (size / 4 = 3.5)").matches(message)); + assertTrue(new JMSSelectorFilter("not (size / 4.0 = 3.5)").matches(message)); + + assertTrue(new JMSSelectorFilter("not size / 4 = 3.5").matches(message)); + assertTrue(new JMSSelectorFilter("not size / 4.0 = 3.5").matches(message)); + + assertTrue(new JMSSelectorFilter("not (size * 2 = 21.0)").matches(message)); + assertTrue(new JMSSelectorFilter("not (size * 2.0 = 21.0)").matches(message)); + + assertTrue(new JMSSelectorFilter("not size * 2 = 21.0").matches(message)); + assertTrue(new JMSSelectorFilter("not size * 2.0 = 21.0").matches(message)); + } + + @Test + void arithmeticOperatorsPrecedence() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("size")).thenReturn(10); @@ -290,13 +501,23 @@ public void arithmeticOperatorsPrecedence() throws Exception } @Test - public void logicOperatorsPrecedence() throws Exception + void logicOperatorsPrecedence() throws Exception { final Filterable message = mock(Filterable.class); when(message.getHeader("a")).thenReturn(1); when(message.getHeader("b")).thenReturn(2); when(message.getHeader("c")).thenReturn(3); + + assertTrue(new JMSSelectorFilter("True or True and False").matches(message)); + assertTrue(new JMSSelectorFilter("False and True or True").matches(message)); + + assertFalse(new JMSSelectorFilter("(True or True) and False").matches(message)); + assertTrue(new JMSSelectorFilter("True or (True and False)").matches(message)); + + assertFalse(new JMSSelectorFilter("False and (True or True)").matches(message)); + assertTrue(new JMSSelectorFilter("(False and True) or True").matches(message)); + assertTrue(new JMSSelectorFilter("a = 1 and b = 2 or c = 3").matches(message)); assertFalse(new JMSSelectorFilter("not a = 1 and b = 2").matches(message)); assertTrue(new JMSSelectorFilter("a = 1 and (b = 2 or c = 3)").matches(message)); @@ -309,11 +530,28 @@ public void logicOperatorsPrecedence() throws Exception when(message.getHeader("a")).thenReturn(1); when(message.getHeader("b")).thenReturn(2); when(message.getHeader("c")).thenReturn(4); + assertTrue(new JMSSelectorFilter("a = 1 and b = 2 or c = 3").matches(message)); when(message.getHeader("a")).thenReturn(1); when(message.getHeader("b")).thenReturn(1); when(message.getHeader("c")).thenReturn(3); + assertTrue(new JMSSelectorFilter("a = 1 and b = 2 or c = 3").matches(message)); + + when(message.getHeader("a")).thenReturn(1); + when(message.getHeader("b")).thenReturn(2); + when(message.getHeader("c")).thenReturn(3); + + assertTrue(new JMSSelectorFilter("a = 1 and not b = 2 or c = 3").matches(message)); + assertTrue(new JMSSelectorFilter("(a = 1 and not b = 2) or c = 3").matches(message)); + assertFalse(new JMSSelectorFilter("a = 1 and not (b = 2 or c = 3)").matches(message)); + assertTrue(new JMSSelectorFilter("not (a = 1 and not b = 2) or c = 3").matches(message)); + + assertTrue(new JMSSelectorFilter("a = 1 or not b = 2 and c = 3").matches(message)); + assertTrue(new JMSSelectorFilter("(a = 1 or not b = 2) and c = 3").matches(message)); + assertTrue(new JMSSelectorFilter("a = 1 or (not b = 2 and c = 3)").matches(message)); + assertTrue(new JMSSelectorFilter("a = 1 or not (b = 2 and c = 3)").matches(message)); + assertFalse(new JMSSelectorFilter("not (a = 1 or not b = 2) and c = 3").matches(message)); } }