
org.tinygroup.commons.match.AntPathStringMatcher Maven / Gradle / Ivy
/**
* Copyright (c) 1997-2013, www.tinygroup.org ([email protected]).
*
* Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html
*
* 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 org.tinygroup.commons.match;
import org.tinygroup.commons.tools.StringEscapeUtil;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Package-protected helper class for {@link AntPathMatcher}. Tests whether or not a string matches against a pattern
* using a regular expression.
*
* The pattern may contain special characters: '*' means zero or more characters; '?' means one and only one
* character; '{' and '}' indicate a URI template pattern.
*
* @author Arjen Poutsma
* @since 3.0
*/
public class AntPathStringMatcher {
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{([^/]+?)\\}");
private static final String DEFAULT_VARIABLE_PATTERN = "([^/]*?)";
private final Pattern pattern;
private String str;
private final List variableNames = new LinkedList();
private final Map uriTemplateVariables=new HashMap();
/** Construct a new instance of the AntPatchStringMatcher
. */
public AntPathStringMatcher(String pattern, String str) {
this.str = str;
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());
}
private String quote(String s, int start, int end) {
if (start == end) {
return "";
}
return Pattern.quote(s.substring(start, end));
}
/**
* Main entry point.
*
* @return true
if the string matches against the pattern, or false
otherwise.
*/
public boolean matches() {
Matcher matcher = pattern.matcher(str);
if (matcher.matches()) {
if (uriTemplateVariables != null) {
for (int i = 1; i <= matcher.groupCount(); i++) {
String name = this.variableNames.get(i - 1);
String value = StringEscapeUtil.unescapeURL(matcher.group(i));
uriTemplateVariables.put(name, value);
}
}
return true;
}
else {
return false;
}
}
public List getVariableNames() {
return variableNames;
}
public Map getUriTemplateVariables() {
return uriTemplateVariables;
}
}