![JAR search and dependency download from the Maven repository](/logo.png)
jetbrick.util.WildcharPathUtils Maven / Gradle / Ivy
/**
* Copyright 2013-2016 Guoqiang Chen, Shanghai, China. All rights reserved.
*
* Author: Guoqiang Chen
* Email: [email protected]
* WebURL: https://github.com/subchen
*
* Licensed 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 jetbrick.util;
/**
* Checks whether a path matches a given wildcard pattern.
* Possible patterns allow to match single characters ('?') or any count of
* characters ('*'). Wildcard characters can be escaped (by an '\').
* When matching path, deep tree wildcard also can be used ('**').
*
* This method uses recursive matching, as in linux or windows. regexp works the same.
* This method is very fast, comparing to similar implementations.
*/
public class WildcharPathUtils {
protected static final String PATH_MATCH = "**";
protected static final String PATH_SEPARATORS = "/\\";
/**
* Matches path against pattern using *, ? and ** wildcards.
* Both path and the pattern are tokenized on path separators (both \ and /).
* '**' represents deep tree wildcard, as in Ant.
*/
public static boolean matchPath(String path, String pattern) {
String[] pathElements = StringUtils.splitChars(path, PATH_SEPARATORS);
String[] patternElements = StringUtils.splitChars(pattern, PATH_SEPARATORS);
return matchTokens(pathElements, patternElements);
}
/**
* Matches path to at least one pattern.
* Returns index of matched pattern or -1
otherwise.
* @see #matchPath(String, String)
*/
public static int matchPathOne(String path, String[] patterns) {
for (int i = 0; i < patterns.length; i++) {
if (matchPath(path, patterns[i]) == true) {
return i;
}
}
return -1;
}
/**
* Match tokenized string and pattern.
*/
protected static boolean matchTokens(String[] tokens, String[] patterns) {
int patNdxStart = 0;
int patNdxEnd = patterns.length - 1;
int tokNdxStart = 0;
int tokNdxEnd = tokens.length - 1;
while (patNdxStart <= patNdxEnd && tokNdxStart <= tokNdxEnd) { // find first **
String patDir = patterns[patNdxStart];
if (patDir.equals(PATH_MATCH)) {
break;
}
if (!WildcharUtils.match(tokens[tokNdxStart], patDir)) {
return false;
}
patNdxStart++;
tokNdxStart++;
}
if (tokNdxStart > tokNdxEnd) {
for (int i = patNdxStart; i <= patNdxEnd; i++) { // string is finished
if (!patterns[i].equals(PATH_MATCH)) {
return false;
}
}
return true;
}
if (patNdxStart > patNdxEnd) {
return false; // string is not finished, but pattern is
}
while (patNdxStart <= patNdxEnd && tokNdxStart <= tokNdxEnd) { // to the last **
String patDir = patterns[patNdxEnd];
if (patDir.equals(PATH_MATCH)) {
break;
}
if (!WildcharUtils.match(tokens[tokNdxEnd], patDir)) {
return false;
}
patNdxEnd--;
tokNdxEnd--;
}
if (tokNdxStart > tokNdxEnd) {
for (int i = patNdxStart; i <= patNdxEnd; i++) { // string is finished
if (!patterns[i].equals(PATH_MATCH)) {
return false;
}
}
return true;
}
while ((patNdxStart != patNdxEnd) && (tokNdxStart <= tokNdxEnd)) {
int patIdxTmp = -1;
for (int i = patNdxStart + 1; i <= patNdxEnd; i++) {
if (patterns[i].equals(PATH_MATCH)) {
patIdxTmp = i;
break;
}
}
if (patIdxTmp == patNdxStart + 1) {
patNdxStart++; // skip **/** situation
continue;
}
// find the pattern between padIdxStart & padIdxTmp in str between strIdxStart & strIdxEnd
int patLength = (patIdxTmp - patNdxStart - 1);
int strLength = (tokNdxEnd - tokNdxStart + 1);
int ndx = -1;
strLoop: for (int i = 0; i <= strLength - patLength; i++) {
for (int j = 0; j < patLength; j++) {
String subPat = patterns[patNdxStart + j + 1];
String subStr = tokens[tokNdxStart + i + j];
if (!WildcharUtils.match(subStr, subPat)) {
continue strLoop;
}
}
ndx = tokNdxStart + i;
break;
}
if (ndx == -1) {
return false;
}
patNdxStart = patIdxTmp;
tokNdxStart = ndx + patLength;
}
for (int i = patNdxStart; i <= patNdxEnd; i++) {
if (!patterns[i].equals(PATH_MATCH)) {
return false;
}
}
return true;
}
}