antpathmatcher实现ant风格核心代码
时间: 2023-07-30 08:10:54 浏览: 113
AntPathMatcher是Spring Framework中的一个工具类,用于实现Ant风格的路径匹配。其核心代码如下:
```java
public class AntPathMatcher implements PathMatcher {
private static final String DEFAULT_PATH_SEPARATOR = "/";
private String pathSeparator = DEFAULT_PATH_SEPARATOR;
public boolean isPattern(String path) {
return (path.indexOf('*') != -1 || path.indexOf('?') != -1);
}
public boolean match(String pattern, String path) {
if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) {
return false;
}
String[] pattDirs = tokenizePattern(pattern);
String[] pathDirs = tokenizePath(path);
int pattIdxStart = 0;
int pattIdxEnd = pattDirs.length - 1;
int pathIdxStart = 0;
int pathIdxEnd = pathDirs.length - 1;
while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
String pattDir = pattDirs[pattIdxStart];
if ("**".equals(pattDir)) {
break;
}
if (!matchStrings(pattDir, pathDirs[pathIdxStart])) {
return false;
}
pattIdxStart++;
pathIdxStart++;
}
if (pathIdxStart > pathIdxEnd) {
for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
if (!"**".equals(pattDirs[i])) {
return false;
}
}
return true;
} else {
if (pattIdxStart > pattIdxEnd) {
return false;
}
}
while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
String pattDir = pattDirs[pattIdxEnd];
if ("**".equals(pattDir)) {
break;
}
if (!matchStrings(pattDir, pathDirs[pathIdxEnd])) {
return false;
}
pattIdxEnd--;
pathIdxEnd--;
}
if (pathIdxStart > pathIdxEnd) {
for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
if (!"**".equals(pattDirs[i])) {
return false;
}
}
return true;
}
while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) {
int patIdxTmp = -1;
for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) {
if ("**".equals(pattDirs[i])) {
patIdxTmp = i;
break;
}
}
if (patIdxTmp == pattIdxStart + 1) {
pattIdxStart++;
continue;
}
int patLength = (patIdxTmp - pattIdxStart - 1);
int strLength = (pathIdxEnd - pathIdxStart + 1);
int foundIdx = -1;
strLoop:
for (int i = 0; i <= strLength - patLength; i++) {
for (int j = 0; j < patLength; j++) {
String subPat = pattDirs[pattIdxStart + j + 1];
String subStr = pathDirs[pathIdxStart + i + j];
if (!matchStrings(subPat, subStr)) {
continue strLoop;
}
}
foundIdx = pathIdxStart + i;
break;
}
if (foundIdx == -1) {
return false;
}
pattIdxStart = patIdxTmp;
pathIdxStart = foundIdx + patLength;
}
for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
if (!"**".equals(pattDirs[i])) {
return false;
}
}
return true;
}
protected boolean matchStrings(String pattern, String str) {
return new AntPathStringMatcher(pattern).matchStrings(str);
}
protected String[] tokenizePath(String path) {
return StringUtils.tokenizeToStringArray(path, this.pathSeparator, false, true);
}
protected String[] tokenizePattern(String pattern) {
return StringUtils.tokenizeToStringArray(pattern, this.pathSeparator, false, true);
}
public void setPathSeparator(String pathSeparator) {
this.pathSeparator = pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR;
}
}
```
AntPathMatcher的match方法,是路径匹配的核心方法。该方法首先将pattern和path分别按照路径分隔符("/")进行分割,得到pattDirs和pathDirs两个数组。然后分别从头遍历这两个数组,进行路径匹配。
在遍历过程中,如果pattDirs中遇到了"**",则表示后面的路径可以匹配任意内容,直接返回true。如果pattDirs和pathDirs在某个位置上不能匹配,则返回false。
如果遍历完了pattDirs和pathDirs,发现它们的长度都一样,则表示完全匹配,返回true。如果pattDirs和pathDirs长度不一样,则需要进一步处理。
在处理时,首先从尾部开始遍历pattDirs和pathDirs,直到找到第一个不匹配的位置。如果这时pathDirs中的内容已经全部匹配完了,则表示匹配成功,返回true。
如果pathDirs还有未匹配的内容,但pattDirs已经遍历完了,则表示匹配失败,返回false。否则,继续处理未匹配的内容。
在处理未匹配的内容时,从pattDirs中找到第一个"**",如果"**"后面的路径可以匹配pathDirs中的未匹配内容,则继续匹配。否则,返回false。
如果最后pattDirs中所有的路径都可以与pathDirs中的未匹配内容匹配,则返回true。如果pattDirs中还有未匹配的内容,则表示匹配失败,返回false。
AntPathMatcher的核心代码比较复杂,但它可以很好地实现Ant风格的路径匹配。
阅读全文