activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cshan...@apache.org
Subject [1/2] activemq git commit: https://issues.apache.org/jira/browse/AMQ-6036
Date Thu, 04 Feb 2016 16:11:10 GMT
Repository: activemq
Updated Branches:
  refs/heads/master 25ff5699f -> 5eeb62a6b


https://issues.apache.org/jira/browse/AMQ-6036

Parsing message selector for wildcard matches for ignoreWildcardSelectors feature


Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/278d29da
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/278d29da
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/278d29da

Branch: refs/heads/master
Commit: 278d29dadc9bc92971d35e9433caeabb347323b9
Parents: 25ff569
Author: Patrik Dudits <patrik@dudits.net>
Authored: Mon Nov 9 09:18:16 2015 +0100
Committer: Patrik Dudits <patrik@dudits.net>
Committed: Thu Feb 4 16:51:51 2016 +0100

----------------------------------------------------------------------
 .../plugin/SubQueueSelectorCacheBroker.java     | 57 ++++++++++++++++++-
 ...SubQueueSelectorCacheBrokerWildcardTest.java | 60 ++++++++++++++++++++
 2 files changed, 114 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq/blob/278d29da/activemq-broker/src/main/java/org/apache/activemq/plugin/SubQueueSelectorCacheBroker.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/plugin/SubQueueSelectorCacheBroker.java
b/activemq-broker/src/main/java/org/apache/activemq/plugin/SubQueueSelectorCacheBroker.java
index f76f75e..30c8784 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/plugin/SubQueueSelectorCacheBroker.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/plugin/SubQueueSelectorCacheBroker.java
@@ -27,6 +27,8 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.management.JMException;
 import javax.management.ObjectName;
@@ -165,9 +167,9 @@ public class SubQueueSelectorCacheBroker extends BrokerFilter implements
Runnabl
         return super.addConsumer(context, info);
     }
 
-    // trivial check for SQL92/selector wildcards
-    private boolean hasWildcards(String selector) {
-        return selector.contains("%") || selector.contains("_");
+
+    static boolean hasWildcards(String selector) {
+        return new WildcardFinder(selector).hasWildcards();
     }
 
     @Override
@@ -306,5 +308,54 @@ public class SubQueueSelectorCacheBroker extends BrokerFilter implements
Runnabl
     public void setIgnoreWildcardSelectors(boolean ignoreWildcardSelectors) {
         this.ignoreWildcardSelectors = ignoreWildcardSelectors;
     }
+
+    // find wildcards inside like operator arguments
+    static class WildcardFinder {
+
+        private static final Pattern LIKE_PATTERN=Pattern.compile(
+                "\\bLIKE\\s+'(?<like>([^']|'')+)'(\\s+ESCAPE\\s+'(?<escape>.)')?",
+                Pattern.CASE_INSENSITIVE);
+
+        private static final String REGEX_SPECIAL = ".+?*(){}[]\\-";
+        private final Matcher matcher;
+
+        WildcardFinder(String selector) {
+            this.matcher = LIKE_PATTERN.matcher(selector);
+        }
+
+        private String getLike() {
+            return matcher.group("like");
+        }
+
+        private String getEscape() {
+            String escapeChar = matcher.group("escape");
+            if (escapeChar == null) {
+                return null;
+            } else if (REGEX_SPECIAL.contains(escapeChar)) {
+                escapeChar = "\\"+escapeChar;
+            }
+            return escapeChar;
+        }
+
+        private boolean hasLikeOperator() {
+            return matcher.find();
+        }
+
+        boolean hasWildcardInCurrentMatch() {
+            String wildcards = "[_%]";
+            if (getEscape() != null) {
+                wildcards = "(^|[^" + getEscape() + "])" + wildcards;
+            }
+            return Pattern.compile(wildcards).matcher(getLike()).find();
+        }
+
+        public boolean hasWildcards() {
+            while(hasLikeOperator()) {
+                if (hasWildcardInCurrentMatch())
+                    return true;
+            }
+            return false;
+        }
+    }
 }
 

http://git-wip-us.apache.org/repos/asf/activemq/blob/278d29da/activemq-broker/src/test/java/org/apache/activemq/plugin/SubQueueSelectorCacheBrokerWildcardTest.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/test/java/org/apache/activemq/plugin/SubQueueSelectorCacheBrokerWildcardTest.java
b/activemq-broker/src/test/java/org/apache/activemq/plugin/SubQueueSelectorCacheBrokerWildcardTest.java
new file mode 100644
index 0000000..bc9c357
--- /dev/null
+++ b/activemq-broker/src/test/java/org/apache/activemq/plugin/SubQueueSelectorCacheBrokerWildcardTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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.activemq.plugin;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests that presence of wildcard characters is correctly identified by SubQueueSelectorCacheBroker
+ */
+public class SubQueueSelectorCacheBrokerWildcardTest {
+    @Test
+    public void testSimpleWildcardEvaluation()  {
+        assertWildcard(true, "modelInstanceId = '170' AND modelClassId LIKE 'com.whatever.something.%'");
+        assertWildcard(true, "JMSMessageId LIKE '%'");
+        assertWildcard(false, "modelClassId = 'com.whatever.something.%'");
+    }
+
+    @Test
+    public void testEscapedWildcardEvaluation() {
+        assertWildcard(true, "foo LIKE '!_%' ESCAPE '!'");
+        assertWildcard(false, "_foo__ LIKE '!_!%' ESCAPE '!'");
+        assertWildcard(true, "_foo_ LIKE '_%' ESCAPE '.'");
+        assertWildcard(true, "JMSMessageId LIKE '%' ESCAPE '.'");
+        assertWildcard(false, "_foo_ LIKE '\\_\\%' ESCAPE '\\'");
+    }
+
+    @Test
+    public void testNonWildard() {
+        assertWildcard(false, "type = 'UPDATE_ENTITY'");
+        assertWildcard(false, "a_property = 1");
+        assertWildcard(false, "percentage = '100%'");
+    }
+
+    @Test
+    public void testApostrophes() {
+        assertWildcard(true, "quote LIKE '''In G_d We Trust'''");
+        assertWildcard(true, "quote LIKE '''In Gd We Trust''' OR quote not like '''In G_d
We Trust'''");
+    }
+
+    static void assertWildcard(boolean expected, String selector) {
+        assertEquals("Wildcard should "+(!expected ? " NOT ":"")+" be found in "+selector,
expected, SubQueueSelectorCacheBroker.hasWildcards(selector));
+    }
+}


Mime
View raw message