Revert change to support {/...} var syntax

Issue: SPR-12750
This commit is contained in:
Rossen Stoyanchev
2015-05-14 10:06:33 -04:00
parent e843bcc725
commit 2c408b7069
5 changed files with 13 additions and 235 deletions

View File

@@ -22,11 +22,11 @@ import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -646,62 +646,13 @@ final class HierarchicalUriComponents extends UriComponents {
*/
static final class FullPathComponent implements PathComponent {
// Pattern used to split the path into segments: '/' if not preceded by '{',
// using negative look-behind
private static final Pattern DELIMITER_PATTERN = Pattern.compile("(?<!\\{)/");
private final List<PartialPath> partialPaths;
private final String path;
public FullPathComponent(String path) {
this.partialPaths = Collections.unmodifiableList(initPartialPaths(path));
this.path = path;
}
private FullPathComponent(List<PartialPath> partialPaths) {
this.partialPaths = Collections.unmodifiableList(partialPaths);
this.path = initPath(partialPaths);
}
private static String initPath(List<PartialPath> partialPaths) {
StringBuilder builder = new StringBuilder();
for (PartialPath partialPath : partialPaths) {
builder.append(partialPath.getValue());
}
return builder.toString();
}
private static List<PartialPath> initPartialPaths(String path) {
List<PartialPath> result = new ArrayList<PartialPath>();
int startIdx;
int endIdx = 0;
while ((startIdx = path.indexOf("{/", endIdx)) != -1) {
if (startIdx > endIdx) {
String prevPart = path.substring(endIdx, startIdx);
result.add(new PartialPath(prevPart, Type.PATH));
}
endIdx = path.indexOf('}', startIdx + 2) + 1;
if (endIdx == -1) {
throw new IllegalArgumentException("Path \"" + path + "\" has no " +
"closing \"}\" after \"{/\" at index " + startIdx);
}
String part = path.substring(startIdx, endIdx);
result.add(new PartialPath(part, Type.PATH_SEGMENT));
}
if (endIdx < path.length()) {
String endPart = path.substring(endIdx);
result.add(new PartialPath(endPart, Type.PATH));
}
return result;
}
List<PartialPath> getPartialPaths() {
return this.partialPaths;
}
@Override
public String getPath() {
return this.path;
@@ -709,41 +660,25 @@ final class HierarchicalUriComponents extends UriComponents {
@Override
public List<String> getPathSegments() {
String[] pathSegments = DELIMITER_PATTERN.split(getPath());
List<String> result = new ArrayList<String>(pathSegments.length);
for (String pathSegment : pathSegments) {
if (StringUtils.hasLength(pathSegment)) {
result.add(pathSegment);
}
}
return Collections.unmodifiableList(result);
String delimiter = new String(new char[]{PATH_DELIMITER});
String[] pathSegments = StringUtils.tokenizeToStringArray(path, delimiter);
return Collections.unmodifiableList(Arrays.asList(pathSegments));
}
@Override
public PathComponent encode(String encoding) throws UnsupportedEncodingException {
List<PartialPath> result = new ArrayList<PartialPath>();
for (PartialPath partialPath : this.partialPaths) {
PartialPath encoded = partialPath.encode(encoding);
result.add(encoded);
}
return new FullPathComponent(result);
}
String encodedPath = encodeUriComponent(getPath(),encoding, Type.PATH);
return new FullPathComponent(encodedPath); }
@Override
public void verify() {
for (PartialPath partialPath : this.partialPaths) {
partialPath.verify();
}
verifyUriComponent(this.path, Type.PATH);
}
@Override
public PathComponent expand(UriTemplateVariables uriVariables) {
List<PartialPath> result = new ArrayList<PartialPath>();
for (PartialPath partialPath : this.partialPaths) {
PartialPath expanded = partialPath.expand(uriVariables);
result.add(expanded);
}
return new FullPathComponent(result);
String expandedPath = expandUriComponent(getPath(), uriVariables);
return new FullPathComponent(expandedPath);
}
@Override
@@ -762,47 +697,6 @@ final class HierarchicalUriComponents extends UriComponents {
return getPath().hashCode();
}
/**
* Represents a part of the full path, with a separate encoding type.
* Required because of {/...} uri variables, which need to encoded as PATH_SEGMENT
* rather than PATH.
*/
static final class PartialPath implements Serializable {
final String value;
final Type type;
private PartialPath(String value, Type type) {
Assert.hasLength(value);
Assert.isTrue(Type.PATH == type || Type.PATH_SEGMENT == type);
this.value = value;
this.type = type;
}
public String getValue() {
return this.value;
}
private PartialPath expand(UriTemplateVariables uriVariables) {
String expandedValue = expandUriComponent(this.value, uriVariables);
return new PartialPath(expandedValue, this.type);
}
private PartialPath encode(String encoding) throws UnsupportedEncodingException {
String encodedPath = encodeUriComponent(this.value, encoding, this.type);
return new PartialPath(encodedPath, this.type);
}
public void verify() {
verifyUriComponent(this.value, this.type);
}
@Override
public String toString() {
return this.value;
}
}
}
/**

View File

@@ -45,7 +45,7 @@ public abstract class UriComponents implements Serializable {
private static final String DEFAULT_ENCODING = "UTF-8";
/** Captures URI template variable names. */
private static final Pattern NAMES_PATTERN = Pattern.compile("\\{(/?[^/]+?)\\}");
private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)\\}");
private final String scheme;
@@ -237,9 +237,6 @@ public abstract class UriComponents implements Serializable {
}
private static String getVariableName(String match) {
if (match.length() > 0 && match.charAt(0) == '/') {
match = match.substring(1);
}
int colonIdx = match.indexOf(':');
return (colonIdx != -1 ? match.substring(0, colonIdx) : match);
}
@@ -255,7 +252,7 @@ public abstract class UriComponents implements Serializable {
*/
public interface UriTemplateVariables {
public static final Object SKIP_VALUE = UriTemplateVariables.class;
Object SKIP_VALUE = UriTemplateVariables.class;
/**
* Get the value for the given URI variable name.

View File

@@ -16,13 +16,8 @@
package org.springframework.web.util;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.net.URI;
import java.net.URISyntaxException;
@@ -239,24 +234,6 @@ public class UriComponentsBuilderTests {
assertEquals("bar@baz", result.getQueryParams().getFirst("foo"));
}
//SPR-12750
@Test
public void fromUriStringWithSlashPrefixedVariable() {
UriComponents result = UriComponentsBuilder.fromUriString(
"http://example.com/part1/{/part2}/{var1}/url/{/urlvar}?foo=bar@baz&bar={barvalue}")
.build();
assertTrue(StringUtils.isEmpty(result.getUserInfo()));
assertEquals("example.com", result.getHost());
assertEquals("/part1/{/part2}/{var1}/url/{/urlvar}", result.getPath());
assertEquals(Arrays.asList("part1", "{/part2}", "{var1}", "url", "{/urlvar}"),
result.getPathSegments());
assertTrue(result.getQueryParams().containsKey("foo"));
assertEquals("bar@baz", result.getQueryParams().getFirst("foo"));
assertTrue(result.getQueryParams().containsKey("bar"));
assertEquals("{barvalue}", result.getQueryParams().getFirst("bar"));
}
@Test
public void fromHttpRequest() throws URISyntaxException {
MockHttpServletRequest request = new MockHttpServletRequest();

View File

@@ -30,8 +30,6 @@ import java.util.Arrays;
import org.junit.Test;
import org.springframework.web.util.HierarchicalUriComponents.FullPathComponent;
/**
* @author Arjen Poutsma
* @author Phillip Webb
@@ -167,49 +165,4 @@ public class UriComponentsTests {
assertThat(uriComponents1, not(equalTo(uriComponents3)));
}
@Test
public void partialPath() throws Exception {
FullPathComponent l;
l = new FullPathComponent("x");
assertEquals(1, l.getPartialPaths().size());
assertEquals("x", l.getPartialPaths().get(0).value);
assertEquals(HierarchicalUriComponents.Type.PATH, l.getPartialPaths().get(0).type);
l = new FullPathComponent("/foo");
assertEquals(1, l.getPartialPaths().size());
assertEquals("/foo", l.getPartialPaths().get(0).value);
assertEquals(HierarchicalUriComponents.Type.PATH, l.getPartialPaths().get(0).type);
l = new FullPathComponent("{/foo}");
assertEquals(1, l.getPartialPaths().size());
assertEquals("{/foo}", l.getPartialPaths().get(0).value);
assertEquals(HierarchicalUriComponents.Type.PATH_SEGMENT, l.getPartialPaths().get(0).type);
l = new FullPathComponent("/foo{/bar}");
assertEquals(2, l.getPartialPaths().size());
assertEquals("/foo", l.getPartialPaths().get(0).value);
assertEquals(HierarchicalUriComponents.Type.PATH, l.getPartialPaths().get(0).type);
assertEquals("{/bar}", l.getPartialPaths().get(1).value);
assertEquals(HierarchicalUriComponents.Type.PATH_SEGMENT, l.getPartialPaths().get(1).type);
l = new FullPathComponent("{/foo}{/bar}");
assertEquals(2, l.getPartialPaths().size());
assertEquals("{/foo}", l.getPartialPaths().get(0).value);
assertEquals(HierarchicalUriComponents.Type.PATH_SEGMENT, l.getPartialPaths().get(0).type);
assertEquals("{/bar}", l.getPartialPaths().get(1).value);
assertEquals(HierarchicalUriComponents.Type.PATH_SEGMENT, l.getPartialPaths().get(1).type);
l = new FullPathComponent("foo{/bar}baz");
assertEquals(3, l.getPartialPaths().size());
assertEquals("foo", l.getPartialPaths().get(0).value);
assertEquals(HierarchicalUriComponents.Type.PATH, l.getPartialPaths().get(0).type);
assertEquals("{/bar}", l.getPartialPaths().get(1).value);
assertEquals(HierarchicalUriComponents.Type.PATH_SEGMENT, l.getPartialPaths().get(1).type);
assertEquals("baz", l.getPartialPaths().get(2).value);
assertEquals(HierarchicalUriComponents.Type.PATH, l.getPartialPaths().get(2).type);
}
}

View File

@@ -63,49 +63,6 @@ public class UriTemplateTests {
assertEquals("Invalid expanded template", new URI("http://example.com/hotels/1/bookings/42"), result);
}
//SPR-12750
@Test
public void expandSlashPrefixedVariable() throws Exception {
Map<String, String> uriVariables = new HashMap<String, String>(2);
uriVariables.put("hotel", "1");
uriVariables.put("publicpath", "pics/logo.png");
uriVariables.put("scale", "150x150");
UriTemplate template = new UriTemplate(
"http://example.com/hotels/{hotel}/pic/{/publicpath}/size/{scale}");
URI result = template.expand(uriVariables);
assertEquals("Invalid expanded template",
new URI("http://example.com/hotels/1/pic/pics%2Flogo.png/size/150x150"),
result);
}
@Test
public void expandSlashPrefixedVariableInBetween() throws Exception {
Map<String, String> uriVariables = new HashMap<String, String>(2);
uriVariables.put("var1", "foo/bar");
uriVariables.put("var2", "baz");
UriTemplate template = new UriTemplate(
"http://example.com/part1/before-{/var1}-after/{var2}");
URI result = template.expand(uriVariables);
assertEquals("Invalid expanded template",
new URI("http://example.com/part1/before-foo%2Fbar-after/baz"),
result);
}
@Test
public void expandSlashPrefixedVariableAfterNonPrefixedVariable() throws Exception {
Map<String, String> uriVariables = new HashMap<String, String>(2);
uriVariables.put("var1", "foo/bar");
uriVariables.put("var2", "baz");
uriVariables.put("var3", "qux");
UriTemplate template = new UriTemplate(
"http://example.com/part1/before-{/var1}-{var2}-after/{var3}");
URI result = template.expand(uriVariables);
assertEquals("Invalid expanded template",
new URI("http://example.com/part1/before-foo%2Fbar-baz-after/qux"),
result);
}
@Test
public void expandMapDuplicateVariables() throws Exception {
UriTemplate template = new UriTemplate("/order/{c}/{c}/{c}");