Minor refactoring in PathPatternParser
Remove the separator constructor argument (but preserve internal functionality) now that PathPatternParser is more explicitly purposed for URL paths and in any case the use of an alternate separator would also requires a similar input option on the PathContainer parsing side.
This commit is contained in:
parent
1794f1cea4
commit
b6d1fd9d22
|
@ -33,19 +33,11 @@ import org.springframework.web.util.pattern.PatternParseException.PatternMessage
|
|||
*/
|
||||
class InternalPathPatternParser {
|
||||
|
||||
private PathPatternParser parser;
|
||||
private final PathPatternParser parser;
|
||||
|
||||
// The expected path separator to split path elements during parsing
|
||||
char separator = PathPatternParser.DEFAULT_SEPARATOR;
|
||||
private final char separator = '/';
|
||||
|
||||
// Is the parser producing case sensitive PathPattern matchers
|
||||
boolean caseSensitive = true;
|
||||
|
||||
// If true the PathPatterns produced by the parser will allow patterns
|
||||
// that don't have a trailing slash to match paths that may or may not
|
||||
// have a trailing slash
|
||||
private boolean matchOptionalTrailingSlash = false;
|
||||
|
||||
// The input data for parsing
|
||||
private char[] pathPatternData = new char[0];
|
||||
|
||||
|
@ -90,19 +82,8 @@ class InternalPathPatternParser {
|
|||
PathElement currentPE;
|
||||
|
||||
|
||||
/**
|
||||
* @param separator the path separator to look for when parsing
|
||||
* @param caseSensitive true if PathPatterns should be sensitive to case
|
||||
* @param matchOptionalTrailingSlash true if patterns without a trailing slash
|
||||
* can match paths that do have a trailing slash
|
||||
*/
|
||||
public InternalPathPatternParser(char separator, boolean caseSensitive, boolean matchOptionalTrailingSlash) {
|
||||
this.separator = separator;
|
||||
this.caseSensitive = caseSensitive;
|
||||
this.matchOptionalTrailingSlash = matchOptionalTrailingSlash;
|
||||
this.parser = new PathPatternParser(this.separator);
|
||||
this.parser.setCaseSensitive(this.caseSensitive);
|
||||
this.parser.setMatchOptionalTrailingSlash(this.matchOptionalTrailingSlash);
|
||||
InternalPathPatternParser(PathPatternParser parentParser) {
|
||||
this.parser = parentParser;
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,8 +191,8 @@ class InternalPathPatternParser {
|
|||
if (this.pathElementStart != -1) {
|
||||
pushPathElement(createPathElement());
|
||||
}
|
||||
return new PathPattern(
|
||||
pathPattern, this.parser, this.headPE, this.separator, this.caseSensitive, this.matchOptionalTrailingSlash);
|
||||
return new PathPattern(pathPattern, this.parser, this.headPE, this.separator,
|
||||
this.parser.isCaseSensitive(), this.parser.isMatchOptionalTrailingSlash());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,7 +328,7 @@ class InternalPathPatternParser {
|
|||
// It is a full capture of this element (possibly with constraint), for example: /foo/{abc}/
|
||||
try {
|
||||
newPE = new CaptureVariablePathElement(this.pathElementStart, getPathElementText(),
|
||||
this.caseSensitive, this.separator);
|
||||
this.parser.isCaseSensitive(), this.separator);
|
||||
}
|
||||
catch (PatternSyntaxException pse) {
|
||||
throw new PatternParseException(pse,
|
||||
|
@ -364,7 +345,7 @@ class InternalPathPatternParser {
|
|||
PatternMessage.CAPTURE_ALL_IS_STANDALONE_CONSTRUCT);
|
||||
}
|
||||
RegexPathElement newRegexSection = new RegexPathElement(this.pathElementStart,
|
||||
getPathElementText(), this.caseSensitive,
|
||||
getPathElementText(), this.parser.isCaseSensitive(),
|
||||
this.pathPatternData, this.separator);
|
||||
for (String variableName : newRegexSection.getVariableNames()) {
|
||||
recordCapturedVariable(this.pathElementStart, variableName);
|
||||
|
@ -379,16 +360,16 @@ class InternalPathPatternParser {
|
|||
}
|
||||
else {
|
||||
newPE = new RegexPathElement(this.pathElementStart, getPathElementText(),
|
||||
this.caseSensitive, this.pathPatternData, this.separator);
|
||||
this.parser.isCaseSensitive(), this.pathPatternData, this.separator);
|
||||
}
|
||||
}
|
||||
else if (this.singleCharWildcardCount != 0) {
|
||||
newPE = new SingleCharWildcardedPathElement(this.pathElementStart, getPathElementText(),
|
||||
this.singleCharWildcardCount, this.caseSensitive, this.separator);
|
||||
this.singleCharWildcardCount, this.parser.isCaseSensitive(), this.separator);
|
||||
}
|
||||
else {
|
||||
newPE = new LiteralPathElement(this.pathElementStart, getPathElementText(),
|
||||
this.caseSensitive, this.separator);
|
||||
this.parser.isCaseSensitive(), this.separator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,34 +32,11 @@ package org.springframework.web.util.pattern;
|
|||
*/
|
||||
public class PathPatternParser {
|
||||
|
||||
public final static char DEFAULT_SEPARATOR = '/';
|
||||
|
||||
|
||||
private char separator = DEFAULT_SEPARATOR;
|
||||
|
||||
private boolean matchOptionalTrailingSlash = true;
|
||||
|
||||
private boolean caseSensitive = true;
|
||||
|
||||
|
||||
/**
|
||||
* Create a path pattern parser that will use the default separator '/'
|
||||
* when parsing patterns.
|
||||
* @see #DEFAULT_SEPARATOR
|
||||
*/
|
||||
public PathPatternParser() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a path pattern parser that will use the supplied separator when
|
||||
* parsing patterns.
|
||||
* @param separator the separator expected to divide pattern elements
|
||||
*/
|
||||
public PathPatternParser(char separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether a {@link PathPattern} produced by this parser should should
|
||||
* automatically match request paths with a trailing slash.
|
||||
|
@ -75,6 +52,13 @@ public class PathPatternParser {
|
|||
this.matchOptionalTrailingSlash = matchOptionalTrailingSlash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether optional trailing slashing match is enabled.
|
||||
*/
|
||||
public boolean isMatchOptionalTrailingSlash() {
|
||||
return this.matchOptionalTrailingSlash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether path pattern matching should be case-sensitive.
|
||||
* <p>The default is {@code true}.
|
||||
|
@ -83,6 +67,13 @@ public class PathPatternParser {
|
|||
this.caseSensitive = caseSensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether case-sensitive pattern matching is enabled.
|
||||
*/
|
||||
public boolean isCaseSensitive() {
|
||||
return this.caseSensitive;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the path pattern data, a character at a time, breaking it into
|
||||
|
@ -95,12 +86,7 @@ public class PathPatternParser {
|
|||
* @throws PatternParseException in case of parse errors
|
||||
*/
|
||||
public PathPattern parse(String pathPattern) throws PatternParseException {
|
||||
return createDelegate().parse(pathPattern);
|
||||
}
|
||||
|
||||
private InternalPathPatternParser createDelegate() {
|
||||
return new InternalPathPatternParser(
|
||||
this.separator, this.caseSensitive, this.matchOptionalTrailingSlash);
|
||||
return new InternalPathPatternParser(this).parse(pathPattern);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -114,12 +114,6 @@ public class PathPatternParserTests {
|
|||
pp2 = caseSensitiveParser.parse("/abc");
|
||||
assertFalse(pp1.equals(pp2));
|
||||
assertNotEquals(pp1.hashCode(), pp2.hashCode());
|
||||
|
||||
PathPatternParser alternateSeparatorParser = new PathPatternParser(':');
|
||||
pp1 = caseInsensitiveParser.parse("abc");
|
||||
pp2 = alternateSeparatorParser.parse("abc");
|
||||
assertFalse(pp1.equals(pp2));
|
||||
assertNotEquals(pp1.hashCode(), pp2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
@ -51,9 +50,6 @@ import static org.junit.Assert.fail;
|
|||
*/
|
||||
public class PathPatternTests {
|
||||
|
||||
private char separator = PathPatternParser.DEFAULT_SEPARATOR;
|
||||
|
||||
|
||||
@Test
|
||||
public void pathContainer() {
|
||||
assertEquals("[/][abc][/][def]",elementsToString(toPathContainer("/abc/def").elements()));
|
||||
|
@ -770,69 +766,6 @@ public class PathPatternTests {
|
|||
assertMatches(p,"bAb");
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void alternativeDelimiter() {
|
||||
try {
|
||||
this.separator = '.';
|
||||
|
||||
// test exact matching
|
||||
// checkMatches("test", "test");
|
||||
// checkMatches(".test", ".test");
|
||||
// checkNoMatch(".test/jpg", "test/jpg");
|
||||
// checkNoMatch("test", ".test");
|
||||
// checkNoMatch(".test", "test");
|
||||
|
||||
// test matching with ?'s
|
||||
checkMatches("t?st", "test");
|
||||
checkMatches("??st", "test");
|
||||
checkMatches("tes?", "test");
|
||||
checkMatches("te??", "test");
|
||||
checkMatches("?es?", "test");
|
||||
checkNoMatch("tes?", "tes");
|
||||
checkNoMatch("tes?", "testt");
|
||||
checkNoMatch("tes?", "tsst");
|
||||
|
||||
// test matching with *'s
|
||||
checkMatches("*", "test");
|
||||
checkMatches("test*", "test");
|
||||
checkMatches("test*", "testTest");
|
||||
checkMatches("*test*", "AnothertestTest");
|
||||
checkMatches("*test", "Anothertest");
|
||||
checkMatches("*/*", "test/");
|
||||
checkMatches("*/*", "test/test");
|
||||
checkMatches("*/*", "test/test/test");
|
||||
checkMatches("test*aaa", "testblaaaa");
|
||||
checkNoMatch("test*", "tst");
|
||||
checkNoMatch("test*", "tsttest");
|
||||
checkNoMatch("*test*", "tsttst");
|
||||
checkNoMatch("*test", "tsttst");
|
||||
checkNoMatch("*/*", "tsttst");
|
||||
checkNoMatch("test*aaa", "test");
|
||||
checkNoMatch("test*aaa", "testblaaab");
|
||||
|
||||
// test matching with ?'s and .'s
|
||||
checkMatches(".?", ".a");
|
||||
checkMatches(".?.a", ".a.a");
|
||||
checkMatches(".a.?", ".a.b");
|
||||
checkMatches(".??.a", ".aa.a");
|
||||
checkMatches(".a.??", ".a.bb");
|
||||
checkMatches(".?", ".a");
|
||||
|
||||
// test matching with **'s
|
||||
checkMatches(".**", ".testing.testing");
|
||||
checkMatches(".*.**", ".testing.testing");
|
||||
checkMatches(".bla*bla.test", ".blaXXXbla.test");
|
||||
checkMatches(".*bla.test", ".XXXbla.test");
|
||||
checkNoMatch(".bla*bla.test", ".blaXXXbl.test");
|
||||
checkNoMatch(".*bla.test", "XXXblab.test");
|
||||
checkNoMatch(".*bla.test", "XXXbl.test");
|
||||
}
|
||||
finally {
|
||||
this.separator = PathPatternParser.DEFAULT_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractPathWithinPattern_spr15259() {
|
||||
checkExtractPathWithinPattern("/**","//","/");
|
||||
|
@ -1319,7 +1252,7 @@ public class PathPatternTests {
|
|||
}
|
||||
|
||||
private void checkMatches(String uriTemplate, String path) {
|
||||
PathPatternParser parser = new PathPatternParser(this.separator);
|
||||
PathPatternParser parser = new PathPatternParser();
|
||||
parser.setMatchOptionalTrailingSlash(true);
|
||||
PathPattern p = parser.parse(uriTemplate);
|
||||
PathContainer pc = toPathContainer(path);
|
||||
|
|
Loading…
Reference in New Issue