Nullability fine-tuning (RequestContext, LocaleResolver)
Includes page-level JSTL time zone support for JSP tags. Issue: SPR-15720 Issue: SPR-15746
This commit is contained in:
@@ -175,9 +175,9 @@ class DefaultPathContainer implements PathContainer {
|
||||
return EMPTY_PATH;
|
||||
}
|
||||
|
||||
Assert.isTrue(fromIndex < toIndex, "fromIndex: " + fromIndex + " should be < toIndex " + toIndex);
|
||||
Assert.isTrue(fromIndex >= 0 && fromIndex < elements.size(), "Invalid fromIndex: " + fromIndex);
|
||||
Assert.isTrue(toIndex >= 0 && toIndex <= elements.size(), "Invalid toIndex: " + toIndex);
|
||||
Assert.isTrue(fromIndex < toIndex, () -> "fromIndex: " + fromIndex + " should be < toIndex " + toIndex);
|
||||
Assert.isTrue(fromIndex >= 0 && fromIndex < elements.size(), () -> "Invalid fromIndex: " + fromIndex);
|
||||
Assert.isTrue(toIndex >= 0 && toIndex <= elements.size(), () -> "Invalid toIndex: " + toIndex);
|
||||
|
||||
List<Element> subList = elements.subList(fromIndex, toIndex);
|
||||
String path = subList.stream().map(Element::value).collect(Collectors.joining(""));
|
||||
@@ -200,7 +200,7 @@ class DefaultPathContainer implements PathContainer {
|
||||
DefaultPathSegment(String value, String valueDecoded, String semicolonContent,
|
||||
MultiValueMap<String, String> params) {
|
||||
|
||||
Assert.isTrue(!value.contains("/"), "Invalid path segment value: " + value);
|
||||
Assert.isTrue(!value.contains("/"), () -> "Invalid path segment value: " + value);
|
||||
this.value = value;
|
||||
this.valueDecoded = valueDecoded;
|
||||
this.valueDecodedChars = valueDecoded.toCharArray();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.http.server.reactive;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
@@ -69,15 +70,16 @@ public interface PathContainer {
|
||||
* Return the original, raw (encoded) value for the path component.
|
||||
*/
|
||||
String value();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A path separator element.
|
||||
*/
|
||||
interface Separator extends Element {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A path segment element.
|
||||
*/
|
||||
@@ -104,7 +106,6 @@ public interface PathContainer {
|
||||
* Path parameters parsed from the path segment.
|
||||
*/
|
||||
MultiValueMap<String, String> parameters();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.server.reactive.PathContainer.Element;
|
||||
import org.springframework.http.server.reactive.PathContainer.Segment;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
|
||||
/**
|
||||
* A path element representing capturing the rest of a path. In the pattern
|
||||
@@ -67,8 +66,8 @@ class CaptureTheRestPathElement extends PathElement {
|
||||
for (int i = pathIndex; i < matchingContext.pathLength; i++) {
|
||||
Element element = matchingContext.pathElements.get(i);
|
||||
if (element instanceof Segment) {
|
||||
MultiValueMap<String, String> parameters = ((Segment)element).parameters();
|
||||
if (parameters != null && parameters.size()!=0) {
|
||||
MultiValueMap<String, String> parameters = ((Segment) element).parameters();
|
||||
if (!parameters.isEmpty()) {
|
||||
if (parametersCollector == null) {
|
||||
parametersCollector = new LinkedMultiValueMap<>();
|
||||
}
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.http.server.reactive.PathContainer.Segment;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A path element representing capturing a piece of the path as a variable. In the pattern
|
||||
@@ -116,7 +114,7 @@ class CaptureVariablePathElement extends PathElement {
|
||||
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
|
||||
match = true; // no more data but matches up to this point
|
||||
}
|
||||
else {
|
||||
else if (this.next != null) {
|
||||
match = this.next.matches(pathIndex, matchingContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.pattern.PatternParseException.PatternMessage;
|
||||
|
||||
/**
|
||||
@@ -117,11 +116,10 @@ class InternalPathPatternParser {
|
||||
* @throws PatternParseException in case of parse errors
|
||||
*/
|
||||
public PathPattern parse(String pathPattern) throws PatternParseException {
|
||||
if (pathPattern == null) {
|
||||
pathPattern = "";
|
||||
}
|
||||
Assert.notNull(pathPattern, "Path pattern must not be null");
|
||||
|
||||
this.pathPatternData = pathPattern.toCharArray();
|
||||
this.pathPatternLength = pathPatternData.length;
|
||||
this.pathPatternLength = this.pathPatternData.length;
|
||||
this.headPE = null;
|
||||
this.currentPE = null;
|
||||
this.capturedVariableNames = null;
|
||||
|
||||
@@ -34,6 +34,7 @@ class LiteralPathElement extends PathElement {
|
||||
|
||||
private boolean caseSensitive;
|
||||
|
||||
|
||||
public LiteralPathElement(int pos, char[] literalText, boolean caseSensitive, char separator) {
|
||||
super(pos, separator);
|
||||
this.len = literalText.length;
|
||||
@@ -50,6 +51,7 @@ class LiteralPathElement extends PathElement {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean matches(int pathIndex, MatchingContext matchingContext) {
|
||||
if (pathIndex >= matchingContext.pathLength) {
|
||||
@@ -104,22 +106,22 @@ class LiteralPathElement extends PathElement {
|
||||
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
|
||||
return true; // no more data but everything matched so far
|
||||
}
|
||||
return this.next.matches(pathIndex, matchingContext);
|
||||
return (this.next != null && this.next.matches(pathIndex, matchingContext));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNormalizedLength() {
|
||||
return len;
|
||||
return this.len;
|
||||
}
|
||||
|
||||
public char[] getChars() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "Literal(" + String.valueOf(this.text) + ")";
|
||||
}
|
||||
|
||||
public char[] getChars() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
import org.springframework.http.server.reactive.PathContainer.Segment;
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
|
||||
/**
|
||||
* A regex path element. Used to represent any complicated element of the path.
|
||||
@@ -36,9 +35,9 @@ import org.springframework.http.server.reactive.PathContainer.Segment;
|
||||
*/
|
||||
class RegexPathElement extends PathElement {
|
||||
|
||||
private final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
|
||||
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
|
||||
|
||||
private final String DEFAULT_VARIABLE_PATTERN = "(.*)";
|
||||
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
|
||||
|
||||
|
||||
private char[] regex;
|
||||
@@ -145,9 +144,9 @@ class RegexPathElement extends PathElement {
|
||||
// No more pattern, is there more data?
|
||||
// If pattern is capturing variables there must be some actual data to bind to them
|
||||
matches = (pathIndex + 1) >= matchingContext.pathLength &&
|
||||
((this.variableNames.size() == 0) ? true : textToMatch.length() > 0);
|
||||
(this.variableNames.isEmpty() || textToMatch.length() > 0);
|
||||
if (!matches && matchingContext.isAllowOptionalTrailingSlash()) {
|
||||
matches = ((this.variableNames.size() == 0) ? true : textToMatch.length() > 0) &&
|
||||
matches = (this.variableNames.isEmpty() || textToMatch.length() > 0) &&
|
||||
(pathIndex + 2) >= matchingContext.pathLength &&
|
||||
matchingContext.isSeparator(pathIndex + 1);
|
||||
}
|
||||
@@ -155,9 +154,9 @@ class RegexPathElement extends PathElement {
|
||||
}
|
||||
else {
|
||||
if (matchingContext.isMatchStartMatching && (pathIndex + 1 >= matchingContext.pathLength)) {
|
||||
return true; // no more data but matches up to this point
|
||||
return true; // no more data but matches up to this point
|
||||
}
|
||||
matches = this.next.matches(pathIndex + 1, matchingContext);
|
||||
matches = (this.next != null && this.next.matches(pathIndex + 1, matchingContext));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ class SeparatorPathElement extends PathElement {
|
||||
else {
|
||||
pathIndex++;
|
||||
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
|
||||
return true; // no more data but matches up to this point
|
||||
return true; // no more data but matches up to this point
|
||||
}
|
||||
return this.next.matches(pathIndex, matchingContext);
|
||||
return (this.next != null && this.next.matches(pathIndex, matchingContext));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -114,7 +114,7 @@ class SingleCharWildcardedPathElement extends PathElement {
|
||||
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
|
||||
return true; // no more data but everything matched so far
|
||||
}
|
||||
return this.next.matches(pathIndex, matchingContext);
|
||||
return (this.next != null && this.next.matches(pathIndex, matchingContext));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
import org.springframework.http.server.reactive.PathContainer.Element;
|
||||
import org.springframework.http.server.reactive.PathContainer.Segment;
|
||||
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
|
||||
|
||||
/**
|
||||
* A wildcard path element. In the pattern '/foo/*/goo' the * is
|
||||
@@ -80,7 +80,7 @@ class WildcardPathElement extends PathElement {
|
||||
if (segmentData == null || segmentData.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
return this.next.matches(pathIndex, matchingContext);
|
||||
return (this.next != null && this.next.matches(pathIndex, matchingContext));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user