소스 검색

TermExpressionParser增加对带空格字符串的支持

Jia_RG 5 년 전
부모
커밋
59a7cc7c5e

+ 32 - 5
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/param/TermExpressionParser.java

@@ -19,19 +19,37 @@ public class TermExpressionParser {
 
         NestConditional<?> nest = null;
 
+        // 字符容器
         char[] buf = new char[128];
+        // 记录词项的长度, Arrays.copyOf使用
         byte len = 0;
+        // 空格数量?
         byte spaceLen = 0;
-
+        // 当前列
         char[] currentColumn = null;
-
-        String currentTermType = null;
+        // 当前列对应的值
         char[] currentValue = null;
-        char[] all = expression.toCharArray();
+        // 当前条件类型 eq btw in ...
+        String currentTermType = null;
+        // 当前链接类型 and / or
         String currentType = "and";
+        // 是否是引号, 单引号 / 双引号
+        byte quotationMarks = 0;
+        // 表达式字符数组
+        char[] all = expression.toCharArray();
+
         for (char c : all) {
 
-            if (c == '(') {
+            if (c == '\'' || c == '"') {
+                if (quotationMarks != 0) {
+                    // 碰到(结束的)单/双引号, 标志归零, 跳过
+                    quotationMarks = 0;
+                    continue;
+                }
+                // 碰到(开始的)单/双引号, 做记录, 跳过
+                quotationMarks++;
+                continue;
+            } else if (c == '(') {
                 nest = (nest == null ?
                         (currentType.equals("or") ? conditional.orNest() : conditional.nest()) :
                         (currentType.equals("or") ? nest.orNest() : nest.nest()));
@@ -70,6 +88,11 @@ public class TermExpressionParser {
                 if (len == 0) {
                     continue;
                 }
+                if (quotationMarks != 0) {
+                    // 如果当前字符是空格,并且前面迭代时碰到过单/双引号, 不处理并且添加到buf中
+                    buf[len++] = c;
+                    continue;
+                }
                 spaceLen++;
                 if (currentColumn == null && (spaceLen == 1 || spaceLen % 5 == 0)) {
                     currentColumn = Arrays.copyOf(buf, len);
@@ -117,6 +140,10 @@ public class TermExpressionParser {
                         len = 0;
                         spaceLen++;
                     }
+                } else {
+                    currentColumn = Arrays.copyOf(buf, len);
+                    len = 0;
+                    spaceLen++;
                 }
                 continue;
             }

+ 24 - 0
hsweb-commons/hsweb-commons-entity/src/test/java/org/hswebframework/web/commons/entity/param/TermExpressionParserTest.java

@@ -51,7 +51,31 @@ public class TermExpressionParserTest {
         Assert.assertEquals(terms.get(2).getValue(), "test2");
         Assert.assertEquals(terms.get(2).getTermType(), "like");
 
+    }
+
+    /**
+     * 测试日期字符串空格解析,'2019-07-26 12:00:00'
+     */
+    @Test
+    public void testDateSpace() {
+        String expression = "(name=测试 or age=10) and (birth btw \"2019-07-26 12:00:00, 2019-08-04 12:00:00\" or startTime <= '2019-08-04 12:00:00') and finishTime >= '2019-08-01 00:00:00'";
+        List<Term> terms = TermExpressionParser.parse(expression);
+        System.out.println(JSON.toJSONString(terms, SerializerFeature.PrettyFormat));
+
+        Assert.assertEquals(terms.size(), 3);
+        Assert.assertEquals(terms.get(0).getTerms().size(), 2);
+
+        Assert.assertEquals(terms.get(1).getTerms().get(0).getColumn(), "birth");
+        Assert.assertEquals(terms.get(1).getTerms().get(0).getTermType(), "btw");
+        Assert.assertEquals(terms.get(1).getTerms().get(0).getValue(), "2019-07-26 12:00:00, 2019-08-04 12:00:00");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getColumn(), "startTime");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getTermType(), "lte");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getValue(), "2019-08-04 12:00:00");
+        Assert.assertEquals(terms.get(1).getTerms().get(1).getType(), Term.Type.or);
 
+        Assert.assertEquals(terms.get(2).getColumn(), "finishTime");
+        Assert.assertEquals(terms.get(2).getValue(), "2019-08-01 00:00:00");
+        Assert.assertEquals(terms.get(2).getTermType(), "gte");
     }
 
 }