public Map<String, String> extractUriTemplateVariables(String pattern, String path) { Map<String, String> variables = new LinkedHashMap<String, String>(); boolean result = doMatch(pattern, path, true, variables); assertState(result, "Pattern \"" + pattern + "\" is not a match for \"" + path + "\""); return variables; }
private int getWildCardCount(String pattern) { if (pattern.endsWith(".*")) { pattern = pattern.substring(0, pattern.length() - 2); } return countOccurrencesOf(pattern, "*"); }
/** * Check whether the given String has actual text. * More specifically, returns {@code true} if the string not {@code null}, * its length is greater than 0, and it contains at least one non-whitespace character. * @param str the String to check (may be {@code null}) * @return {@code true} if the String is not {@code null}, its length is * greater than 0, and it does not contain whitespace only * @see #hasText(CharSequence) */ public static boolean hasText(String str) { return hasText((CharSequence) str); }
public static Map<String, String> decodePathParams(String pathTemplate, String path) { // Ignore trailing slashes on either the template or path. if (pathTemplate.endsWith("/")) pathTemplate = pathTemplate.substring(0, pathTemplate.length() - 1); if (path.endsWith("/")) path = path.substring(0, path.length() - 1); if (!pathParamExtractor.match(pathTemplate, path)) { throw new PathParameterMatchingException( "Cannot decode path params - path template and URI path do not match.", pathTemplate, path); } return pathParamExtractor.extractUriTemplateVariables(pathTemplate, path); }
/** * Tokenize the given path pattern into parts, based on this matcher's settings. * <p>Performs caching based on {@link #setCachePatterns}, delegating to * {@link #tokenizePath(String)} for the actual tokenization algorithm. * @param pattern the pattern to tokenize * @return the tokenized pattern parts */ protected String[] tokenizePattern(String pattern) { String[] tokenized = null; Boolean cachePatterns = this.cachePatterns; if (cachePatterns == null || cachePatterns.booleanValue()) { tokenized = this.tokenizedPatternCache.get(pattern); } if (tokenized == null) { tokenized = tokenizePath(pattern); if (cachePatterns == null && this.tokenizedPatternCache.size() >= CACHE_TURNOFF_THRESHOLD) { // Try to adapt to the runtime situation that we're encountering: // There are obviously too many different patterns coming in here... // So let's turn off the cache since the patterns are unlikely to be reoccurring. deactivatePatternCache(); return tokenized; } if (cachePatterns == null || cachePatterns.booleanValue()) { this.tokenizedPatternCache.put(pattern, tokenized); } } return tokenized; }
if (!hasText(pattern1) && !hasText(pattern2)) { return ""; if (!hasText(pattern1)) { return pattern2; if (!hasText(pattern2)) { return pattern1; if (!pattern1.equals(pattern2) && !pattern1ContainsUriVar && match(pattern1, pattern2)) { // /* + /hotel -> /hotel ; "/*.*" + "/*.html" -> /*.html return slashConcat(pattern1.substring(0, pattern1.length() - 2), pattern2); return slashConcat(pattern1, pattern2); if (pattern1ContainsUriVar || starDotPos1 == -1) { return slashConcat(pattern1, pattern2);
/** * Tokenize the given path String into parts, based on this matcher's settings. * @param path the path to tokenize * @return the tokenized path parts */ protected String[] tokenizePath(String path) { return tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true); }
/** * @return Returns the first pattern found in the collection that matches the given request if one exists. Order of * paths can be significant so when creating a MultiMatcher use an ordered collection if some path may match * multiple patterns. */ @Override public Optional<String> matchesPath(RequestInfo<?> request) { if (request == null || request.getPath() == null) return Optional.empty(); // Ignore trailing slashes on the actual path. String path = MatcherUtil.stripEndSlash(request.getPath()); return matchingPathTemplates .stream() // Ignore trailing slashes on the template. .filter(pathTemplate -> pathParamExtractor.match(pathTemplate, path)) .findFirst(); }
/** * Main entry point. * @return {@code true} if the string matches against the pattern, or {@code false} otherwise. */ public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) { Matcher matcher = this.pattern.matcher(str); if (matcher.matches()) { if (uriTemplateVariables != null) { // SPR-8455 assertIsTrue(this.variableNames.size() == matcher.groupCount(), "The number of capturing groups in the pattern segment " + this.pattern + " does not match the number of URI template variables it defines, which can occur if " + " capturing groups are used in a URI template regex. Use non-capturing groups instead."); for (int i = 1; i <= matcher.groupCount(); i++) { String name = this.variableNames.get(i - 1); String value = matcher.group(i); uriTemplateVariables.put(name, value); } } return true; } else { return false; } } }
return toStringArray(tokens);
@Test(expected = IllegalStateException.class) public void assertState_throws_IllegalStateException_if_passed_false_expression() { // expect AntPathMatcher.assertState(false, "blah"); }
public boolean match(String pattern, String path) { return doMatch(pattern, path, true, null); }
deactivatePatternCache(); return matcher;
@Test @DataProvider(value = { " | | ", "/hotels | null | /hotels", "null | /hotels | /hotels", "/hotels | /bookings | /hotels/bookings", "/hotels | bookings | /hotels/bookings", "/hotels/* | /bookings | /hotels/bookings", "/hotels/** | /bookings | /hotels/**/bookings", "/hotels | {hotel} | /hotels/{hotel}", "/hotels/* | {hotel} | /hotels/{hotel}", "/hotels/** | {hotel} | /hotels/**/{hotel}", "/*.html | /hotels.html | /hotels.html", "/*.html | /hotels | /hotels.html", "/* | /hotel | /hotel", "/*.* | /*.html | /*.html", "/usr | /user | /usr/user", "/{foo} | /bar | /{foo}/bar", "foo | foo | foo/foo", "/*.html | bar.things | bar.html", }, splitBy = "\\|") public void combine_works_as_expected_for_known_data(String pattern1, String pattern2, String expected) { // expect assertThat(matcher.combine(pattern1, pattern2), is(expected)); }
String[] patternParts = tokenizeToStringArray(pattern, this.pathSeparator, this.trimTokens, true); String[] pathParts = tokenizeToStringArray(path, this.pathSeparator, this.trimTokens, true);
/** * {@inheritDoc} */ public Optional<String> matchesPath(RequestInfo<?> request) { if (request == null || request.getPath() == null) return Optional.empty(); // Ignore trailing slashes on actual path. String path = MatcherUtil.stripEndSlash(request.getPath()); if (pathParamExtractor.match(matchingPathTemplate, path)) { return cachedMatchesPathResponse; } else { return Optional.empty(); } }
@Test(expected = IllegalArgumentException.class) public void assertIsTrue_throws_IllegalArgumentException_if_passed_false_expression() { // expect AntPathMatcher.assertIsTrue(false, "blah"); } }
@Test public void toStringArray_returns_null_if_passed_null() { // expect assertThat(AntPathMatcher.toStringArray(null), nullValue()); }
public boolean matchStart(String pattern, String path) { return doMatch(pattern, path, false, null); }
@Test @DataProvider(value = { "null | null | 0", "blah | null | 0", "null | blah | 0", " | blah | 0", "blah | | 0", "foofoofoo | foo | 3" }, splitBy = "\\|") public void countOccurrencesOf_works_as_expected_for_known_data(String str, String sub, int expected) { // expect assertThat(AntPathMatcher.countOccurrencesOf(str, sub), is(expected)); }