diff --git a/commit_db/openapi-generator_bugs.csv b/commit_db/openapi-generator_bugs.csv index b2f68490..668e75db 100644 --- a/commit_db/openapi-generator_bugs.csv +++ b/commit_db/openapi-generator_bugs.csv @@ -4,3 +4,4 @@ bug_id,revision.id.buggy,revision.id.fixed,report.id,report.url 3,1b60ee1799a6831a9cd59cb833db63d4ee4eb06b,68b944e6e62fa69669e97a8c2041a7eb7ed3314a,OpenAPITools_openapi-generator-14536,https://github.com/OpenAPITools/openapi-generator/issues/14531 4,564939a4a8eb73f26a5878445c058875e2a1f2a9,f45523dd1a6c4c02d1745c13104beadfa103fa26,OpenAPITools_openapi-generator-14768,https://github.com/OpenAPITools/openapi-generator/issues/11185 5,7f480cb9360e98308a16d0adae1f8a2d8fad2ae6,1531ad48d0f5ed03036d5253e60cd5077d0d90ad,OpenAPITools_openapi-generator-16050,https://github.com/OpenAPITools/openapi-generator/issues/15476 +6,7c7634dda95eeb015e3a64375abf124f9031fecd,6c35fe1035bb8930e62928de15f4a6dedc23fb98,OpenAPITools_openapi-generator-17759,https://github.com/OpenAPITools/openapi-generator/issues/17757 diff --git a/commit_db/rocketmq_bugs.csv b/commit_db/rocketmq_bugs.csv index af9b74db..74733387 100644 --- a/commit_db/rocketmq_bugs.csv +++ b/commit_db/rocketmq_bugs.csv @@ -16,3 +16,4 @@ bug_id,revision.id.buggy,revision.id.fixed,report.id,report.url 15,d79737788078707168c0258c4af0d800de32c137,d0a69be563785ca815dc31ef1aab4c1bc5588c01,apache_rocketmq-7073,https://github.com/apache/rocketmq/issues/6810 16,d000ef947d7c99918ceba0fa451c1e29fd84ba07,f82718ae3b77a16b553c03f672dc971a2d5d48fa,apache_rocketmq-7209,https://github.com/apache/rocketmq/issues/7208 17,dddd58d2cc8622eb70f55b447ffb772700c0e916,1a8e7cb17cb29ed33b0196b52e452a6e76ade781,apache_rocketmq-7346,https://github.com/apache/rocketmq/issues/7345 +18,9e4fd0e68a1ea6ab1b1f3344ac9ae79af29a32c2,806454bc5e29d2f157cde99bdb082f94cdb377fa,apache_rocketmq-7712,https://github.com/apache/rocketmq/issues/7710 diff --git a/data/prod_diff/FasterXML_jackson-databind-4273.diff b/data/prod_diff/FasterXML_jackson-databind-4273.diff deleted file mode 100644 index cdc25a78..00000000 --- a/data/prod_diff/FasterXML_jackson-databind-4273.diff +++ /dev/null @@ -1,76 +0,0 @@ -diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializer.java -index df3a3b4e54..232add68ef 100644 ---- a/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializer.java -+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializer.java -@@ -4,6 +4,9 @@ import java.io.IOException; - import java.lang.reflect.Type; - import java.math.BigDecimal; - import java.math.BigInteger; -+import java.text.DecimalFormat; -+import java.text.DecimalFormatSymbols; -+import java.text.NumberFormat; - - import com.fasterxml.jackson.annotation.JsonFormat; - -@@ -38,6 +41,11 @@ public class NumberSerializer - - protected final boolean _isInt; - -+ /** -+ * @since 2.17 -+ */ -+ protected final NumberFormat _format; -+ - /** - * @since 2.5 - */ -@@ -45,6 +53,16 @@ public class NumberSerializer - super(rawType, false); - // since this will NOT be constructed for Integer or Long, only case is: - _isInt = (rawType == BigInteger.class); -+ _format = null; -+ } -+ -+ /** -+ * @since 2.17 -+ */ -+ public NumberSerializer(NumberSerializer src, NumberFormat format) { -+ super(src); -+ _isInt = src._isInt; -+ _format = format; - } - - @Override -@@ -55,6 +73,21 @@ public class NumberSerializer - if (format != null) { - switch (format.getShape()) { - case STRING: -+ if (format.hasPattern()) { -+ DecimalFormat decimalFormat; -+ try { -+ if (format.hasLocale()) { -+ decimalFormat = new DecimalFormat(format.getPattern(), -+ DecimalFormatSymbols.getInstance(format.getLocale())); -+ } else { -+ decimalFormat = new DecimalFormat(format.getPattern()); -+ } -+ } catch (IllegalArgumentException e) { -+ return prov.reportBadDefinition(handledType(), -+ String.format("Invalid `DecimalFormat`: \"%s\"", format.getPattern())); -+ } -+ return new NumberSerializer(this, decimalFormat); -+ } - // [databind#2264]: Need special handling for `BigDecimal` - if (((Class) handledType()) == BigDecimal.class) { - return bigDecimalAsStringSerializer(); -@@ -69,6 +102,10 @@ public class NumberSerializer - @Override - public void serialize(Number value, JsonGenerator g, SerializerProvider provider) throws IOException - { -+ if (_format != null) { -+ g.writeString(_format.format(value)); -+ return; -+ } - // should mostly come in as one of these two: - if (value instanceof BigDecimal) { - g.writeNumber((BigDecimal) value); diff --git a/data/prod_diff/OpenAPITools_openapi-generator-17759.diff b/data/prod_diff/OpenAPITools_openapi-generator-17759.diff new file mode 100644 index 00000000..a982f9fc --- /dev/null +++ b/data/prod_diff/OpenAPITools_openapi-generator-17759.diff @@ -0,0 +1,30 @@ +diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +index c1ae3cc8fbb..4b3dcc56612 100644 +--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java ++++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +@@ -1003,21 +1003,21 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code + if (items.getMinimum() != null && items.getMaximum() != null) { + return String.format(Locale.ROOT, "@DecimalMin(value = \"%s\", inclusive = %s) @DecimalMax(value = \"%s\", inclusive = %s)", + items.getMinimum(), +- Optional.ofNullable(items.getExclusiveMinimum()).orElse(Boolean.FALSE), ++ !Optional.ofNullable(items.getExclusiveMinimum()).orElse(Boolean.FALSE), + items.getMaximum(), +- Optional.ofNullable(items.getExclusiveMaximum()).orElse(Boolean.FALSE)); ++ !Optional.ofNullable(items.getExclusiveMaximum()).orElse(Boolean.FALSE)); + } + + if (items.getMinimum() != null) { + return String.format(Locale.ROOT, "@DecimalMin( value = \"%s\", inclusive = %s)", + items.getMinimum(), +- Optional.ofNullable(items.getExclusiveMinimum()).orElse(Boolean.FALSE)); ++ !Optional.ofNullable(items.getExclusiveMinimum()).orElse(Boolean.FALSE)); + } + + if (items.getMaximum() != null) { + return String.format(Locale.ROOT, "@DecimalMax( value = \"%s\", inclusive = %s)", + items.getMaximum(), +- Optional.ofNullable(items.getExclusiveMaximum()).orElse(Boolean.FALSE)); ++ !Optional.ofNullable(items.getExclusiveMaximum()).orElse(Boolean.FALSE)); + } + + return ""; diff --git a/data/prod_diff/apache_rocketmq-6864.diff b/data/prod_diff/apache_rocketmq-6864.diff deleted file mode 100644 index 6a25faa3..00000000 --- a/data/prod_diff/apache_rocketmq-6864.diff +++ /dev/null @@ -1,1874 +0,0 @@ -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java b/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java -index b793cdf97..ff9d84af0 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java -@@ -69,6 +69,90 @@ public abstract class ComparisonExpression extends BinaryExpression implements B - return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right)); - } - -+ static class ContainsExpression extends UnaryExpression implements BooleanExpression { -+ -+ String search; -+ -+ public ContainsExpression(Expression right, String search) { -+ super(right); -+ this.search = search; -+ } -+ -+ public String getExpressionSymbol() { -+ return "CONTAINS"; -+ } -+ -+ public Object evaluate(EvaluationContext message) throws Exception { -+ -+ if (search == null || search.length() == 0) { -+ return Boolean.FALSE; -+ } -+ -+ Object rv = this.getRight().evaluate(message); -+ -+ if (rv == null) { -+ return Boolean.FALSE; -+ } -+ -+ if (!(rv instanceof String)) { -+ return Boolean.FALSE; -+ } -+ -+ return ((String)rv).contains(search) ? Boolean.TRUE : Boolean.FALSE; -+ } -+ -+ public boolean matches(EvaluationContext message) throws Exception { -+ Object object = evaluate(message); -+ return object != null && object == Boolean.TRUE; -+ } -+ } -+ -+ static class NotContainsExpression extends UnaryExpression implements BooleanExpression { -+ -+ String search; -+ -+ public NotContainsExpression(Expression right, String search) { -+ super(right); -+ this.search = search; -+ } -+ -+ public String getExpressionSymbol() { -+ return "NOT CONTAINS"; -+ } -+ -+ public Object evaluate(EvaluationContext message) throws Exception { -+ -+ if (search == null || search.length() == 0) { -+ return Boolean.FALSE; -+ } -+ -+ Object rv = this.getRight().evaluate(message); -+ -+ if (rv == null) { -+ return Boolean.FALSE; -+ } -+ -+ if (!(rv instanceof String)) { -+ return Boolean.FALSE; -+ } -+ -+ return ((String)rv).contains(search) ? Boolean.FALSE : Boolean.TRUE; -+ } -+ -+ public boolean matches(EvaluationContext message) throws Exception { -+ Object object = evaluate(message); -+ return object != null && object == Boolean.TRUE; -+ } -+ } -+ -+ public static BooleanExpression createContains(Expression left, String search) { -+ return new ContainsExpression(left, search); -+ } -+ -+ public static BooleanExpression createNotContains(Expression left, String search) { -+ return new NotContainsExpression(left, search); -+ } -+ - @SuppressWarnings({"rawtypes", "unchecked"}) - public static BooleanExpression createInFilter(Expression left, List elements) { - -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java -index 0a327bea1..39762509e 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/ParseException.java -@@ -202,4 +202,4 @@ public class ParseException extends Exception { - } - - } --/* JavaCC - OriginalChecksum=4c829b0daa2c9af00ddafe2441eb9097 (do not edit this line) */ -+/* JavaCC - OriginalChecksum=60cf9c227a487e4be49599bc903f0a6a (do not edit this line) */ -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java -index 5658391fd..d23e6ee97 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java -@@ -41,10 +41,10 @@ import java.util.ArrayList; - public class SelectorParser implements SelectorParserConstants { - - private static final Cache PARSE_CACHE = CacheBuilder.newBuilder().maximumSize(100).build(); -- // private static final String CONVERT_STRING_EXPRESSIONS_PREFIX = "convert_string_expressions:"; -+// private static final String CONVERT_STRING_EXPRESSIONS_PREFIX = "convert_string_expressions:"; - - public static BooleanExpression parse(String sql) throws MQFilterException { -- // sql = "("+sql+")"; -+// sql = "("+sql+")"; - Object result = PARSE_CACHE.getIfPresent(sql); - if (result instanceof MQFilterException) { - throw (MQFilterException) result; -@@ -52,14 +52,14 @@ public class SelectorParser implements SelectorParserConstants { - return (BooleanExpression) result; - } else { - -- // boolean convertStringExpressions = false; -- // if( sql.startsWith(CONVERT_STRING_EXPRESSIONS_PREFIX)) { -- // convertStringExpressions = true; -- // sql = sql.substring(CONVERT_STRING_EXPRESSIONS_PREFIX.length()); -- // } -- // if( convertStringExpressions ) { -- // ComparisonExpression.CONVERT_STRING_EXPRESSIONS.set(true); -- // } -+// boolean convertStringExpressions = false; -+// if( sql.startsWith(CONVERT_STRING_EXPRESSIONS_PREFIX)) { -+// convertStringExpressions = true; -+// sql = sql.substring(CONVERT_STRING_EXPRESSIONS_PREFIX.length()); -+// } -+// if( convertStringExpressions ) { -+// ComparisonExpression.CONVERT_STRING_EXPRESSIONS.set(true); -+// } - ComparisonExpression.CONVERT_STRING_EXPRESSIONS.set(true); - try { - -@@ -71,9 +71,9 @@ public class SelectorParser implements SelectorParserConstants { - throw t; - } finally { - ComparisonExpression.CONVERT_STRING_EXPRESSIONS.remove(); -- // if( convertStringExpressions ) { -- // ComparisonExpression.CONVERT_STRING_EXPRESSIONS.remove(); -- // } -+// if( convertStringExpressions ) { -+// ComparisonExpression.CONVERT_STRING_EXPRESSIONS.remove(); -+// } - } - } - } -@@ -114,8 +114,7 @@ public class SelectorParser implements SelectorParserConstants { - Expression left = null; - left = orExpression(); - { -- if (true) -- return asBooleanExpression(left); -+ if (true) return asBooleanExpression(left); - } - throw new Error("Missing return statement in function"); - } -@@ -138,8 +137,7 @@ public class SelectorParser implements SelectorParserConstants { - left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right)); - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -162,8 +160,7 @@ public class SelectorParser implements SelectorParserConstants { - left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right)); - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -176,21 +173,21 @@ public class SelectorParser implements SelectorParserConstants { - while (true) { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { - case IS: -- case 22: - case 23: -+ case 24: - break; - default: - jjLa1[2] = jjGen; - break label_3; - } - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 22: -- jj_consume_token(22); -+ case 23: -+ jj_consume_token(23); - right = comparisonExpression(); - left = ComparisonExpression.createEqual(left, right); - break; -- case 23: -- jj_consume_token(23); -+ case 24: -+ jj_consume_token(24); - right = comparisonExpression(); - left = ComparisonExpression.createNotEqual(left, right); - break; -@@ -217,8 +214,7 @@ public class SelectorParser implements SelectorParserConstants { - } - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -238,111 +234,127 @@ public class SelectorParser implements SelectorParserConstants { - case NOT: - case BETWEEN: - case IN: -- case 24: -+ case CONTAINS: - case 25: - case 26: - case 27: -+ case 28: - break; - default: - jjLa1[5] = jjGen; - break label_4; - } - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 24: -- jj_consume_token(24); -- right = unaryExpr(); -- left = ComparisonExpression.createGreaterThan(left, right); -- break; - case 25: - jj_consume_token(25); - right = unaryExpr(); -- left = ComparisonExpression.createGreaterThanEqual(left, right); -+ left = ComparisonExpression.createGreaterThan(left, right); - break; - case 26: - jj_consume_token(26); - right = unaryExpr(); -- left = ComparisonExpression.createLessThan(left, right); -+ left = ComparisonExpression.createGreaterThanEqual(left, right); - break; - case 27: - jj_consume_token(27); - right = unaryExpr(); -+ left = ComparisonExpression.createLessThan(left, right); -+ break; -+ case 28: -+ jj_consume_token(28); -+ right = unaryExpr(); - left = ComparisonExpression.createLessThanEqual(left, right); - break; -- case BETWEEN: -- jj_consume_token(BETWEEN); -- low = unaryExpr(); -- jj_consume_token(AND); -- high = unaryExpr(); -- left = ComparisonExpression.createBetween(left, low, high); -+ case CONTAINS: -+ jj_consume_token(CONTAINS); -+ t = stringLitteral(); -+ left = ComparisonExpression.createContains(left, t); - break; - default: - jjLa1[8] = jjGen; - if (jj_2_2(2)) { - jj_consume_token(NOT); -- jj_consume_token(BETWEEN); -- low = unaryExpr(); -- jj_consume_token(AND); -- high = unaryExpr(); -- left = ComparisonExpression.createNotBetween(left, low, high); -+ jj_consume_token(CONTAINS); -+ t = stringLitteral(); -+ left = ComparisonExpression.createNotContains(left, t); - } else { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case IN: -- jj_consume_token(IN); -- jj_consume_token(28); -- t = stringLitteral(); -- list = new ArrayList(); -- list.add(t); -- label_5: -- while (true) { -- switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 29: -- break; -- default: -- jjLa1[6] = jjGen; -- break label_5; -- } -- jj_consume_token(29); -- t = stringLitteral(); -- list.add(t); -- } -- jj_consume_token(30); -- left = ComparisonExpression.createInFilter(left, list); -+ case BETWEEN: -+ jj_consume_token(BETWEEN); -+ low = unaryExpr(); -+ jj_consume_token(AND); -+ high = unaryExpr(); -+ left = ComparisonExpression.createBetween(left, low, high); - break; - default: - jjLa1[9] = jjGen; - if (jj_2_3(2)) { - jj_consume_token(NOT); -- jj_consume_token(IN); -- jj_consume_token(28); -- t = stringLitteral(); -- list = new ArrayList(); -- list.add(t); -- label_6: -- while (true) { -- switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 29: -- break; -- default: -- jjLa1[7] = jjGen; -- break label_6; -- } -- jj_consume_token(29); -- t = stringLitteral(); -- list.add(t); -- } -- jj_consume_token(30); -- left = ComparisonExpression.createNotInFilter(left, list); -+ jj_consume_token(BETWEEN); -+ low = unaryExpr(); -+ jj_consume_token(AND); -+ high = unaryExpr(); -+ left = ComparisonExpression.createNotBetween(left, low, high); - } else { -- jj_consume_token(-1); -- throw new ParseException(); -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case IN: -+ jj_consume_token(IN); -+ jj_consume_token(29); -+ t = stringLitteral(); -+ list = new ArrayList(); -+ list.add(t); -+ label_5: -+ while (true) { -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case 30: -+ break; -+ default: -+ jjLa1[6] = jjGen; -+ break label_5; -+ } -+ jj_consume_token(30); -+ t = stringLitteral(); -+ list.add(t); -+ } -+ jj_consume_token(31); -+ left = ComparisonExpression.createInFilter(left, list); -+ break; -+ default: -+ jjLa1[10] = jjGen; -+ if (jj_2_4(2)) { -+ jj_consume_token(NOT); -+ jj_consume_token(IN); -+ jj_consume_token(29); -+ t = stringLitteral(); -+ list = new ArrayList(); -+ list.add(t); -+ label_6: -+ while (true) { -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case 30: -+ break; -+ default: -+ jjLa1[7] = jjGen; -+ break label_6; -+ } -+ jj_consume_token(30); -+ t = stringLitteral(); -+ list.add(t); -+ } -+ jj_consume_token(31); -+ left = ComparisonExpression.createNotInFilter(left, list); -+ } else { -+ jj_consume_token(-1); -+ throw new ParseException(); -+ } -+ } - } - } - } - } - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -350,13 +362,13 @@ public class SelectorParser implements SelectorParserConstants { - final public Expression unaryExpr() throws ParseException { - String s = null; - Expression left = null; -- if (jj_2_4(2147483647)) { -- jj_consume_token(31); -+ if (jj_2_5(2147483647)) { -+ jj_consume_token(32); - left = unaryExpr(); - } else { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 32: -- jj_consume_token(32); -+ case 33: -+ jj_consume_token(33); - left = unaryExpr(); - left = UnaryExpression.createNegate(left); - break; -@@ -372,18 +384,17 @@ public class SelectorParser implements SelectorParserConstants { - case FLOATING_POINT_LITERAL: - case STRING_LITERAL: - case ID: -- case 28: -+ case 29: - left = primaryExpr(); - break; - default: -- jjLa1[10] = jjGen; -+ jjLa1[11] = jjGen; - jj_consume_token(-1); - throw new ParseException(); - } - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -402,19 +413,18 @@ public class SelectorParser implements SelectorParserConstants { - case ID: - left = variable(); - break; -- case 28: -- jj_consume_token(28); -+ case 29: -+ jj_consume_token(29); - left = orExpression(); -- jj_consume_token(30); -+ jj_consume_token(31); - break; - default: -- jjLa1[11] = jjGen; -+ jjLa1[12] = jjGen; - jj_consume_token(-1); - throw new ParseException(); - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -449,13 +459,12 @@ public class SelectorParser implements SelectorParserConstants { - left = BooleanConstantExpression.NULL; - break; - default: -- jjLa1[12] = jjGen; -+ jjLa1[13] = jjGen; - jj_consume_token(-1); - throw new ParseException(); - } - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -474,8 +483,7 @@ public class SelectorParser implements SelectorParserConstants { - rc.append(c); - } - { -- if (true) -- return rc.toString(); -+ if (true) return rc.toString(); - } - throw new Error("Missing return statement in function"); - } -@@ -486,8 +494,7 @@ public class SelectorParser implements SelectorParserConstants { - t = jj_consume_token(ID); - left = new PropertyExpression(t.image); - { -- if (true) -- return left; -+ if (true) return left; - } - throw new Error("Missing return statement in function"); - } -@@ -540,94 +547,26 @@ public class SelectorParser implements SelectorParserConstants { - } - } - -- private boolean jj_3R_7() { -- Token xsp; -- xsp = jjScanpos; -- if (jj_3R_8()) { -- jjScanpos = xsp; -- if (jj_3R_9()) { -- jjScanpos = xsp; -- if (jj_3R_10()) { -- jjScanpos = xsp; -- if (jj_3R_11()) -- return true; -- } -- } -- } -- return false; -- } -- -- private boolean jj_3R_43() { -- if (jj_scan_token(29)) -- return true; -- if (jj_3R_27()) -- return true; -- return false; -- } -- -- private boolean jj_3R_24() { -- if (jj_scan_token(NULL)) -- return true; -- return false; -- } -- -- private boolean jj_3R_35() { -- 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_3_1() { -- if (jj_scan_token(IS)) -- return true; -- if (jj_scan_token(NULL)) -+ private boolean jj_2_5(int xla) { -+ jjLa = xla; -+ jjLastpos = jjScanpos = token; -+ try { -+ return !jj_3_5(); -+ } catch (LookaheadSuccess ls) { - return true; -- return false; -+ } finally { -+ jj_save(4, xla); -+ } - } - -- private boolean jj_3R_23() { -- if (jj_scan_token(FALSE)) -- return true; -+ private boolean jj_3R_21() { -+ if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; - return false; - } - - private boolean jj_3R_34() { -- if (jj_scan_token(23)) -- return true; -- if (jj_3R_30()) -- return true; -- return false; -- } -- -- private boolean jj_3R_22() { -- if (jj_scan_token(TRUE)) -- return true; -- return false; -- } -- -- private boolean jj_3_3() { -- if (jj_scan_token(NOT)) -- return true; -- if (jj_scan_token(IN)) -- return true; -- if (jj_scan_token(28)) -- return true; -- if (jj_3R_27()) -- return true; -- Token xsp; -- while (true) { -- xsp = jjScanpos; -- if (jj_3R_43()) { -- jjScanpos = xsp; -- break; -- } -- } -- if (jj_scan_token(30)) -- return true; -+ if (jj_scan_token(24)) return true; -+ if (jj_3R_30()) return true; - return false; - } - -@@ -640,8 +579,7 @@ public class SelectorParser implements SelectorParserConstants { - jjScanpos = xsp; - if (jj_3_1()) { - jjScanpos = xsp; -- if (jj_3R_35()) -- return true; -+ if (jj_3R_35()) return true; - } - } - } -@@ -649,78 +587,47 @@ public class SelectorParser implements SelectorParserConstants { - } - - private boolean jj_3R_33() { -- if (jj_scan_token(22)) -- return true; -- if (jj_3R_30()) -- return true; -- return false; -- } -- -- private boolean jj_3R_42() { -- if (jj_scan_token(29)) -- return true; -- if (jj_3R_27()) -- return true; -- return false; -- } -- -- private boolean jj_3R_21() { -- if (jj_scan_token(FLOATING_POINT_LITERAL)) -- return true; -+ if (jj_scan_token(23)) return true; -+ if (jj_3R_30()) return true; - return false; - } - - private boolean jj_3R_20() { -- if (jj_scan_token(DECIMAL_LITERAL)) -- return true; -+ if (jj_scan_token(DECIMAL_LITERAL)) return true; - return false; - } - -- private boolean jj_3R_28() { -- if (jj_3R_30()) -- return true; -+ private boolean jj_3R_42() { -+ if (jj_scan_token(IN)) return true; -+ if (jj_scan_token(29)) return true; -+ if (jj_3R_27()) return true; - Token xsp; - while (true) { - xsp = jjScanpos; -- if (jj_3R_31()) { -+ if (jj_3R_43()) { - jjScanpos = xsp; - break; - } - } -+ if (jj_scan_token(31)) return true; - return false; - } - -- private boolean jj_3R_41() { -- if (jj_scan_token(IN)) -- return true; -- if (jj_scan_token(28)) -- return true; -- if (jj_3R_27()) -- return true; -+ private boolean jj_3R_19() { -+ if (jj_3R_27()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_28() { -+ if (jj_3R_30()) return true; - Token xsp; - while (true) { - xsp = jjScanpos; -- if (jj_3R_42()) { -+ if (jj_3R_31()) { - jjScanpos = xsp; - break; - } - } -- if (jj_scan_token(30)) -- return true; -- return false; -- } -- -- private boolean jj_3R_19() { -- if (jj_3R_27()) -- return true; -- return false; -- } -- -- private boolean jj_3R_29() { -- if (jj_scan_token(AND)) -- return true; -- if (jj_3R_28()) -- return true; - return false; - } - -@@ -737,8 +644,7 @@ public class SelectorParser implements SelectorParserConstants { - jjScanpos = xsp; - if (jj_3R_23()) { - jjScanpos = xsp; -- if (jj_3R_24()) -- return true; -+ if (jj_3R_24()) return true; - } - } - } -@@ -747,35 +653,61 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -+ private boolean jj_3_3() { -+ if (jj_scan_token(NOT)) return true; -+ if (jj_scan_token(BETWEEN)) return true; -+ if (jj_3R_7()) return true; -+ if (jj_scan_token(AND)) return true; -+ if (jj_3R_7()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_41() { -+ if (jj_scan_token(BETWEEN)) return true; -+ if (jj_3R_7()) return true; -+ if (jj_scan_token(AND)) return true; -+ if (jj_3R_7()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_29() { -+ if (jj_scan_token(AND)) return true; -+ if (jj_3R_28()) return true; -+ return false; -+ } -+ - private boolean jj_3_2() { -- if (jj_scan_token(NOT)) -- return true; -- if (jj_scan_token(BETWEEN)) -- return true; -- if (jj_3R_7()) -- return true; -- if (jj_scan_token(AND)) -- return true; -- if (jj_3R_7()) -- return true; -+ if (jj_scan_token(NOT)) return true; -+ if (jj_scan_token(CONTAINS)) return true; -+ if (jj_3R_27()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_15() { -+ if (jj_scan_token(29)) return true; -+ if (jj_3R_18()) return true; -+ if (jj_scan_token(31)) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_14() { -+ if (jj_3R_17()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_13() { -+ if (jj_3R_16()) return true; - return false; - } - - private boolean jj_3R_40() { -- if (jj_scan_token(BETWEEN)) -- return true; -- if (jj_3R_7()) -- return true; -- if (jj_scan_token(AND)) -- return true; -- if (jj_3R_7()) -- return true; -+ if (jj_scan_token(CONTAINS)) return true; -+ if (jj_3R_27()) return true; - return false; - } - - private boolean jj_3R_25() { -- if (jj_3R_28()) -- return true; -+ if (jj_3R_28()) return true; - Token xsp; - while (true) { - xsp = jjScanpos; -@@ -787,77 +719,62 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_39() { -- if (jj_scan_token(27)) -- return true; -- if (jj_3R_7()) -- return true; -+ private boolean jj_3R_17() { -+ if (jj_scan_token(ID)) return true; - return false; - } - -- private boolean jj_3R_15() { -- if (jj_scan_token(28)) -- return true; -- if (jj_3R_18()) -- return true; -- if (jj_scan_token(30)) -- return true; -+ private boolean jj_3R_12() { -+ Token xsp; -+ xsp = jjScanpos; -+ if (jj_3R_13()) { -+ jjScanpos = xsp; -+ if (jj_3R_14()) { -+ jjScanpos = xsp; -+ if (jj_3R_15()) return true; -+ } -+ } - return false; - } - -- private boolean jj_3R_14() { -- if (jj_3R_17()) -- return true; -+ private boolean jj_3R_39() { -+ if (jj_scan_token(28)) return true; -+ if (jj_3R_7()) return true; - return false; - } - - private boolean jj_3R_38() { -- if (jj_scan_token(26)) -- return true; -- if (jj_3R_7()) -- return true; -+ if (jj_scan_token(27)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_13() { -- if (jj_3R_16()) -- return true; -+ private boolean jj_3R_11() { -+ if (jj_3R_12()) return true; - return false; - } - - private boolean jj_3R_26() { -- if (jj_scan_token(OR)) -- return true; -- if (jj_3R_25()) -- return true; -+ if (jj_scan_token(OR)) return true; -+ if (jj_3R_25()) return true; - return false; - } - -- private boolean jj_3R_17() { -- if (jj_scan_token(ID)) -- return true; -+ private boolean jj_3R_37() { -+ if (jj_scan_token(26)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_37() { -- if (jj_scan_token(25)) -- return true; -- if (jj_3R_7()) -- return true; -+ private boolean jj_3_5() { -+ if (jj_scan_token(32)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_12() { -- Token xsp; -- xsp = jjScanpos; -- if (jj_3R_13()) { -- jjScanpos = xsp; -- if (jj_3R_14()) { -- jjScanpos = xsp; -- if (jj_3R_15()) -- return true; -- } -- } -+ private boolean jj_3R_10() { -+ if (jj_scan_token(NOT)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -@@ -878,8 +795,13 @@ public class SelectorParser implements SelectorParserConstants { - jjScanpos = xsp; - if (jj_3R_41()) { - jjScanpos = xsp; -- if (jj_3_3()) -- return true; -+ if (jj_3_3()) { -+ jjScanpos = xsp; -+ if (jj_3R_42()) { -+ jjScanpos = xsp; -+ if (jj_3_4()) return true; -+ } -+ } - } - } - } -@@ -891,22 +813,24 @@ public class SelectorParser implements SelectorParserConstants { - } - - private boolean jj_3R_36() { -- if (jj_scan_token(24)) -- return true; -- if (jj_3R_7()) -- return true; -+ if (jj_scan_token(25)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_11() { -- if (jj_3R_12()) -- return true; -+ private boolean jj_3R_9() { -+ if (jj_scan_token(33)) return true; -+ if (jj_3R_7()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_27() { -+ if (jj_scan_token(STRING_LITERAL)) return true; - return false; - } - - private boolean jj_3R_18() { -- if (jj_3R_25()) -- return true; -+ if (jj_3R_25()) return true; - Token xsp; - while (true) { - xsp = jjScanpos; -@@ -918,55 +842,95 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3_4() { -- if (jj_scan_token(31)) -- return true; -- if (jj_3R_7()) -- return true; -+ private boolean jj_3R_8() { -+ if (jj_scan_token(32)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_10() { -- if (jj_scan_token(NOT)) -- return true; -- if (jj_3R_7()) -- return true; -+ private boolean jj_3R_7() { -+ Token xsp; -+ xsp = jjScanpos; -+ if (jj_3R_8()) { -+ jjScanpos = xsp; -+ if (jj_3R_9()) { -+ jjScanpos = xsp; -+ if (jj_3R_10()) { -+ jjScanpos = xsp; -+ if (jj_3R_11()) return true; -+ } -+ } -+ } - return false; - } - -- private boolean jj_3R_9() { -- if (jj_scan_token(32)) -- return true; -- if (jj_3R_7()) -- return true; -+ private boolean jj_3R_44() { -+ if (jj_scan_token(30)) return true; -+ if (jj_3R_27()) return true; - return false; - } - -- private boolean jj_3R_27() { -- if (jj_scan_token(STRING_LITERAL)) -- return true; -+ private boolean jj_3R_30() { -+ if (jj_3R_7()) return true; -+ Token xsp; -+ while (true) { -+ xsp = jjScanpos; -+ if (jj_3R_32()) { -+ jjScanpos = xsp; -+ break; -+ } -+ } - return false; - } - -- private boolean jj_3R_30() { -- if (jj_3R_7()) -- return true; -+ private boolean jj_3R_24() { -+ if (jj_scan_token(NULL)) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_23() { -+ if (jj_scan_token(FALSE)) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_35() { -+ 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_3R_22() { -+ if (jj_scan_token(TRUE)) 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(29)) return true; -+ if (jj_3R_27()) return true; - Token xsp; - while (true) { - xsp = jjScanpos; -- if (jj_3R_32()) { -+ if (jj_3R_44()) { - jjScanpos = xsp; - break; - } - } -+ if (jj_scan_token(31)) return true; - return false; - } - -- private boolean jj_3R_8() { -- if (jj_scan_token(31)) -- return true; -- if (jj_3R_7()) -- 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_3R_43() { -+ if (jj_scan_token(30)) return true; -+ if (jj_3R_27()) return true; - return false; - } - -@@ -987,7 +951,7 @@ public class SelectorParser implements SelectorParserConstants { - private Token jjScanpos, jjLastpos; - private int jjLa; - private int jjGen; -- final private int[] jjLa1 = new int[13]; -+ final private int[] jjLa1 = new int[14]; - static private int[] jjLa10; - static private int[] jjLa11; - -@@ -997,16 +961,14 @@ public class SelectorParser implements SelectorParserConstants { - } - - private static void jj_la1_init_0() { -- jjLa10 = new int[] { -- 0x400, 0x200, 0xc10000, 0xc00000, 0x10000, 0xf001900, 0x20000000, 0x20000000, 0xf000800, -- 0x1000, 0x1036e100, 0x1036e000, 0x16e000}; -+ jjLa10 = new int[]{0x400, 0x200, 0x1810000, 0x1800000, 0x10000, 0x1e021900, 0x40000000, 0x40000000, 0x1e020000, 0x800, 0x1000, 0x206ce100, 0x206ce000, 0x2ce000,}; - } - - private static void jj_la1_init_1() { -- jjLa11 = new int[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}; -+ jjLa11 = new int[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0,}; - } - -- final private JJCalls[] jj2Rtns = new JJCalls[4]; -+ final private JJCalls[] jj2Rtns = new JJCalls[5]; - private boolean jjRescan = false; - private int jjGc = 0; - -@@ -1030,10 +992,8 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 13; i++) -- jjLa1[i] = -1; -- for (int i = 0; i < jj2Rtns.length; i++) -- jj2Rtns[i] = new JJCalls(); -+ for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - - /** -@@ -1056,10 +1016,8 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 13; i++) -- jjLa1[i] = -1; -- for (int i = 0; i < jj2Rtns.length; i++) -- jj2Rtns[i] = new JJCalls(); -+ for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - - /** -@@ -1071,10 +1029,8 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 13; i++) -- jjLa1[i] = -1; -- for (int i = 0; i < jj2Rtns.length; i++) -- jj2Rtns[i] = new JJCalls(); -+ for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - - /** -@@ -1086,10 +1042,8 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 13; i++) -- jjLa1[i] = -1; -- for (int i = 0; i < jj2Rtns.length; i++) -- jj2Rtns[i] = new JJCalls(); -+ for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - - /** -@@ -1100,10 +1054,8 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 13; i++) -- jjLa1[i] = -1; -- for (int i = 0; i < jj2Rtns.length; i++) -- jj2Rtns[i] = new JJCalls(); -+ for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - - /** -@@ -1114,18 +1066,14 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 13; i++) -- jjLa1[i] = -1; -- for (int i = 0; i < jj2Rtns.length; i++) -- jj2Rtns[i] = new JJCalls(); -+ for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - - private Token jj_consume_token(int kind) throws ParseException { - Token oldToken; -- if ((oldToken = token).next != null) -- token = token.next; -- else -- token = token.next = tokenSource.getNextToken(); -+ if ((oldToken = token).next != null) token = token.next; -+ else token = token.next = tokenSource.getNextToken(); - jjNtk = -1; - if (token.kind == kind) { - jjGen++; -@@ -1134,8 +1082,7 @@ public class SelectorParser implements SelectorParserConstants { - for (int i = 0; i < jj2Rtns.length; i++) { - JJCalls c = jj2Rtns[i]; - while (c != null) { -- if (c.gen < jjGen) -- c.first = null; -+ if (c.gen < jjGen) c.first = null; - c = c.next; - } - } -@@ -1170,24 +1117,20 @@ public class SelectorParser implements SelectorParserConstants { - i++; - tok = tok.next; - } -- if (tok != null) -- jj_add_error_token(kind, i); -+ if (tok != null) jj_add_error_token(kind, i); - } -- if (jjScanpos.kind != kind) -- return true; -- if (jjLa == 0 && jjScanpos == jjLastpos) -- throw jjLs; -+ if (jjScanpos.kind != kind) return true; -+ if (jjLa == 0 && jjScanpos == jjLastpos) throw jjLs; - return false; - } - -+ - /** - * Get the next Token. - */ - final public Token getNextToken() { -- if (token.next != null) -- token = token.next; -- else -- token = token.next = tokenSource.getNextToken(); -+ if (token.next != null) token = token.next; -+ else token = token.next = tokenSource.getNextToken(); - jjNtk = -1; - jjGen++; - return token; -@@ -1199,10 +1142,8 @@ public class SelectorParser implements SelectorParserConstants { - final public Token getToken(int index) { - Token t = token; - for (int i = 0; i < index; i++) { -- if (t.next != null) -- t = t.next; -- else -- t = t.next = tokenSource.getNextToken(); -+ if (t.next != null) t = t.next; -+ else t = t.next = tokenSource.getNextToken(); - } - return t; - } -@@ -1221,8 +1162,7 @@ public class SelectorParser implements SelectorParserConstants { - private int jjEndpos; - - private void jj_add_error_token(int kind, int pos) { -- if (pos >= 100) -- return; -+ if (pos >= 100) return; - if (pos == jjEndpos + 1) { - jjLasttokens[jjEndpos++] = kind; - } else if (jjEndpos != 0) { -@@ -1243,8 +1183,7 @@ public class SelectorParser implements SelectorParserConstants { - break jj_entries_loop; - } - } -- if (pos != 0) -- jjLasttokens[(jjEndpos = pos) - 1] = kind; -+ if (pos != 0) jjLasttokens[(jjEndpos = pos) - 1] = kind; - } - } - -@@ -1253,12 +1192,12 @@ public class SelectorParser implements SelectorParserConstants { - */ - public ParseException generateParseException() { - jjExpentries.clear(); -- boolean[] la1tokens = new boolean[33]; -+ boolean[] la1tokens = new boolean[34]; - if (jjKind >= 0) { - la1tokens[jjKind] = true; - jjKind = -1; - } -- for (int i = 0; i < 13; i++) { -+ for (int i = 0; i < 14; i++) { - if (jjLa1[i] == jjGen) { - for (int j = 0; j < 32; j++) { - if ((jjLa10[i] & (1 << j)) != 0) { -@@ -1270,7 +1209,7 @@ public class SelectorParser implements SelectorParserConstants { - } - } - } -- for (int i = 0; i < 33; i++) { -+ for (int i = 0; i < 34; i++) { - if (la1tokens[i]) { - jjExpentry = new int[1]; - jjExpentry[0] = i; -@@ -1301,7 +1240,7 @@ public class SelectorParser implements SelectorParserConstants { - - private void jj_rescan_token() { - jjRescan = true; -- for (int i = 0; i < 4; i++) { -+ for (int i = 0; i < 5; i++) { - try { - JJCalls p = jj2Rtns[i]; - do { -@@ -1321,11 +1260,13 @@ public class SelectorParser implements SelectorParserConstants { - case 3: - jj_3_4(); - break; -+ case 4: -+ jj_3_5(); -+ break; - } - } - p = p.next; -- } -- while (p != null); -+ } while (p != null); - } catch (LookaheadSuccess ls) { - } - } -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java -index 915658ca6..8f849cb51 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java -@@ -75,23 +75,27 @@ public interface SelectorParserConstants { - /** - * RegularExpression Id. - */ -- int DECIMAL_LITERAL = 17; -+ int CONTAINS = 17; - /** - * RegularExpression Id. - */ -- int FLOATING_POINT_LITERAL = 18; -+ int DECIMAL_LITERAL = 18; - /** - * RegularExpression Id. - */ -- int EXPONENT = 19; -+ int FLOATING_POINT_LITERAL = 19; - /** - * RegularExpression Id. - */ -- int STRING_LITERAL = 20; -+ int EXPONENT = 20; - /** - * RegularExpression Id. - */ -- int ID = 21; -+ int STRING_LITERAL = 21; -+ /** -+ * RegularExpression Id. -+ */ -+ int ID = 22; - - /** - * Lexical state. -@@ -119,6 +123,7 @@ public interface SelectorParserConstants { - "\"FALSE\"", - "\"NULL\"", - "\"IS\"", -+ "\"CONTAINS\"", - "", - "", - "", -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java -index b5bac9824..9d42eea71 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java -@@ -59,33 +59,35 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedKind = 1; - return jjMoveNfa_0(5, 0); - case 40: -- jjmatchedKind = 28; -+ jjmatchedKind = 29; - return jjMoveNfa_0(5, 0); - case 41: -- jjmatchedKind = 30; -+ jjmatchedKind = 31; - return jjMoveNfa_0(5, 0); - case 43: -- jjmatchedKind = 31; -+ jjmatchedKind = 32; - return jjMoveNfa_0(5, 0); - case 44: -- jjmatchedKind = 29; -+ jjmatchedKind = 30; - return jjMoveNfa_0(5, 0); - case 45: -- jjmatchedKind = 32; -+ jjmatchedKind = 33; - return jjMoveNfa_0(5, 0); - case 60: -- jjmatchedKind = 26; -- return jjMoveStringLiteralDfa1_0(0x8800000L); -+ jjmatchedKind = 27; -+ return jjMoveStringLiteralDfa1_0(0x11000000L); - case 61: -- jjmatchedKind = 22; -+ jjmatchedKind = 23; - return jjMoveNfa_0(5, 0); - case 62: -- jjmatchedKind = 24; -- return jjMoveStringLiteralDfa1_0(0x2000000L); -+ jjmatchedKind = 25; -+ return jjMoveStringLiteralDfa1_0(0x4000000L); - case 65: - return jjMoveStringLiteralDfa1_0(0x200L); - case 66: - return jjMoveStringLiteralDfa1_0(0x800L); -+ case 67: -+ return jjMoveStringLiteralDfa1_0(0x20000L); - case 70: - return jjMoveStringLiteralDfa1_0(0x4000L); - case 73: -@@ -100,6 +102,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveStringLiteralDfa1_0(0x200L); - case 98: - return jjMoveStringLiteralDfa1_0(0x800L); -+ case 99: -+ return jjMoveStringLiteralDfa1_0(0x20000L); - case 102: - return jjMoveStringLiteralDfa1_0(0x4000L); - case 105: -@@ -123,17 +127,17 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - } - switch (curChar) { - case 61: -- if ((active0 & 0x2000000L) != 0L) { -- jjmatchedKind = 25; -+ if ((active0 & 0x4000000L) != 0L) { -+ jjmatchedKind = 26; - jjmatchedPos = 1; -- } else if ((active0 & 0x8000000L) != 0L) { -- jjmatchedKind = 27; -+ } else if ((active0 & 0x10000000L) != 0L) { -+ jjmatchedKind = 28; - jjmatchedPos = 1; - } - break; - case 62: -- if ((active0 & 0x800000L) != 0L) { -- jjmatchedKind = 23; -+ if ((active0 & 0x1000000L) != 0L) { -+ jjmatchedKind = 24; - jjmatchedPos = 1; - } - break; -@@ -148,7 +152,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - } - return jjMoveStringLiteralDfa2_0(active0, 0x200L); - case 79: -- return jjMoveStringLiteralDfa2_0(active0, 0x100L); -+ return jjMoveStringLiteralDfa2_0(active0, 0x20100L); - case 82: - if ((active0 & 0x400L) != 0L) { - jjmatchedKind = 10; -@@ -174,7 +178,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - } - return jjMoveStringLiteralDfa2_0(active0, 0x200L); - case 111: -- return jjMoveStringLiteralDfa2_0(active0, 0x100L); -+ return jjMoveStringLiteralDfa2_0(active0, 0x20100L); - case 114: - if ((active0 & 0x400L) != 0L) { - jjmatchedKind = 10; -@@ -212,6 +216,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - break; - case 76: - return jjMoveStringLiteralDfa3_0(active0, 0xc000L); -+ case 78: -+ return jjMoveStringLiteralDfa3_0(active0, 0x20000L); - case 84: - if ((active0 & 0x100L) != 0L) { - jjmatchedKind = 8; -@@ -228,6 +234,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - break; - case 108: - return jjMoveStringLiteralDfa3_0(active0, 0xc000L); -+ case 110: -+ return jjMoveStringLiteralDfa3_0(active0, 0x20000L); - case 116: - if ((active0 & 0x100L) != 0L) { - jjmatchedKind = 8; -@@ -265,6 +273,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - break; - case 83: - return jjMoveStringLiteralDfa4_0(active0, 0x4000L); -+ case 84: -+ return jjMoveStringLiteralDfa4_0(active0, 0x20000L); - case 87: - return jjMoveStringLiteralDfa4_0(active0, 0x800L); - case 101: -@@ -281,6 +291,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - break; - case 115: - return jjMoveStringLiteralDfa4_0(active0, 0x4000L); -+ case 116: -+ return jjMoveStringLiteralDfa4_0(active0, 0x20000L); - case 119: - return jjMoveStringLiteralDfa4_0(active0, 0x800L); - default: -@@ -298,12 +310,16 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveNfa_0(5, 3); - } - switch (curChar) { -+ case 65: -+ return jjMoveStringLiteralDfa5_0(active0, 0x20000L); - case 69: - if ((active0 & 0x4000L) != 0L) { - jjmatchedKind = 14; - jjmatchedPos = 4; - } - return jjMoveStringLiteralDfa5_0(active0, 0x800L); -+ case 97: -+ return jjMoveStringLiteralDfa5_0(active0, 0x20000L); - case 101: - if ((active0 & 0x4000L) != 0L) { - jjmatchedKind = 14; -@@ -327,8 +343,12 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - switch (curChar) { - case 69: - return jjMoveStringLiteralDfa6_0(active0, 0x800L); -+ case 73: -+ return jjMoveStringLiteralDfa6_0(active0, 0x20000L); - case 101: - return jjMoveStringLiteralDfa6_0(active0, 0x800L); -+ case 105: -+ return jjMoveStringLiteralDfa6_0(active0, 0x20000L); - default: - break; - } -@@ -349,19 +369,46 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedKind = 11; - jjmatchedPos = 6; - } -- break; -+ return jjMoveStringLiteralDfa7_0(active0, 0x20000L); - case 110: - if ((active0 & 0x800L) != 0L) { - jjmatchedKind = 11; - jjmatchedPos = 6; - } -- break; -+ return jjMoveStringLiteralDfa7_0(active0, 0x20000L); - default: - break; - } - return jjMoveNfa_0(5, 6); - } - -+ private int jjMoveStringLiteralDfa7_0(long old0, long active0) { -+ if (((active0 &= old0)) == 0L) -+ return jjMoveNfa_0(5, 6); -+ try { -+ curChar = inputStream.readChar(); -+ } catch (java.io.IOException e) { -+ return jjMoveNfa_0(5, 6); -+ } -+ switch (curChar) { -+ case 83: -+ if ((active0 & 0x20000L) != 0L) { -+ jjmatchedKind = 17; -+ jjmatchedPos = 7; -+ } -+ break; -+ case 115: -+ if ((active0 & 0x20000L) != 0L) { -+ jjmatchedKind = 17; -+ jjmatchedPos = 7; -+ } -+ break; -+ default: -+ break; -+ } -+ return jjMoveNfa_0(5, 7); -+ } -+ - static final long[] JJ_BIT_VEC_0 = { - 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL - }; -@@ -396,8 +443,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddStates(0, 3); - else if (curChar == 36) { -- if (kind > 21) -- kind = 21; -+ if (kind > 22) -+ kind = 22; - jjCheckNAdd(28); - } else if (curChar == 39) - jjCheckNAddStates(4, 6); -@@ -408,12 +455,12 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - else if (curChar == 45) - jjstateSet[jjnewStateCnt++] = 0; - if ((0x3fe000000000000L & l) != 0L) { -- if (kind > 17) -- kind = 17; -+ if (kind > 18) -+ kind = 18; - jjCheckNAddTwoStates(15, 16); - } else if (curChar == 48) { -- if (kind > 17) -- kind = 17; -+ if (kind > 18) -+ kind = 18; - } - break; - case 0: -@@ -465,21 +512,21 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjstateSet[jjnewStateCnt++] = 6; - break; - case 13: -- if (curChar == 48 && kind > 17) -- kind = 17; -+ if (curChar == 48 && kind > 18) -+ kind = 18; - break; - case 14: - if ((0x3fe000000000000L & l) == 0L) - break; -- if (kind > 17) -- kind = 17; -+ if (kind > 18) -+ kind = 18; - jjCheckNAddTwoStates(15, 16); - break; - case 15: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 17) -- kind = 17; -+ if (kind > 18) -+ kind = 18; - jjCheckNAddTwoStates(15, 16); - break; - case 17: -@@ -489,8 +536,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 18: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 19) -+ kind = 19; - jjCheckNAddTwoStates(18, 19); - break; - case 20: -@@ -500,8 +547,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 21: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 19) -+ kind = 19; - jjCheckNAdd(21); - break; - case 22: -@@ -518,21 +565,21 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjCheckNAddStates(4, 6); - break; - case 26: -- if (curChar == 39 && kind > 20) -- kind = 20; -+ if (curChar == 39 && kind > 21) -+ kind = 21; - break; - case 27: - if (curChar != 36) - break; -- if (kind > 21) -- kind = 21; -+ if (kind > 22) -+ kind = 22; - jjCheckNAdd(28); - break; - case 28: - if ((0x3ff001000000000L & l) == 0L) - break; -- if (kind > 21) -- kind = 21; -+ if (kind > 22) -+ kind = 22; - jjCheckNAdd(28); - break; - case 29: -@@ -546,15 +593,15 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 31: - if (curChar != 46) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 19) -+ kind = 19; - jjCheckNAddTwoStates(32, 33); - break; - case 32: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 19) -+ kind = 19; - jjCheckNAddTwoStates(32, 33); - break; - case 34: -@@ -564,8 +611,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 35: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 19) -+ kind = 19; - jjCheckNAdd(35); - break; - case 36: -@@ -579,15 +626,14 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 39: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 19) -+ kind = 19; - jjCheckNAdd(39); - break; - default: - break; - } -- } -- while (i != startsAt); -+ } while (i != startsAt); - } else if (curChar < 128) { - long l = 1L << (curChar & 077); - do { -@@ -596,8 +642,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 28: - if ((0x7fffffe87fffffeL & l) == 0L) - break; -- if (kind > 21) -- kind = 21; -+ if (kind > 22) -+ kind = 22; - jjCheckNAdd(28); - break; - case 1: -@@ -611,8 +657,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjCheckNAddTwoStates(10, 8); - break; - case 16: -- if ((0x100000001000L & l) != 0L && kind > 17) -- kind = 17; -+ if ((0x100000001000L & l) != 0L && kind > 18) -+ kind = 18; - break; - case 19: - if ((0x2000000020L & l) != 0L) -@@ -632,8 +678,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - default: - break; - } -- } -- while (i != startsAt); -+ } while (i != startsAt); - } else { - int hiByte = (int) (curChar >> 8); - int i1 = hiByte >> 6; -@@ -662,8 +707,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - default: - break; - } -- } -- while (i != startsAt); -+ } while (i != startsAt); - } - if (kind != 0x7fffffff) { - jjmatchedKind = kind; -@@ -722,8 +766,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - */ - public static final String[] JJ_STR_LITERAL_IMAGES = { - "", null, null, null, null, null, null, null, null, null, null, null, null, -- null, null, null, null, null, null, null, null, null, "\75", "\74\76", "\76", -- "\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55"}; -+ null, null, null, null, null, null, null, null, null, null, "\75", "\74\76", "\76", -+ "\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55",}; - - /** - * Lexer state names. -@@ -732,7 +776,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - "DEFAULT", - }; - static final long[] JJ_TO_TOKEN = { -- 0x1fff7ff01L, -+ 0x3ffefff01L, - }; - static final long[] JJ_TO_SKIP = { - 0xfeL, -@@ -905,8 +949,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - private void jjAddStates(int start, int end) { - do { - jjstateSet[jjnewStateCnt++] = JJ_NEXT_STATES[start]; -- } -- while (start++ != end); -+ } while (start++ != end); - } - - private void jjCheckNAddTwoStates(int state1, int state2) { -@@ -917,8 +960,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - private void jjCheckNAddStates(int start, int end) { - do { - jjCheckNAdd(JJ_NEXT_STATES[start]); -- } -- while (start++ != end); -+ } while (start++ != end); - } - - } -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java -index 42626f0f2..b8e375e51 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java -@@ -501,4 +501,4 @@ public class SimpleCharStream { - } - - } --/* JavaCC - OriginalChecksum=af79bfe4b18b4b4ea9720ffeb7e52fc5 (do not edit this line) */ -+/* JavaCC - OriginalChecksum=ea3493f692d4975c1ad70c4a750107d3 (do not edit this line) */ -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java -index 8e6a48a08..edb788008 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java -@@ -149,4 +149,4 @@ public class Token implements java.io.Serializable { - } - - } --/* JavaCC - OriginalChecksum=6b0af88eb45a551d929d3cdd9582f827 (do not edit this line) */ -+/* JavaCC - OriginalChecksum=20094f1ccfbf423c6d9e770d6a7a0188 (do not edit this line) */ -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java -index 0aeb27cf4..4a8f2c86a 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java -@@ -172,4 +172,4 @@ public class TokenMgrError extends Error { - this(LexicalError(eofSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); - } - } --/* JavaCC - OriginalChecksum=e960778c8dcd73e167ed5bfddd59f288 (do not edit this line) */ -+/* JavaCC - OriginalChecksum=de79709675790dcbad2e0d728aa630d1 (do not edit this line) */ diff --git a/data/prod_diff/apache_rocketmq-6915.diff b/data/prod_diff/apache_rocketmq-6915.diff deleted file mode 100644 index 2f686e9d..00000000 --- a/data/prod_diff/apache_rocketmq-6915.diff +++ /dev/null @@ -1,1731 +0,0 @@ -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java b/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java -index ff9d84af0..14fd7045b 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/expression/ComparisonExpression.java -@@ -153,6 +153,174 @@ public abstract class ComparisonExpression extends BinaryExpression implements B - return new NotContainsExpression(left, search); - } - -+ static class StartsWithExpression extends UnaryExpression implements BooleanExpression { -+ -+ String search; -+ -+ public StartsWithExpression(Expression right, String search) { -+ super(right); -+ this.search = search; -+ } -+ -+ public String getExpressionSymbol() { -+ return "STARTSWITH"; -+ } -+ -+ public Object evaluate(EvaluationContext message) throws Exception { -+ -+ if (search == null || search.length() == 0) { -+ return Boolean.FALSE; -+ } -+ -+ Object rv = this.getRight().evaluate(message); -+ -+ if (rv == null) { -+ return Boolean.FALSE; -+ } -+ -+ if (!(rv instanceof String)) { -+ return Boolean.FALSE; -+ } -+ -+ return ((String)rv).startsWith(search) ? Boolean.TRUE : Boolean.FALSE; -+ } -+ -+ public boolean matches(EvaluationContext message) throws Exception { -+ Object object = evaluate(message); -+ return object != null && object == Boolean.TRUE; -+ } -+ } -+ -+ static class NotStartsWithExpression extends UnaryExpression implements BooleanExpression { -+ -+ String search; -+ -+ public NotStartsWithExpression(Expression right, String search) { -+ super(right); -+ this.search = search; -+ } -+ -+ public String getExpressionSymbol() { -+ return "NOT STARTSWITH"; -+ } -+ -+ public Object evaluate(EvaluationContext message) throws Exception { -+ -+ if (search == null || search.length() == 0) { -+ return Boolean.FALSE; -+ } -+ -+ Object rv = this.getRight().evaluate(message); -+ -+ if (rv == null) { -+ return Boolean.FALSE; -+ } -+ -+ if (!(rv instanceof String)) { -+ return Boolean.FALSE; -+ } -+ -+ return ((String)rv).startsWith(search) ? Boolean.FALSE : Boolean.TRUE; -+ } -+ -+ public boolean matches(EvaluationContext message) throws Exception { -+ Object object = evaluate(message); -+ return object != null && object == Boolean.TRUE; -+ } -+ } -+ -+ public static BooleanExpression createStartsWith(Expression left, String search) { -+ return new StartsWithExpression(left, search); -+ } -+ -+ public static BooleanExpression createNotStartsWith(Expression left, String search) { -+ return new NotStartsWithExpression(left, search); -+ } -+ -+ static class EndsWithExpression extends UnaryExpression implements BooleanExpression { -+ -+ String search; -+ -+ public EndsWithExpression(Expression right, String search) { -+ super(right); -+ this.search = search; -+ } -+ -+ public String getExpressionSymbol() { -+ return "ENDSWITH"; -+ } -+ -+ public Object evaluate(EvaluationContext message) throws Exception { -+ -+ if (search == null || search.length() == 0) { -+ return Boolean.FALSE; -+ } -+ -+ Object rv = this.getRight().evaluate(message); -+ -+ if (rv == null) { -+ return Boolean.FALSE; -+ } -+ -+ if (!(rv instanceof String)) { -+ return Boolean.FALSE; -+ } -+ -+ return ((String)rv).endsWith(search) ? Boolean.TRUE : Boolean.FALSE; -+ } -+ -+ public boolean matches(EvaluationContext message) throws Exception { -+ Object object = evaluate(message); -+ return object != null && object == Boolean.TRUE; -+ } -+ } -+ -+ static class NotEndsWithExpression extends UnaryExpression implements BooleanExpression { -+ -+ String search; -+ -+ public NotEndsWithExpression(Expression right, String search) { -+ super(right); -+ this.search = search; -+ } -+ -+ public String getExpressionSymbol() { -+ return "NOT ENDSWITH"; -+ } -+ -+ public Object evaluate(EvaluationContext message) throws Exception { -+ -+ if (search == null || search.length() == 0) { -+ return Boolean.FALSE; -+ } -+ -+ Object rv = this.getRight().evaluate(message); -+ -+ if (rv == null) { -+ return Boolean.FALSE; -+ } -+ -+ if (!(rv instanceof String)) { -+ return Boolean.FALSE; -+ } -+ -+ return ((String)rv).endsWith(search) ? Boolean.FALSE : Boolean.TRUE; -+ } -+ -+ public boolean matches(EvaluationContext message) throws Exception { -+ Object object = evaluate(message); -+ return object != null && object == Boolean.TRUE; -+ } -+ } -+ -+ public static BooleanExpression createEndsWith(Expression left, String search) { -+ return new EndsWithExpression(left, search); -+ } -+ -+ public static BooleanExpression createNotEndsWith(Expression left, String search) { -+ return new NotEndsWithExpression(left, search); -+ } -+ - @SuppressWarnings({"rawtypes", "unchecked"}) - public static BooleanExpression createInFilter(Expression left, List elements) { - -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java -index d23e6ee97..0aaf2bc01 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParser.java -@@ -173,21 +173,21 @@ public class SelectorParser implements SelectorParserConstants { - while (true) { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { - case IS: -- case 23: -- case 24: -+ case 25: -+ case 26: - break; - default: - jjLa1[2] = jjGen; - break label_3; - } - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 23: -- jj_consume_token(23); -+ case 25: -+ jj_consume_token(25); - right = comparisonExpression(); - left = ComparisonExpression.createEqual(left, right); - break; -- case 24: -- jj_consume_token(24); -+ case 26: -+ jj_consume_token(26); - right = comparisonExpression(); - left = ComparisonExpression.createNotEqual(left, right); - break; -@@ -235,33 +235,35 @@ public class SelectorParser implements SelectorParserConstants { - case BETWEEN: - case IN: - case CONTAINS: -- case 25: -- case 26: -+ case STARTSWITH: -+ case ENDSWITH: - case 27: - case 28: -+ case 29: -+ case 30: - break; - default: - jjLa1[5] = jjGen; - break label_4; - } - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 25: -- jj_consume_token(25); -+ case 27: -+ jj_consume_token(27); - right = unaryExpr(); - left = ComparisonExpression.createGreaterThan(left, right); - break; -- case 26: -- jj_consume_token(26); -+ case 28: -+ jj_consume_token(28); - right = unaryExpr(); - left = ComparisonExpression.createGreaterThanEqual(left, right); - break; -- case 27: -- jj_consume_token(27); -+ case 29: -+ jj_consume_token(29); - right = unaryExpr(); - left = ComparisonExpression.createLessThan(left, right); - break; -- case 28: -- jj_consume_token(28); -+ case 30: -+ jj_consume_token(30); - right = unaryExpr(); - left = ComparisonExpression.createLessThanEqual(left, right); - break; -@@ -279,73 +281,105 @@ public class SelectorParser implements SelectorParserConstants { - left = ComparisonExpression.createNotContains(left, t); - } else { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case BETWEEN: -- jj_consume_token(BETWEEN); -- low = unaryExpr(); -- jj_consume_token(AND); -- high = unaryExpr(); -- left = ComparisonExpression.createBetween(left, low, high); -+ case STARTSWITH: -+ jj_consume_token(STARTSWITH); -+ t = stringLitteral(); -+ left = ComparisonExpression.createStartsWith(left, t); - break; - default: - jjLa1[9] = jjGen; - if (jj_2_3(2)) { - jj_consume_token(NOT); -- jj_consume_token(BETWEEN); -- low = unaryExpr(); -- jj_consume_token(AND); -- high = unaryExpr(); -- left = ComparisonExpression.createNotBetween(left, low, high); -+ jj_consume_token(STARTSWITH); -+ t = stringLitteral(); -+ left = ComparisonExpression.createNotStartsWith(left, t); - } else { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case IN: -- jj_consume_token(IN); -- jj_consume_token(29); -+ case ENDSWITH: -+ jj_consume_token(ENDSWITH); - t = stringLitteral(); -- list = new ArrayList(); -- list.add(t); -- label_5: -- while (true) { -- switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 30: -- break; -- default: -- jjLa1[6] = jjGen; -- break label_5; -- } -- jj_consume_token(30); -- t = stringLitteral(); -- list.add(t); -- } -- jj_consume_token(31); -- left = ComparisonExpression.createInFilter(left, list); -+ left = ComparisonExpression.createEndsWith(left, t); - break; - default: - jjLa1[10] = jjGen; - if (jj_2_4(2)) { - jj_consume_token(NOT); -- jj_consume_token(IN); -- jj_consume_token(29); -+ jj_consume_token(ENDSWITH); - t = stringLitteral(); -- list = new ArrayList(); -- list.add(t); -- label_6: -- while (true) { -- switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 30: -- break; -- default: -- jjLa1[7] = jjGen; -- break label_6; -- } -- jj_consume_token(30); -- t = stringLitteral(); -- list.add(t); -- } -- jj_consume_token(31); -- left = ComparisonExpression.createNotInFilter(left, list); -+ left = ComparisonExpression.createNotEndsWith(left, t); - } else { -- jj_consume_token(-1); -- throw new ParseException(); -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case BETWEEN: -+ jj_consume_token(BETWEEN); -+ low = unaryExpr(); -+ jj_consume_token(AND); -+ high = unaryExpr(); -+ left = ComparisonExpression.createBetween(left, low, high); -+ break; -+ default: -+ jjLa1[11] = jjGen; -+ if (jj_2_5(2)) { -+ jj_consume_token(NOT); -+ jj_consume_token(BETWEEN); -+ low = unaryExpr(); -+ jj_consume_token(AND); -+ high = unaryExpr(); -+ left = ComparisonExpression.createNotBetween(left, low, high); -+ } else { -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case IN: -+ jj_consume_token(IN); -+ jj_consume_token(31); -+ t = stringLitteral(); -+ list = new ArrayList(); -+ list.add(t); -+ label_5: -+ while (true) { -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case 32: -+ break; -+ default: -+ jjLa1[6] = jjGen; -+ break label_5; -+ } -+ jj_consume_token(32); -+ t = stringLitteral(); -+ list.add(t); -+ } -+ jj_consume_token(33); -+ left = ComparisonExpression.createInFilter(left, list); -+ break; -+ default: -+ jjLa1[12] = jjGen; -+ if (jj_2_6(2)) { -+ jj_consume_token(NOT); -+ jj_consume_token(IN); -+ jj_consume_token(31); -+ t = stringLitteral(); -+ list = new ArrayList(); -+ list.add(t); -+ label_6: -+ while (true) { -+ switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -+ case 32: -+ break; -+ default: -+ jjLa1[7] = jjGen; -+ break label_6; -+ } -+ jj_consume_token(32); -+ t = stringLitteral(); -+ list.add(t); -+ } -+ jj_consume_token(33); -+ left = ComparisonExpression.createNotInFilter(left, list); -+ } else { -+ jj_consume_token(-1); -+ throw new ParseException(); -+ } -+ } -+ } -+ } - } - } - } -@@ -362,13 +396,13 @@ public class SelectorParser implements SelectorParserConstants { - final public Expression unaryExpr() throws ParseException { - String s = null; - Expression left = null; -- if (jj_2_5(2147483647)) { -- jj_consume_token(32); -+ if (jj_2_7(2147483647)) { -+ jj_consume_token(34); - left = unaryExpr(); - } else { - switch ((jjNtk == -1) ? jj_ntk() : jjNtk) { -- case 33: -- jj_consume_token(33); -+ case 35: -+ jj_consume_token(35); - left = unaryExpr(); - left = UnaryExpression.createNegate(left); - break; -@@ -384,11 +418,11 @@ public class SelectorParser implements SelectorParserConstants { - case FLOATING_POINT_LITERAL: - case STRING_LITERAL: - case ID: -- case 29: -+ case 31: - left = primaryExpr(); - break; - default: -- jjLa1[11] = jjGen; -+ jjLa1[13] = jjGen; - jj_consume_token(-1); - throw new ParseException(); - } -@@ -413,13 +447,13 @@ public class SelectorParser implements SelectorParserConstants { - case ID: - left = variable(); - break; -- case 29: -- jj_consume_token(29); -- left = orExpression(); -+ case 31: - jj_consume_token(31); -+ left = orExpression(); -+ jj_consume_token(33); - break; - default: -- jjLa1[12] = jjGen; -+ jjLa1[14] = jjGen; - jj_consume_token(-1); - throw new ParseException(); - } -@@ -459,7 +493,7 @@ public class SelectorParser implements SelectorParserConstants { - left = BooleanConstantExpression.NULL; - break; - default: -- jjLa1[13] = jjGen; -+ jjLa1[15] = jjGen; - jj_consume_token(-1); - throw new ParseException(); - } -@@ -478,7 +512,7 @@ public class SelectorParser implements SelectorParserConstants { - String image = t.image; - for (int i = 1; i < image.length() - 1; i++) { - char c = image.charAt(i); -- if (c == '\'') -+ if (c == '\u005c'') - i++; - rc.append(c); - } -@@ -559,17 +593,44 @@ public class SelectorParser implements SelectorParserConstants { - } - } - -- private boolean jj_3R_21() { -- if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; -- return false; -+ private boolean jj_2_6(int xla) { -+ jjLa = xla; -+ jjLastpos = jjScanpos = token; -+ try { -+ return !jj_3_6(); -+ } catch (LookaheadSuccess ls) { -+ return true; -+ } finally { -+ jj_save(5, xla); -+ } -+ } -+ -+ private boolean jj_2_7(int xla) { -+ jjLa = xla; -+ jjLastpos = jjScanpos = token; -+ try { -+ return !jj_3_7(); -+ } catch (LookaheadSuccess ls) { -+ return true; -+ } finally { -+ jj_save(6, xla); -+ } - } - - private boolean jj_3R_34() { -- if (jj_scan_token(24)) return true; -+ if (jj_scan_token(26)) return true; - if (jj_3R_30()) return true; - return false; - } - -+ private boolean jj_3R_43() { -+ if (jj_scan_token(BETWEEN)) return true; -+ if (jj_3R_7()) return true; -+ if (jj_scan_token(AND)) return true; -+ if (jj_3R_7()) return true; -+ return false; -+ } -+ - private boolean jj_3R_31() { - Token xsp; - xsp = jjScanpos; -@@ -587,67 +648,67 @@ public class SelectorParser implements SelectorParserConstants { - } - - private boolean jj_3R_33() { -- if (jj_scan_token(23)) return true; -+ if (jj_scan_token(25)) return true; - if (jj_3R_30()) return true; - return false; - } - -- private boolean jj_3R_20() { -- if (jj_scan_token(DECIMAL_LITERAL)) return true; -+ private boolean jj_3_4() { -+ if (jj_scan_token(NOT)) return true; -+ if (jj_scan_token(ENDSWITH)) return true; -+ if (jj_3R_27()) return true; - return false; - } - -- private boolean jj_3R_42() { -- if (jj_scan_token(IN)) return true; -- if (jj_scan_token(29)) return true; -- if (jj_3R_27()) return true; -- Token xsp; -- while (true) { -- xsp = jjScanpos; -- if (jj_3R_43()) { -- jjScanpos = xsp; -- break; -- } -- } -+ private boolean jj_3R_15() { - if (jj_scan_token(31)) return true; -+ if (jj_3R_18()) return true; -+ if (jj_scan_token(33)) return true; - return false; - } - -- private boolean jj_3R_19() { -+ private boolean jj_3R_14() { -+ if (jj_3R_17()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_13() { -+ if (jj_3R_16()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_42() { -+ if (jj_scan_token(ENDSWITH)) return true; - if (jj_3R_27()) return true; - return false; - } - -- private boolean jj_3R_28() { -- if (jj_3R_30()) return true; -+ private boolean jj_3R_17() { -+ if (jj_scan_token(ID)) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_12() { - Token xsp; -- while (true) { -- xsp = jjScanpos; -- if (jj_3R_31()) { -+ xsp = jjScanpos; -+ if (jj_3R_13()) { -+ jjScanpos = xsp; -+ if (jj_3R_14()) { - jjScanpos = xsp; -- break; -+ if (jj_3R_15()) return true; - } - } - return false; - } - -- private boolean jj_3R_16() { -+ private boolean jj_3R_28() { -+ if (jj_3R_30()) return true; - Token xsp; -- xsp = jjScanpos; -- if (jj_3R_19()) { -- jjScanpos = xsp; -- if (jj_3R_20()) { -+ while (true) { -+ xsp = jjScanpos; -+ if (jj_3R_31()) { - jjScanpos = xsp; -- if (jj_3R_21()) { -- jjScanpos = xsp; -- if (jj_3R_22()) { -- jjScanpos = xsp; -- if (jj_3R_23()) { -- jjScanpos = xsp; -- if (jj_3R_24()) return true; -- } -- } -- } -+ break; - } - } - return false; -@@ -655,18 +716,19 @@ public class SelectorParser implements SelectorParserConstants { - - private boolean jj_3_3() { - if (jj_scan_token(NOT)) return true; -- if (jj_scan_token(BETWEEN)) return true; -- if (jj_3R_7()) return true; -- if (jj_scan_token(AND)) return true; -- if (jj_3R_7()) return true; -+ if (jj_scan_token(STARTSWITH)) return true; -+ if (jj_3R_27()) return true; - return false; - } - - private boolean jj_3R_41() { -- if (jj_scan_token(BETWEEN)) return true; -- if (jj_3R_7()) return true; -- if (jj_scan_token(AND)) return true; -- if (jj_3R_7()) return true; -+ if (jj_scan_token(STARTSWITH)) return true; -+ if (jj_3R_27()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_11() { -+ if (jj_3R_12()) return true; - return false; - } - -@@ -676,6 +738,12 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -+ private boolean jj_3_7() { -+ if (jj_scan_token(34)) return true; -+ if (jj_3R_7()) return true; -+ return false; -+ } -+ - private boolean jj_3_2() { - if (jj_scan_token(NOT)) return true; - if (jj_scan_token(CONTAINS)) return true; -@@ -683,26 +751,26 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_15() { -- if (jj_scan_token(29)) return true; -- if (jj_3R_18()) return true; -- if (jj_scan_token(31)) return true; -+ private boolean jj_3R_10() { -+ if (jj_scan_token(NOT)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_14() { -- if (jj_3R_17()) return true; -+ private boolean jj_3R_40() { -+ if (jj_scan_token(CONTAINS)) return true; -+ if (jj_3R_27()) return true; - return false; - } - -- private boolean jj_3R_13() { -- if (jj_3R_16()) return true; -+ private boolean jj_3R_9() { -+ if (jj_scan_token(35)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_40() { -- if (jj_scan_token(CONTAINS)) return true; -- if (jj_3R_27()) return true; -+ private boolean jj_3R_27() { -+ if (jj_scan_token(STRING_LITERAL)) return true; - return false; - } - -@@ -719,38 +787,43 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_17() { -- if (jj_scan_token(ID)) return true; -+ private boolean jj_3R_8() { -+ if (jj_scan_token(34)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_12() { -+ private boolean jj_3R_39() { -+ if (jj_scan_token(30)) return true; -+ if (jj_3R_7()) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_7() { - Token xsp; - xsp = jjScanpos; -- if (jj_3R_13()) { -+ if (jj_3R_8()) { - jjScanpos = xsp; -- if (jj_3R_14()) { -+ if (jj_3R_9()) { - jjScanpos = xsp; -- if (jj_3R_15()) return true; -+ if (jj_3R_10()) { -+ jjScanpos = xsp; -+ if (jj_3R_11()) return true; -+ } - } - } - return false; - } - -- private boolean jj_3R_39() { -- if (jj_scan_token(28)) return true; -- if (jj_3R_7()) return true; -- return false; -- } -- - private boolean jj_3R_38() { -- if (jj_scan_token(27)) return true; -+ if (jj_scan_token(29)) return true; - if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3R_11() { -- if (jj_3R_12()) return true; -+ private boolean jj_3R_46() { -+ if (jj_scan_token(32)) return true; -+ if (jj_3R_27()) return true; - return false; - } - -@@ -761,19 +834,18 @@ public class SelectorParser implements SelectorParserConstants { - } - - private boolean jj_3R_37() { -- if (jj_scan_token(26)) return true; -+ if (jj_scan_token(28)) return true; - if (jj_3R_7()) return true; - return false; - } - -- private boolean jj_3_5() { -- if (jj_scan_token(32)) return true; -- if (jj_3R_7()) return true; -+ private boolean jj_3R_24() { -+ if (jj_scan_token(NULL)) return true; - return false; - } - -- private boolean jj_3R_10() { -- if (jj_scan_token(NOT)) return true; -+ private boolean jj_3R_36() { -+ if (jj_scan_token(27)) return true; - if (jj_3R_7()) return true; - return false; - } -@@ -799,7 +871,19 @@ public class SelectorParser implements SelectorParserConstants { - jjScanpos = xsp; - if (jj_3R_42()) { - jjScanpos = xsp; -- if (jj_3_4()) return true; -+ if (jj_3_4()) { -+ jjScanpos = xsp; -+ if (jj_3R_43()) { -+ jjScanpos = xsp; -+ if (jj_3_5()) { -+ jjScanpos = xsp; -+ if (jj_3R_44()) { -+ jjScanpos = xsp; -+ if (jj_3_6()) return true; -+ } -+ } -+ } -+ } - } - } - } -@@ -812,20 +896,8 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_36() { -- if (jj_scan_token(25)) return true; -- if (jj_3R_7()) return true; -- return false; -- } -- -- private boolean jj_3R_9() { -- if (jj_scan_token(33)) return true; -- if (jj_3R_7()) return true; -- return false; -- } -- -- private boolean jj_3R_27() { -- if (jj_scan_token(STRING_LITERAL)) return true; -+ private boolean jj_3R_23() { -+ if (jj_scan_token(FALSE)) return true; - return false; - } - -@@ -842,30 +914,30 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_8() { -- if (jj_scan_token(32)) return true; -- if (jj_3R_7()) return true; -+ private boolean jj_3R_22() { -+ if (jj_scan_token(TRUE)) return true; - return false; - } - -- private boolean jj_3R_7() { -+ private boolean jj_3_6() { -+ if (jj_scan_token(NOT)) return true; -+ if (jj_scan_token(IN)) return true; -+ if (jj_scan_token(31)) return true; -+ if (jj_3R_27()) return true; - Token xsp; -- xsp = jjScanpos; -- if (jj_3R_8()) { -- jjScanpos = xsp; -- if (jj_3R_9()) { -+ while (true) { -+ xsp = jjScanpos; -+ if (jj_3R_46()) { - jjScanpos = xsp; -- if (jj_3R_10()) { -- jjScanpos = xsp; -- if (jj_3R_11()) return true; -- } -+ break; - } - } -+ if (jj_scan_token(33)) return true; - return false; - } - -- private boolean jj_3R_44() { -- if (jj_scan_token(30)) return true; -+ private boolean jj_3R_45() { -+ if (jj_scan_token(32)) return true; - if (jj_3R_27()) return true; - return false; - } -@@ -883,13 +955,13 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_24() { -- if (jj_scan_token(NULL)) return true; -+ private boolean jj_3R_21() { -+ if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; - return false; - } - -- private boolean jj_3R_23() { -- if (jj_scan_token(FALSE)) return true; -+ private boolean jj_3R_20() { -+ if (jj_scan_token(DECIMAL_LITERAL)) return true; - return false; - } - -@@ -900,25 +972,24 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_22() { -- if (jj_scan_token(TRUE)) return true; -- return false; -- } -- -- private boolean jj_3_4() { -- if (jj_scan_token(NOT)) return true; -+ private boolean jj_3R_44() { - if (jj_scan_token(IN)) return true; -- if (jj_scan_token(29)) return true; -+ if (jj_scan_token(31)) return true; - if (jj_3R_27()) return true; - Token xsp; - while (true) { - xsp = jjScanpos; -- if (jj_3R_44()) { -+ if (jj_3R_45()) { - jjScanpos = xsp; - break; - } - } -- if (jj_scan_token(31)) return true; -+ if (jj_scan_token(33)) return true; -+ return false; -+ } -+ -+ private boolean jj_3R_19() { -+ if (jj_3R_27()) return true; - return false; - } - -@@ -928,9 +999,34 @@ public class SelectorParser implements SelectorParserConstants { - return false; - } - -- private boolean jj_3R_43() { -- if (jj_scan_token(30)) return true; -- if (jj_3R_27()) return true; -+ private boolean jj_3R_16() { -+ Token xsp; -+ xsp = jjScanpos; -+ if (jj_3R_19()) { -+ jjScanpos = xsp; -+ if (jj_3R_20()) { -+ jjScanpos = xsp; -+ if (jj_3R_21()) { -+ jjScanpos = xsp; -+ if (jj_3R_22()) { -+ jjScanpos = xsp; -+ if (jj_3R_23()) { -+ jjScanpos = xsp; -+ if (jj_3R_24()) return true; -+ } -+ } -+ } -+ } -+ } -+ return false; -+ } -+ -+ private boolean jj_3_5() { -+ if (jj_scan_token(NOT)) return true; -+ if (jj_scan_token(BETWEEN)) return true; -+ if (jj_3R_7()) return true; -+ if (jj_scan_token(AND)) return true; -+ if (jj_3R_7()) return true; - return false; - } - -@@ -951,7 +1047,7 @@ public class SelectorParser implements SelectorParserConstants { - private Token jjScanpos, jjLastpos; - private int jjLa; - private int jjGen; -- final private int[] jjLa1 = new int[14]; -+ final private int[] jjLa1 = new int[16]; - static private int[] jjLa10; - static private int[] jjLa11; - -@@ -961,14 +1057,14 @@ public class SelectorParser implements SelectorParserConstants { - } - - private static void jj_la1_init_0() { -- jjLa10 = new int[]{0x400, 0x200, 0x1810000, 0x1800000, 0x10000, 0x1e021900, 0x40000000, 0x40000000, 0x1e020000, 0x800, 0x1000, 0x206ce100, 0x206ce000, 0x2ce000,}; -+ jjLa10 = new int[]{0x400, 0x200, 0x6010000, 0x6000000, 0x10000, 0x780e1900, 0x0, 0x0, 0x78020000, 0x40000, 0x80000, 0x800, 0x1000, 0x81b0e100, 0x81b0e000, 0xb0e000,}; - } - - private static void jj_la1_init_1() { -- jjLa11 = new int[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0,}; -+ jjLa11 = new int[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0,}; - } - -- final private JJCalls[] jj2Rtns = new JJCalls[5]; -+ final private JJCalls[] jj2Rtns = new JJCalls[7]; - private boolean jjRescan = false; - private int jjGc = 0; - -@@ -992,7 +1088,7 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < 16; i++) jjLa1[i] = -1; - for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - -@@ -1016,7 +1112,7 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < 16; i++) jjLa1[i] = -1; - for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - -@@ -1029,7 +1125,7 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < 16; i++) jjLa1[i] = -1; - for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - -@@ -1042,7 +1138,7 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < 16; i++) jjLa1[i] = -1; - for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - -@@ -1054,7 +1150,7 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < 16; i++) jjLa1[i] = -1; - for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - -@@ -1066,7 +1162,7 @@ public class SelectorParser implements SelectorParserConstants { - token = new Token(); - jjNtk = -1; - jjGen = 0; -- for (int i = 0; i < 14; i++) jjLa1[i] = -1; -+ for (int i = 0; i < 16; i++) jjLa1[i] = -1; - for (int i = 0; i < jj2Rtns.length; i++) jj2Rtns[i] = new JJCalls(); - } - -@@ -1170,19 +1266,21 @@ public class SelectorParser implements SelectorParserConstants { - for (int i = 0; i < jjEndpos; i++) { - jjExpentry[i] = jjLasttokens[i]; - } -- jj_entries_loop: -+ boolean exists = false; - for (java.util.Iterator it = jjExpentries.iterator(); it.hasNext(); ) { -+ exists = true; - int[] oldentry = (int[]) (it.next()); - if (oldentry.length == jjExpentry.length) { - for (int i = 0; i < jjExpentry.length; i++) { - if (oldentry[i] != jjExpentry[i]) { -- continue jj_entries_loop; -+ exists = false; -+ break; - } - } -- jjExpentries.add(jjExpentry); -- break jj_entries_loop; -+ if (exists) break; - } - } -+ if (!exists) jjExpentries.add(jjExpentry); - if (pos != 0) jjLasttokens[(jjEndpos = pos) - 1] = kind; - } - } -@@ -1192,12 +1290,12 @@ public class SelectorParser implements SelectorParserConstants { - */ - public ParseException generateParseException() { - jjExpentries.clear(); -- boolean[] la1tokens = new boolean[34]; -+ boolean[] la1tokens = new boolean[36]; - if (jjKind >= 0) { - la1tokens[jjKind] = true; - jjKind = -1; - } -- for (int i = 0; i < 14; i++) { -+ for (int i = 0; i < 16; i++) { - if (jjLa1[i] == jjGen) { - for (int j = 0; j < 32; j++) { - if ((jjLa10[i] & (1 << j)) != 0) { -@@ -1209,7 +1307,7 @@ public class SelectorParser implements SelectorParserConstants { - } - } - } -- for (int i = 0; i < 34; i++) { -+ for (int i = 0; i < 36; i++) { - if (la1tokens[i]) { - jjExpentry = new int[1]; - jjExpentry[0] = i; -@@ -1240,7 +1338,7 @@ public class SelectorParser implements SelectorParserConstants { - - private void jj_rescan_token() { - jjRescan = true; -- for (int i = 0; i < 5; i++) { -+ for (int i = 0; i < 7; i++) { - try { - JJCalls p = jj2Rtns[i]; - do { -@@ -1263,6 +1361,12 @@ public class SelectorParser implements SelectorParserConstants { - case 4: - jj_3_5(); - break; -+ case 5: -+ jj_3_6(); -+ break; -+ case 6: -+ jj_3_7(); -+ break; - } - } - p = p.next; -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java -index 8f849cb51..8f228be8b 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java -@@ -79,23 +79,31 @@ public interface SelectorParserConstants { - /** - * RegularExpression Id. - */ -- int DECIMAL_LITERAL = 18; -+ int STARTSWITH = 18; - /** - * RegularExpression Id. - */ -- int FLOATING_POINT_LITERAL = 19; -+ int ENDSWITH = 19; - /** - * RegularExpression Id. - */ -- int EXPONENT = 20; -+ int DECIMAL_LITERAL = 20; - /** - * RegularExpression Id. - */ -- int STRING_LITERAL = 21; -+ int FLOATING_POINT_LITERAL = 21; - /** - * RegularExpression Id. - */ -- int ID = 22; -+ int EXPONENT = 22; -+ /** -+ * RegularExpression Id. -+ */ -+ int STRING_LITERAL = 23; -+ /** -+ * RegularExpression Id. -+ */ -+ int ID = 24; - - /** - * Lexical state. -@@ -124,6 +132,8 @@ public interface SelectorParserConstants { - "\"NULL\"", - "\"IS\"", - "\"CONTAINS\"", -+ "\"STARTSWITH\"", -+ "\"ENDSWITH\"", - "", - "", - "", -diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java -index 9d42eea71..6d9b85517 100644 ---- a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java -+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java -@@ -59,35 +59,37 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedKind = 1; - return jjMoveNfa_0(5, 0); - case 40: -- jjmatchedKind = 29; -+ jjmatchedKind = 31; - return jjMoveNfa_0(5, 0); - case 41: -- jjmatchedKind = 31; -+ jjmatchedKind = 33; - return jjMoveNfa_0(5, 0); - case 43: -- jjmatchedKind = 32; -+ jjmatchedKind = 34; - return jjMoveNfa_0(5, 0); - case 44: -- jjmatchedKind = 30; -+ jjmatchedKind = 32; - return jjMoveNfa_0(5, 0); - case 45: -- jjmatchedKind = 33; -+ jjmatchedKind = 35; - return jjMoveNfa_0(5, 0); - case 60: -- jjmatchedKind = 27; -- return jjMoveStringLiteralDfa1_0(0x11000000L); -+ jjmatchedKind = 29; -+ return jjMoveStringLiteralDfa1_0(0x44000000L); - case 61: -- jjmatchedKind = 23; -+ jjmatchedKind = 25; - return jjMoveNfa_0(5, 0); - case 62: -- jjmatchedKind = 25; -- return jjMoveStringLiteralDfa1_0(0x4000000L); -+ jjmatchedKind = 27; -+ return jjMoveStringLiteralDfa1_0(0x10000000L); - case 65: - return jjMoveStringLiteralDfa1_0(0x200L); - case 66: - return jjMoveStringLiteralDfa1_0(0x800L); - case 67: - return jjMoveStringLiteralDfa1_0(0x20000L); -+ case 69: -+ return jjMoveStringLiteralDfa1_0(0x80000L); - case 70: - return jjMoveStringLiteralDfa1_0(0x4000L); - case 73: -@@ -96,6 +98,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveStringLiteralDfa1_0(0x8100L); - case 79: - return jjMoveStringLiteralDfa1_0(0x400L); -+ case 83: -+ return jjMoveStringLiteralDfa1_0(0x40000L); - case 84: - return jjMoveStringLiteralDfa1_0(0x2000L); - case 97: -@@ -104,6 +108,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveStringLiteralDfa1_0(0x800L); - case 99: - return jjMoveStringLiteralDfa1_0(0x20000L); -+ case 101: -+ return jjMoveStringLiteralDfa1_0(0x80000L); - case 102: - return jjMoveStringLiteralDfa1_0(0x4000L); - case 105: -@@ -112,6 +118,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveStringLiteralDfa1_0(0x8100L); - case 111: - return jjMoveStringLiteralDfa1_0(0x400L); -+ case 115: -+ return jjMoveStringLiteralDfa1_0(0x40000L); - case 116: - return jjMoveStringLiteralDfa1_0(0x2000L); - default: -@@ -127,17 +135,17 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - } - switch (curChar) { - case 61: -- if ((active0 & 0x4000000L) != 0L) { -- jjmatchedKind = 26; -- jjmatchedPos = 1; -- } else if ((active0 & 0x10000000L) != 0L) { -+ if ((active0 & 0x10000000L) != 0L) { - jjmatchedKind = 28; - jjmatchedPos = 1; -+ } else if ((active0 & 0x40000000L) != 0L) { -+ jjmatchedKind = 30; -+ jjmatchedPos = 1; - } - break; - case 62: -- if ((active0 & 0x1000000L) != 0L) { -- jjmatchedKind = 24; -+ if ((active0 & 0x4000000L) != 0L) { -+ jjmatchedKind = 26; - jjmatchedPos = 1; - } - break; -@@ -150,7 +158,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedKind = 12; - jjmatchedPos = 1; - } -- return jjMoveStringLiteralDfa2_0(active0, 0x200L); -+ return jjMoveStringLiteralDfa2_0(active0, 0x80200L); - case 79: - return jjMoveStringLiteralDfa2_0(active0, 0x20100L); - case 82: -@@ -165,6 +173,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 1; - } - break; -+ case 84: -+ return jjMoveStringLiteralDfa2_0(active0, 0x40000L); - case 85: - return jjMoveStringLiteralDfa2_0(active0, 0x8000L); - case 97: -@@ -176,7 +186,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedKind = 12; - jjmatchedPos = 1; - } -- return jjMoveStringLiteralDfa2_0(active0, 0x200L); -+ return jjMoveStringLiteralDfa2_0(active0, 0x80200L); - case 111: - return jjMoveStringLiteralDfa2_0(active0, 0x20100L); - case 114: -@@ -191,6 +201,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 1; - } - break; -+ case 116: -+ return jjMoveStringLiteralDfa2_0(active0, 0x40000L); - case 117: - return jjMoveStringLiteralDfa2_0(active0, 0x8000L); - default: -@@ -208,12 +220,14 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveNfa_0(5, 1); - } - switch (curChar) { -+ case 65: -+ return jjMoveStringLiteralDfa3_0(active0, 0x40000L); - case 68: - if ((active0 & 0x200L) != 0L) { - jjmatchedKind = 9; - jjmatchedPos = 2; - } -- break; -+ return jjMoveStringLiteralDfa3_0(active0, 0x80000L); - case 76: - return jjMoveStringLiteralDfa3_0(active0, 0xc000L); - case 78: -@@ -226,12 +240,14 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveStringLiteralDfa3_0(active0, 0x800L); - case 85: - return jjMoveStringLiteralDfa3_0(active0, 0x2000L); -+ case 97: -+ return jjMoveStringLiteralDfa3_0(active0, 0x40000L); - case 100: - if ((active0 & 0x200L) != 0L) { - jjmatchedKind = 9; - jjmatchedPos = 2; - } -- break; -+ return jjMoveStringLiteralDfa3_0(active0, 0x80000L); - case 108: - return jjMoveStringLiteralDfa3_0(active0, 0xc000L); - case 110: -@@ -271,8 +287,10 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 3; - } - break; -+ case 82: -+ return jjMoveStringLiteralDfa4_0(active0, 0x40000L); - case 83: -- return jjMoveStringLiteralDfa4_0(active0, 0x4000L); -+ return jjMoveStringLiteralDfa4_0(active0, 0x84000L); - case 84: - return jjMoveStringLiteralDfa4_0(active0, 0x20000L); - case 87: -@@ -289,8 +307,10 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 3; - } - break; -+ case 114: -+ return jjMoveStringLiteralDfa4_0(active0, 0x40000L); - case 115: -- return jjMoveStringLiteralDfa4_0(active0, 0x4000L); -+ return jjMoveStringLiteralDfa4_0(active0, 0x84000L); - case 116: - return jjMoveStringLiteralDfa4_0(active0, 0x20000L); - case 119: -@@ -318,6 +338,10 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 4; - } - return jjMoveStringLiteralDfa5_0(active0, 0x800L); -+ case 84: -+ return jjMoveStringLiteralDfa5_0(active0, 0x40000L); -+ case 87: -+ return jjMoveStringLiteralDfa5_0(active0, 0x80000L); - case 97: - return jjMoveStringLiteralDfa5_0(active0, 0x20000L); - case 101: -@@ -326,6 +350,10 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 4; - } - return jjMoveStringLiteralDfa5_0(active0, 0x800L); -+ case 116: -+ return jjMoveStringLiteralDfa5_0(active0, 0x40000L); -+ case 119: -+ return jjMoveStringLiteralDfa5_0(active0, 0x80000L); - default: - break; - } -@@ -344,11 +372,15 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 69: - return jjMoveStringLiteralDfa6_0(active0, 0x800L); - case 73: -- return jjMoveStringLiteralDfa6_0(active0, 0x20000L); -+ return jjMoveStringLiteralDfa6_0(active0, 0xa0000L); -+ case 83: -+ return jjMoveStringLiteralDfa6_0(active0, 0x40000L); - case 101: - return jjMoveStringLiteralDfa6_0(active0, 0x800L); - case 105: -- return jjMoveStringLiteralDfa6_0(active0, 0x20000L); -+ return jjMoveStringLiteralDfa6_0(active0, 0xa0000L); -+ case 115: -+ return jjMoveStringLiteralDfa6_0(active0, 0x40000L); - default: - break; - } -@@ -370,12 +402,20 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjmatchedPos = 6; - } - return jjMoveStringLiteralDfa7_0(active0, 0x20000L); -+ case 84: -+ return jjMoveStringLiteralDfa7_0(active0, 0x80000L); -+ case 87: -+ return jjMoveStringLiteralDfa7_0(active0, 0x40000L); - case 110: - if ((active0 & 0x800L) != 0L) { - jjmatchedKind = 11; - jjmatchedPos = 6; - } - return jjMoveStringLiteralDfa7_0(active0, 0x20000L); -+ case 116: -+ return jjMoveStringLiteralDfa7_0(active0, 0x80000L); -+ case 119: -+ return jjMoveStringLiteralDfa7_0(active0, 0x40000L); - default: - break; - } -@@ -391,12 +431,28 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveNfa_0(5, 6); - } - switch (curChar) { -+ case 72: -+ if ((active0 & 0x80000L) != 0L) { -+ jjmatchedKind = 19; -+ jjmatchedPos = 7; -+ } -+ break; -+ case 73: -+ return jjMoveStringLiteralDfa8_0(active0, 0x40000L); - case 83: - if ((active0 & 0x20000L) != 0L) { - jjmatchedKind = 17; - jjmatchedPos = 7; - } - break; -+ case 104: -+ if ((active0 & 0x80000L) != 0L) { -+ jjmatchedKind = 19; -+ jjmatchedPos = 7; -+ } -+ break; -+ case 105: -+ return jjMoveStringLiteralDfa8_0(active0, 0x40000L); - case 115: - if ((active0 & 0x20000L) != 0L) { - jjmatchedKind = 17; -@@ -409,6 +465,52 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - return jjMoveNfa_0(5, 7); - } - -+ private int jjMoveStringLiteralDfa8_0(long old0, long active0) { -+ if (((active0 &= old0)) == 0L) -+ return jjMoveNfa_0(5, 7); -+ try { -+ curChar = inputStream.readChar(); -+ } catch (java.io.IOException e) { -+ return jjMoveNfa_0(5, 7); -+ } -+ switch (curChar) { -+ case 84: -+ return jjMoveStringLiteralDfa9_0(active0, 0x40000L); -+ case 116: -+ return jjMoveStringLiteralDfa9_0(active0, 0x40000L); -+ default: -+ break; -+ } -+ return jjMoveNfa_0(5, 8); -+ } -+ -+ private int jjMoveStringLiteralDfa9_0(long old0, long active0) { -+ if (((active0 &= old0)) == 0L) -+ return jjMoveNfa_0(5, 8); -+ try { -+ curChar = inputStream.readChar(); -+ } catch (java.io.IOException e) { -+ return jjMoveNfa_0(5, 8); -+ } -+ switch (curChar) { -+ case 72: -+ if ((active0 & 0x40000L) != 0L) { -+ jjmatchedKind = 18; -+ jjmatchedPos = 9; -+ } -+ break; -+ case 104: -+ if ((active0 & 0x40000L) != 0L) { -+ jjmatchedKind = 18; -+ jjmatchedPos = 9; -+ } -+ break; -+ default: -+ break; -+ } -+ return jjMoveNfa_0(5, 9); -+ } -+ - static final long[] JJ_BIT_VEC_0 = { - 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL - }; -@@ -443,8 +545,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - if ((0x3ff000000000000L & l) != 0L) - jjCheckNAddStates(0, 3); - else if (curChar == 36) { -- if (kind > 22) -- kind = 22; -+ if (kind > 24) -+ kind = 24; - jjCheckNAdd(28); - } else if (curChar == 39) - jjCheckNAddStates(4, 6); -@@ -455,12 +557,12 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - else if (curChar == 45) - jjstateSet[jjnewStateCnt++] = 0; - if ((0x3fe000000000000L & l) != 0L) { -- if (kind > 18) -- kind = 18; -+ if (kind > 20) -+ kind = 20; - jjCheckNAddTwoStates(15, 16); - } else if (curChar == 48) { -- if (kind > 18) -- kind = 18; -+ if (kind > 20) -+ kind = 20; - } - break; - case 0: -@@ -512,21 +614,21 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjstateSet[jjnewStateCnt++] = 6; - break; - case 13: -- if (curChar == 48 && kind > 18) -- kind = 18; -+ if (curChar == 48 && kind > 20) -+ kind = 20; - break; - case 14: - if ((0x3fe000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 20) -+ kind = 20; - jjCheckNAddTwoStates(15, 16); - break; - case 15: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 18) -- kind = 18; -+ if (kind > 20) -+ kind = 20; - jjCheckNAddTwoStates(15, 16); - break; - case 17: -@@ -536,8 +638,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 18: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 19) -- kind = 19; -+ if (kind > 21) -+ kind = 21; - jjCheckNAddTwoStates(18, 19); - break; - case 20: -@@ -547,8 +649,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 21: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 19) -- kind = 19; -+ if (kind > 21) -+ kind = 21; - jjCheckNAdd(21); - break; - case 22: -@@ -565,21 +667,21 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjCheckNAddStates(4, 6); - break; - case 26: -- if (curChar == 39 && kind > 21) -- kind = 21; -+ if (curChar == 39 && kind > 23) -+ kind = 23; - break; - case 27: - if (curChar != 36) - break; -- if (kind > 22) -- kind = 22; -+ if (kind > 24) -+ kind = 24; - jjCheckNAdd(28); - break; - case 28: - if ((0x3ff001000000000L & l) == 0L) - break; -- if (kind > 22) -- kind = 22; -+ if (kind > 24) -+ kind = 24; - jjCheckNAdd(28); - break; - case 29: -@@ -593,15 +695,15 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 31: - if (curChar != 46) - break; -- if (kind > 19) -- kind = 19; -+ if (kind > 21) -+ kind = 21; - jjCheckNAddTwoStates(32, 33); - break; - case 32: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 19) -- kind = 19; -+ if (kind > 21) -+ kind = 21; - jjCheckNAddTwoStates(32, 33); - break; - case 34: -@@ -611,8 +713,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 35: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 19) -- kind = 19; -+ if (kind > 21) -+ kind = 21; - jjCheckNAdd(35); - break; - case 36: -@@ -626,8 +728,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 39: - if ((0x3ff000000000000L & l) == 0L) - break; -- if (kind > 19) -- kind = 19; -+ if (kind > 21) -+ kind = 21; - jjCheckNAdd(39); - break; - default: -@@ -642,8 +744,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - case 28: - if ((0x7fffffe87fffffeL & l) == 0L) - break; -- if (kind > 22) -- kind = 22; -+ if (kind > 24) -+ kind = 24; - jjCheckNAdd(28); - break; - case 1: -@@ -657,8 +759,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - jjCheckNAddTwoStates(10, 8); - break; - case 16: -- if ((0x100000001000L & l) != 0L && kind > 18) -- kind = 18; -+ if ((0x100000001000L & l) != 0L && kind > 20) -+ kind = 20; - break; - case 19: - if ((0x2000000020L & l) != 0L) -@@ -766,8 +868,8 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - */ - public static final String[] JJ_STR_LITERAL_IMAGES = { - "", null, null, null, null, null, null, null, null, null, null, null, null, -- null, null, null, null, null, null, null, null, null, null, "\75", "\74\76", "\76", -- "\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55",}; -+ null, null, null, null, null, null, null, null, null, null, null, null, "\75", -+ "\74\76", "\76", "\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55",}; - - /** - * Lexer state names. -@@ -776,7 +878,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - "DEFAULT", - }; - static final long[] JJ_TO_TOKEN = { -- 0x3ffefff01L, -+ 0xfffbfff01L, - }; - static final long[] JJ_TO_SKIP = { - 0xfeL, -@@ -836,8 +938,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - */ - public void SwitchTo(int lexState) { - if (lexState >= 1 || lexState < 0) -- throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", -- TokenMgrError.INVALID_LEXICAL_STATE); -+ throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); - else - curLexState = lexState; - } -@@ -934,8 +1035,7 @@ public class SelectorParserTokenManager implements SelectorParserConstants { - inputStream.backup(1); - errorAfter = curPos <= 1 ? "" : inputStream.GetImage(); - } -- throw new TokenMgrError(eofSeen, curLexState, errorLine, errorColumn, errorAfter, curChar, -- TokenMgrError.LEXICAL_ERROR); -+ throw new TokenMgrError(eofSeen, curLexState, errorLine, errorColumn, errorAfter, curChar, TokenMgrError.LEXICAL_ERROR); - } - } - diff --git a/data/prod_diff/apache_rocketmq-6958.diff b/data/prod_diff/apache_rocketmq-6958.diff deleted file mode 100644 index 5ba9d6ea..00000000 --- a/data/prod_diff/apache_rocketmq-6958.diff +++ /dev/null @@ -1,769 +0,0 @@ -diff --git a/common/src/main/java/org/apache/rocketmq/common/constant/HAProxyConstants.java b/common/src/main/java/org/apache/rocketmq/common/constant/HAProxyConstants.java -new file mode 100644 -index 000000000..c1ae0cca1 ---- /dev/null -+++ b/common/src/main/java/org/apache/rocketmq/common/constant/HAProxyConstants.java -@@ -0,0 +1,28 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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 org.apache.rocketmq.common.constant; -+ -+public class HAProxyConstants { -+ -+ public static final String PROXY_PROTOCOL_PREFIX = "proxy_protocol_"; -+ public static final String PROXY_PROTOCOL_ADDR = PROXY_PROTOCOL_PREFIX + "addr"; -+ public static final String PROXY_PROTOCOL_PORT = PROXY_PROTOCOL_PREFIX + "port"; -+ public static final String PROXY_PROTOCOL_SERVER_ADDR = PROXY_PROTOCOL_PREFIX + "server_addr"; -+ public static final String PROXY_PROTOCOL_SERVER_PORT = PROXY_PROTOCOL_PREFIX + "server_port"; -+ public static final String PROXY_PROTOCOL_TLV_PREFIX = PROXY_PROTOCOL_PREFIX + "tlv_0x"; -+} -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java -index 0ca6a1fcb..437b9216b 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java -@@ -50,7 +50,7 @@ public class GrpcServerBuilder { - protected GrpcServerBuilder(ThreadPoolExecutor executor, int port) { - serverBuilder = NettyServerBuilder.forPort(port); - -- serverBuilder.protocolNegotiator(new OptionalSSLProtocolNegotiator()); -+ serverBuilder.protocolNegotiator(new ProxyAndTlsProtocolNegotiator()); - - // build server - int bossLoopNum = ConfigurationManager.getProxyConfig().getGrpcBossLoopNum(); -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/OptionalSSLProtocolNegotiator.java b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java -similarity index 51% -rename from proxy/src/main/java/org/apache/rocketmq/proxy/grpc/OptionalSSLProtocolNegotiator.java -rename to proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java -index 670e1c1a2..ceb9becc0 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/OptionalSSLProtocolNegotiator.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java -@@ -16,36 +16,53 @@ - */ - package org.apache.rocketmq.proxy.grpc; - -+import io.grpc.Attributes; - import io.grpc.netty.shaded.io.grpc.netty.GrpcHttp2ConnectionHandler; - import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts; - import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiationEvent; - import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiator; - import io.grpc.netty.shaded.io.grpc.netty.InternalProtocolNegotiators; -+import io.grpc.netty.shaded.io.grpc.netty.ProtocolNegotiationEvent; - import io.grpc.netty.shaded.io.netty.buffer.ByteBuf; - import io.grpc.netty.shaded.io.netty.channel.ChannelHandler; - import io.grpc.netty.shaded.io.netty.channel.ChannelHandlerContext; -+import io.grpc.netty.shaded.io.netty.channel.ChannelInboundHandlerAdapter; - import io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder; -+import io.grpc.netty.shaded.io.netty.handler.codec.ProtocolDetectionResult; -+import io.grpc.netty.shaded.io.netty.handler.codec.ProtocolDetectionState; -+import io.grpc.netty.shaded.io.netty.handler.codec.haproxy.HAProxyMessage; -+import io.grpc.netty.shaded.io.netty.handler.codec.haproxy.HAProxyMessageDecoder; -+import io.grpc.netty.shaded.io.netty.handler.codec.haproxy.HAProxyProtocolVersion; - import io.grpc.netty.shaded.io.netty.handler.ssl.ClientAuth; - import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext; - import io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler; - import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory; - import io.grpc.netty.shaded.io.netty.handler.ssl.util.SelfSignedCertificate; - import io.grpc.netty.shaded.io.netty.util.AsciiString; --import java.io.InputStream; --import java.nio.file.Files; --import java.nio.file.Paths; --import java.util.List; -+import io.grpc.netty.shaded.io.netty.util.CharsetUtil; -+import org.apache.commons.collections.CollectionUtils; -+import org.apache.commons.lang3.StringUtils; -+import org.apache.rocketmq.common.constant.HAProxyConstants; - import org.apache.rocketmq.common.constant.LoggerName; - import org.apache.rocketmq.logging.org.slf4j.Logger; - import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; - import org.apache.rocketmq.proxy.config.ConfigurationManager; - import org.apache.rocketmq.proxy.config.ProxyConfig; -+import org.apache.rocketmq.proxy.grpc.constant.AttributeKeys; - import org.apache.rocketmq.remoting.common.TlsMode; - import org.apache.rocketmq.remoting.netty.TlsSystemConfig; - --public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator.ProtocolNegotiator { -+import java.io.InputStream; -+import java.nio.file.Files; -+import java.nio.file.Paths; -+import java.util.List; -+ -+public class ProxyAndTlsProtocolNegotiator implements InternalProtocolNegotiator.ProtocolNegotiator { - protected static final Logger log = LoggerFactory.getLogger(LoggerName.PROXY_LOGGER_NAME); - -+ private static final String HA_PROXY_DECODER = "HAProxyDecoder"; -+ private static final String HA_PROXY_HANDLER = "HAProxyHandler"; -+ private static final String TLS_MODE_HANDLER = "TlsModeHandler"; - /** - * the length of the ssl record header (in bytes) - */ -@@ -53,7 +70,7 @@ public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator - - private static SslContext sslContext; - -- public OptionalSSLProtocolNegotiator() { -+ public ProxyAndTlsProtocolNegotiator() { - sslContext = loadSslContext(); - } - -@@ -64,11 +81,12 @@ public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator - - @Override - public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) { -- return new PortUnificationServerHandler(grpcHandler); -+ return new ProxyAndTlsProtocolHandler(grpcHandler); - } - - @Override -- public void close() {} -+ public void close() { -+ } - - private static SslContext loadSslContext() { - try { -@@ -85,8 +103,8 @@ public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator - String tlsCertPath = ConfigurationManager.getProxyConfig().getTlsCertPath(); - try (InputStream serverKeyInputStream = Files.newInputStream( - Paths.get(tlsKeyPath)); -- InputStream serverCertificateStream = Files.newInputStream( -- Paths.get(tlsCertPath))) { -+ InputStream serverCertificateStream = Files.newInputStream( -+ Paths.get(tlsCertPath))) { - SslContext res = GrpcSslContexts.forServer(serverCertificateStream, - serverKeyInputStream) - .trustManager(InsecureTrustManagerFactory.INSTANCE) -@@ -102,12 +120,95 @@ public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator - } - } - -- public static class PortUnificationServerHandler extends ByteToMessageDecoder { -+ private static class ProxyAndTlsProtocolHandler extends ByteToMessageDecoder { -+ -+ private final GrpcHttp2ConnectionHandler grpcHandler; -+ -+ public ProxyAndTlsProtocolHandler(GrpcHttp2ConnectionHandler grpcHandler) { -+ this.grpcHandler = grpcHandler; -+ } -+ -+ @Override -+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { -+ try { -+ ProtocolDetectionResult ha = HAProxyMessageDecoder.detectProtocol( -+ in); -+ if (ha.state() == ProtocolDetectionState.NEEDS_MORE_DATA) { -+ return; -+ } -+ if (ha.state() == ProtocolDetectionState.DETECTED) { -+ ctx.pipeline().addAfter(ctx.name(), HA_PROXY_DECODER, new HAProxyMessageDecoder()) -+ .addAfter(HA_PROXY_DECODER, HA_PROXY_HANDLER, new HAProxyMessageHandler()) -+ .addAfter(HA_PROXY_HANDLER, TLS_MODE_HANDLER, new TlsModeHandler(grpcHandler)); -+ } else { -+ ctx.pipeline().addAfter(ctx.name(), TLS_MODE_HANDLER, new TlsModeHandler(grpcHandler)); -+ } -+ -+ ctx.fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault()); -+ ctx.pipeline().remove(this); -+ } catch (Exception e) { -+ log.error("process proxy protocol negotiator failed.", e); -+ throw e; -+ } -+ } -+ } -+ -+ private static class HAProxyMessageHandler extends ChannelInboundHandlerAdapter { -+ -+ private ProtocolNegotiationEvent pne = InternalProtocolNegotiationEvent.getDefault(); -+ -+ @Override -+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { -+ if (msg instanceof HAProxyMessage) { -+ replaceEventWithMessage((HAProxyMessage) msg); -+ ctx.fireUserEventTriggered(pne); -+ } else { -+ super.channelRead(ctx, msg); -+ } -+ ctx.pipeline().remove(this); -+ } -+ -+ /** -+ * The definition of key refers to the implementation of nginx -+ * ngx_http_core_module -+ * -+ * @param msg -+ */ -+ private void replaceEventWithMessage(HAProxyMessage msg) { -+ Attributes.Builder builder = InternalProtocolNegotiationEvent.getAttributes(pne).toBuilder(); -+ if (StringUtils.isNotBlank(msg.sourceAddress())) { -+ builder.set(AttributeKeys.PROXY_PROTOCOL_ADDR, msg.sourceAddress()); -+ } -+ if (msg.sourcePort() > 0) { -+ builder.set(AttributeKeys.PROXY_PROTOCOL_PORT, String.valueOf(msg.sourcePort())); -+ } -+ if (StringUtils.isNotBlank(msg.destinationAddress())) { -+ builder.set(AttributeKeys.PROXY_PROTOCOL_SERVER_ADDR, msg.destinationAddress()); -+ } -+ if (msg.destinationPort() > 0) { -+ builder.set(AttributeKeys.PROXY_PROTOCOL_SERVER_PORT, String.valueOf(msg.destinationPort())); -+ } -+ if (CollectionUtils.isNotEmpty(msg.tlvs())) { -+ msg.tlvs().forEach(tlv -> { -+ Attributes.Key key = AttributeKeys.valueOf( -+ HAProxyConstants.PROXY_PROTOCOL_TLV_PREFIX + String.format("%02x", tlv.typeByteValue())); -+ String value = StringUtils.trim(tlv.content().toString(CharsetUtil.UTF_8)); -+ builder.set(key, value); -+ }); -+ } -+ pne = InternalProtocolNegotiationEvent -+ .withAttributes(InternalProtocolNegotiationEvent.getDefault(), builder.build()); -+ } -+ } -+ -+ private static class TlsModeHandler extends ByteToMessageDecoder { -+ -+ private ProtocolNegotiationEvent pne = InternalProtocolNegotiationEvent.getDefault(); - - private final ChannelHandler ssl; - private final ChannelHandler plaintext; - -- public PortUnificationServerHandler(GrpcHttp2ConnectionHandler grpcHandler) { -+ public TlsModeHandler(GrpcHttp2ConnectionHandler grpcHandler) { - this.ssl = InternalProtocolNegotiators.serverTls(sslContext) - .newHandler(grpcHandler); - this.plaintext = InternalProtocolNegotiators.serverPlaintext() -@@ -115,8 +216,7 @@ public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator - } - - @Override -- protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) -- throws Exception { -+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { - try { - TlsMode tlsMode = TlsSystemConfig.tlsMode; - if (TlsMode.ENFORCING.equals(tlsMode)) { -@@ -134,12 +234,21 @@ public class OptionalSSLProtocolNegotiator implements InternalProtocolNegotiator - ctx.pipeline().addAfter(ctx.name(), null, this.plaintext); - } - } -- ctx.fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault()); -+ ctx.fireUserEventTriggered(pne); - ctx.pipeline().remove(this); - } catch (Exception e) { - log.error("process ssl protocol negotiator failed.", e); - throw e; - } - } -+ -+ @Override -+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { -+ if (evt instanceof ProtocolNegotiationEvent) { -+ pne = (ProtocolNegotiationEvent) evt; -+ } else { -+ super.userEventTriggered(ctx, evt); -+ } -+ } - } - } -\ No newline at end of file -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/constant/AttributeKeys.java b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/constant/AttributeKeys.java -new file mode 100644 -index 000000000..096a5ba3d ---- /dev/null -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/constant/AttributeKeys.java -@@ -0,0 +1,44 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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 org.apache.rocketmq.proxy.grpc.constant; -+ -+import io.grpc.Attributes; -+import org.apache.rocketmq.common.constant.HAProxyConstants; -+ -+import java.util.Map; -+import java.util.concurrent.ConcurrentHashMap; -+ -+public class AttributeKeys { -+ -+ public static final Attributes.Key PROXY_PROTOCOL_ADDR = -+ Attributes.Key.create(HAProxyConstants.PROXY_PROTOCOL_ADDR); -+ -+ public static final Attributes.Key PROXY_PROTOCOL_PORT = -+ Attributes.Key.create(HAProxyConstants.PROXY_PROTOCOL_PORT); -+ -+ public static final Attributes.Key PROXY_PROTOCOL_SERVER_ADDR = -+ Attributes.Key.create(HAProxyConstants.PROXY_PROTOCOL_SERVER_ADDR); -+ -+ public static final Attributes.Key PROXY_PROTOCOL_SERVER_PORT = -+ Attributes.Key.create(HAProxyConstants.PROXY_PROTOCOL_SERVER_PORT); -+ -+ private static final Map> ATTRIBUTES_KEY_MAP = new ConcurrentHashMap<>(); -+ -+ public static Attributes.Key valueOf(String name) { -+ return ATTRIBUTES_KEY_MAP.computeIfAbsent(name, key -> Attributes.Key.create(name)); -+ } -+} -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/interceptor/HeaderInterceptor.java b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/interceptor/HeaderInterceptor.java -index 1cbb00361..13893e5ed 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/interceptor/HeaderInterceptor.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/interceptor/HeaderInterceptor.java -@@ -18,11 +18,16 @@ - package org.apache.rocketmq.proxy.grpc.interceptor; - - import com.google.common.net.HostAndPort; -+import io.grpc.Attributes; - import io.grpc.Grpc; - import io.grpc.Metadata; - import io.grpc.ServerCall; - import io.grpc.ServerCallHandler; - import io.grpc.ServerInterceptor; -+import org.apache.commons.lang3.StringUtils; -+import org.apache.rocketmq.common.constant.HAProxyConstants; -+import org.apache.rocketmq.proxy.grpc.constant.AttributeKeys; -+ - import java.net.InetSocketAddress; - import java.net.SocketAddress; - -@@ -33,13 +38,27 @@ public class HeaderInterceptor implements ServerInterceptor { - Metadata headers, - ServerCallHandler next - ) { -- SocketAddress remoteSocketAddress = call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR); -- String remoteAddress = parseSocketAddress(remoteSocketAddress); -+ String remoteAddress = getProxyProtocolAddress(call.getAttributes()); -+ if (StringUtils.isBlank(remoteAddress)) { -+ SocketAddress remoteSocketAddress = call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR); -+ remoteAddress = parseSocketAddress(remoteSocketAddress); -+ } - headers.put(InterceptorConstants.REMOTE_ADDRESS, remoteAddress); - - SocketAddress localSocketAddress = call.getAttributes().get(Grpc.TRANSPORT_ATTR_LOCAL_ADDR); - String localAddress = parseSocketAddress(localSocketAddress); - headers.put(InterceptorConstants.LOCAL_ADDRESS, localAddress); -+ -+ for (Attributes.Key key : call.getAttributes().keys()) { -+ if (!StringUtils.startsWith(key.toString(), HAProxyConstants.PROXY_PROTOCOL_PREFIX)) { -+ continue; -+ } -+ Metadata.Key headerKey -+ = Metadata.Key.of(key.toString(), Metadata.ASCII_STRING_MARSHALLER); -+ String headerValue = String.valueOf(call.getAttributes().get(key)); -+ headers.put(headerKey, headerValue); -+ } -+ - return next.startCall(call, headers); - } - -@@ -55,4 +74,13 @@ public class HeaderInterceptor implements ServerInterceptor { - - return ""; - } -+ -+ private String getProxyProtocolAddress(Attributes attributes) { -+ String proxyProtocolAddr = attributes.get(AttributeKeys.PROXY_PROTOCOL_ADDR); -+ String proxyProtocolPort = attributes.get(AttributeKeys.PROXY_PROTOCOL_PORT); -+ if (StringUtils.isBlank(proxyProtocolAddr) || StringUtils.isBlank(proxyProtocolPort)) { -+ return null; -+ } -+ return proxyProtocolAddr + ":" + proxyProtocolPort; -+ } - } -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/MultiProtocolRemotingServer.java b/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/MultiProtocolRemotingServer.java -index 1142132b7..858b1f022 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/MultiProtocolRemotingServer.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/MultiProtocolRemotingServer.java -@@ -20,8 +20,6 @@ package org.apache.rocketmq.proxy.remoting; - import io.netty.channel.ChannelPipeline; - import io.netty.channel.socket.SocketChannel; - import io.netty.handler.timeout.IdleStateHandler; --import java.io.IOException; --import java.security.cert.CertificateException; - import org.apache.rocketmq.common.constant.LoggerName; - import org.apache.rocketmq.logging.org.slf4j.Logger; - import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; -@@ -36,6 +34,9 @@ import org.apache.rocketmq.remoting.netty.NettyRemotingServer; - import org.apache.rocketmq.remoting.netty.NettyServerConfig; - import org.apache.rocketmq.remoting.netty.TlsSystemConfig; - -+import java.io.IOException; -+import java.security.cert.CertificateException; -+ - /** - * support remoting and http2 protocol at one port - */ -diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java b/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java -index 75e25a83a..d0750b678 100644 ---- a/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java -+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/common/RemotingHelper.java -@@ -21,14 +21,8 @@ import io.netty.channel.ChannelFuture; - import io.netty.channel.ChannelFutureListener; - import io.netty.util.Attribute; - import io.netty.util.AttributeKey; --import java.io.IOException; --import java.lang.reflect.Field; --import java.net.InetSocketAddress; --import java.net.SocketAddress; --import java.nio.ByteBuffer; --import java.nio.channels.SocketChannel; --import java.util.HashMap; --import java.util.Map; -+import org.apache.commons.lang3.StringUtils; -+import org.apache.rocketmq.common.constant.HAProxyConstants; - import org.apache.rocketmq.common.constant.LoggerName; - import org.apache.rocketmq.common.utils.NetworkUtil; - import org.apache.rocketmq.logging.org.slf4j.Logger; -@@ -43,6 +37,15 @@ import org.apache.rocketmq.remoting.protocol.RemotingCommand; - import org.apache.rocketmq.remoting.protocol.RequestCode; - import org.apache.rocketmq.remoting.protocol.ResponseCode; - -+import java.io.IOException; -+import java.lang.reflect.Field; -+import java.net.InetSocketAddress; -+import java.net.SocketAddress; -+import java.nio.ByteBuffer; -+import java.nio.channels.SocketChannel; -+import java.util.HashMap; -+import java.util.Map; -+ - public class RemotingHelper { - public static final String DEFAULT_CHARSET = "UTF-8"; - public static final String DEFAULT_CIDR_ALL = "0.0.0.0/0"; -@@ -50,6 +53,9 @@ public class RemotingHelper { - private static final Logger log = LoggerFactory.getLogger(LoggerName.ROCKETMQ_REMOTING_NAME); - private static final AttributeKey REMOTE_ADDR_KEY = AttributeKey.valueOf("RemoteAddr"); - -+ private static final AttributeKey PROXY_PROTOCOL_ADDR = AttributeKey.valueOf(HAProxyConstants.PROXY_PROTOCOL_ADDR); -+ private static final AttributeKey PROXY_PROTOCOL_PORT = AttributeKey.valueOf(HAProxyConstants.PROXY_PROTOCOL_PORT); -+ - public static final AttributeKey CLIENT_ID_KEY = AttributeKey.valueOf("ClientId"); - - public static final AttributeKey VERSION_KEY = AttributeKey.valueOf("Version"); -@@ -203,12 +209,16 @@ public class RemotingHelper { - if (null == channel) { - return ""; - } -+ String addr = getProxyProtocolAddress(channel); -+ if (StringUtils.isNotBlank(addr)) { -+ return addr; -+ } - Attribute att = channel.attr(REMOTE_ADDR_KEY); - if (att == null) { - // mocked in unit test - return parseChannelRemoteAddr0(channel); - } -- String addr = att.get(); -+ addr = att.get(); - if (addr == null) { - addr = parseChannelRemoteAddr0(channel); - att.set(addr); -@@ -216,6 +226,18 @@ public class RemotingHelper { - return addr; - } - -+ private static String getProxyProtocolAddress(Channel channel) { -+ if (!channel.hasAttr(PROXY_PROTOCOL_ADDR)) { -+ return null; -+ } -+ String proxyProtocolAddr = getAttributeValue(PROXY_PROTOCOL_ADDR, channel); -+ String proxyProtocolPort = getAttributeValue(PROXY_PROTOCOL_PORT, channel); -+ if (StringUtils.isBlank(proxyProtocolAddr) || proxyProtocolPort == null) { -+ return null; -+ } -+ return proxyProtocolAddr + ":" + proxyProtocolPort; -+ } -+ - private static String parseChannelRemoteAddr0(final Channel channel) { - SocketAddress remote = channel.remoteAddress(); - final String addr = remote != null ? remote.toString() : ""; -@@ -255,7 +277,7 @@ public class RemotingHelper { - return ""; - } - -- public static int parseSocketAddressPort(SocketAddress socketAddress) { -+ public static Integer parseSocketAddressPort(SocketAddress socketAddress) { - if (socketAddress instanceof InetSocketAddress) { - return ((InetSocketAddress) socketAddress).getPort(); - } -diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/AttributeKeys.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/AttributeKeys.java -new file mode 100644 -index 000000000..4e69ab82d ---- /dev/null -+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/AttributeKeys.java -@@ -0,0 +1,45 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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 org.apache.rocketmq.remoting.netty; -+ -+ -+import io.netty.util.AttributeKey; -+import org.apache.rocketmq.common.constant.HAProxyConstants; -+ -+import java.util.Map; -+import java.util.concurrent.ConcurrentHashMap; -+ -+public class AttributeKeys { -+ -+ public static final AttributeKey PROXY_PROTOCOL_ADDR = -+ AttributeKey.valueOf(HAProxyConstants.PROXY_PROTOCOL_ADDR); -+ -+ public static final AttributeKey PROXY_PROTOCOL_PORT = -+ AttributeKey.valueOf(HAProxyConstants.PROXY_PROTOCOL_PORT); -+ -+ public static final AttributeKey PROXY_PROTOCOL_SERVER_ADDR = -+ AttributeKey.valueOf(HAProxyConstants.PROXY_PROTOCOL_SERVER_ADDR); -+ -+ public static final AttributeKey PROXY_PROTOCOL_SERVER_PORT = -+ AttributeKey.valueOf(HAProxyConstants.PROXY_PROTOCOL_SERVER_PORT); -+ -+ private static final Map> ATTRIBUTE_KEY_MAP = new ConcurrentHashMap<>(); -+ -+ public static AttributeKey valueOf(String name) { -+ return ATTRIBUTE_KEY_MAP.computeIfAbsent(name, AttributeKeys::valueOf); -+ } -+} -diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java -index 9f39d672e..94ffd8d07 100644 ---- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java -+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java -@@ -24,6 +24,7 @@ import io.netty.channel.ChannelDuplexHandler; - import io.netty.channel.ChannelFuture; - import io.netty.channel.ChannelHandler; - import io.netty.channel.ChannelHandlerContext; -+import io.netty.channel.ChannelInboundHandlerAdapter; - import io.netty.channel.ChannelInitializer; - import io.netty.channel.ChannelOption; - import io.netty.channel.ChannelPipeline; -@@ -36,27 +37,25 @@ import io.netty.channel.epoll.EpollServerSocketChannel; - import io.netty.channel.nio.NioEventLoopGroup; - import io.netty.channel.socket.SocketChannel; - import io.netty.channel.socket.nio.NioServerSocketChannel; -+import io.netty.handler.codec.ProtocolDetectionResult; -+import io.netty.handler.codec.ProtocolDetectionState; -+import io.netty.handler.codec.haproxy.HAProxyMessage; -+import io.netty.handler.codec.haproxy.HAProxyMessageDecoder; -+import io.netty.handler.codec.haproxy.HAProxyProtocolVersion; - import io.netty.handler.timeout.IdleState; - import io.netty.handler.timeout.IdleStateEvent; - import io.netty.handler.timeout.IdleStateHandler; -+import io.netty.util.AttributeKey; -+import io.netty.util.CharsetUtil; - import io.netty.util.HashedWheelTimer; - import io.netty.util.Timeout; - import io.netty.util.TimerTask; - import io.netty.util.concurrent.DefaultEventExecutorGroup; --import java.io.IOException; --import java.net.InetSocketAddress; --import java.security.cert.CertificateException; --import java.util.NoSuchElementException; --import java.util.concurrent.ConcurrentHashMap; --import java.util.concurrent.ConcurrentMap; --import java.util.concurrent.ExecutorService; --import java.util.concurrent.Executors; --import java.util.concurrent.ScheduledExecutorService; --import java.util.concurrent.ScheduledThreadPoolExecutor; --import java.util.concurrent.ThreadPoolExecutor; --import java.util.concurrent.TimeUnit; -+import org.apache.commons.collections.CollectionUtils; -+import org.apache.commons.lang3.StringUtils; - import org.apache.rocketmq.common.Pair; - import org.apache.rocketmq.common.ThreadFactoryImpl; -+import org.apache.rocketmq.common.constant.HAProxyConstants; - import org.apache.rocketmq.common.constant.LoggerName; - import org.apache.rocketmq.common.utils.NetworkUtil; - import org.apache.rocketmq.logging.org.slf4j.Logger; -@@ -71,6 +70,19 @@ import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; - import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException; - import org.apache.rocketmq.remoting.protocol.RemotingCommand; - -+import java.io.IOException; -+import java.net.InetSocketAddress; -+import java.security.cert.CertificateException; -+import java.util.NoSuchElementException; -+import java.util.concurrent.ConcurrentHashMap; -+import java.util.concurrent.ConcurrentMap; -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; -+import java.util.concurrent.ScheduledExecutorService; -+import java.util.concurrent.ScheduledThreadPoolExecutor; -+import java.util.concurrent.ThreadPoolExecutor; -+import java.util.concurrent.TimeUnit; -+ - @SuppressWarnings("NullableProblems") - public class NettyRemotingServer extends NettyRemotingAbstract implements RemotingServer { - private static final Logger log = LoggerFactory.getLogger(LoggerName.ROCKETMQ_REMOTING_NAME); -@@ -96,6 +108,9 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti - private final ConcurrentMap remotingServerTable = new ConcurrentHashMap<>(); - - public static final String HANDSHAKE_HANDLER_NAME = "handshakeHandler"; -+ public static final String HA_PROXY_DECODER = "HAProxyDecoder"; -+ public static final String HA_PROXY_HANDLER = "HAProxyHandler"; -+ public static final String TLS_MODE_HANDLER = "TlsModeHandler"; - public static final String TLS_HANDLER_NAME = "sslHandler"; - public static final String FILE_REGION_ENCODER_NAME = "fileRegionEncoder"; - -@@ -387,7 +402,7 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti - } - - private void prepareSharableHandlers() { -- handshakeHandler = new HandshakeHandler(TlsSystemConfig.tlsMode); -+ handshakeHandler = new HandshakeHandler(); - encoder = new NettyEncoder(); - connectionManageHandler = new NettyConnectManageHandler(); - serverHandler = new NettyServerHandler(); -@@ -437,11 +452,51 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti - @ChannelHandler.Sharable - public class HandshakeHandler extends SimpleChannelInboundHandler { - -+ private final TlsModeHandler tlsModeHandler; -+ -+ public HandshakeHandler() { -+ tlsModeHandler = new TlsModeHandler(TlsSystemConfig.tlsMode); -+ } -+ -+ @Override -+ protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) { -+ try { -+ ProtocolDetectionResult ha = HAProxyMessageDecoder.detectProtocol(in); -+ if (ha.state() == ProtocolDetectionState.NEEDS_MORE_DATA) { -+ return; -+ } -+ if (ha.state() == ProtocolDetectionState.DETECTED) { -+ ctx.pipeline().addAfter(defaultEventExecutorGroup, ctx.name(), HA_PROXY_DECODER, new HAProxyMessageDecoder()) -+ .addAfter(defaultEventExecutorGroup, HA_PROXY_DECODER, HA_PROXY_HANDLER, new HAProxyMessageHandler()) -+ .addAfter(defaultEventExecutorGroup, HA_PROXY_HANDLER, TLS_MODE_HANDLER, tlsModeHandler); -+ } else { -+ ctx.pipeline().addAfter(defaultEventExecutorGroup, ctx.name(), TLS_MODE_HANDLER, tlsModeHandler); -+ } -+ -+ try { -+ // Remove this handler -+ ctx.pipeline().remove(this); -+ } catch (NoSuchElementException e) { -+ log.error("Error while removing HandshakeHandler", e); -+ } -+ -+ // Hand over this message to the next . -+ ctx.fireChannelRead(in.retain()); -+ } catch (Exception e) { -+ log.error("process proxy protocol negotiator failed.", e); -+ throw e; -+ } -+ } -+ } -+ -+ @ChannelHandler.Sharable -+ public class TlsModeHandler extends SimpleChannelInboundHandler { -+ - private final TlsMode tlsMode; - - private static final byte HANDSHAKE_MAGIC_CODE = 0x16; - -- HandshakeHandler(TlsMode tlsMode) { -+ TlsModeHandler(TlsMode tlsMode) { - this.tlsMode = tlsMode; - } - -@@ -461,7 +516,7 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti - case ENFORCING: - if (null != sslContext) { - ctx.pipeline() -- .addAfter(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, TLS_HANDLER_NAME, sslContext.newHandler(ctx.channel().alloc())) -+ .addAfter(defaultEventExecutorGroup, TLS_MODE_HANDLER, TLS_HANDLER_NAME, sslContext.newHandler(ctx.channel().alloc())) - .addAfter(defaultEventExecutorGroup, TLS_HANDLER_NAME, FILE_REGION_ENCODER_NAME, new FileRegionEncoder()); - log.info("Handlers prepended to channel pipeline to establish SSL connection"); - } else { -@@ -483,7 +538,7 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti - // Remove this handler - ctx.pipeline().remove(this); - } catch (NoSuchElementException e) { -- log.error("Error while removing HandshakeHandler", e); -+ log.error("Error while removing TlsModeHandler", e); - } - - // Hand over this message to the next . -@@ -706,4 +761,46 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti - return NettyRemotingServer.this.getCallbackExecutor(); - } - } -+ -+ public static class HAProxyMessageHandler extends ChannelInboundHandlerAdapter { -+ -+ @Override -+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { -+ if (msg instanceof HAProxyMessage) { -+ fillChannelWithMessage((HAProxyMessage) msg, ctx.channel()); -+ } else { -+ super.channelRead(ctx, msg); -+ } -+ ctx.pipeline().remove(this); -+ } -+ -+ /** -+ * The definition of key refers to the implementation of nginx -+ * ngx_http_core_module -+ * @param msg -+ * @param channel -+ */ -+ private void fillChannelWithMessage(HAProxyMessage msg, Channel channel) { -+ if (StringUtils.isNotBlank(msg.sourceAddress())) { -+ channel.attr(AttributeKeys.PROXY_PROTOCOL_ADDR).set(msg.sourceAddress()); -+ } -+ if (msg.sourcePort() > 0) { -+ channel.attr(AttributeKeys.PROXY_PROTOCOL_PORT).set(String.valueOf(msg.sourcePort())); -+ } -+ if (StringUtils.isNotBlank(msg.destinationAddress())) { -+ channel.attr(AttributeKeys.PROXY_PROTOCOL_SERVER_ADDR).set(msg.destinationAddress()); -+ } -+ if (msg.destinationPort() > 0) { -+ channel.attr(AttributeKeys.PROXY_PROTOCOL_SERVER_PORT).set(String.valueOf(msg.destinationPort())); -+ } -+ if (CollectionUtils.isNotEmpty(msg.tlvs())) { -+ msg.tlvs().forEach(tlv -> { -+ AttributeKey key = AttributeKeys.valueOf( -+ HAProxyConstants.PROXY_PROTOCOL_TLV_PREFIX + String.format("%02x", tlv.typeByteValue())); -+ String value = StringUtils.trim(tlv.content().toString(CharsetUtil.UTF_8)); -+ channel.attr(key).set(value); -+ }); -+ } -+ } -+ } - } diff --git a/data/prod_diff/apache_rocketmq-6969.diff b/data/prod_diff/apache_rocketmq-6969.diff deleted file mode 100644 index 29fcd6c2..00000000 --- a/data/prod_diff/apache_rocketmq-6969.diff +++ /dev/null @@ -1,220 +0,0 @@ -diff --git a/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java b/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java -index cdbd9ea9b..72aa8ca71 100644 ---- a/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java -+++ b/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessResource.java -@@ -223,7 +223,7 @@ public class PlainAccessResource implements AccessResource { - if (!request.hasGroup()) { - throw new AclException("Consumer heartbeat doesn't have group"); - } else { -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - } - } - } else if (SendMessageRequest.getDescriptor().getFullName().equals(rpcFullName)) { -@@ -240,15 +240,15 @@ public class PlainAccessResource implements AccessResource { - accessResource.addResourceAndPerm(topic, Permission.PUB); - } else if (ReceiveMessageRequest.getDescriptor().getFullName().equals(rpcFullName)) { - ReceiveMessageRequest request = (ReceiveMessageRequest) messageV3; -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - accessResource.addResourceAndPerm(request.getMessageQueue().getTopic(), Permission.SUB); - } else if (AckMessageRequest.getDescriptor().getFullName().equals(rpcFullName)) { - AckMessageRequest request = (AckMessageRequest) messageV3; -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - accessResource.addResourceAndPerm(request.getTopic(), Permission.SUB); - } else if (ForwardMessageToDeadLetterQueueRequest.getDescriptor().getFullName().equals(rpcFullName)) { - ForwardMessageToDeadLetterQueueRequest request = (ForwardMessageToDeadLetterQueueRequest) messageV3; -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - accessResource.addResourceAndPerm(request.getTopic(), Permission.SUB); - } else if (EndTransactionRequest.getDescriptor().getFullName().equals(rpcFullName)) { - EndTransactionRequest request = (EndTransactionRequest) messageV3; -@@ -264,7 +264,7 @@ public class PlainAccessResource implements AccessResource { - } - if (command.getSettings().hasSubscription()) { - Subscription subscription = command.getSettings().getSubscription(); -- accessResource.addResourceAndPerm(subscription.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(subscription.getGroup(), Permission.SUB); - for (SubscriptionEntry entry : subscription.getSubscriptionsList()) { - accessResource.addResourceAndPerm(entry.getTopic(), Permission.SUB); - } -@@ -275,17 +275,17 @@ public class PlainAccessResource implements AccessResource { - } - } else if (NotifyClientTerminationRequest.getDescriptor().getFullName().equals(rpcFullName)) { - NotifyClientTerminationRequest request = (NotifyClientTerminationRequest) messageV3; -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - } else if (QueryRouteRequest.getDescriptor().getFullName().equals(rpcFullName)) { - QueryRouteRequest request = (QueryRouteRequest) messageV3; - accessResource.addResourceAndPerm(request.getTopic(), Permission.ANY); - } else if (QueryAssignmentRequest.getDescriptor().getFullName().equals(rpcFullName)) { - QueryAssignmentRequest request = (QueryAssignmentRequest) messageV3; -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - accessResource.addResourceAndPerm(request.getTopic(), Permission.SUB); - } else if (ChangeInvisibleDurationRequest.getDescriptor().getFullName().equals(rpcFullName)) { - ChangeInvisibleDurationRequest request = (ChangeInvisibleDurationRequest) messageV3; -- accessResource.addResourceAndPerm(request.getGroup(), Permission.SUB); -+ accessResource.addGroupResourceAndPerm(request.getGroup(), Permission.SUB); - accessResource.addResourceAndPerm(request.getTopic(), Permission.SUB); - } - } catch (Throwable t) { -@@ -299,6 +299,11 @@ public class PlainAccessResource implements AccessResource { - addResourceAndPerm(resourceName, permission); - } - -+ private void addGroupResourceAndPerm(Resource resource, byte permission) { -+ String resourceName = NamespaceUtil.wrapNamespace(resource.getResourceNamespace(), resource.getName()); -+ addResourceAndPerm(getRetryTopic(resourceName), permission); -+ } -+ - public static PlainAccessResource build(PlainAccessConfig plainAccessConfig, RemoteAddressStrategy remoteAddressStrategy) { - PlainAccessResource plainAccessResource = new PlainAccessResource(); - plainAccessResource.setAccessKey(plainAccessConfig.getAccessKey()); -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/ProxyStartup.java b/proxy/src/main/java/org/apache/rocketmq/proxy/ProxyStartup.java -index ea13bb808..06d5f4525 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/ProxyStartup.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/ProxyStartup.java -@@ -29,11 +29,14 @@ import org.apache.commons.cli.DefaultParser; - import org.apache.commons.cli.Option; - import org.apache.commons.cli.Options; - import org.apache.commons.lang3.StringUtils; -+import org.apache.rocketmq.acl.AccessValidator; -+import org.apache.rocketmq.acl.plain.PlainAccessValidator; - import org.apache.rocketmq.broker.BrokerController; - import org.apache.rocketmq.broker.BrokerStartup; - import org.apache.rocketmq.common.MixAll; - import org.apache.rocketmq.common.constant.LoggerName; - import org.apache.rocketmq.common.thread.ThreadPoolMonitor; -+import org.apache.rocketmq.common.utils.ServiceProvider; - import org.apache.rocketmq.logging.org.slf4j.Logger; - import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; - import org.apache.rocketmq.common.utils.AbstractStartAndShutdown; -@@ -75,16 +78,17 @@ public class ProxyStartup { - - MessagingProcessor messagingProcessor = createMessagingProcessor(); - -+ List accessValidators = loadAccessValidators(); - // create grpcServer - GrpcServer grpcServer = GrpcServerBuilder.newBuilder(executor, ConfigurationManager.getProxyConfig().getGrpcServerPort()) - .addService(createServiceProcessor(messagingProcessor)) - .addService(ChannelzService.newInstance(100)) - .addService(ProtoReflectionService.newInstance()) -- .configInterceptor() -+ .configInterceptor(accessValidators) - .build(); - PROXY_START_AND_SHUTDOWN.appendStartAndShutdown(grpcServer); - -- RemotingProtocolServer remotingServer = new RemotingProtocolServer(messagingProcessor); -+ RemotingProtocolServer remotingServer = new RemotingProtocolServer(messagingProcessor, accessValidators); - PROXY_START_AND_SHUTDOWN.appendStartAndShutdown(remotingServer); - - // start servers one by one. -@@ -109,6 +113,15 @@ public class ProxyStartup { - log.info(new Date() + " rocketmq-proxy startup successfully"); - } - -+ protected static List loadAccessValidators() { -+ List accessValidators = ServiceProvider.load(AccessValidator.class); -+ if (accessValidators.isEmpty()) { -+ log.info("ServiceProvider loaded no AccessValidator, using default org.apache.rocketmq.acl.plain.PlainAccessValidator"); -+ accessValidators.add(new PlainAccessValidator()); -+ } -+ return accessValidators; -+ } -+ - protected static void initConfiguration(CommandLineArgument commandLineArgument) throws Exception { - if (StringUtils.isNotBlank(commandLineArgument.getProxyConfigPath())) { - System.setProperty(Configuration.CONFIG_PATH_PROPERTY, commandLineArgument.getProxyConfigPath()); -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java -index 437b9216b..9cddd3013 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/GrpcServerBuilder.java -@@ -28,9 +28,7 @@ import java.util.List; - import java.util.concurrent.ThreadPoolExecutor; - import java.util.concurrent.TimeUnit; - import org.apache.rocketmq.acl.AccessValidator; --import org.apache.rocketmq.acl.plain.PlainAccessValidator; - import org.apache.rocketmq.common.constant.LoggerName; --import org.apache.rocketmq.common.utils.ServiceProvider; - import org.apache.rocketmq.logging.org.slf4j.Logger; - import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; - import org.apache.rocketmq.proxy.config.ConfigurationManager; -@@ -98,14 +96,8 @@ public class GrpcServerBuilder { - return new GrpcServer(this.serverBuilder.build()); - } - -- public GrpcServerBuilder configInterceptor() { -+ public GrpcServerBuilder configInterceptor(List accessValidators) { - // grpc interceptors, including acl, logging etc. -- List accessValidators = ServiceProvider.load(AccessValidator.class); -- if (accessValidators.isEmpty()) { -- log.info("ServiceProvider loaded no AccessValidator, using default org.apache.rocketmq.acl.plain.PlainAccessValidator"); -- accessValidators.add(new PlainAccessValidator()); -- } -- - this.serverBuilder.intercept(new AuthenticationInterceptor(accessValidators)); - - this.serverBuilder -diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java b/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java -index f08094c16..bcc9edd09 100644 ---- a/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java -+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java -@@ -19,7 +19,6 @@ package org.apache.rocketmq.proxy.remoting; - - import com.google.common.util.concurrent.ThreadFactoryBuilder; - import io.netty.channel.Channel; --import java.util.ArrayList; - import java.util.List; - import java.util.concurrent.BlockingQueue; - import java.util.concurrent.CompletableFuture; -@@ -28,15 +27,14 @@ import java.util.concurrent.ScheduledExecutorService; - import java.util.concurrent.ThreadPoolExecutor; - import java.util.concurrent.TimeUnit; - import org.apache.rocketmq.acl.AccessValidator; --import org.apache.rocketmq.acl.plain.PlainAccessValidator; - import org.apache.rocketmq.client.exception.MQClientException; - import org.apache.rocketmq.common.constant.LoggerName; - import org.apache.rocketmq.common.future.FutureTaskExt; - import org.apache.rocketmq.common.thread.ThreadPoolMonitor; - import org.apache.rocketmq.common.thread.ThreadPoolStatusMonitor; -+import org.apache.rocketmq.common.utils.StartAndShutdown; - import org.apache.rocketmq.logging.org.slf4j.Logger; - import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; --import org.apache.rocketmq.common.utils.StartAndShutdown; - import org.apache.rocketmq.proxy.config.ConfigurationManager; - import org.apache.rocketmq.proxy.config.ProxyConfig; - import org.apache.rocketmq.proxy.processor.MessagingProcessor; -@@ -86,11 +84,11 @@ public class RemotingProtocolServer implements StartAndShutdown, RemotingProxyOu - protected final ThreadPoolExecutor defaultExecutor; - protected final ScheduledExecutorService timerExecutor; - -- public RemotingProtocolServer(MessagingProcessor messagingProcessor) { -+ public RemotingProtocolServer(MessagingProcessor messagingProcessor, List accessValidators) { - this.messagingProcessor = messagingProcessor; - this.remotingChannelManager = new RemotingChannelManager(this, messagingProcessor.getProxyRelayService()); - -- RequestPipeline pipeline = createRequestPipeline(); -+ RequestPipeline pipeline = createRequestPipeline(accessValidators); - this.getTopicRouteActivity = new GetTopicRouteActivity(pipeline, messagingProcessor); - this.clientManagerActivity = new ClientManagerActivity(pipeline, messagingProcessor, remotingChannelManager); - this.consumerManagerActivity = new ConsumerManagerActivity(pipeline, messagingProcessor); -@@ -254,15 +252,12 @@ public class RemotingProtocolServer implements StartAndShutdown, RemotingProxyOu - return future; - } - -- protected RequestPipeline createRequestPipeline() { -+ protected RequestPipeline createRequestPipeline(List accessValidators) { - RequestPipeline pipeline = (ctx, request, context) -> { - }; -- -- List accessValidatorList = new ArrayList<>(); -- accessValidatorList.add(new PlainAccessValidator()); - // add pipeline - // the last pipe add will execute at the first -- return pipeline.pipe(new AuthenticationPipeline(accessValidatorList)); -+ return pipeline.pipe(new AuthenticationPipeline(accessValidators)); - } - - protected class ThreadPoolHeadSlowTimeMillsMonitor implements ThreadPoolStatusMonitor { diff --git a/data/prod_diff/apache_rocketmq-7712.diff b/data/prod_diff/apache_rocketmq-7712.diff new file mode 100644 index 00000000..5383f3c6 --- /dev/null +++ b/data/prod_diff/apache_rocketmq-7712.diff @@ -0,0 +1,23 @@ +diff --git a/common/src/main/java/org/apache/rocketmq/common/UtilAll.java b/common/src/main/java/org/apache/rocketmq/common/UtilAll.java +index 19efa9aa9..3629ae648 100644 +--- a/common/src/main/java/org/apache/rocketmq/common/UtilAll.java ++++ b/common/src/main/java/org/apache/rocketmq/common/UtilAll.java +@@ -43,6 +43,7 @@ import java.util.function.Supplier; + import java.util.zip.CRC32; + import java.util.zip.DeflaterOutputStream; + import java.util.zip.InflaterInputStream; ++import java.util.Collections; + import org.apache.commons.lang3.StringUtils; + import org.apache.commons.validator.routines.InetAddressValidator; + import org.apache.rocketmq.common.constant.LoggerName; +@@ -681,6 +682,10 @@ public class UtilAll { + return null; + } + ++ if (StringUtils.isBlank(str)) { ++ return Collections.EMPTY_LIST; ++ } ++ + String[] addrArray = str.split(splitter); + return Arrays.asList(addrArray); + } diff --git a/data/prod_diff/jhy_jsoup-2017.diff b/data/prod_diff/jhy_jsoup-2017.diff deleted file mode 100644 index 24eb416b..00000000 --- a/data/prod_diff/jhy_jsoup-2017.diff +++ /dev/null @@ -1,163 +0,0 @@ -diff --git a/src/main/java/org/jsoup/select/Elements.java b/src/main/java/org/jsoup/select/Elements.java -index 31838e1f..a64f322b 100644 ---- a/src/main/java/org/jsoup/select/Elements.java -+++ b/src/main/java/org/jsoup/select/Elements.java -@@ -14,14 +14,17 @@ import java.util.ArrayList; - import java.util.Arrays; - import java.util.Collection; - import java.util.HashSet; -+import java.util.Iterator; - import java.util.LinkedHashSet; - import java.util.List; -+import java.util.function.Predicate; -+import java.util.function.UnaryOperator; - - /** - A list of {@link Element}s, with methods that act on every element in the list. --

-- To get an {@code Elements} object, use the {@link Element#select(String)} method. --

-+

To get an {@code Elements} object, use the {@link Element#select(String)} method.

-+

Methods that {@link #set(int, Element) set}, {@link #remove(int) remove}, or {@link #replaceAll(UnaryOperator) -+ replace} Elements in the list will also act on the underlying {@link org.jsoup.nodes.Document DOM}.

- - @author Jonathan Hedley, jonathan@hedley.net */ - public class Elements extends ArrayList { -@@ -431,6 +434,7 @@ public class Elements extends ArrayList { - - /** - * Remove each matched element from the DOM. This is similar to setting the outer HTML of each element to nothing. -+ *

The elements will still be retained in this list, in case further processing of them is desired.

- *

- * E.g. HTML: {@code

Hello

there

}
- * doc.select("p").remove();
-@@ -440,6 +444,7 @@ public class Elements extends ArrayList { - * @return this, for chaining - * @see Element#empty() - * @see #empty() -+ * @see #clear() - */ - public Elements remove() { - for (Element element : this) { -@@ -683,4 +688,121 @@ public class Elements extends ArrayList { - return nodes; - } - -+ // list methods that update the DOM: -+ -+ /** -+ Replace the Element at the specified index in this list, and in the DOM. -+ * @param index index of the element to replace -+ * @param element element to be stored at the specified position -+ * @return the old Element at this index -+ * @since 1.17.1 -+ */ -+ @Override public Element set(int index, Element element) { -+ Validate.notNull(element); -+ Element old = super.set(index, element); -+ old.replaceWith(element); -+ return old; -+ } -+ -+ /** -+ Remove the Element at the specified index in this ist, and from the DOM. -+ * @param index the index of the element to be removed -+ * @return the old element at this index -+ * @since 1.17.1 -+ */ -+ @Override public Element remove(int index) { -+ Element old = super.remove(index); -+ old.remove(); -+ return old; -+ } -+ -+ /** -+ Remove the specified Element from this list, and from th DOM -+ * @param o element to be removed from this list, if present -+ * @return if this list contained the Element -+ * @since 1.17.1 -+ */ -+ @Override public boolean remove(Object o) { -+ int index = super.indexOf(o); -+ if (index == -1) { -+ return false; -+ } else { -+ remove(index); -+ return true; -+ } -+ } -+ -+ /** -+ Removes all the elements from this list, and each of them from the DOM. -+ * @since 1.17.1 -+ * @see #remove() -+ */ -+ @Override public void clear() { -+ remove(); -+ super.clear(); -+ } -+ -+ /** -+ Removes from this list, and from the DOM, each of the elements that are contained in the specified collection and -+ are in this list. -+ * @param c collection containing elements to be removed from this list -+ * @return {@code true} if elements were removed from this list -+ * @since 1.17.1 -+ */ -+ @Override public boolean removeAll(Collection c) { -+ boolean anyRemoved = false; -+ for (Object o : c) { -+ anyRemoved |= this.remove(o); -+ } -+ return anyRemoved; -+ } -+ -+ /** -+ Retain in this list, and in the DOM, only the elements that are in the specified collection and are in this list. -+ In other words, remove elements from this list and the DOM any item that is in this list but not in the specified -+ collection. -+ * @param c collection containing elements to be retained in this list -+ * @return {@code true} if elements were removed from this list -+ * @since 1.17.1 -+ */ -+ @Override public boolean retainAll(Collection c) { -+ boolean anyRemoved = false; -+ for (Iterator it = this.iterator(); it.hasNext(); ) { -+ Element el = it.next(); -+ if (!c.contains(el)) { -+ it.remove(); -+ anyRemoved = true; -+ } -+ } -+ return anyRemoved; -+ } -+ -+ /** -+ Remove from the list, and from the DOM, all elements in this list that mach the given filter. -+ * @param filter a predicate which returns {@code true} for elements to be removed -+ * @return {@code true} if elements were removed from this list -+ * @since 1.17.1 -+ */ -+ @Override public boolean removeIf(Predicate filter) { -+ boolean anyRemoved = false; -+ for (Iterator it = this.iterator(); it.hasNext(); ) { -+ Element el = it.next(); -+ if (filter.test(el)) { -+ it.remove(); -+ anyRemoved = true; -+ } -+ } -+ return anyRemoved; -+ } -+ -+ /** -+ Replace each element in this list with the result of the operator, and update the DOM. -+ * @param operator the operator to apply to each element -+ * @since 1.17.1 -+ */ -+ @Override public void replaceAll(UnaryOperator operator) { -+ for (int i = 0; i < this.size(); i++) { -+ this.set(i, operator.apply(this.get(i))); -+ } -+ } - } diff --git a/data/project_id.json b/data/project_id.json index 782d2b9b..8d676cce 100644 --- a/data/project_id.json +++ b/data/project_id.json @@ -91,7 +91,7 @@ }, "openapi-generator": { "owner": "OpenAPITools", - "number_of_bugs": 5, + "number_of_bugs": 6, "commit_db": "commit_db/openapi-generator_bugs.csv", "repo_path": "/root/framework/repos/openapi-generator", "requirements": { @@ -170,7 +170,7 @@ }, "rocketmq": { "owner": "apache", - "number_of_bugs": 17, + "number_of_bugs": 18, "commit_db": "commit_db/rocketmq_bugs.csv", "repo_path": "/root/framework/repos/rocketmq", "requirements": { diff --git a/data/test_diff/OpenAPITools_openapi-generator-17759.diff b/data/test_diff/OpenAPITools_openapi-generator-17759.diff new file mode 100644 index 00000000..36300658 --- /dev/null +++ b/data/test_diff/OpenAPITools_openapi-generator-17759.diff @@ -0,0 +1,137 @@ +diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaValidationArrayPrimitivesTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaValidationArrayPrimitivesTest.java +index 7d20e42b195..648df284a0e 100644 +--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaValidationArrayPrimitivesTest.java ++++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaValidationArrayPrimitivesTest.java +@@ -64,13 +64,13 @@ public class JavaValidationArrayPrimitivesTest { + .withType("List<@Max(10) Integer>") + .toType() + .hasProperty("numberMinMax") +- .withType("List<@DecimalMin(value = \"1\", inclusive = false) @DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMin(value = \"1\", inclusive = true) @DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("numberMin") +- .withType("List<@DecimalMin(value = \"1\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMin(value = \"1\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("numberMax") +- .withType("List<@DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("stringPatternWithMin") + .withType("Set<@Pattern(regexp = \"^\\\\d{3}-\\\\d{2}-\\\\d{4}$\") @Size(min = 10) String>") +@@ -88,7 +88,7 @@ public class JavaValidationArrayPrimitivesTest { + .withType("Set<@Size(max = 1) String>") + .toType() + .hasProperty("stringNumbers") +- .withType("Set<@DecimalMin(value = \"1\", inclusive = false) @DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("Set<@DecimalMin(value = \"1\", inclusive = true) @DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("intMinMaxNullable") + .withType("List<@Min(1) @Max(10) Integer>") +@@ -100,13 +100,13 @@ public class JavaValidationArrayPrimitivesTest { + .withType("List<@Max(10) Integer>") + .toType() + .hasProperty("numberMinMaxNullable") +- .withType("List<@DecimalMin(value = \"1\", inclusive = false) @DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMin(value = \"1\", inclusive = true) @DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("numberMinNullable") +- .withType("List<@DecimalMin(value = \"1\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMin(value = \"1\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("numberMaxNullable") +- .withType("List<@DecimalMax(value = \"10\", inclusive = true) BigDecimal>") ++ .withType("List<@DecimalMax(value = \"10\", inclusive = false) BigDecimal>") + .toType(); + } + +@@ -138,13 +138,13 @@ public class JavaValidationArrayPrimitivesTest { + .withType("List<@Max(10) Integer>") + .toType() + .hasProperty("numberMinMax") +- .withType("List<@DecimalMin(value = \"1\", inclusive = false) @DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMin(value = \"1\", inclusive = true) @DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("numberMin") +- .withType("List<@DecimalMin(value = \"1\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMin(value = \"1\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("numberMax") +- .withType("List<@DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("List<@DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("stringPatternWithMin") + .withType("JsonNullable>") +@@ -162,7 +162,7 @@ public class JavaValidationArrayPrimitivesTest { + .withType("JsonNullable>") + .toType() + .hasProperty("stringNumbers") +- .withType("Set<@DecimalMin(value = \"1\", inclusive = false) @DecimalMax(value = \"10\", inclusive = false) BigDecimal>") ++ .withType("Set<@DecimalMin(value = \"1\", inclusive = true) @DecimalMax(value = \"10\", inclusive = true) BigDecimal>") + .toType() + .hasProperty("intMinMaxNullable") + .withType("JsonNullable>") +@@ -174,13 +174,13 @@ public class JavaValidationArrayPrimitivesTest { + .withType("JsonNullable>") + .toType() + .hasProperty("numberMinMaxNullable") +- .withType("JsonNullable>") ++ .withType("JsonNullable>") + .toType() + .hasProperty("numberMinNullable") +- .withType("JsonNullable>") ++ .withType("JsonNullable>") + .toType() + .hasProperty("numberMaxNullable") +- .withType("JsonNullable>") ++ .withType("JsonNullable>") + .toType(); + } + +diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +index b6d5ee64209..edf1c088aa1 100644 +--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java ++++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +@@ -973,8 +973,6 @@ public class SpringCodegenTest { + .withType( "Set" ); + } + +- +- + @Test + public void shouldAddValidAnnotationIntoCollectionWhenBeanValidationIsEnabled_issue17150() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); +@@ -1025,13 +1023,13 @@ public class SpringCodegenTest { + .withType( "List<@Max(10) Integer>" ) + .toType() + .hasProperty("numberMinMax") +- .withType( "List<@DecimalMin(value = \"1\", inclusive = false) @DecimalMax(value = \"10\", inclusive = false) BigDecimal>" ) ++ .withType( "List<@DecimalMin(value = \"1\", inclusive = true) @DecimalMax(value = \"10\", inclusive = true) BigDecimal>" ) + .toType() + .hasProperty("numberMin") +- .withType( "List<@DecimalMin(value = \"1\", inclusive = false) BigDecimal>" ) ++ .withType( "List<@DecimalMin(value = \"1\", inclusive = true) BigDecimal>" ) + .toType() + .hasProperty("numberMax") +- .withType( "List<@DecimalMax(value = \"10\", inclusive = false) BigDecimal>" ) ++ .withType( "List<@DecimalMax(value = \"10\", inclusive = true) BigDecimal>" ) + .toType() + + .hasProperty("stringPatternNullable") +@@ -1056,13 +1054,13 @@ public class SpringCodegenTest { + .withType( "JsonNullable>" ) + .toType() + .hasProperty("numberMinMaxNullable") +- .withType( "JsonNullable>" ) ++ .withType( "JsonNullable>" ) + .toType() + .hasProperty("numberMinNullable") +- .withType( "JsonNullable>" ) ++ .withType( "JsonNullable>" ) + .toType() + .hasProperty("numberMaxNullable") +- .withType( "JsonNullable>" ) ++ .withType( "JsonNullable>" ) + .toType() + ; + } diff --git a/data/test_diff/apache_rocketmq-7712.diff b/data/test_diff/apache_rocketmq-7712.diff new file mode 100644 index 00000000..b217ff16 --- /dev/null +++ b/data/test_diff/apache_rocketmq-7712.diff @@ -0,0 +1,20 @@ +diff --git a/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java b/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java +index 2d22d5254..a2b498f07 100644 +--- a/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java ++++ b/common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java +@@ -142,6 +142,15 @@ public class UtilAllTest { + assertEquals("", UtilAll.join(objects, comma)); + } + ++ @Test ++ public void testSplit() { ++ List list = Arrays.asList("groupA=DENY", "groupB=PUB|SUB", "groupC=SUB"); ++ String comma = ","; ++ assertEquals(list, UtilAll.split("groupA=DENY,groupB=PUB|SUB,groupC=SUB", comma)); ++ assertEquals(null, UtilAll.split(null, comma)); ++ assertEquals(Collections.EMPTY_LIST, UtilAll.split("", comma)); ++ } ++ + static class DemoConfig { + private int demoWidth = 0; + private int demoLength = 0; diff --git a/debug/collector.py b/debug/collector.py index 79ab8bf2..cb1d942b 100644 --- a/debug/collector.py +++ b/debug/collector.py @@ -121,6 +121,22 @@ def remove_test_diff (): if name not in all_bug: sp.run(["rm", "-rf", f"/root/framework/data/test_diff/{name}.diff"]) +def remove_prod_diff (): + all_bug = [] + for file in os.listdir("/root/framework/verified_bug/"): + with open("/root/framework/verified_bug/" + file, 'r') as f: + active_bug_list = json.load(f) + for key in active_bug_list.keys(): + all_bug.append(key) + i = 0 + bug_dict = defaultdict(int) + + for diff in os.listdir("/root/framework/data/prod_diff/"): + bug_dict[diff.split("_")[-2] + "_" + diff.split("_")[-1].split("-")[0]] += 1 + name = diff.replace(".diff", "") + if name not in all_bug: + sp.run(["rm", "-rf", f"/root/framework/data/prod_diff/{name}.diff"]) + if __name__ == '__main__': @@ -129,4 +145,4 @@ def remove_test_diff (): find_og_collector() find_total_bug() remove_test_diff() - \ No newline at end of file + remove_prod_diff() \ No newline at end of file diff --git a/repos/assertj b/repos/assertj index cdeb4899..86b25caa 160000 --- a/repos/assertj +++ b/repos/assertj @@ -1 +1 @@ -Subproject commit cdeb48992f24daf4d63d102a7b4eabd74e950a39 +Subproject commit 86b25caa0a1a40c5778b53b7c549a86b00b87547 diff --git a/repos/dubbo b/repos/dubbo index f995ef50..b0779569 160000 --- a/repos/dubbo +++ b/repos/dubbo @@ -1 +1 @@ -Subproject commit f995ef506c2e3306f9cbcd4bc33ad169a3da0b7e +Subproject commit b0779569538ef1b5bd47d62618de1520f1e18489 diff --git a/repos/jackson-core b/repos/jackson-core index a4ca94f4..25b93530 160000 --- a/repos/jackson-core +++ b/repos/jackson-core @@ -1 +1 @@ -Subproject commit a4ca94f4cfe2030d1313a0038f0b8de6fd6b811e +Subproject commit 25b935309fda75e6c66e045b2adecf151fc9ac3e diff --git a/repos/jackson-databind b/repos/jackson-databind index 094f7b44..c210bdc7 160000 --- a/repos/jackson-databind +++ b/repos/jackson-databind @@ -1 +1 @@ -Subproject commit 094f7b445d95a768c529e7d8305809cb9f500022 +Subproject commit c210bdc72bd657af775e1912102d9e0d38a166f3 diff --git a/repos/openapi-generator b/repos/openapi-generator index 3224e863..6c35fe10 160000 --- a/repos/openapi-generator +++ b/repos/openapi-generator @@ -1 +1 @@ -Subproject commit 3224e86377836d26e579168b9aadb79f4b43af8f +Subproject commit 6c35fe1035bb8930e62928de15f4a6dedc23fb98 diff --git a/repos/rocketmq b/repos/rocketmq index 91349f30..af1936d9 160000 --- a/repos/rocketmq +++ b/repos/rocketmq @@ -1 +1 @@ -Subproject commit 91349f30b96db2e16b71d65a535d81f11b60bda5 +Subproject commit af1936d93ad9adab9527e19ceb5c89bb3a907e49 diff --git a/verified_bug/verified_bugs_OpenAPITools_openapi-generator.json b/verified_bug/verified_bugs_OpenAPITools_openapi-generator.json index c0d22a05..d436bf19 100644 --- a/verified_bug/verified_bugs_OpenAPITools_openapi-generator.json +++ b/verified_bug/verified_bugs_OpenAPITools_openapi-generator.json @@ -149,5 +149,43 @@ ".org.openapitools.codegen.DefaultCodegenTest.java" ] } + }, + "OpenAPITools_openapi-generator-17759": { + "bug_id": "OpenAPITools_openapi-generator-17759", + "PR_number": 17759, + "PR_createdAt": "2024-02-01T00:03:28Z", + "merge_commit": "6c35fe1035bb8930e62928de15f4a6dedc23fb98", + "buggy_commits": [ + { + "oid": "7c7634dda95eeb015e3a64375abf124f9031fecd", + "message": "add operation id option (#17750)" + }, + { + "oid": "b4a7dc3b5aee7521a43c40b924597bc20b673ee0", + "message": "Fix OpenAPITools#17757 - Include minimum and maximum values in arrays with number items" + } + ], + "issue": { + "url": "https://github.com/OpenAPITools/openapi-generator/issues/17757", + "createdAt": "2024-01-31T22:45:33Z", + "content": "bug_report_all/OpenAPITools_openapi-generator-17759.json" + }, + "changed_tests": [ + "modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaValidationArrayPrimitivesTest.java", + "modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java" + ], + "PR_url": "https://github.com/OpenAPITools/openapi-generator/pull/17759", + "merge_commit_url": "https://github.com/OpenAPITools/openapi-generator/commit/6c35fe1035bb8930e62928de15f4a6dedc23fb98", + "buggy_commit": "7c7634dda95eeb015e3a64375abf124f9031fecd", + "execution_result": { + "valid_tests": [ + ".org.openapitools.codegen.java.JavaValidationArrayPrimitivesTest.java", + ".org.openapitools.codegen.java.spring.SpringCodegenTest.java" + ], + "success_tests": [ + ".org.openapitools.codegen.java.JavaValidationArrayPrimitivesTest.java", + ".org.openapitools.codegen.java.spring.SpringCodegenTest.java" + ] + } } } \ No newline at end of file diff --git a/verified_bug/verified_bugs_apache_rocketmq.json b/verified_bug/verified_bugs_apache_rocketmq.json index dad67c84..5836a858 100644 --- a/verified_bug/verified_bugs_apache_rocketmq.json +++ b/verified_bug/verified_bugs_apache_rocketmq.json @@ -551,5 +551,36 @@ ".org.apache.rocketmq.tieredstore.file.TieredFlatFileTest.java" ] } + }, + "apache_rocketmq-7712": { + "bug_id": "apache_rocketmq-7712", + "PR_number": 7712, + "PR_createdAt": "2024-01-02T01:57:39Z", + "merge_commit": "806454bc5e29d2f157cde99bdb082f94cdb377fa", + "buggy_commits": [ + { + "oid": "9e4fd0e68a1ea6ab1b1f3344ac9ae79af29a32c2", + "message": "[ISSUE #7697] Fix can't open controller metricsExporter. (#7705)" + } + ], + "issue": { + "url": "https://github.com/apache/rocketmq/issues/7710", + "createdAt": "2024-01-01T11:13:31Z", + "content": "bug_report_all/apache_rocketmq-7712.json" + }, + "changed_tests": [ + "common/src/test/java/org/apache/rocketmq/common/UtilAllTest.java" + ], + "PR_url": "https://github.com/apache/rocketmq/pull/7712", + "merge_commit_url": "https://github.com/apache/rocketmq/commit/806454bc5e29d2f157cde99bdb082f94cdb377fa", + "buggy_commit": "9e4fd0e68a1ea6ab1b1f3344ac9ae79af29a32c2", + "execution_result": { + "valid_tests": [ + ".org.apache.rocketmq.common.UtilAllTest.java" + ], + "success_tests": [ + ".org.apache.rocketmq.common.UtilAllTest.java" + ] + } } } \ No newline at end of file diff --git a/verify_bug.py b/verify_bug.py index f0220936..461f2fd4 100644 --- a/verify_bug.py +++ b/verify_bug.py @@ -144,7 +144,7 @@ }, 'iluwatar_java-design-patterns': { 'repo_path': file_path + '/repos/java-design-patterns', - 'project_name': 'iluwatar_java-design-patterns' + 'project_name': 'iluwatar_java-design-patterns', }, 'dbeaver_dbeaver': { 'repo_path': file_path + '/repos/dbeaver', @@ -152,11 +152,13 @@ }, 'seata_seata': { 'repo_path': file_path + '/repos/seata', - 'project_name': 'seata_seata' + 'project_name': 'seata_seata', + 'project_id': 'seata' }, 'OpenAPITools_openapi-generator': { 'repo_path': file_path + '/repos/openapi-generator', - 'project_name': 'OpenAPITools_openapi-generator' + 'project_name': 'OpenAPITools_openapi-generator', + 'project_id': 'openapi-generator' }, 'apache_shardingsphere': { 'repo_path': file_path + '/repos/shardingsphere', @@ -164,7 +166,8 @@ }, 'alibaba_nacos': { 'repo_path': file_path + '/repos/nacos', - 'project_name': 'alibaba_nacos' + 'project_name': 'alibaba_nacos', + 'project_id': 'nacos' }, 'keycloak_keycloak': { 'repo_path': file_path + '/repos/keycloak', @@ -180,7 +183,8 @@ }, 'iBotPeaches_Apktool': { 'repo_path': file_path + '/repos/Apktool', - 'project_name': 'iBotPeaches_Apktool' + 'project_name': 'iBotPeaches_Apktool', + 'project_id': 'Apktool' }, 'spring-projects_spring-framework': { 'repo_path': file_path + '/repos/spring-framework', @@ -188,11 +192,13 @@ }, 'square_retrofit': { 'repo_path': file_path + '/repos/retrofit', - 'project_name': 'square_retrofit' + 'project_name': 'square_retrofit', + 'project_id': 'retrofit' }, 'javaparser_javaparser': { 'repo_path': file_path + '/repos/javaparser', - 'project_name': 'javaparser_javaparser' + 'project_name': 'javaparser_javaparser', + 'project_id': 'javaparser' } } @@ -289,9 +295,106 @@ def get_project_from_bug_id(bug_id): for project_identifier in config: if project_identifier in bug_id: return project_identifier + +def get_project_id_from_project(project): + return config[project]['project_id'] + +def find_env (pid): + with open("/root/framework/data/project_id.json", "r") as f: + project_id = json.load(f) + if pid not in project_id.keys(): + output = "No matching project id" + return output -def verify_in_buggy_version(buggy_commit, test_patch_dir, repo_path, test_prefix, build): + requirements = project_id[pid]["requirements"] + if len(requirements["extra"]) != 0: + extra = requirements["extra"] + + build = requirements["build"] + jdk_required = requirements["jdk"] + wrapper = requirements["wrapper"] + + mvn_required = None + mvnw = False + gradlew = False + + if build == "maven": + if wrapper: + mvnw = True + else: + mvn_required = requirements["version"] + elif build == "gradle": + if wrapper: + gradlew = True + + JAVA_HOME = mvn_path = None + if jdk_required == '8': + JAVA_HOME = '/usr/lib/jvm/java-8-openjdk-amd64' + elif jdk_required == '11': + JAVA_HOME = '/usr/lib/jvm/java-11-openjdk-amd64' + elif jdk_required == '17': + JAVA_HOME = '/usr/lib/jvm/java-17-openjdk-amd64' + + if mvn_required is None: + mvn_path = None + elif mvn_required == '3.8.6': + mvn_path = '/opt/apache-maven-3.8.6/bin' + elif mvn_required == '3.8.1': + mvn_path = '/opt/apache-maven-3.8.1/bin' + + new_env = os.environ.copy() + new_env['JAVA_HOME'] = JAVA_HOME + if mvn_path is not None: + new_env['PATH'] = os.pathsep.join([mvn_path, new_env['PATH']]) + + return new_env, mvnw, gradlew + + +def run_test (new_env, mvnw, gradlew, test_case, path, command=None): + + if not mvnw and not gradlew: + default = ['timeout', '30m', 'mvn', 'test', f'-Dtest={test_case}', '-DfailIfNoTests=false', '--errors'] + if command is not None: + extra_command = command.split() + new_command = default + extra_command + run = sp.run(new_command, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + else: + run = sp.run(default, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + + elif mvnw: + default = ['timeout', '10m', './mvnw', 'test', f'-Dtest={test_case}', '-DfailIfNoTests=false', '--errors'] + if command is not None: + extra_command = command.split() + new_command = default + extra_command + + run = sp.run(new_command, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + else: + run = sp.run(default, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + elif gradlew: + default = ["./gradlew", "test", "--tests", f'{test_case}', '--info', '--stacktrace'] + if command is not None: + if 'test' in command: + new_command = ["./gradlew", command, '--tests', f'{test_case}'] + run = sp.run(new_command, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + else: + run = sp.run(new_command, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + else: + run = sp.run(default, + env=new_env, stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) + + stdout = run.stdout.decode() + stderr = run.stderr.decode() + + return stdout, stderr + +def verify_in_buggy_version(buggy_commit, test_patch_dir, repo_path, test_prefix, build, pid): #print(repo_path, buggy_commit, test_patch_dir) p = sp.run(['git', 'reset', '--hard', 'HEAD'], @@ -328,6 +431,17 @@ def verify_in_buggy_version(buggy_commit, test_patch_dir, repo_path, test_prefix print("changed_test_files: ", changed_test_files) + + new_env, mvnw, gradlew = find_env(pid) + + with open("/root/framework/data/project_id.json", "r") as f: + project_id = json.load(f) + + if len(project_id[pid]['requirements']['extra']) != 0: + command = project_id[pid]['requirements']['extra']['command'] + else: + command = None + fix_build_env(repo_path) modules = [] @@ -358,33 +472,13 @@ def find_repo_path (x): valid_tests = [] for idx, test_id in enumerate(changed_test_id): - if build == "maven": + captured_stdout, captured_stderr = run_test (new_env, mvnw, gradlew, test_id, repo_path, command) - test_process = sp.run(['timeout', '30m', 'mvn', 'clean', 'test', '-Denforcer.skip=true', - f'-Dtest={test_id}', '-DfailIfNoTests=false', '-Dsurefire.failIfNoSpecifiedTests=false'], stdout=sp.PIPE, stderr=sp.PIPE, cwd=repo_path) - elif build == 'gradle': - - test_process = sp.run(['./gradlew', 'clean', ':test', - '--tests', f'{test_id}'], stdout=sp.PIPE, stderr=sp.PIPE, cwd=repo_path) - elif build == "maven-specify": - - test_process = sp.run(['timeout', '10m', './mvnw', 'clean', 'test', '-DfailIfNoTests=false', '-Denforcer.skip=true', - '-Djacoco.skip=true', '-Dcheckstyle.skip=true', - '-Dmaven.javadoc.skip=true', "-Dargline='-Xmx1024m'", - f'-Dtest={test_id}', - '-Dsurefire.failIfNoSpecifiedTests=false'], stdout=sp.PIPE, stderr=sp.PIPE, cwd=repo_path) - - captured_stdout = test_process.stdout.decode() - captured_stderr = test_process.stderr.decode() - - - if build == 'maven' and 'There are test failures' in captured_stdout: - print("There are test failures") - valid_tests.append(test_id) - elif build == 'maven-specify' and 'There are test failures' in captured_stdout: + #print(captured_stdout) + if 'There are test failures' in captured_stdout: print("There are test failures") valid_tests.append(test_id) - elif build == 'gradle' and 'There were failing tests' in captured_stderr: + elif 'There were failing tests' in captured_stderr: print("There were failing tests") valid_tests.append(test_id) @@ -394,7 +488,7 @@ def find_repo_path (x): return valid_tests, repo_path, modules -def verify_in_fixed_version(fixed_commit, target_test_classes, repo_path, test_prefix, build, modules): +def verify_in_fixed_version(fixed_commit, target_test_classes, repo_path, test_prefix, build, modules, pid): sp.run(['git', 'reset', '--hard', 'HEAD'], cwd=repo_path, stdout=sp.DEVNULL, stderr=sp.DEVNULL) @@ -403,39 +497,33 @@ def verify_in_fixed_version(fixed_commit, target_test_classes, repo_path, test_p sp.run(['git', 'checkout', fixed_commit], cwd=repo_path) + + new_env, mvnw, gradlew = find_env(pid) + + with open("/root/framework/data/project_id.json", "r") as f: + project_id = json.load(f) + + if len(project_id[pid]['requirements']['extra']) != 0: + command = project_id[pid]['requirements']['extra']['command'] + else: + command = None + fix_build_env(repo_path) valid_tests = [] print("target_test_classes: ", target_test_classes) for idx, test_id in enumerate(target_test_classes): - print(test_id) - if build == 'maven': - test_process = sp.run(['mvn', 'clean', 'test', '-Denforcer.skip=true', - f'-Dtest={test_id}', '-DfailIfNoTests=false', '-Dsurefire.failIfNoSpecifiedTests=false'], capture_output=True, cwd=repo_path) - - elif build == 'gradle': - test_process = sp.run(['./gradlew', 'clean', ':test', - '--tests', f'{test_id}'], stdout=sp.PIPE, stderr=sp.PIPE, cwd=repo_path) - elif build == "maven-specify": - test_process = sp.run(['timeout', '25m', './mvnw', 'clean', 'test', '-DfailIfNoTests=false', '-Denforcer.skip=true', - '-Djacoco.skip=true', '-Dcheckstyle.skip=true', - '-Dmaven.javadoc.skip=true', "-Dargline='-Xmx1024m'", - f'-Dtest={test_id}', - '-Dsurefire.failIfNoSpecifiedTests=false'], stdout=sp.PIPE, stderr=sp.PIPE, cwd=repo_path) - captured_stdout = test_process.stdout.decode() - captured_stderr = test_process.stderr.decode() - - if build == 'maven' and 'BUILD SUCCESS' in captured_stdout: + + captured_stdout, captured_stderr = run_test (new_env, mvnw, gradlew, test_id, repo_path, command) + + if 'BUILD SUCCESS' in captured_stdout: print("Maven build success") valid_tests.append(test_id) - elif build == 'gradle' and 'BUILD SUCCESSFUL' in captured_stdout: + elif 'BUILD SUCCESSFUL' in captured_stdout: print("Gradle build success") valid_tests.append(test_id) - elif build == 'maven-specify' and 'BUILD SUCCESS' in captured_stdout: - print("Maven specify build success") - valid_tests.append(test_id) - elif (build=='maven-specify' or build=='maven') and 'There are test failures' in captured_stdout: + elif 'There are test failures' in captured_stdout or 'There were failing tests' in captured_stdout: print("Test failed in fixed version") return valid_tests @@ -452,12 +540,14 @@ def verify_bug(bug_id, buggy_commit, fixed_commit, build='maven'): print(bug_id) test_patch_dir = os.path.abspath(os.path.join( './collected/test_diff', f'{bug_id}.diff')) + + pid = get_project_id_from_project (project) valid_tests, specified_repo_path, modules = verify_in_buggy_version( - buggy_commit, test_patch_dir, repo_path, test_prefix, build) + buggy_commit, test_patch_dir, repo_path, test_prefix, build, pid) success_tests = verify_in_fixed_version( - fixed_commit, valid_tests, specified_repo_path, test_prefix, build, modules) + fixed_commit, valid_tests, specified_repo_path, test_prefix, build, modules, pid) print("valid: ", valid_tests, "success: ", success_tests) return valid_tests, success_tests @@ -773,6 +863,7 @@ def fetch_prod_diff (report_map): if test_output.find("Failure") != -1: print("failure for fixed version") wrong_bugs.append(bug_name) + continue for wb in wrong_bugs: print("wrong bug: ", wb)