Skip to content

Commit 9387d8a

Browse files
committed
Add nullability annotations to module/spring-boot-security
See gh-46587
1 parent 8434446 commit 9387d8a

18 files changed

+88
-35
lines changed

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/EndpointRequest.java

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.stream.Collectors;
2828
import java.util.stream.Stream;
2929

30+
import org.jspecify.annotations.Nullable;
3031
import reactor.core.publisher.Mono;
3132

3233
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@@ -157,9 +158,9 @@ public static AdditionalPathsEndpointServerWebExchangeMatcher toAdditionalPaths(
157158
*/
158159
private abstract static class AbstractWebExchangeMatcher<C> extends ApplicationContextServerWebExchangeMatcher<C> {
159160

160-
private volatile ServerWebExchangeMatcher delegate;
161+
private volatile @Nullable ServerWebExchangeMatcher delegate;
161162

162-
private volatile ManagementPortType managementPortType;
163+
private volatile @Nullable ManagementPortType managementPortType;
163164

164165
AbstractWebExchangeMatcher(Class<? extends C> contextClass) {
165166
super(contextClass);
@@ -181,49 +182,59 @@ private ServerWebExchangeMatcher createDelegate(Supplier<C> context) {
181182

182183
protected abstract ServerWebExchangeMatcher createDelegate(C context);
183184

184-
protected final List<ServerWebExchangeMatcher> getDelegateMatchers(Set<String> paths, HttpMethod httpMethod) {
185+
protected final List<ServerWebExchangeMatcher> getDelegateMatchers(Set<String> paths,
186+
@Nullable HttpMethod httpMethod) {
185187
return paths.stream()
186188
.map((path) -> getDelegateMatcher(path, httpMethod))
187189
.collect(Collectors.toCollection(ArrayList::new));
188190
}
189191

190-
private PathPatternParserServerWebExchangeMatcher getDelegateMatcher(String path, HttpMethod httpMethod) {
192+
private PathPatternParserServerWebExchangeMatcher getDelegateMatcher(String path,
193+
@Nullable HttpMethod httpMethod) {
191194
Assert.notNull(path, "'path' must not be null");
192195
return new PathPatternParserServerWebExchangeMatcher(path + "/**", httpMethod);
193196
}
194197

195198
@Override
196199
protected Mono<MatchResult> matches(ServerWebExchange exchange, Supplier<C> context) {
197-
return this.delegate.matches(exchange);
200+
ServerWebExchangeMatcher delegate = this.delegate;
201+
Assert.state(delegate != null, "'delegate' must not be null");
202+
return delegate.matches(exchange);
198203
}
199204

200205
@Override
201-
protected boolean ignoreApplicationContext(ApplicationContext applicationContext) {
206+
protected boolean ignoreApplicationContext(@Nullable ApplicationContext applicationContext) {
202207
ManagementPortType managementPortType = this.managementPortType;
203208
if (managementPortType == null) {
209+
Assert.state(applicationContext != null, "'applicationContext' must not be null");
204210
managementPortType = ManagementPortType.get(applicationContext.getEnvironment());
205211
this.managementPortType = managementPortType;
206212
}
207213
return ignoreApplicationContext(applicationContext, managementPortType);
208214
}
209215

210-
protected boolean ignoreApplicationContext(ApplicationContext applicationContext,
216+
protected boolean ignoreApplicationContext(@Nullable ApplicationContext applicationContext,
211217
ManagementPortType managementPortType) {
212218
return managementPortType == ManagementPortType.DIFFERENT
213219
&& !hasWebServerNamespace(applicationContext, WebServerNamespace.MANAGEMENT);
214220
}
215221

216-
protected final boolean hasWebServerNamespace(ApplicationContext applicationContext,
222+
protected final boolean hasWebServerNamespace(@Nullable ApplicationContext applicationContext,
217223
WebServerNamespace webServerNamespace) {
218224
return WebServerApplicationContext.hasServerNamespace(applicationContext, webServerNamespace.getValue())
219225
|| hasImplicitServerNamespace(applicationContext, webServerNamespace);
220226
}
221227

222-
private boolean hasImplicitServerNamespace(ApplicationContext applicationContext,
228+
private boolean hasImplicitServerNamespace(@Nullable ApplicationContext applicationContext,
223229
WebServerNamespace webServerNamespace) {
224230
return WebServerNamespace.SERVER.equals(webServerNamespace)
225231
&& WebServerApplicationContext.getServerNamespace(applicationContext) == null
226-
&& applicationContext.getParent() == null;
232+
&& getApplicationContextParent(applicationContext) == null;
233+
}
234+
235+
private @Nullable ApplicationContext getApplicationContextParent(
236+
@Nullable ApplicationContext applicationContext) {
237+
return (applicationContext != null) ? applicationContext.getParent() : null;
227238
}
228239

229240
protected final String toString(List<Object> endpoints, String emptyValue) {
@@ -266,7 +277,7 @@ public static final class EndpointServerWebExchangeMatcher extends AbstractWebEx
266277

267278
private final boolean includeLinks;
268279

269-
private final HttpMethod httpMethod;
280+
private final @Nullable HttpMethod httpMethod;
270281

271282
private EndpointServerWebExchangeMatcher(boolean includeLinks) {
272283
this(Collections.emptyList(), Collections.emptyList(), includeLinks, null);
@@ -281,7 +292,7 @@ private EndpointServerWebExchangeMatcher(String[] endpoints, boolean includeLink
281292
}
282293

283294
private EndpointServerWebExchangeMatcher(List<Object> includes, List<Object> excludes, boolean includeLinks,
284-
HttpMethod httpMethod) {
295+
@Nullable HttpMethod httpMethod) {
285296
super(PathMappedEndpoints.class);
286297
this.includes = includes;
287298
this.excludes = excludes;
@@ -386,7 +397,7 @@ public static class AdditionalPathsEndpointServerWebExchangeMatcher
386397

387398
private final List<Object> endpoints;
388399

389-
private final HttpMethod httpMethod;
400+
private final @Nullable HttpMethod httpMethod;
390401

391402
AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace, String... endpoints) {
392403
this(webServerNamespace, Arrays.asList((Object[]) endpoints), null);
@@ -397,7 +408,7 @@ public static class AdditionalPathsEndpointServerWebExchangeMatcher
397408
}
398409

399410
private AdditionalPathsEndpointServerWebExchangeMatcher(WebServerNamespace webServerNamespace,
400-
List<Object> endpoints, HttpMethod httpMethod) {
411+
List<Object> endpoints, @Nullable HttpMethod httpMethod) {
401412
super(PathMappedEndpoints.class);
402413
Assert.notNull(webServerNamespace, "'webServerNamespace' must not be null");
403414
Assert.notNull(endpoints, "'endpoints' must not be null");
@@ -419,7 +430,7 @@ public AdditionalPathsEndpointServerWebExchangeMatcher withHttpMethod(HttpMethod
419430
}
420431

421432
@Override
422-
protected boolean ignoreApplicationContext(ApplicationContext applicationContext,
433+
protected boolean ignoreApplicationContext(@Nullable ApplicationContext applicationContext,
423434
ManagementPortType managementPortType) {
424435
return !hasWebServerNamespace(applicationContext, this.webServerNamespace);
425436
}

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/reactive/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for actuator security using WebFlux.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.security.autoconfigure.actuate.reactive;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/EndpointRequest.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.stream.Stream;
2929

3030
import jakarta.servlet.http.HttpServletRequest;
31+
import org.jspecify.annotations.Nullable;
3132

3233
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
3334
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
@@ -158,9 +159,9 @@ public static AdditionalPathsEndpointRequestMatcher toAdditionalPaths(WebServerN
158159
private abstract static class AbstractRequestMatcher
159160
extends ApplicationContextRequestMatcher<WebApplicationContext> {
160161

161-
private volatile RequestMatcher delegate;
162+
private volatile @Nullable RequestMatcher delegate;
162163

163-
private volatile ManagementPortType managementPortType;
164+
private volatile @Nullable ManagementPortType managementPortType;
164165

165166
AbstractRequestMatcher() {
166167
super(WebApplicationContext.class);
@@ -202,7 +203,9 @@ protected final void initialized(Supplier<WebApplicationContext> context) {
202203

203204
@Override
204205
protected final boolean matches(HttpServletRequest request, Supplier<WebApplicationContext> context) {
205-
return this.delegate.matches(request);
206+
RequestMatcher delegate = this.delegate;
207+
Assert.state(delegate != null, "'delegate' must not be null");
208+
return delegate.matches(request);
206209
}
207210

208211
private RequestMatcher createDelegate(WebApplicationContext context) {
@@ -218,7 +221,7 @@ protected abstract RequestMatcher createDelegate(WebApplicationContext context,
218221
RequestMatcherFactory requestMatcherFactory);
219222

220223
protected final List<RequestMatcher> getDelegateMatchers(RequestMatcherFactory requestMatcherFactory,
221-
RequestMatcherProvider matcherProvider, Set<String> paths, HttpMethod httpMethod) {
224+
RequestMatcherProvider matcherProvider, Set<String> paths, @Nullable HttpMethod httpMethod) {
222225
return paths.stream()
223226
.map((path) -> requestMatcherFactory.antPath(matcherProvider, httpMethod, path, "/**"))
224227
.collect(Collectors.toCollection(ArrayList::new));
@@ -280,7 +283,7 @@ public static final class EndpointRequestMatcher extends AbstractRequestMatcher
280283

281284
private final boolean includeLinks;
282285

283-
private final HttpMethod httpMethod;
286+
private final @Nullable HttpMethod httpMethod;
284287

285288
private EndpointRequestMatcher(boolean includeLinks) {
286289
this(Collections.emptyList(), Collections.emptyList(), includeLinks, null);
@@ -295,7 +298,7 @@ private EndpointRequestMatcher(String[] endpoints, boolean includeLinks) {
295298
}
296299

297300
private EndpointRequestMatcher(List<Object> includes, List<Object> excludes, boolean includeLinks,
298-
HttpMethod httpMethod) {
301+
@Nullable HttpMethod httpMethod) {
299302
this.includes = includes;
300303
this.excludes = excludes;
301304
this.includeLinks = includeLinks;
@@ -402,7 +405,7 @@ public static class AdditionalPathsEndpointRequestMatcher extends AbstractReques
402405

403406
private final List<Object> endpoints;
404407

405-
private final HttpMethod httpMethod;
408+
private final @Nullable HttpMethod httpMethod;
406409

407410
AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, String... endpoints) {
408411
this(webServerNamespace, Arrays.asList((Object[]) endpoints), null);
@@ -413,7 +416,7 @@ public static class AdditionalPathsEndpointRequestMatcher extends AbstractReques
413416
}
414417

415418
private AdditionalPathsEndpointRequestMatcher(WebServerNamespace webServerNamespace, List<Object> endpoints,
416-
HttpMethod httpMethod) {
419+
@Nullable HttpMethod httpMethod) {
417420
Assert.notNull(webServerNamespace, "'webServerNamespace' must not be null");
418421
Assert.notNull(endpoints, "'endpoints' must not be null");
419422
Assert.notEmpty(endpoints, "'endpoints' must not be empty");
@@ -472,7 +475,8 @@ public String toString() {
472475
*/
473476
private static final class RequestMatcherFactory {
474477

475-
RequestMatcher antPath(RequestMatcherProvider matcherProvider, HttpMethod httpMethod, String... parts) {
478+
RequestMatcher antPath(RequestMatcherProvider matcherProvider, @Nullable HttpMethod httpMethod,
479+
String... parts) {
476480
StringBuilder pattern = new StringBuilder();
477481
for (String part : parts) {
478482
Assert.notNull(part, "'part' must not be null");

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/PathPatternRequestMatcherProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.function.Function;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.http.HttpMethod;
2224
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
2325
import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -37,7 +39,7 @@ class PathPatternRequestMatcherProvider implements RequestMatcherProvider {
3739
}
3840

3941
@Override
40-
public RequestMatcher getRequestMatcher(String pattern, HttpMethod httpMethod) {
42+
public RequestMatcher getRequestMatcher(String pattern, @Nullable HttpMethod httpMethod) {
4143
return PathPatternRequestMatcher.withDefaults().matcher(httpMethod, this.pathFactory.apply(pattern));
4244
}
4345

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/RequestMatcherProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.security.autoconfigure.actuate.servlet;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.http.HttpMethod;
2022
import org.springframework.security.web.util.matcher.RequestMatcher;
2123

@@ -37,6 +39,6 @@ public interface RequestMatcherProvider {
3739
* @param httpMethod the http method
3840
* @return a request matcher
3941
*/
40-
RequestMatcher getRequestMatcher(String pattern, HttpMethod httpMethod);
42+
RequestMatcher getRequestMatcher(String pattern, @Nullable HttpMethod httpMethod);
4143

4244
}

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/servlet/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for actuator security using Spring MVC.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.security.autoconfigure.actuate.servlet;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for Spring Security.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.security.autoconfigure;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/ReactiveUserDetailsServiceAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.apache.commons.logging.Log;
2323
import org.apache.commons.logging.LogFactory;
24+
import org.jspecify.annotations.Nullable;
2425

2526
import org.springframework.beans.factory.ObjectProvider;
2627
import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -88,7 +89,7 @@ private UserDetails getUserDetails(SecurityProperties.User user, String password
8889
return User.withUsername(user.getName()).password(password).roles(StringUtils.toStringArray(roles)).build();
8990
}
9091

91-
private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {
92+
private String getOrDeducePassword(SecurityProperties.User user, @Nullable PasswordEncoder encoder) {
9293
String password = user.getPassword();
9394
if (user.isPasswordGenerated()) {
9495
logger.info(String.format("%n%nUsing generated security password: %s%n", user.getPassword()));

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/reactive/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for reactive Spring Security.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.security.autoconfigure.reactive;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/rsocket/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for RSocket support in Spring Security.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.security.autoconfigure.rsocket;
22+
23+
import org.jspecify.annotations.NullMarked;

0 commit comments

Comments
 (0)