Cache AntPathStringMatcher instances

AntPathMatcher now caches AntPathStringMatcher instances by pattern
thus avoiding java.util.regex.Pattern recompilation.

Issue: SPR-9749
master
Rossen Stoyanchev 12 years ago
parent 0a877afa06
commit 34c3e821dd
  1. 14
      spring-core/src/main/java/org/springframework/util/AntPathMatcher.java
  2. 17
      spring-core/src/main/java/org/springframework/util/AntPathStringMatcher.java

@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.util;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -53,6 +54,9 @@ public class AntPathMatcher implements PathMatcher {
private String pathSeparator = DEFAULT_PATH_SEPARATOR;
private final Map<String, AntPathStringMatcher> stringMatcherCache =
new ConcurrentHashMap<String, AntPathStringMatcher>();
/** Set the path separator to use for pattern parsing. Default is "/", as in Ant. */
public void setPathSeparator(String pathSeparator) {
@ -216,8 +220,12 @@ public class AntPathMatcher implements PathMatcher {
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
*/
private boolean matchStrings(String pattern, String str, Map<String, String> uriTemplateVariables) {
AntPathStringMatcher matcher = new AntPathStringMatcher(pattern, str, uriTemplateVariables);
return matcher.matchStrings();
AntPathStringMatcher matcher = this.stringMatcherCache.get(pattern);
if (matcher == null) {
matcher = new AntPathStringMatcher(pattern);
this.stringMatcherCache.put(pattern, matcher);
}
return matcher.matchStrings(str, uriTemplateVariables);
}
/**

@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -41,16 +41,11 @@ class AntPathStringMatcher {
private final Pattern pattern;
private String str;
private final List<String> variableNames = new LinkedList<String>();
private final Map<String, String> uriTemplateVariables;
/** Construct a new instance of the <code>AntPatchStringMatcher</code>. */
AntPathStringMatcher(String pattern, String str, Map<String, String> uriTemplateVariables) {
this.str = str;
this.uriTemplateVariables = uriTemplateVariables;
AntPathStringMatcher(String pattern) {
this.pattern = createPattern(pattern);
}
@ -100,14 +95,14 @@ class AntPathStringMatcher {
*
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
*/
public boolean matchStrings() {
public boolean matchStrings(String str, Map<String, String> uriTemplateVariables) {
Matcher matcher = pattern.matcher(str);
if (matcher.matches()) {
if (uriTemplateVariables != null) {
// SPR-8455
Assert.isTrue(variableNames.size() == matcher.groupCount(),
"The number of capturing groups in the pattern segment " + pattern +
" does not match the number of URI template variables it defines, which can occur if " +
Assert.isTrue(variableNames.size() == matcher.groupCount(),
"The number of capturing groups in the pattern segment " + 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);

Loading…
Cancel
Save