SPR-5251: URI Templates support infix variables: A-{B}-C
This commit is contained in:
@@ -28,12 +28,7 @@ class AntPatchStringMatcher {
|
|||||||
|
|
||||||
private final Map<String, String> uriTemplateVariables;
|
private final Map<String, String> uriTemplateVariables;
|
||||||
|
|
||||||
/**
|
/** Constructs a new instance of the <code>AntPatchStringMatcher</code>. */
|
||||||
* Constructs a new instance of the <code>AntPatchStringMatcher</code>.
|
|
||||||
* @param pattern
|
|
||||||
* @param str
|
|
||||||
* @param uriTemplateVariables
|
|
||||||
*/
|
|
||||||
AntPatchStringMatcher(String pattern, String str, Map<String, String> uriTemplateVariables) {
|
AntPatchStringMatcher(String pattern, String str, Map<String, String> uriTemplateVariables) {
|
||||||
patArr = pattern.toCharArray();
|
patArr = pattern.toCharArray();
|
||||||
strArr = str.toCharArray();
|
strArr = str.toCharArray();
|
||||||
@@ -42,12 +37,6 @@ class AntPatchStringMatcher {
|
|||||||
strIdxEnd = strArr.length - 1;
|
strIdxEnd = strArr.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTemplateVariable(String varName, String varValue) {
|
|
||||||
if (uriTemplateVariables != null) {
|
|
||||||
uriTemplateVariables.put(varName, varValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addTemplateVariable(int curlyIdxStart, int curlyIdxEnd, int valIdxStart, int valIdxEnd) {
|
private void addTemplateVariable(int curlyIdxStart, int curlyIdxEnd, int valIdxStart, int valIdxEnd) {
|
||||||
if (uriTemplateVariables != null) {
|
if (uriTemplateVariables != null) {
|
||||||
String varName = new String(patArr, curlyIdxStart + 1, curlyIdxEnd - curlyIdxStart - 1);
|
String varName = new String(patArr, curlyIdxStart + 1, curlyIdxEnd - curlyIdxStart - 1);
|
||||||
@@ -56,6 +45,11 @@ class AntPatchStringMatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the string matches against the pattern, or <code>false</code> otherwise.
|
||||||
|
*/
|
||||||
boolean matchStrings() {
|
boolean matchStrings() {
|
||||||
if (shortcutPossible()) {
|
if (shortcutPossible()) {
|
||||||
return doShortcut();
|
return doShortcut();
|
||||||
@@ -82,10 +76,16 @@ class AntPatchStringMatcher {
|
|||||||
// process pattern between stars. padIdxStart and patIdxEnd point
|
// process pattern between stars. padIdxStart and patIdxEnd point
|
||||||
// always to a '*'.
|
// always to a '*'.
|
||||||
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
|
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
|
||||||
int patIdxTmp = findNextStar();
|
int patIdxTmp;
|
||||||
if (patIdxTmp == patIdxStart + 1 && patArr[patIdxTmp] == '*') {
|
if (patArr[patIdxStart] == '{') {
|
||||||
// Two stars next to each other, skip the first one.
|
patIdxTmp = findClosingCurly();
|
||||||
patIdxStart++;
|
addTemplateVariable(patIdxStart, patIdxTmp, strIdxStart, strIdxEnd);
|
||||||
|
patIdxStart = patIdxTmp + 1;
|
||||||
|
strIdxStart = strIdxEnd + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
patIdxTmp = findNextStarOrCurly();
|
||||||
|
if (consecutiveStars(patIdxTmp)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Find the pattern between padIdxStart & padIdxTmp in str between
|
// Find the pattern between padIdxStart & padIdxTmp in str between
|
||||||
@@ -119,9 +119,27 @@ class AntPatchStringMatcher {
|
|||||||
return onlyStarsLeft();
|
return onlyStarsLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findNextStar() {
|
private boolean consecutiveStars(int patIdxTmp) {
|
||||||
|
if (patIdxTmp == patIdxStart + 1 && patArr[patIdxStart] == '*' && patArr[patIdxTmp] == '*') {
|
||||||
|
// Two stars next to each other, skip the first one.
|
||||||
|
patIdxStart++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findNextStarOrCurly() {
|
||||||
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
|
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
|
||||||
if (patArr[i] == '*') {
|
if (patArr[i] == '*' || patArr[i] == '{') {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findClosingCurly() {
|
||||||
|
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
|
||||||
|
if (patArr[i] == '}') {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,7 +295,11 @@ public class AntPathMatcherTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void extractUriTemplateVariables() throws Exception {
|
public void extractUriTemplateVariables() throws Exception {
|
||||||
Map<String,String> result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1");
|
Map<String,String> result;
|
||||||
|
result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1");
|
||||||
|
assertEquals(Collections.singletonMap("hotel", "1"), result);
|
||||||
|
|
||||||
|
result = pathMatcher.extractUriTemplateVariables("/h?tels/{hotel}", "/hotels/1");
|
||||||
assertEquals(Collections.singletonMap("hotel", "1"), result);
|
assertEquals(Collections.singletonMap("hotel", "1"), result);
|
||||||
|
|
||||||
result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}/bookings/{booking}", "/hotels/1/bookings/2");
|
result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}/bookings/{booking}", "/hotels/1/bookings/2");
|
||||||
@@ -306,6 +310,12 @@ public class AntPathMatcherTests {
|
|||||||
|
|
||||||
result = pathMatcher.extractUriTemplateVariables("/**/hotels/**/{hotel}", "/foo/hotels/bar/1");
|
result = pathMatcher.extractUriTemplateVariables("/**/hotels/**/{hotel}", "/foo/hotels/bar/1");
|
||||||
assertEquals(Collections.singletonMap("hotel", "1"), result);
|
assertEquals(Collections.singletonMap("hotel", "1"), result);
|
||||||
|
|
||||||
|
result = pathMatcher.extractUriTemplateVariables("/{page}.html", "/42.html");
|
||||||
|
assertEquals(Collections.singletonMap("page", "42"), result);
|
||||||
|
|
||||||
|
result = pathMatcher.extractUriTemplateVariables("/A-{B}-C", "/A-b-C");
|
||||||
|
assertEquals(Collections.singletonMap("B", "b"), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user