Skip to content

Commit 00f4c36

Browse files
committed
Nullability fine-tuning (RequestContext, LocaleResolver)
Includes page-level JSTL time zone support for JSP tags. Issue: SPR-15720 Issue: SPR-15746
1 parent 4a3ca17 commit 00f4c36

25 files changed

+207
-227
lines changed

spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ class WiretapConnector implements ClientHttpConnector {
5050
this.delegate = delegate;
5151
}
5252

53-
public ClientHttpConnector getDelegate() {
54-
return this.delegate;
55-
}
5653

5754
@Override
5855
public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
@@ -69,7 +66,7 @@ public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
6966
.map(response -> {
7067
WiretapClientHttpRequest wrappedRequest = requestRef.get();
7168
String requestId = wrappedRequest.getHeaders().getFirst(WebTestClient.WEBTESTCLIENT_REQUEST_ID);
72-
Assert.notNull(requestId, "No \"" + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "\" header");
69+
Assert.state(requestId != null, () -> "No \"" + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "\" header");
7370
WiretapClientHttpResponse wrappedResponse = new WiretapClientHttpResponse(response);
7471
ExchangeResult result = new ExchangeResult(wrappedRequest, wrappedResponse);
7572
this.exchanges.put(requestId, result);
@@ -82,7 +79,7 @@ public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
8279
*/
8380
public ExchangeResult claimRequest(String requestId) {
8481
ExchangeResult result = this.exchanges.remove(requestId);
85-
Assert.notNull(result, "No match for " + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "=" + requestId);
82+
Assert.state(result != null, () -> "No match for " + WebTestClient.WEBTESTCLIENT_REQUEST_ID + "=" + requestId);
8683
return result;
8784
}
8885

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ static PathContainer subPath(PathContainer container, int fromIndex, int toIndex
175175
return EMPTY_PATH;
176176
}
177177

178-
Assert.isTrue(fromIndex < toIndex, "fromIndex: " + fromIndex + " should be < toIndex " + toIndex);
179-
Assert.isTrue(fromIndex >= 0 && fromIndex < elements.size(), "Invalid fromIndex: " + fromIndex);
180-
Assert.isTrue(toIndex >= 0 && toIndex <= elements.size(), "Invalid toIndex: " + toIndex);
178+
Assert.isTrue(fromIndex < toIndex, () -> "fromIndex: " + fromIndex + " should be < toIndex " + toIndex);
179+
Assert.isTrue(fromIndex >= 0 && fromIndex < elements.size(), () -> "Invalid fromIndex: " + fromIndex);
180+
Assert.isTrue(toIndex >= 0 && toIndex <= elements.size(), () -> "Invalid toIndex: " + toIndex);
181181

182182
List<Element> subList = elements.subList(fromIndex, toIndex);
183183
String path = subList.stream().map(Element::value).collect(Collectors.joining(""));
@@ -200,7 +200,7 @@ private static class DefaultPathSegment implements PathContainer.Segment {
200200
DefaultPathSegment(String value, String valueDecoded, String semicolonContent,
201201
MultiValueMap<String, String> params) {
202202

203-
Assert.isTrue(!value.contains("/"), "Invalid path segment value: " + value);
203+
Assert.isTrue(!value.contains("/"), () -> "Invalid path segment value: " + value);
204204
this.value = value;
205205
this.valueDecoded = valueDecoded;
206206
this.valueDecodedChars = valueDecoded.toCharArray();

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
1617
package org.springframework.http.server.reactive;
1718

1819
import java.nio.charset.Charset;
@@ -69,15 +70,16 @@ interface Element {
6970
* Return the original, raw (encoded) value for the path component.
7071
*/
7172
String value();
72-
7373
}
7474

75+
7576
/**
7677
* A path separator element.
7778
*/
7879
interface Separator extends Element {
7980
}
8081

82+
8183
/**
8284
* A path segment element.
8385
*/
@@ -104,7 +106,6 @@ interface Segment extends Element {
104106
* Path parameters parsed from the path segment.
105107
*/
106108
MultiValueMap<String, String> parameters();
107-
108109
}
109110

110111
}

spring-web/src/main/java/org/springframework/web/util/pattern/CaptureTheRestPathElement.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616

1717
package org.springframework.web.util.pattern;
1818

19-
import org.springframework.util.LinkedMultiValueMap;
20-
import org.springframework.util.MultiValueMap;
21-
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
22-
2319
import java.util.List;
2420

2521
import org.springframework.http.server.reactive.PathContainer.Element;
2622
import org.springframework.http.server.reactive.PathContainer.Segment;
23+
import org.springframework.util.LinkedMultiValueMap;
24+
import org.springframework.util.MultiValueMap;
25+
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
2726

2827
/**
2928
* A path element representing capturing the rest of a path. In the pattern
@@ -67,8 +66,8 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
6766
for (int i = pathIndex; i < matchingContext.pathLength; i++) {
6867
Element element = matchingContext.pathElements.get(i);
6968
if (element instanceof Segment) {
70-
MultiValueMap<String, String> parameters = ((Segment)element).parameters();
71-
if (parameters != null && parameters.size()!=0) {
69+
MultiValueMap<String, String> parameters = ((Segment) element).parameters();
70+
if (!parameters.isEmpty()) {
7271
if (parametersCollector == null) {
7372
parametersCollector = new LinkedMultiValueMap<>();
7473
}

spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@
1616

1717
package org.springframework.web.util.pattern;
1818

19-
import java.nio.charset.StandardCharsets;
2019
import java.util.regex.Matcher;
2120
import java.util.regex.Pattern;
2221

23-
import org.springframework.lang.Nullable;
24-
import org.springframework.web.util.UriUtils;
2522
import org.springframework.http.server.reactive.PathContainer.Segment;
23+
import org.springframework.lang.Nullable;
2624

2725
/**
2826
* A path element representing capturing a piece of the path as a variable. In the pattern
@@ -116,7 +114,7 @@ public boolean matches(int pathIndex, PathPattern.MatchingContext matchingContex
116114
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
117115
match = true; // no more data but matches up to this point
118116
}
119-
else {
117+
else if (this.next != null) {
120118
match = this.next.matches(pathIndex, matchingContext);
121119
}
122120
}

spring-web/src/main/java/org/springframework/web/util/pattern/InternalPathPatternParser.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@
1616

1717
package org.springframework.web.util.pattern;
1818

19-
import java.nio.charset.StandardCharsets;
2019
import java.util.ArrayList;
2120
import java.util.List;
2221
import java.util.regex.PatternSyntaxException;
2322

2423
import org.springframework.lang.Nullable;
25-
import org.springframework.web.util.UriUtils;
24+
import org.springframework.util.Assert;
2625
import org.springframework.web.util.pattern.PatternParseException.PatternMessage;
2726

2827
/**
@@ -117,11 +116,10 @@ public InternalPathPatternParser(char separator, boolean caseSensitive, boolean
117116
* @throws PatternParseException in case of parse errors
118117
*/
119118
public PathPattern parse(String pathPattern) throws PatternParseException {
120-
if (pathPattern == null) {
121-
pathPattern = "";
122-
}
119+
Assert.notNull(pathPattern, "Path pattern must not be null");
120+
123121
this.pathPatternData = pathPattern.toCharArray();
124-
this.pathPatternLength = pathPatternData.length;
122+
this.pathPatternLength = this.pathPatternData.length;
125123
this.headPE = null;
126124
this.currentPE = null;
127125
this.capturedVariableNames = null;

spring-web/src/main/java/org/springframework/web/util/pattern/LiteralPathElement.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class LiteralPathElement extends PathElement {
3434

3535
private boolean caseSensitive;
3636

37+
3738
public LiteralPathElement(int pos, char[] literalText, boolean caseSensitive, char separator) {
3839
super(pos, separator);
3940
this.len = literalText.length;
@@ -50,6 +51,7 @@ public LiteralPathElement(int pos, char[] literalText, boolean caseSensitive, ch
5051
}
5152
}
5253

54+
5355
@Override
5456
public boolean matches(int pathIndex, MatchingContext matchingContext) {
5557
if (pathIndex >= matchingContext.pathLength) {
@@ -104,22 +106,22 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
104106
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
105107
return true; // no more data but everything matched so far
106108
}
107-
return this.next.matches(pathIndex, matchingContext);
109+
return (this.next != null && this.next.matches(pathIndex, matchingContext));
108110
}
109111
}
110112

111113
@Override
112114
public int getNormalizedLength() {
113-
return len;
115+
return this.len;
116+
}
117+
118+
public char[] getChars() {
119+
return this.text;
114120
}
115121

116122

117123
public String toString() {
118124
return "Literal(" + String.valueOf(this.text) + ")";
119125
}
120-
121-
public char[] getChars() {
122-
return this.text;
123-
}
124126

125127
}

spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616

1717
package org.springframework.web.util.pattern;
1818

19-
import java.nio.charset.StandardCharsets;
20-
2119
import org.springframework.lang.Nullable;
2220
import org.springframework.util.LinkedMultiValueMap;
2321
import org.springframework.util.MultiValueMap;
24-
import org.springframework.web.util.UriUtils;
2522
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
2623

2724
/**

spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616

1717
package org.springframework.web.util.pattern;
1818

19-
import java.nio.charset.StandardCharsets;
2019
import java.util.LinkedList;
2120
import java.util.List;
2221
import java.util.regex.Matcher;
2322
import java.util.regex.Pattern;
2423

25-
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
2624
import org.springframework.http.server.reactive.PathContainer.Segment;
25+
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
2726

2827
/**
2928
* A regex path element. Used to represent any complicated element of the path.
@@ -36,9 +35,9 @@
3635
*/
3736
class RegexPathElement extends PathElement {
3837

39-
private final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
38+
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
4039

41-
private final String DEFAULT_VARIABLE_PATTERN = "(.*)";
40+
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
4241

4342

4443
private char[] regex;
@@ -145,19 +144,19 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
145144
// No more pattern, is there more data?
146145
// If pattern is capturing variables there must be some actual data to bind to them
147146
matches = (pathIndex + 1) >= matchingContext.pathLength &&
148-
((this.variableNames.size() == 0) ? true : textToMatch.length() > 0);
147+
(this.variableNames.isEmpty() || textToMatch.length() > 0);
149148
if (!matches && matchingContext.isAllowOptionalTrailingSlash()) {
150-
matches = ((this.variableNames.size() == 0) ? true : textToMatch.length() > 0) &&
149+
matches = (this.variableNames.isEmpty() || textToMatch.length() > 0) &&
151150
(pathIndex + 2) >= matchingContext.pathLength &&
152151
matchingContext.isSeparator(pathIndex + 1);
153152
}
154153
}
155154
}
156155
else {
157156
if (matchingContext.isMatchStartMatching && (pathIndex + 1 >= matchingContext.pathLength)) {
158-
return true; // no more data but matches up to this point
157+
return true; // no more data but matches up to this point
159158
}
160-
matches = this.next.matches(pathIndex + 1, matchingContext);
159+
matches = (this.next != null && this.next.matches(pathIndex + 1, matchingContext));
161160
}
162161
}
163162

spring-web/src/main/java/org/springframework/web/util/pattern/SeparatorPathElement.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
5252
else {
5353
pathIndex++;
5454
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
55-
return true; // no more data but matches up to this point
55+
return true; // no more data but matches up to this point
5656
}
57-
return this.next.matches(pathIndex, matchingContext);
57+
return (this.next != null && this.next.matches(pathIndex, matchingContext));
5858
}
5959
}
6060
return false;

spring-web/src/main/java/org/springframework/web/util/pattern/SingleCharWildcardedPathElement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
114114
if (matchingContext.isMatchStartMatching && pathIndex == matchingContext.pathLength) {
115115
return true; // no more data but everything matched so far
116116
}
117-
return this.next.matches(pathIndex, matchingContext);
117+
return (this.next != null && this.next.matches(pathIndex, matchingContext));
118118
}
119119
}
120120

spring-web/src/main/java/org/springframework/web/util/pattern/WildcardPathElement.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
package org.springframework.web.util.pattern;
1818

19-
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
2019
import org.springframework.http.server.reactive.PathContainer.Element;
2120
import org.springframework.http.server.reactive.PathContainer.Segment;
21+
import org.springframework.web.util.pattern.PathPattern.MatchingContext;
2222

2323
/**
2424
* A wildcard path element. In the pattern '/foo/&ast;/goo' the * is
@@ -80,7 +80,7 @@ public boolean matches(int pathIndex, MatchingContext matchingContext) {
8080
if (segmentData == null || segmentData.length() == 0) {
8181
return false;
8282
}
83-
return this.next.matches(pathIndex, matchingContext);
83+
return (this.next != null && this.next.matches(pathIndex, matchingContext));
8484
}
8585
}
8686

0 commit comments

Comments
 (0)