Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2020-05-22 11:53:36 +0000
committerAlexander Kurtakov2020-07-01 20:06:04 +0000
commit2c0dcf62f0676116ee51753cf60e8f38cd105d99 (patch)
tree96ef883f08223d7f9f4b88948427a53144f81827
parenta373993f5fd26cec102fe67dce28a4359bd366a0 (diff)
downloadrt.equinox.bundles-2c0dcf62f0676116ee51753cf60e8f38cd105d99.tar.gz
rt.equinox.bundles-2c0dcf62f0676116ee51753cf60e8f38cd105d99.tar.xz
rt.equinox.bundles-2c0dcf62f0676116ee51753cf60e8f38cd105d99.zip
Add a method to make the StringMatcher match on prefixes. Internally this just switches on wildcard matching and sets fHasTrailingStar to true. Because the pattern has already been parsed in the constructor, this gives an easy way to specify prefix matching for non-wildcard patterns without needing to escape potential wildcards in the pattern: StringMatcher m = new StringMatcher("foo*bar", false, true); m.usePrefixMatch(); This matcher will match any text starting with "foo*bar" (with a literal '*'), but not, for instance, "foobazbar". Change-Id: I525fbc1d42b16d661988655c8438894f8d6739e8 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java36
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java96
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java18
-rw-r--r--bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java57
6 files changed, 199 insertions, 12 deletions
diff --git a/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF
index c5b6a6e2c..54044befd 100644
--- a/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF
@@ -7,7 +7,7 @@ Automatic-Module-Name: org.eclipse.equinox.common.tests
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Require-Bundle: org.junit,
- org.eclipse.equinox.common;bundle-version="3.12.0",
+ org.eclipse.equinox.common;bundle-version="3.13.0",
org.eclipse.core.tests.harness;bundle-version="3.11.400",
org.eclipse.equinox.registry;bundle-version="3.8.200"
Import-Package: org.eclipse.osgi.service.localization,
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java
new file mode 100644
index 000000000..d4dc5ad38
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.text;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.core.text.StringMatcher;
+import org.junit.Test;
+
+public class StringMatcherOtherTest {
+
+ @Test
+ public void testEmptyNoWildcard() {
+ StringMatcher m = new StringMatcher("", false, true);
+ assertTrue(m.match(""));
+ assertFalse(m.match("foo"));
+ assertFalse(m.match("foo bar"));
+ }
+
+ @Test
+ public void testEmptyWildcard() {
+ StringMatcher m = new StringMatcher("", false, false);
+ assertTrue(m.match(""));
+ assertFalse(m.match("foo"));
+ assertFalse(m.match("foo bar"));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java
new file mode 100644
index 000000000..89d39c466
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.text;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.core.text.StringMatcher;
+import org.junit.Test;
+
+public class StringMatcherPrefixTest {
+
+ @Test
+ public void testNoPrefix() {
+ StringMatcher m = new StringMatcher("foo", false, true);
+ assertTrue(m.match("foo"));
+ assertFalse(m.match("foobar"));
+ assertFalse(m.match("foo bar"));
+ assertFalse(m.match("bar foo"));
+ assertFalse(m.match("bar foo bar"));
+ }
+
+ @Test
+ public void testEmptyNoWildcard() {
+ StringMatcher m = new StringMatcher("", false, true);
+ m.usePrefixMatch();
+ assertTrue(m.match(""));
+ assertFalse(m.match("foo"));
+ assertFalse(m.match("foo bar"));
+ }
+
+ @Test
+ public void testEmptyWildcard() {
+ StringMatcher m = new StringMatcher("", false, false);
+ m.usePrefixMatch();
+ assertTrue(m.match(""));
+ assertTrue(m.match("foo"));
+ assertTrue(m.match("foo bar"));
+ }
+
+ @Test
+ public void testPrefixNoWildcards() {
+ StringMatcher m = new StringMatcher("foo", false, true);
+ m.usePrefixMatch();
+ assertTrue(m.match("foo"));
+ assertTrue(m.match("foobar"));
+ assertTrue(m.match("foo bar"));
+ assertFalse(m.match("bar foo"));
+ assertFalse(m.match("bar foo bar"));
+ }
+
+ @Test
+ public void testPrefixWildcards() {
+ StringMatcher m = new StringMatcher("f?o", false, false);
+ m.usePrefixMatch();
+ assertTrue(m.match("foo"));
+ assertTrue(m.match("foobar"));
+ assertTrue(m.match("foo bar"));
+ assertFalse(m.match("bar foo"));
+ assertFalse(m.match("bar foo bar"));
+ }
+
+ @Test
+ public void testPrefixWildcardsOffSingle() {
+ StringMatcher m = new StringMatcher("f?o", false, true);
+ m.usePrefixMatch();
+ assertFalse(m.match("foo"));
+ assertTrue(m.match("f?o"));
+ assertFalse(m.match("foobar"));
+ assertTrue(m.match("f?obar"));
+ assertTrue(m.match("f?o bar"));
+ assertFalse(m.match("bar f?o"));
+ assertFalse(m.match("bar f?o bar"));
+ }
+
+ @Test
+ public void testPrefixWildcardsOffMulti() {
+ StringMatcher m = new StringMatcher("foo*bar", false, true);
+ m.usePrefixMatch();
+ assertFalse(m.match("foobar"));
+ assertFalse(m.match("foobazbar"));
+ assertTrue(m.match("foo*bar"));
+ assertFalse(m.match("foobarbaz"));
+ assertTrue(m.match("foo*barbaz"));
+ assertFalse(m.match("bar foo*bar"));
+ assertFalse(m.match("bar foo*barbaz"));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java
index dc4074354..7e9f54690 100644
--- a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
package org.eclipse.equinox.common.tests.text;
import org.junit.runner.RunWith;
@@ -6,9 +16,11 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
- StringMatcherFindTest.class,
- StringMatcherPlainTest.class,
- StringMatcherWildcardTest.class
+ StringMatcherFindTest.class,
+ StringMatcherPlainTest.class,
+ StringMatcherWildcardTest.class,
+ StringMatcherPrefixTest.class,
+ StringMatcherOtherTest.class
})
public class StringMatcherTests {
// empty
diff --git a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF
index 0f35a0805..fb17d96df 100644
--- a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF
@@ -15,7 +15,7 @@ Export-Package: org.eclipse.core.internal.boot;x-friends:="org.eclipse.core.reso
org.eclipse.core.filesystem,
org.eclipse.equinox.security",
org.eclipse.core.runtime;common=split;version="3.6.0";mandatory:=common,
- org.eclipse.core.text;version="3.12.0",
+ org.eclipse.core.text;version="3.13.0",
org.eclipse.equinox.events;version="1.0.0"
Bundle-Vendor: %providerName
Bundle-Activator: org.eclipse.core.internal.runtime.Activator
diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java
index 5183ff9db..b4a3371f7 100644
--- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java
+++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java
@@ -27,17 +27,17 @@ public final class StringMatcher {
private final int fLength; // pattern length
- private final boolean fIgnoreWildCards;
-
private final boolean fIgnoreCase;
+ private boolean fIgnoreWildCards;
+
private boolean fHasLeadingStar;
private boolean fHasTrailingStar;
private String fSegments[]; // the given pattern is split into * separated segments
- /* Boundary value beyond which we don't need to search in the text. */
+ /* Minimum length required for a match: shorter texts cannot possibly match. */
private int fBound = 0;
private static final char fSingleWildCard = '\u0000';
@@ -116,21 +116,28 @@ public final class StringMatcher {
* StringMatcher constructor takes in a String object that is a simple pattern.
* The pattern may contain '*' for 0 and many characters and '?' for exactly one
* character.
- *
+ * <p>
* Literal '*' and '?' characters must be escaped in the pattern e.g., "\*"
* means literal "*", etc.
- *
+ * </p>
+ * <p>
* The escape character '\' is an escape only if followed by '*', '?', or '\'.
* All other occurrences are taken literally.
- *
+ * </p>
+ * <p>
* If invoking the StringMatcher with string literals in Java, don't forget
* escape characters are represented by "\\".
+ * </p>
+ * <p
+ * An empty pattern matches only an empty text, unless {@link #usePrefixMatch()}
+ * is used, in which case it always matches.
+ * </p>
*
* @param pattern the pattern to match text against, must not be {@code null}
* @param ignoreCase if true, case is ignored
* @param ignoreWildCards if true, wild cards and their escape sequences are
* ignored (everything is taken literally).
- * @throws IllegalArgumentException if {@code pattern == null}
+ * @throws IllegalArgumentException if {@code pattern == null}
*/
public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
if (pattern == null) {
@@ -149,6 +156,23 @@ public final class StringMatcher {
}
/**
+ * Configures this {@link StringMatcher} to also match on prefix-only matches.
+ * <p>
+ * If the matcher was created with {@code ignoreWildCards == true}, any wildcard
+ * characters in the pattern will still be matched literally.
+ * </p>
+ * <p>
+ * If the pattern is empty, it will match any text.
+ * </p>
+ *
+ * @since 3.13
+ */
+ public void usePrefixMatch() {
+ fIgnoreWildCards = false;
+ fHasTrailingStar = true;
+ }
+
+ /**
* Finds the first occurrence of the pattern between {@code start} (inclusive)
* and {@code end} (exclusive).
* <p>
@@ -485,4 +509,23 @@ public final class StringMatcher {
}
return true;
}
+
+ @Override
+ public String toString() {
+ String flags = ""; //$NON-NLS-1$
+ if (fIgnoreCase) {
+ flags += 'i';
+ }
+ if (fHasTrailingStar) {
+ flags += 't';
+ }
+ if (!fIgnoreWildCards) {
+ flags += '*';
+ }
+ String result = '[' + fPattern;
+ if (!flags.isEmpty()) {
+ result += '/' + flags;
+ }
+ return result + ']';
+ }
}

Back to the top