From static to instance-based PathContainer#subPath

This commit is contained in:
Rossen Stoyanchev 2017-07-10 19:06:12 +02:00
parent 9f7d57f933
commit 2f17c5f3b6
5 changed files with 41 additions and 35 deletions

View File

@ -69,7 +69,7 @@ class DefaultRequestPath implements RequestPath {
counter += ((Segment) element).semicolonContent().length();
}
if (length == counter) {
return DefaultPathContainer.subPath(path, 0, i + 1);
return path.subPath(0, i + 1);
}
}
@ -79,7 +79,7 @@ class DefaultRequestPath implements RequestPath {
}
private static PathContainer extractPathWithinApplication(PathContainer fullPath, PathContainer contextPath) {
return PathContainer.subPath(fullPath, contextPath.elements().size());
return fullPath.subPath(contextPath.elements().size());
}

View File

@ -22,16 +22,21 @@ import java.util.List;
import org.springframework.util.MultiValueMap;
/**
* Structured path representation.
* Structured representation of a path whose {@link Element Elements} are
* accessible as a sequence of either {@link Separator Separator} and/or
* {@link Segment Segment} (element) types.
*
* <p>Typically consumed via {@link ServerHttpRequest#getPath()} but can also
* be created by parsing a path value via {@link #parse(String, Charset)}.
* <p>Each {@code Segment} exposes its own structure decoded safely without the
* risk of encoded reserved characters altering the path or segment structure.
*
* <p>An instance of this class can also be created via
* {@link #parse(String, Charset)}. The path for an HTTP request is parsed once
* and subsequently accessible via {@link ServerHttpRequest#getPath()}.
*
* @author Rossen Stoyanchev
*/
public interface PathContainer {
/**
* The original, raw (encoded) path value including path parameters.
*/
@ -42,6 +47,26 @@ public interface PathContainer {
*/
List<Element> elements();
/**
* Extract a sub-path from the given offset into the elements list.
* @param index the start element index (inclusive)
* @return the sub-path
*/
default PathContainer subPath(int index) {
return subPath(index, elements().size());
}
/**
* Extract a sub-path from the given start offset (inclusive) into the
* element list and to the end offset (exclusive).
* @param startIndex the start element index (inclusive)
* @param endIndex the end element index (exclusive)
* @return the sub-path
*/
default PathContainer subPath(int startIndex, int endIndex) {
return DefaultPathContainer.subPath(this, startIndex, endIndex);
}
/**
* Parse the given path value into a {@link PathContainer}.
@ -53,29 +78,10 @@ public interface PathContainer {
return DefaultPathContainer.parsePath(path, encoding);
}
/**
* Extract a sub-path from the given offset into the path elements list.
* @param path the path to extract from
* @param index the start element index (inclusive)
* @return the sub-path
*/
static PathContainer subPath(PathContainer path, int index) {
return subPath(path, index, path.elements().size());
}
/**
* Extract a sub-path from the given start offset (inclusive) into the path
* element list and to the end offset (exclusive).
* @param path the path to extract from
* @param startIndex the start element index (inclusive)
* @param endIndex the end element index (exclusive)
* @return the sub-path
* Common representation of a path element, e.g. separator or segment.
*/
static PathContainer subPath(PathContainer path, int startIndex, int endIndex) {
return DefaultPathContainer.subPath(path, startIndex, endIndex);
}
interface Element {
/**
@ -86,14 +92,14 @@ public interface PathContainer {
/**
* A path separator element.
* Path separator element.
*/
interface Separator extends Element {
}
/**
* A path segment element.
* Path segment element.
*/
interface Segment extends Element {

View File

@ -205,7 +205,7 @@ public class PathPattern implements Comparable<PathPattern> {
info = new PathRemainingMatchInfo(EMPTY_PATH, matchingContext.getPathMatchResult());
}
else {
info = new PathRemainingMatchInfo(PathContainer.subPath(pathContainer, matchingContext.remainingPathIndex),
info = new PathRemainingMatchInfo(pathContainer.subPath(matchingContext.remainingPathIndex),
matchingContext.getPathMatchResult());
}
return info;

View File

@ -127,17 +127,17 @@ public class DefaultPathContainerTests {
public void subPath() throws Exception {
// basic
PathContainer path = PathContainer.parse("/a/b/c", UTF_8);
assertSame(path, PathContainer.subPath(path, 0));
assertEquals("/b/c", PathContainer.subPath(path, 2).value());
assertEquals("/c", PathContainer.subPath(path, 4).value());
assertSame(path, path.subPath(0));
assertEquals("/b/c", path.subPath(2).value());
assertEquals("/c", path.subPath(4).value());
// root path
path = PathContainer.parse("/", UTF_8);
assertEquals("/", PathContainer.subPath(path, 0).value());
assertEquals("/", path.subPath(0).value());
// trailing slash
path = PathContainer.parse("/a/b/", UTF_8);
assertEquals("/b/", PathContainer.subPath(path, 2).value());
assertEquals("/b/", path.subPath(2).value());
}
}

View File

@ -215,7 +215,7 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
.map(entry -> {
PathContainer path = entry.getKey().extractPathWithinPattern(lookupPath);
int endIndex = lookupPath.elements().size() - path.elements().size();
PathContainer mapping = PathContainer.subPath(lookupPath, 0, endIndex);
PathContainer mapping = lookupPath.subPath(0, endIndex);
if (logger.isTraceEnabled()) {
logger.trace("Invoking ResourceResolverChain for URL pattern " +
"\"" + entry.getKey() + "\"");