Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2020-04-23 14:38:38 +0000
committerThomas Wolf2020-04-28 12:55:22 +0000
commitbf95a3276f46fb67cb7b6dc37319aef6d2bc7cbd (patch)
treee0ca68a0131caf6075d2081810489566dcdbb26b
parent546a68a1d3974f9878143c2538a18947dc5f6b4d (diff)
downloadeclipse.platform.team-bf95a3276f46fb67cb7b6dc37319aef6d2bc7cbd.tar.gz
eclipse.platform.team-bf95a3276f46fb67cb7b6dc37319aef6d2bc7cbd.tar.xz
eclipse.platform.team-bf95a3276f46fb67cb7b6dc37319aef6d2bc7cbd.zip
Remove the copy in org.eclipse.core.net; use the canonical implementation from org.eclipse.equinox.common instead. Rework the copy in org.eclipse.team.core to also delegate to the canonical implementation (re-exported from org.eclipse.core.runtime) for matching. There is one more copy of StringMatcher in team.cvs, but that one has been substantially extended with support for basic character classes. Change-Id: I481280d187fc8bcdcb253ddd857c495afdb120d9 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--bundles/org.eclipse.core.net/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringMatcher.java398
-rw-r--r--bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringUtil.java2
-rw-r--r--bundles/org.eclipse.team.core/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java16
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java413
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/WildcardStringMatcher.java70
7 files changed, 82 insertions, 821 deletions
diff --git a/bundles/org.eclipse.core.net/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.net/META-INF/MANIFEST.MF
index 3586bd124..ec8c18b73 100644
--- a/bundles/org.eclipse.core.net/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.core.net/META-INF/MANIFEST.MF
@@ -7,7 +7,7 @@ Bundle-Activator: org.eclipse.core.internal.net.Activator
Bundle-Vendor: %PLUGIN_PROVIDER
Bundle-Localization: plugin
Require-Bundle: org.eclipse.equinox.security;bundle-version="[1.0.0,2.0.0)",
- org.eclipse.equinox.common;bundle-version="3.4.0",
+ org.eclipse.equinox.common;bundle-version="3.12.0",
org.eclipse.equinox.preferences;bundle-version="3.2.200",
org.eclipse.osgi;bundle-version="3.4.0",
org.eclipse.equinox.registry;bundle-version="3.4.0"
diff --git a/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringMatcher.java b/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringMatcher.java
deleted file mode 100644
index 141e11588..000000000
--- a/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringMatcher.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
- *
- * 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
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.core.internal.net;
-
-import java.util.Vector;
-
-/**
- * A string pattern matcher, suppporting * and ? wildcards.
- * Note: code copied from org.eclipse.jdt.internal.core.util.StringMatcher on April 3, 2001
- * (version 0.1 - 010901H18 [rename jbl]).
- */
-public class StringMatcher {
- protected String fPattern;
- protected int fLength; // pattern length
- protected boolean fIgnoreWildCards;
- protected boolean fIgnoreCase;
- protected boolean fHasLeadingStar;
- protected boolean fHasTrailingStar;
- protected String fSegments[]; //the given pattern is split into * separated segments
-
- /* boundary value beyond which we don't need to search in the text */
- protected int fBound = 0;
-
-
- protected static final char fSingleWildCard = '\u0000';
-
- public static class Position {
- int start; //inclusive
- int end; //exclusive
- public Position(int start, int end) {
- this.start = start;
- this.end = end;
- }
- public int getStart() {
- return start;
- }
- public int getEnd() {
- return end;
- }
- }
- /**
- * Find the first occurrence of the pattern between <code>start</code>)(inclusive)
- * and <code>end</code>(exclusive).
- * @param text the String object to search in
- * @param start the starting index of the search range, inclusive
- * @param end the ending index of the search range, exclusive
- * @return an <code>StringMatcher.Position</code> object that keeps the starting
- * (inclusive) and ending positions (exclusive) of the first occurrence of the
- * pattern in the specified range of the text; return null if not found or subtext
- * is empty (start==end). A pair of zeros is returned if pattern is empty string
- * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
- * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
- */
-
- public StringMatcher.Position find(String text, int start, int end) {
- if (fPattern == null|| text == null)
- throw new IllegalArgumentException();
-
- int tlen = text.length();
- if (start < 0)
- start = 0;
- if (end > tlen)
- end = tlen;
- if (end < 0 ||start >= end )
- return null;
- if (fLength == 0)
- return new Position(start, start);
- if (fIgnoreWildCards) {
- int x = posIn(text, start, end);
- if (x < 0)
- return null;
- return new Position(x, x+fLength);
- }
-
- int segCount = fSegments.length;
- if (segCount == 0)//pattern contains only '*'(s)
- return new Position (start, end);
-
- int curPos = start;
- int matchStart = -1;
- int i;
- for (i = 0; i < segCount && curPos < end; ++i) {
- String current = fSegments[i];
- int nextMatch = regExpPosIn(text, curPos, end, current);
- if (nextMatch < 0 )
- return null;
- if(i == 0)
- matchStart = nextMatch;
- curPos = nextMatch + current.length();
- }
- if (i < segCount)
- return null;
- return new Position(matchStart, curPos);
- }
- /**
- * StringMatcher constructor takes in a String object that is a simple
- * pattern which may contain '*' for 0 and many characters and
- * '?' for exactly one character.
- *
- * Literal '*' and '?' characters must be escaped in the pattern
- * e.g., "\*" means literal "*", etc.
- *
- * Escaping any other character (including the escape character itself),
- * just results in that character in the pattern.
- * e.g., "\a" means "a" and "\\" means "\"
- *
- * If invoking the StringMatcher with string literals in Java, don't forget
- * escape characters are represented by "\\".
- *
- * @param aPattern the pattern to match text with
- * @param ignoreCase if true, case is ignored
- * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
- * (everything is taken literally).
- */
- public StringMatcher(String aPattern, boolean ignoreCase, boolean ignoreWildCards) {
- fIgnoreCase = ignoreCase;
- fIgnoreWildCards = ignoreWildCards;
- fLength = aPattern.length();
-
- /* convert case */
- if (fIgnoreCase) {
- fPattern = aPattern.toUpperCase();
- } else {
- fPattern = aPattern;
- }
-
- if (fIgnoreWildCards) {
- parseNoWildCards();
- } else {
- parseWildCards();
- }
- }
- /**
- * Given the starting (inclusive) and the ending (exclusive) poisitions in the
- * <code>text</code>, determine if the given substring matches with aPattern
- * @return true if the specified portion of the text matches the pattern
- * @param text a String object that contains the substring to match
- * @param start marks the starting position (inclusive) of the substring
- * @param end marks the ending index (exclusive) of the substring
- */
- public boolean match(String text, int start, int end) {
- if (null == text)
- throw new IllegalArgumentException();
-
- if (start > end)
- return false;
-
- if (fIgnoreWildCards)
- return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
- int segCount= fSegments.length;
- if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s)
- return true;
- if (start == end)
- return fLength == 0;
- if (fLength == 0)
- return start == end;
-
- int tlen= text.length();
- if (start < 0)
- start= 0;
- if (end > tlen)
- end= tlen;
-
- int tCurPos= start;
- int bound= end - fBound;
- if ( bound < 0)
- return false;
- int i=0;
- String current= fSegments[i];
- int segLength= current.length();
-
- /* process first segment */
- if (!fHasLeadingStar){
- if(!regExpRegionMatches(text, start, current, 0, segLength)) {
- return false;
- }
- ++i;
- tCurPos= tCurPos + segLength;
- }
- if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) {
- // only one segment to match, no wildcards specified
- return tCurPos == end;
- }
- /* process middle segments */
- while (i < segCount) {
- current= fSegments[i];
- int currentMatch;
- int k= current.indexOf(fSingleWildCard);
- if (k < 0) {
- currentMatch= textPosIn(text, tCurPos, end, current);
- if (currentMatch < 0)
- return false;
- } else {
- currentMatch= regExpPosIn(text, tCurPos, end, current);
- if (currentMatch < 0)
- return false;
- }
- tCurPos= currentMatch + current.length();
- i++;
- }
-
- /* process final segment */
- if (!fHasTrailingStar && tCurPos != end) {
- int clen= current.length();
- return regExpRegionMatches(text, end - clen, current, 0, clen);
- }
- return i == segCount ;
- }
- /**
- * match the given <code>text</code> with the pattern
- * @return true if matched eitherwise false
- * @param text a String object
- */
- public boolean match(String text) {
- return match(text, 0, text.length());
- }
- /**
- * This method parses the given pattern into segments seperated by wildcard '*' characters.
- * Since wildcards are not being used in this case, the pattern consists of a single segment.
- */
- private void parseNoWildCards() {
- fSegments = new String[1];
- fSegments[0] = fPattern;
- fBound = fLength;
- }
- /**
- * This method parses the given pattern into segments seperated by wildcard '*' characters.
- * @param p a String object that is a simple regular expression with '*' and/or '?'
- */
- private void parseWildCards() {
- if(fPattern.startsWith("*"))//$NON-NLS-1$
- fHasLeadingStar = true;
- if(fPattern.endsWith("*")) {//$NON-NLS-1$
- /* make sure it's not an escaped wildcard */
- if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
- fHasTrailingStar = true;
- }
- }
-
- Vector<String> temp = new Vector<>();
-
- int pos = 0;
- StringBuilder buf = new StringBuilder();
- while (pos < fLength) {
- char c = fPattern.charAt(pos++);
- switch (c) {
- case '\\':
- if (pos >= fLength) {
- buf.append(c);
- } else {
- char next = fPattern.charAt(pos++);
- /* if it's an escape sequence */
- if (next == '*' || next == '?' || next == '\\') {
- buf.append(next);
- } else {
- /* not an escape sequence, just insert literally */
- buf.append(c);
- buf.append(next);
- }
- }
- break;
- case '*':
- if (buf.length() > 0) {
- /* new segment */
- temp.addElement(buf.toString());
- fBound += buf.length();
- buf.setLength(0);
- }
- break;
- case '?':
- /* append special character representing single match wildcard */
- buf.append(fSingleWildCard);
- break;
- default:
- buf.append(c);
- }
- }
-
- /* add last buffer to segment list */
- if (buf.length() > 0) {
- temp.addElement(buf.toString());
- fBound += buf.length();
- }
-
- fSegments = new String[temp.size()];
- temp.copyInto(fSegments);
- }
- /**
- * @param text a string which contains no wildcard
- * @param start the starting index in the text for search, inclusive
- * @param end the stopping point of search, exclusive
- * @return the starting index in the text of the pattern , or -1 if not found
- */
- protected int posIn(String text, int start, int end) {//no wild card in pattern
- int max = end - fLength;
-
- if (!fIgnoreCase) {
- int i = text.indexOf(fPattern, start);
- if (i == -1 || i > max)
- return -1;
- return i;
- }
-
- for (int i = start; i <= max; ++i) {
- if (text.regionMatches(true, i, fPattern, 0, fLength))
- return i;
- }
-
- return -1;
- }
- /**
- * @param text a simple regular expression that may only contain '?'(s)
- * @param start the starting index in the text for search, inclusive
- * @param end the stopping point of search, exclusive
- * @param p a simple regular expression that may contains '?'
- * @return the starting index in the text of the pattern , or -1 if not found
- */
- protected int regExpPosIn(String text, int start, int end, String p) {
- int plen = p.length();
-
- int max = end - plen;
- for (int i = start; i <= max; ++i) {
- if (regExpRegionMatches(text, i, p, 0, plen))
- return i;
- }
- return -1;
- }
-
- /**
- *
- * @param text the text
- * @param tStart the start
- * @param p the pattern
- * @param pStart the pattern start
- * @param plen the pattern length
- * @return whether the region matches
- */
- protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) {
- while (plen-- > 0) {
- char tchar = text.charAt(tStart++);
- char pchar = p.charAt(pStart++);
-
- /* process wild cards */
- if (!fIgnoreWildCards) {
- /* skip single wild cards */
- if (pchar == fSingleWildCard) {
- continue;
- }
- }
- if (pchar == tchar)
- continue;
- if (fIgnoreCase) {
- char tc = Character.toUpperCase(tchar);
- if (tc == pchar)
- continue;
- }
- return false;
- }
- return true;
- }
- /**
- * @param text the string to match
- * @param start the starting index in the text for search, inclusive
- * @param end the stopping point of search, exclusive
- * @param p a string that has no wildcard
- * @return the starting index in the text of the pattern , or -1 if not found
- */
- protected int textPosIn(String text, int start, int end, String p) {
-
- int plen = p.length();
- int max = end - plen;
-
- if (!fIgnoreCase) {
- int i = text.indexOf(p, start);
- if (i == -1 || i > max)
- return -1;
- return i;
- }
-
- for (int i = start; i <= max; ++i) {
- if (text.regionMatches(true, i, p, 0, plen))
- return i;
- }
-
- return -1;
- }
-}
diff --git a/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringUtil.java b/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringUtil.java
index f0f2fa41a..c5a77ca74 100644
--- a/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringUtil.java
+++ b/bundles/org.eclipse.core.net/src/org/eclipse/core/internal/net/StringUtil.java
@@ -15,6 +15,8 @@ package org.eclipse.core.internal.net;
import java.util.ArrayList;
+import org.eclipse.core.text.StringMatcher;
+
public class StringUtil {
/**
diff --git a/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF
index e489fc27d..5b60e2f31 100644
--- a/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF
@@ -24,7 +24,7 @@ Export-Package: org.eclipse.team.core,
org.eclipse.team.internal.core.streams;x-friends:="org.eclipse.team.cvs.core,org.eclipse.team.cvs.ssh2,org.eclipse.team.cvs.ui,org.eclipse.team.ui",
org.eclipse.team.internal.core.subscribers;x-friends:="org.eclipse.team.cvs.core,org.eclipse.team.cvs.ssh2,org.eclipse.team.cvs.ui,org.eclipse.team.ui"
Require-Bundle: org.eclipse.core.resources;bundle-version="[3.3.0,4.0.0)",
- org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.core.runtime;bundle-version="[3.18.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.1.0,2.0.0)",
org.eclipse.compare.core;bundle-version="[3.5.200,4.0.0)"
Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
index 3b5145116..d2ff8463e 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
@@ -52,7 +52,7 @@ import org.eclipse.team.internal.core.FileContentManager;
import org.eclipse.team.internal.core.Messages;
import org.eclipse.team.internal.core.Policy;
import org.eclipse.team.internal.core.StorageMergerRegistry;
-import org.eclipse.team.internal.core.StringMatcher;
+import org.eclipse.team.internal.core.WildcardStringMatcher;
import org.eclipse.team.internal.core.TeamPlugin;
import org.eclipse.team.internal.core.TeamResourceChangeListener;
import org.eclipse.team.internal.core.importing.BundleImporterExtension;
@@ -97,7 +97,7 @@ public final class Team {
// The ignore list that is read at startup from the persisted file
protected static SortedMap<String, Boolean> globalIgnore, pluginIgnore;
- private static StringMatcher[] ignoreMatchers;
+ private static WildcardStringMatcher[] ignoreMatchers;
private final static FileContentManager fFileContentManager;
@@ -155,8 +155,8 @@ public final class Team {
}
private static boolean matchesEnabledIgnore(IResource resource) {
- StringMatcher[] matchers = getStringMatchers();
- for (StringMatcher matcher : matchers) {
+ WildcardStringMatcher[] matchers = getStringMatchers();
+ for (WildcardStringMatcher matcher : matchers) {
String resourceName = resource.getName();
if (matcher.isPathPattern()) {
resourceName = resource.getFullPath().toString();
@@ -247,16 +247,16 @@ public final class Team {
return result;
}
- private synchronized static StringMatcher[] getStringMatchers() {
+ private synchronized static WildcardStringMatcher[] getStringMatchers() {
if (ignoreMatchers==null) {
IIgnoreInfo[] ignorePatterns = getAllIgnores();
- ArrayList<StringMatcher> matchers = new ArrayList<>(ignorePatterns.length);
+ ArrayList<WildcardStringMatcher> matchers = new ArrayList<>(ignorePatterns.length);
for (IIgnoreInfo ignorePattern : ignorePatterns) {
if (ignorePattern.getEnabled()) {
- matchers.add(new StringMatcher(ignorePattern.getPattern(), true, false));
+ matchers.add(new WildcardStringMatcher(ignorePattern.getPattern()));
}
}
- ignoreMatchers = new StringMatcher[matchers.size()];
+ ignoreMatchers = new WildcardStringMatcher[matchers.size()];
ignoreMatchers = matchers.toArray(ignoreMatchers);
}
return ignoreMatchers;
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java
deleted file mode 100644
index 6e04483e7..000000000
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
- *
- * 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
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.team.internal.core;
-
-
-import java.util.Vector;
-
-/**
- * A string pattern matcher. Supports '*' and '?' wildcards.
- * Note: code copied from org.eclipse.jdt.internal.core.util.StringMatcher on April 3, 2001
- * (version 0.1 - 010901H18 [rename jbl]). Sync'ed on November 4, 2009 (revision 1.17).
- *
- */
-public class StringMatcher {
- protected String fPattern;
- protected int fLength; // pattern length
- protected boolean fIgnoreWildCards;
- protected boolean fIgnoreCase;
- protected boolean fHasLeadingStar;
- protected boolean fHasTrailingStar;
- protected String fSegments[]; //the given pattern is split into * separated segments
-
- /* boundary value beyond which we don't need to search in the text */
- protected int fBound = 0;
- private boolean fPathPattern;
-
-
- protected static final char fSingleWildCard = '\u0000';
-
- public static class Position {
- int start; //inclusive
- int end; //exclusive
- public Position(int start, int end) {
- this.start = start;
- this.end = end;
- }
- public int getStart() {
- return start;
- }
- public int getEnd() {
- return end;
- }
- }
-
- /**
- * 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.
- *
- * Literal '*' and '?' characters must be escaped in the pattern
- * e.g., "\*" means literal "*", etc.
- *
- * Escaping any other character (including the escape character itself),
- * just results in that character in the pattern.
- * e.g., "\a" means "a" and "\\" means "\"
- *
- * If invoking the StringMatcher with string literals in Java, don't forget
- * escape characters are represented by "\\".
- *
- * @param pattern the pattern to match text against
- * @param ignoreCase if true, case is ignored
- * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
- * (everything is taken literally).
- */
- public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
- if (pattern == null)
- throw new IllegalArgumentException();
- fIgnoreCase = ignoreCase;
- fIgnoreWildCards = ignoreWildCards;
- fPattern= pattern;
- fLength = pattern.length();
- fPathPattern = pattern.indexOf('/') != -1;
-
- if (fIgnoreWildCards) {
- parseNoWildCards();
- } else {
- parseWildCards();
- }
- }
-
- /**
- * Find the first occurrence of the pattern between <code>start</code>(inclusive)
- * and <code>end</code>(exclusive).
- * @param text the String object to search in
- * @param start the starting index of the search range, inclusive
- * @param end the ending index of the search range, exclusive
- * @return an <code>StringMatcher.Position</code> object that keeps the starting
- * (inclusive) and ending positions (exclusive) of the first occurrence of the
- * pattern in the specified range of the text; return null if not found or subtext
- * is empty (start==end). A pair of zeros is returned if pattern is empty string
- * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
- * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
- */
-
- public StringMatcher.Position find(String text, int start, int end) {
- if (fPattern == null|| text == null)
- throw new IllegalArgumentException();
-
- int tlen = text.length();
- if (start < 0)
- start = 0;
- if (end > tlen)
- end = tlen;
- if (end < 0 ||start >= end )
- return null;
- if (fLength == 0)
- return new Position(start, start);
- if (fIgnoreWildCards) {
- int x = posIn(text, start, end);
- if (x < 0)
- return null;
- return new Position(x, x+fLength);
- }
-
- int segCount = fSegments.length;
- if (segCount == 0)//pattern contains only '*'(s)
- return new Position (start, end);
-
- int curPos = start;
- int matchStart = -1;
- int i;
- for (i = 0; i < segCount && curPos < end; ++i) {
- String current = fSegments[i];
- int nextMatch = regExpPosIn(text, curPos, end, current);
- if (nextMatch < 0 )
- return null;
- if(i == 0)
- matchStart = nextMatch;
- curPos = nextMatch + current.length();
- }
- if (i < segCount)
- return null;
- return new Position(matchStart, curPos);
- }
-
- /**
- * match the given <code>text</code> with the pattern
- * @return <code>true</code> if matched otherwise <code>false</code>
- * @param text a String object
- */
- public boolean match(String text) {
- return match(text, 0, text.length());
- }
- /**
- * Given the starting (inclusive) and the ending (exclusive) positions in the
- * <code>text</code>, determine if the given substring matches with aPattern
- * @return true if the specified portion of the text matches the pattern
- * @param text a String object that contains the substring to match
- * @param start marks the starting position (inclusive) of the substring
- * @param end marks the ending index (exclusive) of the substring
- */
- public boolean match(String text, int start, int end) {
- if (null == text)
- throw new IllegalArgumentException();
-
- if (start > end)
- return false;
-
- if (fIgnoreWildCards)
- return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
- int segCount= fSegments.length;
- if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s)
- return true;
- if (start == end)
- return fLength == 0;
- if (fLength == 0)
- return start == end;
-
- int tlen= text.length();
- if (start < 0)
- start= 0;
- if (end > tlen)
- end= tlen;
-
- int tCurPos= start;
- int bound= end - fBound;
- if ( bound < 0)
- return false;
- int i=0;
- String current= fSegments[i];
- int segLength= current.length();
-
- /* process first segment */
- if (!fHasLeadingStar){
- if(!regExpRegionMatches(text, start, current, 0, segLength)) {
- return false;
- } else {
- ++i;
- tCurPos= tCurPos + segLength;
- }
- }
- if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) {
- // only one segment to match, no wildcards specified
- return tCurPos == end;
- }
- /* process middle segments */
- while (i < segCount) {
- current= fSegments[i];
- int currentMatch;
- int k= current.indexOf(fSingleWildCard);
- if (k < 0) {
- currentMatch= textPosIn(text, tCurPos, end, current);
- if (currentMatch < 0)
- return false;
- } else {
- currentMatch= regExpPosIn(text, tCurPos, end, current);
- if (currentMatch < 0)
- return false;
- }
- tCurPos= currentMatch + current.length();
- i++;
- }
-
- /* process final segment */
- if (!fHasTrailingStar && tCurPos != end) {
- int clen= current.length();
- return regExpRegionMatches(text, end - clen, current, 0, clen);
- }
- return i == segCount ;
- }
-
- /**
- * check existence of '/' in the pattern.
- * @return <b>true</b> if pattern contains '/'
- */
- public boolean isPathPattern() {
- return fPathPattern;
- }
-
- /**
- * This method parses the given pattern into segments seperated by wildcard '*' characters.
- * Since wildcards are not being used in this case, the pattern consists of a single segment.
- */
- private void parseNoWildCards() {
- fSegments = new String[1];
- fSegments[0] = fPattern;
- fBound = fLength;
- }
- /**
- * Parses the given pattern into segments seperated by wildcard '*' characters.
- */
- private void parseWildCards() {
- if(fPattern.startsWith("*"))//$NON-NLS-1$
- fHasLeadingStar = true;
- if(fPattern.endsWith("*")) {//$NON-NLS-1$
- /* make sure it's not an escaped wildcard */
- if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
- fHasTrailingStar = true;
- }
- }
-
- Vector<String> temp = new Vector<>();
-
- int pos = 0;
- StringBuilder buf = new StringBuilder();
- while (pos < fLength) {
- char c = fPattern.charAt(pos++);
- switch (c) {
- case '\\':
- if (pos >= fLength) {
- buf.append(c);
- } else {
- char next = fPattern.charAt(pos++);
- /* if it's an escape sequence */
- if (next == '*' || next == '?' || next == '\\') {
- buf.append(next);
- } else {
- /* not an escape sequence, just insert literally */
- buf.append(c);
- buf.append(next);
- }
- }
- break;
- case '*':
- if (buf.length() > 0) {
- /* new segment */
- temp.addElement(buf.toString());
- fBound += buf.length();
- buf.setLength(0);
- }
- break;
- case '?':
- /* append special character representing single match wildcard */
- buf.append(fSingleWildCard);
- break;
- default:
- buf.append(c);
- }
- }
-
- /* add last buffer to segment list */
- if (buf.length() > 0) {
- temp.addElement(buf.toString());
- fBound += buf.length();
- }
-
- fSegments = new String[temp.size()];
- temp.copyInto(fSegments);
- }
- /**
- * @param text a string which contains no wildcard
- * @param start the starting index in the text for search, inclusive
- * @param end the stopping point of search, exclusive
- * @return the starting index in the text of the pattern , or -1 if not found
- */
- protected int posIn(String text, int start, int end) {//no wild card in pattern
- int max = end - fLength;
-
- if (!fIgnoreCase) {
- int i = text.indexOf(fPattern, start);
- if (i == -1 || i > max)
- return -1;
- return i;
- }
-
- for (int i = start; i <= max; ++i) {
- if (text.regionMatches(true, i, fPattern, 0, fLength))
- return i;
- }
-
- return -1;
- }
- /**
- * @param text a simple regular expression that may only contain '?'(s)
- * @param start the starting index in the text for search, inclusive
- * @param end the stopping point of search, exclusive
- * @param p a simple regular expression that may contains '?'
- * @return the starting index in the text of the pattern , or -1 if not found
- */
- protected int regExpPosIn(String text, int start, int end, String p) {
- int plen = p.length();
-
- int max = end - plen;
- for (int i = start; i <= max; ++i) {
- if (regExpRegionMatches(text, i, p, 0, plen))
- return i;
- }
- return -1;
- }
-
- /**
- *
- * @param text the text
- * @param tStart the start
- * @param p the pattern
- * @param pStart the pattern start
- * @param plen the pattern length
- * @return whether the region matches
- */
- protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) {
- while (plen-- > 0) {
- char tchar = text.charAt(tStart++);
- char pchar = p.charAt(pStart++);
-
- /* process wild cards */
- if (!fIgnoreWildCards) {
- /* skip single wild cards */
- if (pchar == fSingleWildCard) {
- continue;
- }
- }
- if (pchar == tchar)
- continue;
- if (fIgnoreCase) {
- if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar))
- continue;
- // comparing after converting to upper case doesn't handle all cases;
- // also compare after converting to lower case
- if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar))
- continue;
- }
- return false;
- }
- return true;
- }
- /**
- * @param text the string to match
- * @param start the starting index in the text for search, inclusive
- * @param end the stopping point of search, exclusive
- * @param p a string that has no wildcard
- * @return the starting index in the text of the pattern , or -1 if not found
- */
- protected int textPosIn(String text, int start, int end, String p) {
-
- int plen = p.length();
- int max = end - plen;
-
- if (!fIgnoreCase) {
- int i = text.indexOf(p, start);
- if (i == -1 || i > max)
- return -1;
- return i;
- }
-
- for (int i = start; i <= max; ++i) {
- if (text.regionMatches(true, i, p, 0, plen))
- return i;
- }
-
- return -1;
- }
-}
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/WildcardStringMatcher.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/WildcardStringMatcher.java
new file mode 100644
index 000000000..823496044
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/WildcardStringMatcher.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
+ *
+ * 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.core;
+
+import org.eclipse.core.text.StringMatcher;
+
+/**
+ * A string pattern matcher. Supports '*' and '?' wildcards.
+ */
+public class WildcardStringMatcher {
+
+ private final StringMatcher fMatcher;
+
+ private final boolean fPathPattern;
+
+ /**
+ * Constructs a wildcard matcher for a pattern that may contain '*' for 0 and
+ * many characters and '?' for exactly one character. Character matching is
+ * case-insensitive.
+ *
+ * Literal '*' and '?' characters must be escaped in the pattern e.g., "\*"
+ * means literal "*", etc.
+ *
+ * The escape character '\' is an escape only if followed by '*', '?', or '\'.
+ * All other occurrences are taken literally.
+ *
+ * If invoking the StringMatcher with string literals in Java, don't forget
+ * escape characters are represented by "\\".
+ *
+ * @param pattern the pattern to match text against
+ * @throws IllegalArgumentException if {@code pattern == null}
+ */
+ public WildcardStringMatcher(String pattern) {
+ fMatcher = new StringMatcher(pattern, true, false);
+ fPathPattern = pattern.indexOf('/') != -1;
+ }
+
+ /**
+ * Determines whether the patterns contains a forward slash.
+ *
+ * @return {@code true} if the pattern contains a '/', {@code false} otherwise
+ */
+ public boolean isPathPattern() {
+ return fPathPattern;
+ }
+
+ /**
+ * Determines whether the given {@code text} matches the pattern.
+ *
+ * @param text String to match; must not be {@code null}
+ * @return {@code true} if the whole {@code text} matches the pattern;
+ * {@code false} otherwise
+ * @throws IllegalArgumentException if {@code text == null}
+ */
+ public boolean match(String text) {
+ return fMatcher.match(text);
+ }
+
+}

Back to the top