Browse Source

Add PathSegmentContainer subPath extracting method

pull/1460/head
Rossen Stoyanchev 8 years ago
parent
commit
97917aa57d
  1. 18
      spring-web/src/main/java/org/springframework/http/server/reactive/DefaultPathSegmentContainer.java
  2. 22
      spring-web/src/main/java/org/springframework/http/server/reactive/DefaultRequestPath.java
  3. 10
      spring-web/src/main/java/org/springframework/http/server/reactive/PathSegmentContainer.java
  4. 14
      spring-web/src/test/java/org/springframework/http/server/reactive/DefaultPathSegmentContainerTests.java

18
spring-web/src/main/java/org/springframework/http/server/reactive/DefaultPathSegmentContainer.java

@ -19,6 +19,7 @@ import java.nio.charset.Charset; @@ -19,6 +19,7 @@ import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@ -56,7 +57,7 @@ class DefaultPathSegmentContainer implements PathSegmentContainer { @@ -56,7 +57,7 @@ class DefaultPathSegmentContainer implements PathSegmentContainer {
private final boolean trailingSlash;
DefaultPathSegmentContainer(String path, List<PathSegment> segments) {
private DefaultPathSegmentContainer(String path, List<PathSegment> segments) {
this.path = path;
this.absolute = path.startsWith("/");
this.pathSegments = Collections.unmodifiableList(segments);
@ -188,6 +189,21 @@ class DefaultPathSegmentContainer implements PathSegmentContainer { @@ -188,6 +189,21 @@ class DefaultPathSegmentContainer implements PathSegmentContainer {
}
}
static PathSegmentContainer subPath(PathSegmentContainer container, int fromIndex, int toIndex) {
List<PathSegment> segments = container.pathSegments();
if (fromIndex == 0 && toIndex == segments.size()) {
return container;
}
Assert.isTrue(fromIndex < toIndex, "fromIndex: " + fromIndex + " should be < toIndex " + toIndex);
Assert.isTrue(fromIndex >= 0 && fromIndex < segments.size(), "Invalid fromIndex: " + fromIndex);
Assert.isTrue(toIndex >= 0 && toIndex <= segments.size(), "Invalid toIndex: " + toIndex);
List<PathSegment> subList = segments.subList(fromIndex, toIndex);
String prefix = fromIndex > 0 || container.isAbsolute() ? "/" : "";
String suffix = toIndex == segments.size() && container.hasTrailingSlash() ? "/" : "";
String path = subList.stream().map(PathSegment::value).collect(Collectors.joining(prefix, "/", suffix));
return new DefaultPathSegmentContainer(path, subList);
}
private static class DefaultPathSegment implements PathSegment {

22
spring-web/src/main/java/org/springframework/http/server/reactive/DefaultRequestPath.java

@ -17,7 +17,6 @@ package org.springframework.http.server.reactive; @@ -17,7 +17,6 @@ package org.springframework.http.server.reactive;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.springframework.util.Assert;
@ -41,16 +40,15 @@ class DefaultRequestPath implements RequestPath { @@ -41,16 +40,15 @@ class DefaultRequestPath implements RequestPath {
DefaultRequestPath(URI uri, String contextPath, Charset charset) {
this.fullPath = PathSegmentContainer.parse(uri.getRawPath(), charset);
this.contextPath = initContextPath(this.fullPath, contextPath);
this.pathWithinApplication = initPathWithinApplication(this.fullPath, this.contextPath);
this.pathWithinApplication = extractPathWithinApplication(this.fullPath, this.contextPath);
}
DefaultRequestPath(RequestPath requestPath, String contextPath) {
this.fullPath = requestPath;
this.contextPath = initContextPath(this.fullPath, contextPath);
this.pathWithinApplication = initPathWithinApplication(this.fullPath, this.contextPath);
this.pathWithinApplication = extractPathWithinApplication(this.fullPath, this.contextPath);
}
private static PathSegmentContainer initContextPath(PathSegmentContainer path, String contextPath) {
if (!StringUtils.hasText(contextPath) || "/".equals(contextPath)) {
return DefaultPathSegmentContainer.EMPTY_PATH;
@ -62,14 +60,13 @@ class DefaultRequestPath implements RequestPath { @@ -62,14 +60,13 @@ class DefaultRequestPath implements RequestPath {
int length = contextPath.length();
int counter = 0;
List<PathSegment> result = new ArrayList<>();
for (PathSegment pathSegment : path.pathSegments()) {
result.add(pathSegment);
counter += 1; // for '/' separators
for (int i=0; i < path.pathSegments().size(); i++) {
PathSegment pathSegment = path.pathSegments().get(i);
counter += 1; // for slash separators
counter += pathSegment.value().length();
counter += pathSegment.semicolonContent().length();
if (length == counter) {
return new DefaultPathSegmentContainer(contextPath, result);
return DefaultPathSegmentContainer.subPath(path, 0, i + 1);
}
}
@ -78,13 +75,10 @@ class DefaultRequestPath implements RequestPath { @@ -78,13 +75,10 @@ class DefaultRequestPath implements RequestPath {
" given path='" + path.value() + "'");
}
private static PathSegmentContainer initPathWithinApplication(PathSegmentContainer path,
private static PathSegmentContainer extractPathWithinApplication(PathSegmentContainer fullPath,
PathSegmentContainer contextPath) {
String value = path.value().substring(contextPath.value().length());
List<PathSegment> pathSegments = new ArrayList<>(path.pathSegments());
pathSegments.removeAll(contextPath.pathSegments());
return new DefaultPathSegmentContainer(value, pathSegments);
return PathSegmentContainer.subPath(fullPath, contextPath.pathSegments().size());
}

10
spring-web/src/main/java/org/springframework/http/server/reactive/PathSegmentContainer.java

@ -67,4 +67,14 @@ public interface PathSegmentContainer { @@ -67,4 +67,14 @@ public interface PathSegmentContainer {
return DefaultPathSegmentContainer.parsePath(path, encoding);
}
/**
* Extract a sub-path starting at the given offset into the path segment list.
* @param path the path to extract from
* @param pathSegmentIndex the start index (inclusive)
* @return the sub-path
*/
static PathSegmentContainer subPath(PathSegmentContainer path, int pathSegmentIndex) {
return DefaultPathSegmentContainer.subPath(path, pathSegmentIndex, path.pathSegments().size());
}
}

14
spring-web/src/test/java/org/springframework/http/server/reactive/DefaultPathSegmentContainerTests.java

@ -27,6 +27,7 @@ import org.springframework.util.MultiValueMap; @@ -27,6 +27,7 @@ import org.springframework.util.MultiValueMap;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
/**
* Unit tests for {@link DefaultPathSegmentContainer}.
@ -121,4 +122,17 @@ public class DefaultPathSegmentContainerTests { @@ -121,4 +122,17 @@ public class DefaultPathSegmentContainerTests {
assertEquals("hasTrailingSlash: '" + input + "'", trailingSlash, path.hasTrailingSlash());
}
@Test
public void subPath() throws Exception {
// basic
PathSegmentContainer path = PathSegmentContainer.parse("/a/b/c", UTF_8);
assertSame(path, PathSegmentContainer.subPath(path, 0));
assertEquals("/b/c", PathSegmentContainer.subPath(path, 1).value());
assertEquals("/c", PathSegmentContainer.subPath(path, 2).value());
// trailing slash
path = PathSegmentContainer.parse("/a/b/", UTF_8);
assertEquals("/b/", PathSegmentContainer.subPath(path, 1).value());
}
}

Loading…
Cancel
Save