Fix overridden methods nullability

Issue: SPR-15869
This commit is contained in:
Sebastien Deleuze
2017-08-17 14:30:14 +02:00
parent 6b6c1d3e53
commit 73cf07e9a4
488 changed files with 1016 additions and 34 deletions

View File

@@ -52,12 +52,14 @@ public abstract class AttributeAccessorSupport implements AttributeAccessor, Ser
}
@Override
@Nullable
public Object getAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.get(name);
}
@Override
@Nullable
public Object removeAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.remove(name);

View File

@@ -282,6 +282,7 @@ public abstract class GenericTypeResolver {
}
@Override
@Nullable
public ResolvableType resolveVariable(TypeVariable<?> variable) {
Type type = this.typeVariableMap.get(variable);
return (type != null ? ResolvableType.forType(type) : null);

View File

@@ -65,6 +65,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
@Override
@Nullable
public String[] getParameterNames(Method method) {
Method originalMethod = BridgeMethodResolver.findBridgedMethod(method);
Class<?> declaringClass = originalMethod.getDeclaringClass();
@@ -80,6 +81,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
}
@Override
@Nullable
public String[] getParameterNames(Constructor<?> ctor) {
Class<?> declaringClass = ctor.getDeclaringClass();
Map<Member, String[]> map = this.parameterNamesCache.get(declaringClass);

View File

@@ -21,6 +21,8 @@ import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import org.springframework.lang.Nullable;
/**
* {@link ParameterNameDiscoverer} implementation that tries several discoverer
* delegates in succession. Those added first in the {@code addDiscoverer} method
@@ -47,6 +49,7 @@ public class PrioritizedParameterNameDiscoverer implements ParameterNameDiscover
@Override
@Nullable
public String[] getParameterNames(Method method) {
for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) {
String[] result = pnd.getParameterNames(method);
@@ -58,6 +61,7 @@ public class PrioritizedParameterNameDiscoverer implements ParameterNameDiscover
}
@Override
@Nullable
public String[] getParameterNames(Constructor<?> ctor) {
for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) {
String[] result = pnd.getParameterNames(ctor);

View File

@@ -1419,6 +1419,7 @@ public class ResolvableType implements Serializable {
private class DefaultVariableResolver implements VariableResolver {
@Override
@Nullable
public ResolvableType resolveVariable(TypeVariable<?> variable) {
return ResolvableType.this.resolveVariable(variable);
}
@@ -1443,6 +1444,7 @@ public class ResolvableType implements Serializable {
}
@Override
@Nullable
public ResolvableType resolveVariable(TypeVariable<?> variable) {
for (int i = 0; i < this.variables.length; i++) {
if (ObjectUtils.nullSafeEquals(SerializableTypeWrapper.unwrap(this.variables[i]),

View File

@@ -372,6 +372,7 @@ abstract class SerializableTypeWrapper {
}
@Override
@Nullable
public Type getType() {
Object result = this.result;
if (result == null) {
@@ -384,6 +385,7 @@ abstract class SerializableTypeWrapper {
}
@Override
@Nullable
public Object getSource() {
return null;
}

View File

@@ -20,6 +20,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import org.springframework.lang.Nullable;
/**
* {@link ParameterNameDiscoverer} implementation which uses JDK 8's reflection facilities
* for introspecting parameter names (based on the "-parameters" compiler flag).
@@ -32,15 +34,18 @@ import java.lang.reflect.Parameter;
public class StandardReflectionParameterNameDiscoverer implements ParameterNameDiscoverer {
@Override
@Nullable
public String[] getParameterNames(Method method) {
return getParameterNames(method.getParameters());
}
@Override
@Nullable
public String[] getParameterNames(Constructor<?> ctor) {
return getParameterNames(ctor.getParameters());
}
@Nullable
private String[] getParameterNames(Parameter[] parameters) {
String[] parameterNames = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {

View File

@@ -85,6 +85,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor<S> implements Anno
}
@Override
@Nullable
public final Object getAttributeValue(Method attributeMethod) {
String attributeName = attributeMethod.getName();
Object attributeValue = getRawAttributeValue(attributeMethod);

View File

@@ -24,6 +24,7 @@ import java.util.List;
import org.springframework.core.DecoratingProxy;
import org.springframework.core.OrderComparator;
import org.springframework.lang.Nullable;
/**
* {@code AnnotationAwareOrderComparator} is an extension of
@@ -58,6 +59,8 @@ public class AnnotationAwareOrderComparator extends OrderComparator {
* elements, in addition to the {@link org.springframework.core.Ordered}
* check in the superclass.
*/
@Override
@Nullable
protected Integer findOrder(Object obj) {
// Check for regular Ordered interface
Integer order = super.findOrder(obj);
@@ -97,6 +100,8 @@ public class AnnotationAwareOrderComparator extends OrderComparator {
* annotation: typically, selecting one object over another in case of
* multiple matches but only one object to be returned.
*/
@Override
@Nullable
public Integer getPriority(Object obj) {
if (obj instanceof Class) {
return OrderUtils.getPriority((Class<?>) obj);

View File

@@ -48,12 +48,14 @@ class DefaultAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAt
@Override
@Nullable
protected Object getRawAttributeValue(Method attributeMethod) {
ReflectionUtils.makeAccessible(attributeMethod);
return ReflectionUtils.invokeMethod(attributeMethod, getSource());
}
@Override
@Nullable
protected Object getRawAttributeValue(String attributeName) {
Method attributeMethod = ReflectionUtils.findMethod(getAnnotationType(), attributeName);
return (attributeMethod != null ? getRawAttributeValue(attributeMethod) : null);

View File

@@ -60,11 +60,13 @@ class MapAnnotationAttributeExtractor extends AbstractAliasAwareAnnotationAttrib
@Override
@Nullable
protected Object getRawAttributeValue(Method attributeMethod) {
return getRawAttributeValue(attributeMethod.getName());
}
@Override
@Nullable
protected Object getRawAttributeValue(String attributeName) {
return getSource().get(attributeName);
}

View File

@@ -20,6 +20,7 @@ import java.util.Comparator;
import java.util.Map;
import org.springframework.core.convert.ConversionService;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.comparator.Comparators;
@@ -119,6 +120,7 @@ public class ConvertingComparator<S, T> implements Comparator<S> {
}
@Override
@Nullable
public T convert(S source) {
return this.conversionService.convert(source, this.targetType);
}

View File

@@ -60,6 +60,7 @@ final class ArrayToArrayConverter implements ConditionalGenericConverter {
}
@Override
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (this.conversionService instanceof GenericConversionService) {
TypeDescriptor targetElement = targetType.getElementTypeDescriptor();

View File

@@ -168,12 +168,14 @@ public class GenericConversionService implements ConfigurableConversionService {
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T convert(@Nullable Object source, Class<T> targetType) {
Assert.notNull(targetType, "Target type to convert to cannot be null");
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType));
}
@Override
@Nullable
public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) {
Assert.notNull(targetType, "Target type to convert to cannot be null");
if (sourceType == null) {
@@ -426,6 +428,7 @@ public class GenericConversionService implements ConfigurableConversionService {
}
@Override
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return convertNullSource(sourceType, targetType);
@@ -694,6 +697,7 @@ public class GenericConversionService implements ConfigurableConversionService {
}
@Override
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return source;
}

View File

@@ -62,6 +62,7 @@ final class MapToMapConverter implements ConditionalGenericConverter {
@Override
@SuppressWarnings("unchecked")
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return null;

View File

@@ -60,7 +60,6 @@ final class ObjectToOptionalConverter implements ConditionalGenericConverter {
}
@Override
@Nullable
public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return Optional.empty();

View File

@@ -386,6 +386,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
catch (AccessControlException ex) {
return (Map) new ReadOnlySystemAttributesMap() {
@Override
@Nullable
protected String getSystemAttribute(String attributeName) {
try {
return System.getenv(attributeName);
@@ -426,6 +427,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
catch (AccessControlException ex) {
return (Map) new ReadOnlySystemAttributesMap() {
@Override
@Nullable
protected String getSystemAttribute(String attributeName) {
try {
return System.getProperty(attributeName);
@@ -524,6 +526,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
}
@Override
@Nullable
public String getProperty(String key) {
return this.propertyResolver.getProperty(key);
}
@@ -534,6 +537,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
}
@Override
@Nullable
public <T> T getProperty(String key, Class<T> targetType) {
return this.propertyResolver.getProperty(key, targetType);
}

View File

@@ -160,6 +160,7 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
}
@Override
@Nullable
public String getProperty(String key) {
return getProperty(key, String.class);
}

View File

@@ -266,6 +266,7 @@ public abstract class CommandLinePropertySource<T> extends EnumerablePropertySou
* #getOptionValues(String)} method.
*/
@Override
@Nullable
public final String getProperty(String name) {
if (this.nonOptionArgsPropertyName.equals(name)) {
Collection<String> nonOptionArguments = this.getNonOptionArgs();

View File

@@ -23,6 +23,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -54,6 +55,7 @@ public class CompositePropertySource extends EnumerablePropertySource<Object> {
@Override
@Nullable
public Object getProperty(String name) {
for (PropertySource<?> propertySource : this.propertySources) {
Object candidate = propertySource.getProperty(name);

View File

@@ -23,6 +23,8 @@ import java.util.List;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.springframework.lang.Nullable;
/**
* {@link CommandLinePropertySource} implementation backed by a JOpt {@link OptionSet}.
*
@@ -94,6 +96,7 @@ public class JOptCommandLinePropertySource extends CommandLinePropertySource<Opt
}
@Override
@Nullable
public List<String> getOptionValues(String name) {
List<?> argValues = this.source.valuesOf(name);
List<String> stringArgValues = new ArrayList<>();

View File

@@ -18,6 +18,7 @@ package org.springframework.core.env;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -36,6 +37,7 @@ public class MapPropertySource extends EnumerablePropertySource<Map<String, Obje
@Override
@Nullable
public Object getProperty(String name) {
return this.source.get(name);
}

View File

@@ -79,6 +79,7 @@ public class MutablePropertySources implements PropertySources {
}
@Override
@Nullable
public PropertySource<?> get(String name) {
int index = this.propertySourceList.indexOf(PropertySource.named(name));
return (index != -1 ? this.propertySourceList.get(index) : null);

View File

@@ -210,6 +210,7 @@ public abstract class PropertySource<T> {
* Always returns {@code null}.
*/
@Override
@Nullable
public String getProperty(String name) {
return null;
}
@@ -239,6 +240,7 @@ public abstract class PropertySource<T> {
}
@Override
@Nullable
public String getProperty(String name) {
throw new UnsupportedOperationException(USAGE_ERROR);
}

View File

@@ -57,16 +57,19 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
}
@Override
@Nullable
public String getProperty(String key) {
return getProperty(key, String.class, true);
}
@Override
@Nullable
public <T> T getProperty(String key, Class<T> targetValueType) {
return getProperty(key, targetValueType, true);
}
@Override
@Nullable
protected String getPropertyAsRawString(String key) {
return getProperty(key, String.class, false);
}

View File

@@ -18,6 +18,8 @@ package org.springframework.core.env;
import java.util.List;
import org.springframework.lang.Nullable;
/**
* {@link CommandLinePropertySource} implementation backed by a simple String array.
*
@@ -109,6 +111,7 @@ public class SimpleCommandLinePropertySource extends CommandLinePropertySource<C
}
@Override
@Nullable
protected List<String> getOptionValues(String name) {
return this.source.getOptionValues(name);
}

View File

@@ -88,6 +88,7 @@ public class SystemEnvironmentPropertySource extends MapPropertySource {
* any underscore/uppercase variant thereof exists in this property source.
*/
@Override
@Nullable
public Object getProperty(String name) {
String actualName = resolvePropertyName(name);
if (logger.isDebugEnabled() && !name.equals(actualName)) {

View File

@@ -27,6 +27,7 @@ import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import org.springframework.core.NestedIOException;
import org.springframework.lang.Nullable;
import org.springframework.util.ResourceUtils;
/**
@@ -202,6 +203,7 @@ public abstract class AbstractResource implements Resource {
* assuming that this resource type does not have a filename.
*/
@Override
@Nullable
public String getFilename() {
return null;
}

View File

@@ -211,6 +211,7 @@ public class ClassPathResource extends AbstractFileResolvingResource {
* @see org.springframework.util.StringUtils#getFilename(String)
*/
@Override
@Nullable
public String getFilename() {
return StringUtils.getFilename(this.path);
}

View File

@@ -91,6 +91,7 @@ public class DefaultResourceLoader implements ResourceLoader {
* @see ClassPathResource
*/
@Override
@Nullable
public ClassLoader getClassLoader() {
return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader());
}

View File

@@ -244,6 +244,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
}
@Override
@Nullable
public ClassLoader getClassLoader() {
return getResourceLoader().getClassLoader();
}

View File

@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.MultiValueMap;
/**
@@ -115,17 +116,20 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements
}
@Override
@Nullable
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return (this.annotations.length > 0 ? AnnotatedElementUtils.getMergedAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName) {
return getAllAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return (this.annotations.length > 0 ? AnnotatedElementUtils.getAllAnnotationAttributes(
getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null);

View File

@@ -19,6 +19,7 @@ package org.springframework.core.type;
import java.lang.reflect.Modifier;
import java.util.LinkedHashSet;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -93,6 +94,7 @@ public class StandardClassMetadata implements ClassMetadata {
}
@Override
@Nullable
public String getEnclosingClassName() {
Class<?> enclosingClass = this.introspectedClass.getEnclosingClass();
return (enclosingClass != null ? enclosingClass.getName() : null);
@@ -104,6 +106,7 @@ public class StandardClassMetadata implements ClassMetadata {
}
@Override
@Nullable
public String getSuperClassName() {
Class<?> superClass = this.introspectedClass.getSuperclass();
return (superClass != null ? superClass.getName() : null);

View File

@@ -21,6 +21,7 @@ import java.lang.reflect.Modifier;
import java.util.Map;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
@@ -115,22 +116,26 @@ public class StandardMethodMetadata implements MethodMetadata {
}
@Override
@Nullable
public Map<String, Object> getAnnotationAttributes(String annotationName) {
return getAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return AnnotatedElementUtils.getMergedAnnotationAttributes(this.introspectedMethod,
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName) {
return getAllAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
return AnnotatedElementUtils.getAllAnnotationAttributes(this.introspectedMethod,
annotationName, classValuesAsString, this.nestedAnnotationsAsMap);

View File

@@ -124,11 +124,13 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
}
@Override
@Nullable
public AnnotationAttributes getAnnotationAttributes(String annotationName) {
return getAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
this.attributesMap, this.metaAnnotationMap, annotationName);
@@ -140,11 +142,13 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName) {
return getAllAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>();
List<AnnotationAttributes> attributes = this.attributesMap.get(annotationName);

View File

@@ -116,11 +116,13 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
}
@Override
@Nullable
public AnnotationAttributes getAnnotationAttributes(String annotationName) {
return getAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
this.attributesMap, this.metaAnnotationMap, annotationName);
@@ -132,11 +134,13 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName) {
return getAllAnnotationAttributes(annotationName, false);
}
@Override
@Nullable
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
if (!this.attributesMap.containsKey(annotationName)) {
return null;

View File

@@ -94,11 +94,13 @@ public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter
}
@Override
@Nullable
protected Boolean matchSuperClass(String superClassName) {
return hasAnnotation(superClassName);
}
@Override
@Nullable
protected Boolean matchInterface(String interfaceName) {
return hasAnnotation(interfaceName);
}

View File

@@ -55,11 +55,13 @@ public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter
}
@Override
@Nullable
protected Boolean matchSuperClass(String superClassName) {
return matchTargetType(superClassName);
}
@Override
@Nullable
protected Boolean matchInterface(String interfaceName) {
return matchTargetType(interfaceName);
}

View File

@@ -29,8 +29,9 @@ import javax.annotation.meta.When;
* A common Spring annotation to declare that the annotated parameter,
* return value or field could be {@code null} under some circumstances.
*
* <p>Should be used at parameters and return values level in association
* with {@link NonNullApi} package-level annotations.
* <p>Should be used at parameters, return values and optionally field level in association
* with {@link NonNullApi} package-level annotations. Methods overrides should repeat parent
* parameter or return value {@code @Nullable} annotations unless they behave differently.
*
* <p>Leverages JSR-305 meta-annotations to indicate its semantics to
* common tools with JSR-305 support.

View File

@@ -405,6 +405,7 @@ public abstract class CollectionUtils {
}
@Override
@Nullable
public V getFirst(K key) {
List<V> values = this.map.get(key);
return (values != null ? values.get(0) : null);

View File

@@ -1005,6 +1005,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
}
@Override
@Nullable
public Reference<K, V> getNext() {
return this.nextReference;
}
@@ -1041,6 +1042,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
}
@Override
@Nullable
public Reference<K, V> getNext() {
return this.nextReference;
}

View File

@@ -76,6 +76,7 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
// MultiValueMap implementation
@Override
@Nullable
public V getFirst(K key) {
List<V> values = this.targetMap.get(key);
return (values != null ? values.get(0) : null);

View File

@@ -16,6 +16,8 @@
package org.springframework.util;
import org.springframework.lang.Nullable;
/**
* Helper class for resolving placeholders in texts. Usually applied to file paths.
*
@@ -94,6 +96,7 @@ public abstract class SystemPropertyUtils {
}
@Override
@Nullable
public String resolvePlaceholder(String placeholderName) {
try {
String propVal = System.getProperty(placeholderName);