Introduce null-safety of Spring Framework API

This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.

In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.

@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.

In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.

Issue: SPR-15540
This commit is contained in:
Sebastien Deleuze
2017-05-27 08:14:59 +02:00
parent 2d37c966b2
commit 87598f48e4
1315 changed files with 4831 additions and 963 deletions

View File

@@ -7,4 +7,7 @@
* <p>These <em>mocks</em> are useful for developing <em>out-of-container</em>
* unit tests for code that depends on environment-specific properties.
*/
@NonNullApi
package org.springframework.mock.env;
import org.springframework.lang.NonNullApi;

View File

@@ -3,4 +3,7 @@
* This package contains {@code MockClientHttpRequest} and
* {@code MockClientHttpResponse}.
*/
@NonNullApi
package org.springframework.mock.http.client;
import org.springframework.lang.NonNullApi;

View File

@@ -1,4 +1,7 @@
/**
* Mock implementations of reactive HTTP client contracts.
*/
@NonNullApi
package org.springframework.mock.http.client.reactive;
import org.springframework.lang.NonNullApi;

View File

@@ -3,4 +3,7 @@
* This package contains {@code MockHttpInputMessage} and
* {@code MockHttpOutputMessage}.
*/
@NonNullApi
package org.springframework.mock.http;
import org.springframework.lang.NonNullApi;

View File

@@ -1,4 +1,7 @@
/**
* Mock implementations of reactive HTTP server contracts.
*/
@NonNullApi
package org.springframework.mock.http.server.reactive;
import org.springframework.lang.NonNullApi;

View File

@@ -17,6 +17,7 @@
package org.springframework.mock.jndi;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
@@ -26,6 +27,7 @@ import javax.naming.spi.NamingManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -95,6 +97,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
* @return the current SimpleNamingContextBuilder instance,
* or {@code null} if none
*/
@Nullable
public static SimpleNamingContextBuilder getCurrentContextBuilder() {
return activated;
}

View File

@@ -6,4 +6,7 @@
* same JNDI names as within a Java EE container, both application code and
* configuration can be reused without changes.
*/
@NonNullApi
package org.springframework.mock.jndi;
import org.springframework.lang.NonNullApi;

View File

@@ -23,6 +23,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -88,6 +89,7 @@ class HeaderValueHolder {
* @return the corresponding HeaderValueHolder,
* or {@code null} if none found
*/
@Nullable
public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) {
Assert.notNull(name, "Header name must not be null");
for (String headerName : headers.keySet()) {

View File

@@ -41,6 +41,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
@@ -58,6 +59,7 @@ import javax.servlet.http.Part;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.LinkedMultiValueMap;
@@ -272,7 +274,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setRequestURI
* @see #MockHttpServletRequest(ServletContext, String, String)
*/
public MockHttpServletRequest(String method, String requestURI) {
public MockHttpServletRequest(@Nullable String method, @Nullable String requestURI) {
this(null, method, requestURI);
}
@@ -282,7 +284,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* (may be {@code null} to use a default {@link MockServletContext})
* @see #MockHttpServletRequest(ServletContext, String, String)
*/
public MockHttpServletRequest(ServletContext servletContext) {
public MockHttpServletRequest(@Nullable ServletContext servletContext) {
this(servletContext, "", "");
}
@@ -299,7 +301,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setPreferredLocales
* @see MockServletContext
*/
public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) {
public MockHttpServletRequest(@Nullable ServletContext servletContext, @Nullable String method, @Nullable String requestURI) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.method = method;
this.requestURI = requestURI;
@@ -409,6 +411,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setContent(byte[])
* @see #getContentAsString()
*/
@Nullable
public byte[] getContentAsByteArray() {
return this.content;
}
@@ -424,6 +427,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setCharacterEncoding(String)
* @see #getContentAsByteArray()
*/
@Nullable
public String getContentAsString() throws IllegalStateException, UnsupportedEncodingException {
Assert.state(this.characterEncoding != null,
"Cannot get content as a String for a null character encoding. " +

View File

@@ -33,12 +33,14 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.StringUtils;
@@ -390,6 +392,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
* @return the associated header value, or {@code null} if none
*/
@Override
@Nullable
public String getHeader(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getStringValue() : null);
@@ -420,6 +423,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
* @param name the name of the header
* @return the associated header value, or {@code null} if none
*/
@Nullable
public Object getHeaderValue(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getValue() : null);

View File

@@ -21,10 +21,12 @@ import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -65,7 +67,7 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
* @param servletContext the ServletContext that the request runs in
* (may be {@code null} to use a default {@link MockServletContext})
*/
public MockMultipartHttpServletRequest(ServletContext servletContext) {
public MockMultipartHttpServletRequest(@Nullable ServletContext servletContext) {
super(servletContext);
setMethod("POST");
setContentType("multipart/form-data");

View File

@@ -29,6 +29,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
@@ -48,6 +49,7 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.MimeType;
@@ -165,7 +167,7 @@ public class MockServletContext implements ServletContext {
* and no base path.
* @param resourceLoader the ResourceLoader to use (or null for the default)
*/
public MockServletContext(ResourceLoader resourceLoader) {
public MockServletContext(@Nullable ResourceLoader resourceLoader) {
this("", resourceLoader);
}
@@ -178,7 +180,7 @@ public class MockServletContext implements ServletContext {
* @param resourceLoader the ResourceLoader to use (or null for the default)
* @see #registerNamedDispatcher
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
public MockServletContext(String resourceBasePath, @Nullable ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : "");
@@ -630,6 +632,7 @@ public class MockServletContext implements ServletContext {
* @see javax.servlet.ServletContext#getServletRegistration(java.lang.String)
*/
@Override
@Nullable
public ServletRegistration getServletRegistration(String servletName) {
return null;
}
@@ -668,6 +671,7 @@ public class MockServletContext implements ServletContext {
* @see javax.servlet.ServletContext#getFilterRegistration(java.lang.String)
*/
@Override
@Nullable
public FilterRegistration getFilterRegistration(String filterName) {
return null;
}

View File

@@ -9,4 +9,7 @@
* existing Servlet API mock objects
* (<a href="http://www.mockobjects.com">MockObjects</a>).
*/
@NonNullApi
package org.springframework.mock.web;
import org.springframework.lang.NonNullApi;

View File

@@ -16,6 +16,8 @@
package org.springframework.test.annotation;
import org.springframework.lang.Nullable;
/**
* <p>
* Strategy interface for retrieving <em>profile values</em> for a given
@@ -47,6 +49,7 @@ public interface ProfileValueSource {
* @return the String value of the <em>profile value</em>, or {@code null}
* if there is no <em>profile value</em> with that key
*/
@Nullable
String get(String key);
}

View File

@@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
@@ -176,7 +177,7 @@ public abstract class ProfileValueUtils {
* {@code null}
*/
private static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource,
IfProfileValue ifProfileValue) {
@Nullable IfProfileValue ifProfileValue) {
if (ifProfileValue == null) {
return true;

View File

@@ -1,4 +1,7 @@
/**
* Support classes for annotation-driven tests.
*/
@NonNullApi
package org.springframework.test.annotation;
import org.springframework.lang.NonNullApi;

View File

@@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -147,6 +148,7 @@ abstract class BootstrapUtils {
}
}
@Nullable
private static Class<?> resolveExplicitTestContextBootstrapper(Class<?> testClass) {
Set<BootstrapWith> annotations = AnnotatedElementUtils.findAllMergedAnnotations(testClass, BootstrapWith.class);
if (annotations.size() < 1) {

View File

@@ -18,6 +18,7 @@ package org.springframework.test.context;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
/**
@@ -69,6 +70,6 @@ public interface CacheAwareContextLoaderDelegate {
* is not part of a hierarchy
* @since 4.1
*/
void closeContext(MergedContextConfiguration mergedContextConfiguration, HierarchyMode hierarchyMode);
void closeContext(MergedContextConfiguration mergedContextConfiguration, @Nullable HierarchyMode hierarchyMode);
}

View File

@@ -25,6 +25,7 @@ import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.style.ToStringCreator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -202,6 +203,7 @@ public class ContextConfigurationAttributes {
* @see ContextConfiguration#classes
* @see #setClasses(Class[])
*/
@Nullable
public Class<?>[] getClasses() {
return this.classes;
}
@@ -237,6 +239,7 @@ public class ContextConfigurationAttributes {
* @see ContextConfiguration#locations
* @see #setLocations(String[])
*/
@Nullable
public String[] getLocations() {
return this.locations;
}
@@ -301,6 +304,7 @@ public class ContextConfigurationAttributes {
* @see ContextConfiguration#name()
* @since 3.2.2
*/
@Nullable
public String getName() {
return this.name;
}

View File

@@ -18,6 +18,8 @@ package org.springframework.test.context;
import java.util.List;
import org.springframework.lang.Nullable;
/**
* Factory for creating {@link ContextCustomizer ContextCustomizers}.
*
@@ -48,6 +50,7 @@ public interface ContextCustomizerFactory {
* @return a {@link ContextCustomizer} or {@code null} if no customizer should
* be used
*/
@Nullable
ContextCustomizer createContextCustomizer(Class<?> testClass, List<ContextConfigurationAttributes> configAttributes);
}

View File

@@ -17,6 +17,7 @@
package org.springframework.test.context;
import org.springframework.context.ApplicationContext;
import org.springframework.lang.Nullable;
/**
* Strategy interface for loading an {@link ApplicationContext application context}
@@ -59,7 +60,7 @@ public interface ContextLoader {
* application context (can be {@code null} or empty)
* @return an array of application context resource locations
*/
String[] processLocations(Class<?> clazz, String... locations);
String[] processLocations(Class<?> clazz, @Nullable String... locations);
/**
* Loads a new {@link ApplicationContext context} based on the supplied

View File

@@ -26,6 +26,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.style.ToStringCreator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -134,9 +135,10 @@ public class MergedContextConfiguration implements Serializable {
/**
* Generate a null-safe {@link String} representation of the supplied
* {@link ContextLoader} based solely on the fully qualified name of the
* loader or &quot;null&quot; if the supplied loaded is {@code null}.
* loader or &quot;null&quot; if the supplied loader is {@code null}.
*/
protected static String nullSafeToString(ContextLoader contextLoader) {
@Nullable
protected static String nullSafeToString(@Nullable ContextLoader contextLoader) {
return (contextLoader != null ? contextLoader.getClass().getName() : "null");
}
@@ -197,7 +199,7 @@ public class MergedContextConfiguration implements Serializable {
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
String[] activeProfiles, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) {
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, null, null, contextLoader,
cacheAwareContextLoaderDelegate, parent);
@@ -238,11 +240,11 @@ public class MergedContextConfiguration implements Serializable {
* @param parent the parent configuration or {@code null} if there is no parent
* @since 4.1
*/
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
String[] activeProfiles, String[] propertySourceLocations, String[] propertySourceProperties,
public MergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
ContextLoader contextLoader, CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
MergedContextConfiguration parent) {
@Nullable MergedContextConfiguration parent) {
this(testClass, locations, classes, contextInitializerClasses, activeProfiles,
propertySourceLocations, propertySourceProperties,
EMPTY_CONTEXT_CUSTOMIZERS, contextLoader,
@@ -273,11 +275,11 @@ public class MergedContextConfiguration implements Serializable {
* @param parent the parent configuration or {@code null} if there is no parent
* @since 4.3
*/
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
String[] activeProfiles, String[] propertySourceLocations, String[] propertySourceProperties,
Set<ContextCustomizer> contextCustomizers, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) {
public MergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
@Nullable Set<ContextCustomizer> contextCustomizers, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
this.testClass = testClass;
this.locations = processStrings(locations);
@@ -416,6 +418,7 @@ public class MergedContextConfiguration implements Serializable {
* @see #getParentApplicationContext()
* @since 3.2.2
*/
@Nullable
public MergedContextConfiguration getParent() {
return this.parent;
}
@@ -429,6 +432,7 @@ public class MergedContextConfiguration implements Serializable {
* @see #getParent()
* @since 3.2.2
*/
@Nullable
public ApplicationContext getParentApplicationContext() {
if (this.parent == null) {
return null;

View File

@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import org.springframework.context.ApplicationContext;
import org.springframework.core.AttributeAccessor;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
/**
@@ -64,6 +65,7 @@ public interface TestContext extends AttributeAccessor, Serializable {
* @return the current test instance (may be {@code null})
* @see #updateState(Object, Method, Throwable)
*/
@Nullable
Object getTestInstance();
/**
@@ -72,6 +74,7 @@ public interface TestContext extends AttributeAccessor, Serializable {
* @return the current test method (may be {@code null})
* @see #updateState(Object, Method, Throwable)
*/
@Nullable
Method getTestMethod();
/**
@@ -82,6 +85,7 @@ public interface TestContext extends AttributeAccessor, Serializable {
* exception was thrown
* @see #updateState(Object, Method, Throwable)
*/
@Nullable
Throwable getTestException();
/**
@@ -94,7 +98,7 @@ public interface TestContext extends AttributeAccessor, Serializable {
* @param hierarchyMode the context cache clearing mode to be applied if the
* context is part of a hierarchy (may be {@code null})
*/
void markApplicationContextDirty(HierarchyMode hierarchyMode);
void markApplicationContextDirty(@Nullable HierarchyMode hierarchyMode);
/**
* Update this test context to reflect the state of the currently executing
@@ -106,6 +110,6 @@ public interface TestContext extends AttributeAccessor, Serializable {
* @param testException the exception that was thrown in the test method, or
* {@code null} if no exception was thrown
*/
void updateState(Object testInstance, Method testMethod, Throwable testException);
void updateState(@Nullable Object testInstance, @Nullable Method testMethod, @Nullable Throwable testException);
}

View File

@@ -25,6 +25,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -364,7 +365,7 @@ public class TestContextManager {
* @see #getTestExecutionListeners()
* @see Throwable#addSuppressed(Throwable)
*/
public void afterTestExecution(Object testInstance, Method testMethod, Throwable exception) throws Exception {
public void afterTestExecution(Object testInstance, Method testMethod, @Nullable Throwable exception) throws Exception {
String callbackName = "afterTestExecution";
prepareForAfterCallback(callbackName, testInstance, testMethod, exception);
@@ -424,7 +425,7 @@ public class TestContextManager {
* @see #getTestExecutionListeners()
* @see Throwable#addSuppressed(Throwable)
*/
public void afterTestMethod(Object testInstance, Method testMethod, Throwable exception) throws Exception {
public void afterTestMethod(Object testInstance, Method testMethod, @Nullable Throwable exception) throws Exception {
String callbackName = "afterTestMethod";
prepareForAfterCallback(callbackName, testInstance, testMethod, exception);

View File

@@ -17,6 +17,7 @@
package org.springframework.test.context.cache;
import org.springframework.context.ApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
import org.springframework.test.context.MergedContextConfiguration;
@@ -88,6 +89,7 @@ public interface ContextCache {
* if not found in the cache
* @see #remove
*/
@Nullable
ApplicationContext get(MergedContextConfiguration key);
/**
@@ -112,7 +114,7 @@ public interface ContextCache {
* @param hierarchyMode the hierarchy mode; may be {@code null} if the context
* is not part of a hierarchy
*/
void remove(MergedContextConfiguration key, HierarchyMode hierarchyMode);
void remove(MergedContextConfiguration key, @Nullable HierarchyMode hierarchyMode);
/**
* Determine the number of contexts currently stored in the cache.

View File

@@ -1,4 +1,7 @@
/**
* Support for context caching within the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.cache;
import org.springframework.lang.NonNullApi;

View File

@@ -2,4 +2,7 @@
* JDBC support classes for the <em>Spring TestContext Framework</em>,
* including support for declarative SQL script execution via {@code @Sql}.
*/
@NonNullApi
package org.springframework.test.context.jdbc;
import org.springframework.lang.NonNullApi;

View File

@@ -31,6 +31,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.lang.Nullable;
/**
* Collection of utilities related to autowiring of individual method parameters.
@@ -88,6 +89,7 @@ abstract class ParameterAutowireUtils {
* @see SynthesizingMethodParameter#forParameter(Parameter)
* @see AutowireCapableBeanFactory#resolveDependency(DependencyDescriptor, String)
*/
@Nullable
static Object resolveDependency(Parameter parameter, Class<?> containingClass, ApplicationContext applicationContext) {
boolean required = findMergedAnnotation(parameter, Autowired.class).map(Autowired::required).orElse(true);
MethodParameter methodParameter = SynthesizingMethodParameter.forParameter(parameter);

View File

@@ -2,4 +2,7 @@
* Core support for integrating the <em>Spring TestContext Framework</em>
* with the JUnit Jupiter extension model in JUnit 5.
*/
@NonNullApi
package org.springframework.test.context.junit.jupiter;
import org.springframework.lang.NonNullApi;

View File

@@ -2,4 +2,7 @@
* Web support for integrating the <em>Spring TestContext Framework</em>
* with the JUnit Jupiter extension model in JUnit 5.
*/
@NonNullApi
package org.springframework.test.context.junit.jupiter.web;
import org.springframework.lang.NonNullApi;

View File

@@ -36,6 +36,7 @@ import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.test.annotation.TestAnnotationUtils;
import org.springframework.test.context.TestContextManager;
@@ -343,6 +344,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
* <p>Can be overridden by subclasses.
* @return the expected exception, or {@code null} if none was specified
*/
@Nullable
protected Class<? extends Throwable> getExpectedException(FrameworkMethod frameworkMethod) {
Test test = frameworkMethod.getAnnotation(Test.class);
return (test != null && test.expected() != Test.None.class ? test.expected() : null);

View File

@@ -2,4 +2,7 @@
* Support classes for integrating the <em>Spring TestContext Framework</em>
* with JUnit 4.12 or higher.
*/
@NonNullApi
package org.springframework.test.context.junit4;
import org.springframework.lang.NonNullApi;

View File

@@ -1,4 +1,7 @@
/**
* Custom JUnit {@code Rules} used in the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.junit4.rules;
import org.springframework.lang.NonNullApi;

View File

@@ -23,6 +23,7 @@ import org.junit.AssumptionViolatedException;
import org.junit.runners.model.Statement;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.util.Assert;
@@ -56,7 +57,7 @@ public class ProfileValueChecker extends Statement {
* @param testMethod the test method to check; may be {@code null} if
* this {@code ProfileValueChecker} is being applied at the class level
*/
public ProfileValueChecker(Statement next, Class<?> testClass, Method testMethod) {
public ProfileValueChecker(Statement next, Class<?> testClass, @Nullable Method testMethod) {
Assert.notNull(next, "The next statement must not be null");
Assert.notNull(testClass, "The test class must not be null");
this.next = next;

View File

@@ -1,4 +1,7 @@
/**
* Custom JUnit {@code Statements} used in the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.junit4.statements;
import org.springframework.lang.NonNullApi;

View File

@@ -11,4 +11,7 @@
* and caching, dependency injection of test fixtures, and transactional test
* management with default rollback semantics.
*/
@NonNullApi
package org.springframework.test.context;
import org.springframework.lang.NonNullApi;

View File

@@ -32,6 +32,7 @@ import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextLoader;
@@ -212,7 +213,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* @see #processContextConfiguration(ContextConfigurationAttributes)
*/
@Override
public final String[] processLocations(Class<?> clazz, String... locations) {
public final String[] processLocations(Class<?> clazz, @Nullable String... locations) {
return (ObjectUtils.isEmpty(locations) && isGenerateDefaultLocations()) ?
generateDefaultLocations(clazz) : modifyLocations(clazz, locations);
}

View File

@@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
@@ -64,7 +65,7 @@ public abstract class AbstractDirtiesContextTestExecutionListener extends Abstra
* context is part of a hierarchy; may be {@code null}
* @since 3.2.2
*/
protected void dirtyContext(TestContext testContext, HierarchyMode hierarchyMode) {
protected void dirtyContext(TestContext testContext, @Nullable HierarchyMode hierarchyMode) {
testContext.markApplicationContextDirty(hierarchyMode);
testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, Boolean.TRUE);
}

View File

@@ -34,6 +34,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.lang.Nullable;
import org.springframework.test.context.BootstrapContext;
import org.springframework.test.context.CacheAwareContextLoaderDelegate;
import org.springframework.test.context.ContextConfiguration;
@@ -350,7 +351,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
* @see MergedContextConfiguration
*/
private MergedContextConfiguration buildMergedContextConfiguration(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributesList, MergedContextConfiguration parentConfig,
List<ContextConfigurationAttributes> configAttributesList, @Nullable MergedContextConfiguration parentConfig,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
boolean requireLocationsClassesOrInitializers) {
@@ -490,6 +491,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
* @throws IllegalArgumentException if supplied configuration attributes are
* {@code null} or <em>empty</em>
*/
@Nullable
protected Class<? extends ContextLoader> resolveExplicitContextLoaderClass(
List<ContextConfigurationAttributes> configAttributesList) {

View File

@@ -21,6 +21,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.style.ToStringCreator;
import org.springframework.lang.Nullable;
import org.springframework.test.context.TestPropertySource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -105,6 +106,7 @@ class TestPropertySourceAttributes {
* @see TestPropertySource#locations
* @see #setLocations(String[])
*/
@Nullable
String[] getLocations() {
return locations;
}
@@ -125,6 +127,7 @@ class TestPropertySourceAttributes {
* @return the inlined properties; potentially {@code null} or <em>empty</em>
* @see TestPropertySource#properties
*/
@Nullable
String[] getProperties() {
return this.properties;
}

View File

@@ -1,4 +1,7 @@
/**
* Support classes for the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.support;
import org.springframework.lang.NonNullApi;

View File

@@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestContextManager;
@@ -239,6 +240,7 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
return testResultException;
}
@Nullable
private RuntimeException throwAsUncheckedException(Throwable t) {
throwAs(t);

View File

@@ -2,4 +2,7 @@
* Support classes for ApplicationContext-based and transactional
* tests run with TestNG and the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.testng;
import org.springframework.lang.NonNullApi;

View File

@@ -17,6 +17,7 @@
package org.springframework.test.context.transaction;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
@@ -26,6 +27,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.test.context.TestContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
@@ -86,7 +88,8 @@ public abstract class TestContextTransactionUtils {
* @throws BeansException if an error occurs while retrieving an explicitly
* named {@code DataSource}
*/
public static DataSource retrieveDataSource(TestContext testContext, String name) {
@Nullable
public static DataSource retrieveDataSource(TestContext testContext, @Nullable String name) {
Assert.notNull(testContext, "TestContext must not be null");
BeanFactory bf = testContext.getApplicationContext().getAutowireCapableBeanFactory();
@@ -158,7 +161,8 @@ public abstract class TestContextTransactionUtils {
* @throws IllegalStateException if more than one TransactionManagementConfigurer
* exists in the ApplicationContext
*/
public static PlatformTransactionManager retrieveTransactionManager(TestContext testContext, String name) {
@Nullable
public static PlatformTransactionManager retrieveTransactionManager(TestContext testContext, @Nullable String name) {
Assert.notNull(testContext, "TestContext must not be null");
BeanFactory bf = testContext.getApplicationContext().getAutowireCapableBeanFactory();

View File

@@ -1,4 +1,7 @@
/**
* Transactional support classes for the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.transaction;
import org.springframework.lang.NonNullApi;

View File

@@ -1,4 +1,7 @@
/**
* Common utilities used within the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.util;
import org.springframework.lang.NonNullApi;

View File

@@ -21,6 +21,7 @@ import java.util.Set;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.style.ToStringCreator;
import org.springframework.lang.Nullable;
import org.springframework.test.context.CacheAwareContextLoaderDelegate;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextLoader;
@@ -97,11 +98,11 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration {
* @param parent the parent configuration or {@code null} if there is no parent
* @since 4.1
*/
public WebMergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
String[] activeProfiles, String[] propertySourceLocations, String[] propertySourceProperties,
public WebMergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
String resourceBasePath, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) {
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, propertySourceLocations,
propertySourceProperties, null, resourceBasePath, contextLoader, cacheAwareContextLoaderDelegate, parent);
@@ -133,11 +134,11 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration {
* @param parent the parent configuration or {@code null} if there is no parent
* @since 4.3
*/
public WebMergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
String[] activeProfiles, String[] propertySourceLocations, String[] propertySourceProperties,
Set<ContextCustomizer> contextCustomizers, String resourceBasePath, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) {
public WebMergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
@Nullable Set<ContextCustomizer> contextCustomizers, String resourceBasePath, ContextLoader contextLoader,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
super(testClass, locations, classes, contextInitializerClasses, activeProfiles, propertySourceLocations,
propertySourceProperties, contextCustomizers, contextLoader, cacheAwareContextLoaderDelegate, parent);

View File

@@ -1,4 +1,7 @@
/**
* Web support classes for the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.web;
import org.springframework.lang.NonNullApi;

View File

@@ -1,4 +1,7 @@
/**
* WebSocket support classes for the <em>Spring TestContext Framework</em>.
*/
@NonNullApi
package org.springframework.test.context.web.socket;
import org.springframework.lang.NonNullApi;

View File

@@ -1,4 +1,7 @@
/**
* Support classes for tests based on JDBC.
*/
@NonNullApi
package org.springframework.test.jdbc;
import org.springframework.lang.NonNullApi;

View File

@@ -24,6 +24,7 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.style.ToStringCreator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -80,6 +81,7 @@ public abstract class MetaAnnotationUtils {
* @see AnnotationUtils#findAnnotationDeclaringClass(Class, Class)
* @see #findAnnotationDescriptorForTypes(Class, Class...)
*/
@Nullable
public static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
Class<?> clazz, Class<T> annotationType) {
@@ -96,6 +98,7 @@ public abstract class MetaAnnotationUtils {
* @return the corresponding annotation descriptor if the annotation was found;
* otherwise {@code null}
*/
@Nullable
private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
Class<?> clazz, Set<Annotation> visited, Class<T> annotationType) {
@@ -165,6 +168,7 @@ public abstract class MetaAnnotationUtils {
* @see #findAnnotationDescriptor(Class, Class)
*/
@SuppressWarnings("unchecked")
@Nullable
public static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(
Class<?> clazz, Class<? extends Annotation>... annotationTypes) {
@@ -182,6 +186,7 @@ public abstract class MetaAnnotationUtils {
* was found; otherwise {@code null}
*/
@SuppressWarnings("unchecked")
@Nullable
private static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Class<?> clazz,
Set<Annotation> visited, Class<? extends Annotation>... annotationTypes) {

View File

@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MethodInvoker;
import org.springframework.util.ObjectUtils;
@@ -96,7 +97,7 @@ public class ReflectionTestUtils {
* @param type the type of the field to set; may be {@code null} if
* {@code name} is specified
*/
public static void setField(Object targetObject, String name, Object value, Class<?> type) {
public static void setField(Object targetObject, @Nullable String name, Object value, Class<?> type) {
setField(targetObject, null, name, value, type);
}
@@ -130,7 +131,7 @@ public class ReflectionTestUtils {
* {@code name} is specified
* @since 4.2
*/
public static void setField(Class<?> targetClass, String name, Object value, Class<?> type) {
public static void setField(Class<?> targetClass, @Nullable String name, Object value, @Nullable Class<?> type) {
setField(null, targetClass, name, value, type);
}
@@ -160,7 +161,7 @@ public class ReflectionTestUtils {
* @see ReflectionUtils#setField(Field, Object, Object)
* @see AopTestUtils#getUltimateTargetObject(Object)
*/
public static void setField(Object targetObject, Class<?> targetClass, String name, Object value, Class<?> type) {
public static void setField(@Nullable Object targetObject, @Nullable Class<?> targetClass, @Nullable String name, Object value, @Nullable Class<?> type) {
Assert.isTrue(targetObject != null || targetClass != null,
"Either targetObject or targetClass for the field must be specified");
@@ -241,7 +242,7 @@ public class ReflectionTestUtils {
* @see ReflectionUtils#getField(Field, Object)
* @see AopTestUtils#getUltimateTargetObject(Object)
*/
public static Object getField(Object targetObject, Class<?> targetClass, String name) {
public static Object getField(@Nullable Object targetObject, @Nullable Class<?> targetClass, String name) {
Assert.isTrue(targetObject != null || targetClass != null,
"Either targetObject or targetClass for the field must be specified");
@@ -402,7 +403,8 @@ public class ReflectionTestUtils {
* @see ReflectionUtils#handleReflectionException(Exception)
*/
@SuppressWarnings("unchecked")
public static <T> T invokeMethod(Object target, String name, Object... args) {
@Nullable
public static <T> T invokeMethod(Object target, String name, @Nullable Object... args) {
Assert.notNull(target, "Target object must not be null");
Assert.hasText(name, "Method name must not be empty");

View File

@@ -19,6 +19,7 @@ package org.springframework.test.util;
import java.io.ByteArrayInputStream;
import java.util.Collections;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -34,6 +35,7 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.SimpleNamespaceContext;
@@ -64,7 +66,7 @@ public class XpathExpectationsHelper {
* formatting specifiers defined in {@link String#format(String, Object...)}
* @throws XPathExpressionException
*/
public XpathExpectationsHelper(String expression, Map<String, String> namespaces, Object... args)
public XpathExpectationsHelper(String expression, @Nullable Map<String, String> namespaces, Object... args)
throws XPathExpressionException {
this.expression = String.format(expression, args);

View File

@@ -1,4 +1,7 @@
/**
* General utility classes for use in unit and integration tests.
*/
@NonNullApi
package org.springframework.test.util;
import org.springframework.lang.NonNullApi;

View File

@@ -27,6 +27,7 @@ import java.util.Set;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -172,6 +173,7 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
}
}
@Nullable
public RequestExpectation findExpectation(ClientHttpRequest request) throws IOException {
for (RequestExpectation expectation : getExpectations()) {
try {

View File

@@ -18,12 +18,14 @@ package org.springframework.test.web.client.match;
import java.io.IOException;
import java.util.Map;
import javax.xml.xpath.XPathExpressionException;
import org.hamcrest.Matcher;
import org.w3c.dom.Node;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.lang.Nullable;
import org.springframework.mock.http.client.MockClientHttpRequest;
import org.springframework.test.util.XpathExpectationsHelper;
import org.springframework.test.web.client.RequestMatcher;
@@ -53,7 +55,7 @@ public class XpathRequestMatchers {
* formatting specifiers defined in {@link String#format(String, Object...)}
* @throws XPathExpressionException
*/
protected XpathRequestMatchers(String expression, Map<String, String> namespaces, Object ... args)
protected XpathRequestMatchers(String expression, @Nullable Map<String, String> namespaces, Object ... args)
throws XPathExpressionException {
this.xpathHelper = new XpathExpectationsHelper(expression, namespaces, args);

View File

@@ -4,4 +4,7 @@
* {@link org.springframework.test.web.client.match.MockRestRequestMatchers}
* to gain access to instances of those implementations.
*/
@NonNullApi
package org.springframework.test.web.client.match;
import org.springframework.lang.NonNullApi;

View File

@@ -2,4 +2,7 @@
* Contains client-side REST testing support.
* @see org.springframework.test.web.client.MockRestServiceServer
*/
@NonNullApi
package org.springframework.test.web.client;
import org.springframework.lang.NonNullApi;

View File

@@ -20,6 +20,7 @@ import java.net.URI;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.test.web.client.ResponseCreator;
/**
@@ -45,7 +46,7 @@ public abstract class MockRestResponseCreators {
* @param body the response body, a "UTF-8" string
* @param mediaType the type of the content, may be {@code null}
*/
public static DefaultResponseCreator withSuccess(String body, MediaType mediaType) {
public static DefaultResponseCreator withSuccess(String body, @Nullable MediaType mediaType) {
return new DefaultResponseCreator(HttpStatus.OK).body(body).contentType(mediaType);
}
@@ -54,7 +55,7 @@ public abstract class MockRestResponseCreators {
* @param body the response body
* @param contentType the type of the content, may be {@code null}
*/
public static DefaultResponseCreator withSuccess(byte[] body, MediaType contentType) {
public static DefaultResponseCreator withSuccess(byte[] body, @Nullable MediaType contentType) {
return new DefaultResponseCreator(HttpStatus.OK).body(body).contentType(contentType);
}
@@ -63,7 +64,7 @@ public abstract class MockRestResponseCreators {
* @param body the response body
* @param contentType the type of the content, may be {@code null}
*/
public static DefaultResponseCreator withSuccess(Resource body, MediaType contentType) {
public static DefaultResponseCreator withSuccess(Resource body, @Nullable MediaType contentType) {
return new DefaultResponseCreator(HttpStatus.OK).body(body).contentType(contentType);
}

View File

@@ -4,4 +4,7 @@
* {@link org.springframework.test.web.client.response.MockRestResponseCreators}
* to gain access to instances of those implementations.
*/
@NonNullApi
package org.springframework.test.web.client.response;
import org.springframework.lang.NonNullApi;

View File

@@ -39,6 +39,7 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ClientHttpRequest;
import org.springframework.lang.Nullable;
import org.springframework.test.util.JsonExpectationsHelper;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
@@ -501,6 +502,7 @@ class DefaultWebTestClient implements WebTestClient {
return new JsonPathAssertions(this, getBodyAsString(), expression, args);
}
@Nullable
private String getBodyAsString() {
if (this.isEmpty) {
return null;

View File

@@ -2,4 +2,7 @@
* Support for testing Spring WebFlux server endpoints via
* {@link org.springframework.test.web.reactive.server.WebTestClient}.
*/
@NonNullApi
package org.springframework.test.web.reactive.server;
import org.springframework.lang.NonNullApi;

View File

@@ -16,6 +16,7 @@
package org.springframework.test.web.servlet;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.FlashMap;
@@ -47,18 +48,21 @@ public interface MvcResult {
* Return the executed handler.
* @return the handler, possibly {@code null} if none were executed
*/
@Nullable
Object getHandler();
/**
* Return interceptors around the handler.
* @return interceptors, or {@code null} if none were selected
*/
@Nullable
HandlerInterceptor[] getInterceptors();
/**
* Return the {@code ModelAndView} prepared by the handler.
* @return a {@code ModelAndView}, or {@code null}
*/
@Nullable
ModelAndView getModelAndView();
/**
@@ -66,6 +70,7 @@ public interface MvcResult {
* through a {@link HandlerExceptionResolver}.
* @return an exception, possibly {@code null}
*/
@Nullable
Exception getResolvedException();
/**

View File

@@ -42,6 +42,7 @@ import com.gargoylesoftware.htmlunit.util.NameValuePair;
import org.springframework.beans.Mergeable;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.RequestBuilder;
@@ -206,7 +207,7 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
* @throws IllegalArgumentException if the contextPath is not a valid
* {@link HttpServletRequest#getContextPath()}
*/
public void setContextPath(String contextPath) {
public void setContextPath(@Nullable String contextPath) {
MockMvcWebConnection.validateContextPath(contextPath);
this.contextPath = contextPath;
}

View File

@@ -29,6 +29,7 @@ import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.util.Cookie;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc;
@@ -90,7 +91,7 @@ public final class MockMvcWebConnection implements WebConnection {
* @param webClient the {@link WebClient} to use. never {@code null}
* @param contextPath the contextPath to use
*/
public MockMvcWebConnection(MockMvc mockMvc, WebClient webClient, String contextPath) {
public MockMvcWebConnection(MockMvc mockMvc, WebClient webClient, @Nullable String contextPath) {
Assert.notNull(mockMvc, "MockMvc must not be null");
Assert.notNull(webClient, "WebClient must not be null");
validateContextPath(contextPath);
@@ -108,7 +109,7 @@ public final class MockMvcWebConnection implements WebConnection {
* a "/" character and not end with a "/" character.
* @param contextPath the path to validate
*/
static void validateContextPath(String contextPath) {
static void validateContextPath(@Nullable String contextPath) {
if (contextPath == null || "".equals(contextPath)) {
return;
}

View File

@@ -22,6 +22,7 @@ import java.util.List;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebConnection;
import org.springframework.lang.Nullable;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.DelegatingWebConnection.DelegateWebConnection;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@@ -92,7 +93,7 @@ public abstract class MockMvcWebConnectionBuilderSupport<T extends MockMvcWebCon
* @return this builder for further customization
*/
@SuppressWarnings("unchecked")
public T contextPath(String contextPath) {
public T contextPath(@Nullable String contextPath) {
this.contextPath = contextPath;
return (T) this;
}

View File

@@ -3,4 +3,7 @@
* and HtmlUnit.
* @see org.springframework.test.web.servlet.MockMvc
*/
package org.springframework.test.web.servlet.htmlunit;
@NonNullApi
package org.springframework.test.web.servlet.htmlunit;
import org.springframework.lang.NonNullApi;

View File

@@ -4,4 +4,7 @@
* @see org.springframework.test.web.servlet.MockMvc
* @see org.openqa.selenium.htmlunit.HtmlUnitDriver
*/
package org.springframework.test.web.servlet.htmlunit.webdriver;
@NonNullApi
package org.springframework.test.web.servlet.htmlunit.webdriver;
import org.springframework.lang.NonNullApi;

View File

@@ -2,4 +2,7 @@
* Contains server-side support for testing Spring MVC applications.
* @see org.springframework.test.web.servlet.MockMvc
*/
@NonNullApi
package org.springframework.test.web.servlet;
import org.springframework.lang.NonNullApi;

View File

@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
@@ -41,6 +42,7 @@ import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
@@ -370,7 +372,7 @@ public class MockHttpServletRequestBuilder
* @param locale the locale, or {@code null} to reset it
* @see #locale(Locale...)
*/
public MockHttpServletRequestBuilder locale(Locale locale) {
public MockHttpServletRequestBuilder locale(@Nullable Locale locale) {
this.locales.clear();
if (locale != null) {
this.locales.add(locale);

View File

@@ -4,4 +4,7 @@
* {@link org.springframework.test.web.servlet.request.MockMvcRequestBuilders}
* to gain access to instances of those implementations.
*/
@NonNullApi
package org.springframework.test.web.servlet.request;
import org.springframework.lang.NonNullApi;

View File

@@ -17,11 +17,13 @@
package org.springframework.test.web.servlet.result;
import java.util.Map;
import javax.xml.xpath.XPathExpressionException;
import org.hamcrest.Matcher;
import org.w3c.dom.Node;
import org.springframework.lang.Nullable;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.util.XpathExpectationsHelper;
import org.springframework.test.web.servlet.ResultMatcher;
@@ -49,7 +51,7 @@ public class XpathResultMatchers {
* @param args arguments to parameterize the XPath expression with using the
* formatting specifiers defined in {@link String#format(String, Object...)}
*/
protected XpathResultMatchers(String expression, Map<String, String> namespaces, Object ... args)
protected XpathResultMatchers(String expression, @Nullable Map<String, String> namespaces, Object ... args)
throws XPathExpressionException {
this.xpathHelper = new XpathExpectationsHelper(expression, namespaces, args);

View File

@@ -4,4 +4,7 @@
* and {@link org.springframework.test.web.servlet.result.MockMvcResultHandlers}
* to access instances of those implementations.
*/
@NonNullApi
package org.springframework.test.web.servlet.result;
import org.springframework.lang.NonNullApi;

View File

@@ -3,4 +3,7 @@
* Use {@link org.springframework.test.web.servlet.setup.MockMvcBuilders}
* to access to instances of those implementations.
*/
@NonNullApi
package org.springframework.test.web.servlet.setup;
import org.springframework.lang.NonNullApi;