Spring源码学习-含有通配符路径解析(上)
2012-05-24 09:29:39 来源:WEB开发网continue strLoop;
}
}
foundIdx = pathIdxStart + i;
break;
}
if (foundIdx == -1) {
return false;
}
pattIdxStart = patIdxTmp;
pathIdxStart = foundIdx + patLength;
}
for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
if (!pattDirs[i].equals("**")) {
return false;
}
}
return true;
}
比较方法如下,
首先,分别将输入路径和待比较路径,按照文件分隔符分割成字符串数组。(例如:{”D:“, "workspace-home", "spring-custom"...})
然后,设置好起始和结束位后,对这两个数组进行while循环(代码中第一个while循环),逐断比较匹配(matchStrings)情况。如果有一段不满足则返回fasle。
由于我们当前的测试路径中不包含**的部分,所以主要的判断基本都在第一个while就可以搞定。这部分工作自然是由matchStrings完成的。
试想一下:如果让你完成一个通配符路径匹配的功能,你会如何去做?是否自然的联想到了正则?似乎是个好选择,看看spring是怎么做的。
private boolean matchStrings(String pattern, String str, Map<String, String> uriTemplateVariables) {
AntPathStringMatcher matcher = new AntPathStringMatcher(pattern, str, uriTemplateVariables);
return matcher.matchStrings();
}
在构造AntPathStringMatcher实例的时候,spring果然也创建了正则:
AntPathStringMatcher(String pattern, String str, Map<String, String> uriTemplateVariables) {
this.str = str;
this.uriTemplateVariables = uriTemplateVariables;
this.pattern = createPattern(pattern);
}
private Pattern createPattern(String pattern) {
StringBuilder patternBuilder = new StringBuilder();
Matcher m = GLOB_PATTERN.matcher(pattern);
int end = 0;
while (m.find()) {
patternBuilder.append(quote(pattern, end, m.start()));
String match = m.group();
if ("?".equals(match)) {
patternBuilder.append('.');
}
else if ("*".equals(match)) {
patternBuilder.append(".*");
}
else if (match.startsWith("{") && match.endsWith("}")) {
int colonIdx = match.indexOf(':');
if (colonIdx == -1) {
patternBuilder.append(DEFAULT_VARIABLE_PATTERN);
variableNames.add(m.group(1));
}
else {
String variablePattern = match.substring(colonIdx + 1, match.length() - 1);
patternBuilder.append('(');
patternBuilder.append(variablePattern);
patternBuilder.append(')');
String variableName = match.substring(1, colonIdx);
variableNames.add(variableName);
}
}
end = m.end();
}
patternBuilder.append(quote(pattern, end, pattern.length()));
return Pattern.compile(patternBuilder.toString());
}
简单说,就是spring先用正则:
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
找到路径中的"?"和"*"通配符,然后转换为Java正则的任意字符"."和".*"。生成另一个正则表达式去匹配查找到的文件的路径。如果匹配则返回true。
更多精彩
赞助商链接