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:
Juergen Hoeller
2017-07-07 18:46:19 +02:00
parent 4a3ca17d3f
commit 00f4c36d7a
25 changed files with 207 additions and 227 deletions

View File

@@ -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();

View File

@@ -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();
}
}

View File

@@ -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<>();
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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;
/**

View File

@@ -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));
}
}

View File

@@ -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;

View File

@@ -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));
}
}

View File

@@ -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/&ast;/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));
}
}