@Nullable all the way: null-safety at field level

This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.

Issue: SPR-15720
This commit is contained in:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -35,6 +35,7 @@ import org.springframework.util.ClassUtils;
*/
public class ConfigurableObjectInputStream extends ObjectInputStream {
@Nullable
private final ClassLoader classLoader;
private final boolean acceptProxyClasses;

View File

@@ -33,6 +33,7 @@ public final class MethodClassKey implements Comparable<MethodClassKey> {
private final Method method;
@Nullable
private final Class<?> targetClass;

View File

@@ -63,31 +63,38 @@ public class MethodParameter {
ClassUtils.isPresent("kotlin.Unit", MethodParameter.class.getClassLoader());
private final Method method;
private final Constructor<?> constructor;
private final Executable executable;
private final int parameterIndex;
@Nullable
private volatile Parameter parameter;
private int nestingLevel = 1;
/** Map from Integer level to Integer type index */
@Nullable
Map<Integer, Integer> typeIndexesPerLevel;
@Nullable
private volatile Class<?> containingClass;
@Nullable
private volatile Class<?> parameterType;
@Nullable
private volatile Type genericParameterType;
@Nullable
private volatile Annotation[] parameterAnnotations;
@Nullable
private volatile ParameterNameDiscoverer parameterNameDiscoverer;
@Nullable
private volatile String parameterName;
@Nullable
private volatile MethodParameter nestedMethodParameter;
@@ -114,10 +121,9 @@ public class MethodParameter {
*/
public MethodParameter(Method method, int parameterIndex, int nestingLevel) {
Assert.notNull(method, "Method must not be null");
this.method = method;
this.executable = method;
this.parameterIndex = validateIndex(method, parameterIndex);
this.nestingLevel = nestingLevel;
this.constructor = null;
}
/**
@@ -139,10 +145,9 @@ public class MethodParameter {
*/
public MethodParameter(Constructor<?> constructor, int parameterIndex, int nestingLevel) {
Assert.notNull(constructor, "Constructor must not be null");
this.constructor = constructor;
this.executable = constructor;
this.parameterIndex = validateIndex(constructor, parameterIndex);
this.nestingLevel = nestingLevel;
this.method = null;
}
/**
@@ -152,8 +157,7 @@ public class MethodParameter {
*/
public MethodParameter(MethodParameter original) {
Assert.notNull(original, "Original must not be null");
this.method = original.method;
this.constructor = original.constructor;
this.executable = original.executable;
this.parameterIndex = original.parameterIndex;
this.parameter = original.parameter;
this.nestingLevel = original.nestingLevel;
@@ -174,7 +178,7 @@ public class MethodParameter {
*/
@Nullable
public Method getMethod() {
return this.method;
return (this.executable instanceof Method ? (Method) this.executable : null);
}
/**
@@ -184,14 +188,14 @@ public class MethodParameter {
*/
@Nullable
public Constructor<?> getConstructor() {
return this.constructor;
return (this.executable instanceof Constructor ? (Constructor) this.executable : null);
}
/**
* Return the class that declares the underlying Method or Constructor.
*/
public Class<?> getDeclaringClass() {
return getMember().getDeclaringClass();
return this.executable.getDeclaringClass();
}
/**
@@ -199,7 +203,7 @@ public class MethodParameter {
* @return the Method or Constructor as Member
*/
public Member getMember() {
return getExecutable();
return this.executable;
}
/**
@@ -209,7 +213,7 @@ public class MethodParameter {
* @return the Method or Constructor as AnnotatedElement
*/
public AnnotatedElement getAnnotatedElement() {
return getExecutable();
return this.executable;
}
/**
@@ -218,7 +222,7 @@ public class MethodParameter {
* @since 5.0
*/
public Executable getExecutable() {
return (this.method != null ? this.method : this.constructor);
return this.executable;
}
/**
@@ -226,10 +230,12 @@ public class MethodParameter {
* @since 5.0
*/
public Parameter getParameter() {
if (this.parameter == null) {
this.parameter = getExecutable().getParameters()[this.parameterIndex];
Parameter parameter = this.parameter;
if (parameter == null) {
parameter = getExecutable().getParameters()[this.parameterIndex];
this.parameter = parameter;
}
return this.parameter;
return parameter;
}
/**
@@ -316,10 +322,11 @@ public class MethodParameter {
* @since 4.3
*/
public MethodParameter nested() {
if (this.nestedMethodParameter != null) {
return this.nestedMethodParameter;
MethodParameter nestedParam = this.nestedMethodParameter;
if (nestedParam != null) {
return nestedParam;
}
MethodParameter nestedParam = clone();
nestedParam = clone();
nestedParam.nestingLevel = this.nestingLevel + 1;
this.nestedMethodParameter = nestedParam;
return nestedParam;
@@ -372,7 +379,8 @@ public class MethodParameter {
}
public Class<?> getContainingClass() {
return (this.containingClass != null ? this.containingClass : getDeclaringClass());
Class<?> containingClass = this.containingClass;
return (containingClass != null ? containingClass : getDeclaringClass());
}
/**
@@ -387,17 +395,18 @@ public class MethodParameter {
* @return the parameter type (never {@code null})
*/
public Class<?> getParameterType() {
if (this.parameterType == null) {
Class<?> paramType = this.parameterType;
if (paramType == null) {
if (this.parameterIndex < 0) {
this.parameterType = (this.method != null ? this.method.getReturnType() : null);
Method method = getMethod();
paramType = (method != null ? method.getReturnType() : void.class);
}
else {
this.parameterType = (this.method != null ?
this.method.getParameterTypes()[this.parameterIndex] :
this.constructor.getParameterTypes()[this.parameterIndex]);
paramType = this.executable.getParameterTypes()[this.parameterIndex];
}
this.parameterType = paramType;
}
return this.parameterType;
return paramType;
}
/**
@@ -406,17 +415,18 @@ public class MethodParameter {
* @since 3.0
*/
public Type getGenericParameterType() {
if (this.genericParameterType == null) {
Type paramType = this.genericParameterType;
if (paramType == null) {
if (this.parameterIndex < 0) {
this.genericParameterType = (this.method != null ? this.method.getGenericReturnType() : void.class);
Method method = getMethod();
paramType = (method != null ? method.getGenericReturnType() : void.class);
}
else {
this.genericParameterType = (this.method != null ?
this.method.getGenericParameterTypes()[this.parameterIndex] :
this.constructor.getGenericParameterTypes()[this.parameterIndex]);
paramType = this.executable.getGenericParameterTypes()[this.parameterIndex];
}
this.genericParameterType = paramType;
}
return this.genericParameterType;
return paramType;
}
/**
@@ -507,17 +517,18 @@ public class MethodParameter {
* Return the annotations associated with the specific method/constructor parameter.
*/
public Annotation[] getParameterAnnotations() {
if (this.parameterAnnotations == null) {
Annotation[][] annotationArray = (this.method != null ?
this.method.getParameterAnnotations() : this.constructor.getParameterAnnotations());
Annotation[] paramAnns = this.parameterAnnotations;
if (paramAnns == null) {
Annotation[][] annotationArray = this.executable.getParameterAnnotations();
if (this.parameterIndex >= 0 && this.parameterIndex < annotationArray.length) {
this.parameterAnnotations = adaptAnnotationArray(annotationArray[this.parameterIndex]);
paramAnns = adaptAnnotationArray(annotationArray[this.parameterIndex]);
}
else {
this.parameterAnnotations = new Annotation[0];
paramAnns = new Annotation[0];
}
this.parameterAnnotations = paramAnns;
}
return this.parameterAnnotations;
return paramAnns;
}
/**
@@ -576,8 +587,13 @@ public class MethodParameter {
public String getParameterName() {
ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;
if (discoverer != null) {
String[] parameterNames = (this.method != null ?
discoverer.getParameterNames(this.method) : discoverer.getParameterNames(this.constructor));
String[] parameterNames = null;
if (this.executable instanceof Method) {
parameterNames = discoverer.getParameterNames((Method) this.executable);
}
else if (this.executable instanceof Constructor) {
parameterNames = discoverer.getParameterNames((Constructor) this.executable);
}
if (parameterNames != null) {
this.parameterName = parameterNames[this.parameterIndex];
}
@@ -626,12 +642,13 @@ public class MethodParameter {
@Override
public int hashCode() {
return (getMember().hashCode() * 31 + this.parameterIndex);
return (getExecutable().hashCode() * 31 + this.parameterIndex);
}
@Override
public String toString() {
return (this.method != null ? "method '" + this.method.getName() + "'" : "constructor") +
Method method = getMethod();
return (method != null ? "method '" + method.getName() + "'" : "constructor") +
" parameter " + this.parameterIndex;
}

View File

@@ -47,6 +47,7 @@ public class OverridingClassLoader extends DecoratingClassLoader {
}
@Nullable
private final ClassLoader overrideDelegate;

View File

@@ -32,12 +32,11 @@ public class ReactiveTypeDescriptor {
private final Class<?> reactiveType;
@Nullable
private final Supplier<?> emptyValueSupplier;
private final boolean multiValue;
private final boolean supportsEmpty;
private final boolean noValue;
@@ -45,14 +44,12 @@ public class ReactiveTypeDescriptor {
* Private constructor. See static factory methods.
*/
private ReactiveTypeDescriptor(Class<?> reactiveType, @Nullable Supplier<?> emptySupplier,
boolean multiValue, boolean canBeEmpty, boolean noValue) {
boolean multiValue, boolean noValue) {
Assert.notNull(reactiveType, "'reactiveType' must not be null");
Assert.isTrue(!canBeEmpty || emptySupplier != null, "Empty value supplier is required.");
this.reactiveType = reactiveType;
this.emptyValueSupplier = emptySupplier;
this.multiValue = multiValue;
this.supportsEmpty = canBeEmpty;
this.noValue = noValue;
}
@@ -69,7 +66,7 @@ public class ReactiveTypeDescriptor {
* Use of this type implies {@link #supportsEmpty()} is true.
*/
public Object getEmptyValue() {
Assert.isTrue(supportsEmpty(), "Empty values not supported.");
Assert.state(this.emptyValueSupplier != null, "Empty values not supported");
return this.emptyValueSupplier.get();
}
@@ -87,7 +84,7 @@ public class ReactiveTypeDescriptor {
* Return {@code true} if the reactive type can complete with no values.
*/
public boolean supportsEmpty() {
return this.supportsEmpty;
return (this.emptyValueSupplier != null);
}
/**
@@ -122,7 +119,7 @@ public class ReactiveTypeDescriptor {
* @param emptySupplier a supplier of an empty-value instance of the reactive type
*/
public static ReactiveTypeDescriptor multiValue(Class<?> type, Supplier<?> emptySupplier) {
return new ReactiveTypeDescriptor(type, emptySupplier, true, true, false);
return new ReactiveTypeDescriptor(type, emptySupplier, true, false);
}
/**
@@ -131,7 +128,7 @@ public class ReactiveTypeDescriptor {
* @param emptySupplier a supplier of an empty-value instance of the reactive type
*/
public static ReactiveTypeDescriptor singleOptionalValue(Class<?> type, Supplier<?> emptySupplier) {
return new ReactiveTypeDescriptor(type, emptySupplier, false, true, false);
return new ReactiveTypeDescriptor(type, emptySupplier, false, false);
}
/**
@@ -139,7 +136,7 @@ public class ReactiveTypeDescriptor {
* @param type the reactive type
*/
public static ReactiveTypeDescriptor singleRequiredValue(Class<?> type) {
return new ReactiveTypeDescriptor(type, null, false, false, false);
return new ReactiveTypeDescriptor(type, null, false, false);
}
/**
@@ -148,7 +145,7 @@ public class ReactiveTypeDescriptor {
* @param emptySupplier a supplier of an empty-value instance of the reactive type
*/
public static ReactiveTypeDescriptor noValue(Class<?> type, Supplier<?> emptySupplier) {
return new ReactiveTypeDescriptor(type, emptySupplier, false, true, true);
return new ReactiveTypeDescriptor(type, emptySupplier, false, true);
}
}

View File

@@ -102,29 +102,37 @@ public class ResolvableType implements Serializable {
/**
* Optional provider for the type.
*/
@Nullable
private final TypeProvider typeProvider;
/**
* The {@code VariableResolver} to use or {@code null} if no resolver is available.
*/
@Nullable
private final VariableResolver variableResolver;
/**
* The component type for an array or {@code null} if the type should be deduced.
*/
@Nullable
private final ResolvableType componentType;
/**
* Copy of the resolved value.
*/
@Nullable
private final Class<?> resolved;
@Nullable
private final Integer hash;
@Nullable
private ResolvableType superType;
@Nullable
private ResolvableType[] interfaces;
@Nullable
private ResolvableType[] generics;
@@ -147,7 +155,7 @@ public class ResolvableType implements Serializable {
* @since 4.2
*/
private ResolvableType(Type type, @Nullable TypeProvider typeProvider,
@Nullable VariableResolver variableResolver, Integer hash) {
@Nullable VariableResolver variableResolver, @Nullable Integer hash) {
this.type = type;
this.typeProvider = typeProvider;
@@ -1131,7 +1139,7 @@ public class ResolvableType implements Serializable {
* @return a {@link ResolvableType} for the specified field
* @see #forField(Field)
*/
public static ResolvableType forField(Field field, int nestingLevel, Class<?> implementationClass) {
public static ResolvableType forField(Field field, int nestingLevel, @Nullable Class<?> implementationClass) {
Assert.notNull(field, "Field must not be null");
ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass());
return forType(null, new FieldTypeProvider(field), owner.asVariableResolver()).getNested(nestingLevel);

View File

@@ -296,6 +296,7 @@ abstract class SerializableTypeWrapper {
@SuppressWarnings("serial")
static class MethodParameterTypeProvider implements TypeProvider {
@Nullable
private final String methodName;
private final Class<?>[] parameterTypes;
@@ -359,6 +360,7 @@ abstract class SerializableTypeWrapper {
private transient Method method;
@Nullable
private transient volatile Object result;
public MethodInvokeTypeProvider(TypeProvider provider, Method method, int index) {
@@ -388,14 +390,15 @@ abstract class SerializableTypeWrapper {
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
this.method = ReflectionUtils.findMethod(this.declaringClass, this.methodName);
if (this.method == null) {
Method method = ReflectionUtils.findMethod(this.declaringClass, this.methodName);
if (method == null) {
throw new IllegalStateException("Cannot find method on deserialization: " + this.methodName);
}
if (this.method.getReturnType() != Type.class && this.method.getReturnType() != Type[].class) {
if (method.getReturnType() != Type.class && method.getReturnType() != Type[].class) {
throw new IllegalStateException(
"Invalid return type on deserialized method - needs to be Type or Type[]: " + this.method);
"Invalid return type on deserialized method - needs to be Type or Type[]: " + method);
}
this.method = method;
}
}

View File

@@ -41,6 +41,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor<S> implements Anno
private final Class<? extends Annotation> annotationType;
@Nullable
private final Object annotatedElement;
private final S source;
@@ -73,6 +74,7 @@ abstract class AbstractAliasAwareAnnotationAttributeExtractor<S> implements Anno
}
@Override
@Nullable
public final Object getAnnotatedElement() {
return this.annotatedElement;
}

View File

@@ -101,6 +101,7 @@ public class AnnotatedElementUtils {
/**
* {@code null} constant used to denote that the search algorithm should continue.
*/
@Nullable
private static final Boolean CONTINUE = null;
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
@@ -1425,8 +1426,8 @@ public class AnnotatedElementUtils {
* <p>If this method returns {@code true}, then {@link #getAggregatedResults()}
* must return a non-null value.
* @return {@code true} if this processor supports aggregated results
* @see #getAggregatedResults
* @since 4.3
* @see #getAggregatedResults
*/
boolean aggregates();
@@ -1437,10 +1438,9 @@ public class AnnotatedElementUtils {
* responsible for asking this processor if it {@link #aggregates} results
* and then adding the post-processed results to the list returned by this
* method.
* @return the list of results aggregated by this processor
* (never {@code null} unless {@link #aggregates} returns {@code false})
* @see #aggregates
* @return the list of results aggregated by this processor (never {@code null})
* @since 4.3
* @see #aggregates
*/
List<T> getAggregatedResults();
}
@@ -1537,7 +1537,7 @@ public class AnnotatedElementUtils {
this.classValuesAsString = classValuesAsString;
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
this.aggregates = aggregates;
this.aggregatedResults = (aggregates ? new ArrayList<>() : null);
this.aggregatedResults = (aggregates ? new ArrayList<>() : Collections.emptyList());
}
@Override

View File

@@ -48,6 +48,7 @@ public class AnnotationAttributes extends LinkedHashMap<String, Object> {
private static final String UNKNOWN = "unknown";
@Nullable
private final Class<? extends Annotation> annotationType;
final String displayName;

View File

@@ -136,6 +136,7 @@ public abstract class AnnotationUtils {
private static final Map<Method, AliasDescriptor> aliasDescriptorCache =
new ConcurrentReferenceHashMap<>(256);
@Nullable
private static transient Log logger;
@@ -1920,6 +1921,7 @@ public abstract class AnnotationUtils {
private final Class<A> annotationType;
@Nullable
private final Class<? extends Annotation> containerAnnotationType;
private final boolean declaredMode;

View File

@@ -34,7 +34,8 @@ import org.springframework.util.ClassUtils;
@SuppressWarnings("unchecked")
public abstract class OrderUtils {
private static Class<? extends Annotation> priorityAnnotationType = null;
@Nullable
private static Class<? extends Annotation> priorityAnnotationType;
static {
try {
@@ -43,6 +44,7 @@ public abstract class OrderUtils {
}
catch (Throwable ex) {
// javax.annotation.Priority not available, or present but not loadable (on JDK 6)
priorityAnnotationType = null;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,10 +29,12 @@ import org.springframework.util.ObjectUtils;
@SuppressWarnings("serial")
public class ConversionFailedException extends ConversionException {
@Nullable
private final TypeDescriptor sourceType;
private final TypeDescriptor targetType;
@Nullable
private final Object value;
@@ -57,6 +59,7 @@ public class ConversionFailedException extends ConversionException {
/**
* Return the source type we tried to convert the value from.
*/
@Nullable
public TypeDescriptor getSourceType() {
return this.sourceType;
}
@@ -71,6 +74,7 @@ public class ConversionFailedException extends ConversionException {
/**
* Return the offending value.
*/
@Nullable
public Object getValue() {
return this.value;
}

View File

@@ -29,6 +29,7 @@ import org.springframework.lang.Nullable;
@SuppressWarnings("serial")
public class ConverterNotFoundException extends ConversionException {
@Nullable
private final TypeDescriptor sourceType;
private final TypeDescriptor targetType;

View File

@@ -52,14 +52,17 @@ public final class Property {
private final Class<?> objectType;
@Nullable
private final Method readMethod;
@Nullable
private final Method writeMethod;
private final String name;
private final MethodParameter methodParameter;
@Nullable
private Annotation[] annotations;
@@ -147,7 +150,7 @@ public final class Property {
}
return StringUtils.uncapitalize(this.readMethod.getName().substring(index));
}
else {
else if (this.writeMethod != null) {
int index = this.writeMethod.getName().indexOf("set");
if (index == -1) {
throw new IllegalArgumentException("Not a setter method");
@@ -155,6 +158,9 @@ public final class Property {
index += 3;
return StringUtils.uncapitalize(this.writeMethod.getName().substring(index));
}
else {
throw new IllegalStateException("Property is neither readable nor writeable");
}
}
private MethodParameter resolveMethodParameter() {

View File

@@ -733,6 +733,7 @@ public class TypeDescriptor implements Serializable {
*/
private class AnnotatedElementAdapter implements AnnotatedElement, Serializable {
@Nullable
private final Annotation[] annotations;
public AnnotatedElementAdapter(@Nullable Annotation[] annotations) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import java.util.UUID;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.lang.Nullable;
/**
* A specialization of {@link GenericConversionService} configured by default
@@ -39,6 +40,7 @@ import org.springframework.core.convert.converter.ConverterRegistry;
*/
public class DefaultConversionService extends GenericConversionService {
@Nullable
private static volatile DefaultConversionService sharedInstance;
@@ -54,14 +56,17 @@ public class DefaultConversionService extends GenericConversionService {
* @since 4.3.5
*/
public static ConversionService getSharedInstance() {
if (sharedInstance == null) {
DefaultConversionService cs = sharedInstance;
if (cs == null) {
synchronized (DefaultConversionService.class) {
if (sharedInstance == null) {
sharedInstance = new DefaultConversionService();
cs = sharedInstance;
if (cs == null) {
cs = new DefaultConversionService();
sharedInstance = cs;
}
}
}
return sharedInstance;
return cs;
}

View File

@@ -132,8 +132,10 @@ final class MapToMapConverter implements ConditionalGenericConverter {
private static class MapEntry {
@Nullable
private final Object key;
@Nullable
private final Object value;
public MapEntry(@Nullable Object key, @Nullable Object value) {

View File

@@ -42,10 +42,13 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private volatile ConfigurableConversionService conversionService;
@Nullable
private PropertyPlaceholderHelper nonStrictHelper;
@Nullable
private PropertyPlaceholderHelper strictHelper;
private boolean ignoreUnresolvableNestedPlaceholders = false;
@@ -54,6 +57,7 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
private String placeholderSuffix = SystemPropertyUtils.PLACEHOLDER_SUFFIX;
@Nullable
private String valueSeparator = SystemPropertyUtils.VALUE_SEPARATOR;
private final Set<String> requiredProperties = new LinkedHashSet<>();
@@ -63,14 +67,17 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
public ConfigurableConversionService getConversionService() {
// Need to provide an independent DefaultConversionService, not the
// shared DefaultConversionService used by PropertySourcesPropertyResolver.
if (this.conversionService == null) {
ConfigurableConversionService cs = this.conversionService;
if (cs == null) {
synchronized (this) {
if (this.conversionService == null) {
this.conversionService = new DefaultConversionService();
cs = this.conversionService;
if (cs == null) {
cs = new DefaultConversionService();
this.conversionService = cs;
}
}
}
return conversionService;
return cs;
}
@Override

View File

@@ -31,6 +31,7 @@ import org.springframework.lang.Nullable;
*/
public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
@Nullable
private final PropertySources propertySources;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,8 +45,10 @@ public class ClassPathResource extends AbstractFileResolvingResource {
private final String path;
@Nullable
private ClassLoader classLoader;
@Nullable
private Class<?> clazz;
@@ -121,6 +123,7 @@ public class ClassPathResource extends AbstractFileResolvingResource {
/**
* Return the ClassLoader that this resource will be obtained from.
*/
@Nullable
public final ClassLoader getClassLoader() {
return (this.clazz != null ? this.clazz.getClassLoader() : this.classLoader);
}

View File

@@ -46,6 +46,7 @@ import org.springframework.util.StringUtils;
*/
public class DefaultResourceLoader implements ResourceLoader {
@Nullable
private ClassLoader classLoader;
private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);

View File

@@ -51,6 +51,7 @@ public class ResourceEditor extends PropertyEditorSupport {
private final ResourceLoader resourceLoader;
@Nullable
private PropertyResolver propertyResolver;
private final boolean ignoreUnresolvablePlaceholders;

View File

@@ -45,6 +45,7 @@ public class UrlResource extends AbstractFileResolvingResource {
/**
* Original URI, if available; used for URI and File access.
*/
@Nullable
private final URI uri;
/**

View File

@@ -47,10 +47,10 @@ public abstract class VfsUtils {
private static final String VFS3_PKG = "org.jboss.vfs.";
private static final String VFS_NAME = "VFS";
private static Method VFS_METHOD_GET_ROOT_URL = null;
private static Method VFS_METHOD_GET_ROOT_URI = null;
private static Method VFS_METHOD_GET_ROOT_URL;
private static Method VFS_METHOD_GET_ROOT_URI;
private static Method VIRTUAL_FILE_METHOD_EXISTS = null;
private static Method VIRTUAL_FILE_METHOD_EXISTS;
private static Method VIRTUAL_FILE_METHOD_GET_INPUT_STREAM;
private static Method VIRTUAL_FILE_METHOD_GET_SIZE;
private static Method VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED;
@@ -63,35 +63,35 @@ public abstract class VfsUtils {
protected static Class<?> VIRTUAL_FILE_VISITOR_INTERFACE;
protected static Method VIRTUAL_FILE_METHOD_VISIT;
private static Field VISITOR_ATTRIBUTES_FIELD_RECURSE = null;
private static Method GET_PHYSICAL_FILE = null;
private static Field VISITOR_ATTRIBUTES_FIELD_RECURSE;
private static Method GET_PHYSICAL_FILE;
static {
ClassLoader loader = VfsUtils.class.getClassLoader();
try {
Class<?> vfsClass = loader.loadClass(VFS3_PKG + VFS_NAME);
VFS_METHOD_GET_ROOT_URL = ReflectionUtils.findMethod(vfsClass, "getChild", URL.class);
VFS_METHOD_GET_ROOT_URI = ReflectionUtils.findMethod(vfsClass, "getChild", URI.class);
VFS_METHOD_GET_ROOT_URL = vfsClass.getMethod("getChild", URL.class);
VFS_METHOD_GET_ROOT_URI = vfsClass.getMethod("getChild", URI.class);
Class<?> virtualFile = loader.loadClass(VFS3_PKG + "VirtualFile");
VIRTUAL_FILE_METHOD_EXISTS = ReflectionUtils.findMethod(virtualFile, "exists");
VIRTUAL_FILE_METHOD_GET_INPUT_STREAM = ReflectionUtils.findMethod(virtualFile, "openStream");
VIRTUAL_FILE_METHOD_GET_SIZE = ReflectionUtils.findMethod(virtualFile, "getSize");
VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED = ReflectionUtils.findMethod(virtualFile, "getLastModified");
VIRTUAL_FILE_METHOD_TO_URI = ReflectionUtils.findMethod(virtualFile, "toURI");
VIRTUAL_FILE_METHOD_TO_URL = ReflectionUtils.findMethod(virtualFile, "toURL");
VIRTUAL_FILE_METHOD_GET_NAME = ReflectionUtils.findMethod(virtualFile, "getName");
VIRTUAL_FILE_METHOD_GET_PATH_NAME = ReflectionUtils.findMethod(virtualFile, "getPathName");
GET_PHYSICAL_FILE = ReflectionUtils.findMethod(virtualFile, "getPhysicalFile");
VIRTUAL_FILE_METHOD_GET_CHILD = ReflectionUtils.findMethod(virtualFile, "getChild", String.class);
VIRTUAL_FILE_METHOD_EXISTS = virtualFile.getMethod("exists");
VIRTUAL_FILE_METHOD_GET_INPUT_STREAM = virtualFile.getMethod("openStream");
VIRTUAL_FILE_METHOD_GET_SIZE = virtualFile.getMethod("getSize");
VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED = virtualFile.getMethod("getLastModified");
VIRTUAL_FILE_METHOD_TO_URI = virtualFile.getMethod("toURI");
VIRTUAL_FILE_METHOD_TO_URL = virtualFile.getMethod("toURL");
VIRTUAL_FILE_METHOD_GET_NAME = virtualFile.getMethod("getName");
VIRTUAL_FILE_METHOD_GET_PATH_NAME = virtualFile.getMethod("getPathName");
GET_PHYSICAL_FILE = virtualFile.getMethod("getPhysicalFile");
VIRTUAL_FILE_METHOD_GET_CHILD = virtualFile.getMethod("getChild", String.class);
VIRTUAL_FILE_VISITOR_INTERFACE = loader.loadClass(VFS3_PKG + "VirtualFileVisitor");
VIRTUAL_FILE_METHOD_VISIT = ReflectionUtils.findMethod(virtualFile, "visit", VIRTUAL_FILE_VISITOR_INTERFACE);
VIRTUAL_FILE_METHOD_VISIT = virtualFile.getMethod("visit", VIRTUAL_FILE_VISITOR_INTERFACE);
Class<?> visitorAttributesClass = loader.loadClass(VFS3_PKG + "VisitorAttributes");
VISITOR_ATTRIBUTES_FIELD_RECURSE = ReflectionUtils.findField(visitorAttributesClass, "RECURSE");
VISITOR_ATTRIBUTES_FIELD_RECURSE = visitorAttributesClass.getField("RECURSE");
}
catch (ClassNotFoundException ex) {
catch (Exception ex) {
throw new IllegalStateException("Could not detect JBoss VFS infrastructure", ex);
}
}

View File

@@ -221,7 +221,7 @@ public abstract class DataBufferUtils {
* @param dataBuffer the data buffer to release
* @return {@code true} if the buffer was released; {@code false} otherwise.
*/
public static boolean release(DataBuffer dataBuffer) {
public static boolean release(@Nullable DataBuffer dataBuffer) {
if (dataBuffer instanceof PooledDataBuffer) {
return ((PooledDataBuffer) dataBuffer).release();
}

View File

@@ -46,8 +46,10 @@ public class EncodedResource implements InputStreamSource {
private final Resource resource;
@Nullable
private final String encoding;
@Nullable
private final Charset charset;

View File

@@ -182,6 +182,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
private static final Log logger = LogFactory.getLog(PathMatchingResourcePatternResolver.class);
@Nullable
private static Method equinoxResolveMethod;
static {

View File

@@ -43,14 +43,17 @@ public abstract class PropertiesLoaderSupport {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
protected Properties[] localProperties;
protected boolean localOverride = false;
@Nullable
private Resource[] locations;
private boolean ignoreResourceNotFound = false;
@Nullable
private String fileEncoding;
private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();

View File

@@ -60,6 +60,7 @@ public class ResourceArrayPropertyEditor extends PropertyEditorSupport {
private final ResourcePatternResolver resourcePatternResolver;
@Nullable
private PropertyResolver propertyResolver;
private final boolean ignoreUnresolvablePlaceholders;

View File

@@ -45,6 +45,7 @@ import org.springframework.util.StringUtils;
public class ResourcePropertySource extends PropertiesPropertySource {
/** The original resource name, if different from the given name */
@Nullable
private final String resourceName;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import java.io.ObjectInputStream;
import org.springframework.core.ConfigurableObjectInputStream;
import org.springframework.core.NestedIOException;
import org.springframework.lang.Nullable;
/**
* A default {@link Deserializer} implementation that reads an input stream
@@ -35,6 +36,7 @@ import org.springframework.core.NestedIOException;
*/
public class DefaultDeserializer implements Deserializer<Object> {
@Nullable
private final ClassLoader classLoader;
@@ -52,7 +54,7 @@ public class DefaultDeserializer implements Deserializer<Object> {
* @since 4.2.1
* @see ConfigurableObjectInputStream#ConfigurableObjectInputStream(InputStream, ClassLoader)
*/
public DefaultDeserializer(ClassLoader classLoader) {
public DefaultDeserializer(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,8 +64,10 @@ public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator implement
/** Internal concurrency throttle used by this executor */
private final ConcurrencyThrottleAdapter concurrencyThrottle = new ConcurrencyThrottleAdapter();
@Nullable
private ThreadFactory threadFactory;
@Nullable
private TaskDecorator taskDecorator;

View File

@@ -47,6 +47,7 @@ public class TaskExecutorAdapter implements AsyncListenableTaskExecutor {
private final Executor concurrentExecutor;
@Nullable
private TaskDecorator taskDecorator;

View File

@@ -27,6 +27,7 @@ import org.springframework.asm.SpringAsmInfo;
import org.springframework.asm.Type;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -42,6 +43,7 @@ abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor {
protected final AnnotationAttributes attributes;
@Nullable
protected final ClassLoader classLoader;
@@ -79,7 +81,7 @@ abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor {
protected Object getEnumValue(String asmTypeDescriptor, String attributeValue) {
Object valueToUse = attributeValue;
try {
Class<?> enumType = this.classLoader.loadClass(Type.getType(asmTypeDescriptor).getClassName());
Class<?> enumType = ClassUtils.forName(Type.getType(asmTypeDescriptor).getClassName(), this.classLoader);
Field enumConstant = ReflectionUtils.findField(enumType, attributeValue);
if (enumConstant != null) {
ReflectionUtils.makeAccessible(enumConstant);

View File

@@ -47,6 +47,7 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib
private final MultiValueMap<String, AnnotationAttributes> attributesMap;
@Nullable
private final Map<String, Set<String>> metaAnnotationMap;

View File

@@ -49,6 +49,7 @@ import org.springframework.util.MultiValueMap;
*/
public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
@Nullable
protected final ClassLoader classLoader;
protected final Set<String> annotationSet = new LinkedHashSet<>(4);

View File

@@ -41,6 +41,7 @@ public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
public static final int DEFAULT_CACHE_LIMIT = 256;
/** MetadataReader cache: either local or shared at the ResourceLoader level */
@Nullable
private Map<Resource, MetadataReader> metadataReaderCache;

View File

@@ -44,7 +44,7 @@ import org.springframework.util.ClassUtils;
*/
class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata {
private String className;
private String className = "";
private boolean isInterface;
@@ -54,13 +54,15 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata
private boolean isFinal;
@Nullable
private String enclosingClassName;
private boolean independentInnerClass;
@Nullable
private String superClassName;
private String[] interfaces;
private String[] interfaces = new String[0];
private Set<String> memberClassNames = new LinkedHashSet<>();
@@ -183,6 +185,7 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata
}
@Override
@Nullable
public String getEnclosingClassName() {
return this.enclosingClassName;
}
@@ -193,6 +196,7 @@ class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata
}
@Override
@Nullable
public String getSuperClassName() {
return this.superClassName;
}

View File

@@ -54,14 +54,14 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho
protected final String returnTypeName;
@Nullable
protected final ClassLoader classLoader;
protected final Set<MethodMetadata> methodMetadataSet;
protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<>(4);
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap =
new LinkedMultiValueMap<>(4);
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<>(4);
public MethodMetadataReadingVisitor(String methodName, int access, String declaringClassName,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import java.util.List;
import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.Type;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
@@ -38,7 +39,7 @@ class RecursiveAnnotationArrayVisitor extends AbstractRecursiveAnnotationVisitor
public RecursiveAnnotationArrayVisitor(
String attributeName, AnnotationAttributes attributes, ClassLoader classLoader) {
String attributeName, AnnotationAttributes attributes, @Nullable ClassLoader classLoader) {
super(classLoader, attributes);
this.attributeName = attributeName;

View File

@@ -26,7 +26,8 @@ import javax.annotation.meta.TypeQualifierDefault;
/**
* A common Spring annotation to declare that parameters and return values
* are to be considered as non-nullable by default for a given package.
* are to be considered as non-nullable by default for a given package,
* along with their underlying fields.
*
* <p>Should be used at package level in association with {@link Nullable}
* annotations at parameter and return value level.
@@ -35,6 +36,7 @@ import javax.annotation.meta.TypeQualifierDefault;
* common tools with JSR-305 support.
*
* @author Sebastien Deleuze
* @author Juergen Hoeller
* @since 5.0
* @see Nullable
* @see javax.annotation.Nonnull
@@ -43,6 +45,6 @@ import javax.annotation.meta.TypeQualifierDefault;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_PARAMETER, ElementType.FIELD})
public @interface NonNullApi {
}

View File

@@ -26,8 +26,8 @@ import javax.annotation.meta.TypeQualifierNickname;
import javax.annotation.meta.When;
/**
* A common Spring annotation to declare that the annotated parameter or
* return value could be {@code null} under some circumstances.
* 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.
@@ -36,11 +36,12 @@ import javax.annotation.meta.When;
* common tools with JSR-305 support.
*
* @author Sebastien Deleuze
* @author Juergen Hoeller
* @since 5.0
* @see NonNullApi
* @see javax.annotation.Nullable
*/
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull(when = When.MAYBE)

View File

@@ -90,6 +90,7 @@ public class AntPathMatcher implements PathMatcher {
private boolean trimTokens = false;
@Nullable
private volatile Boolean cachePatterns;
private final Map<String, String[]> tokenizedPatternCache = new ConcurrentHashMap<>(256);
@@ -800,6 +801,7 @@ public class AntPathMatcher implements PathMatcher {
*/
private static class PatternInfo {
@Nullable
private final String pattern;
private int uriVars;
@@ -812,6 +814,7 @@ public class AntPathMatcher implements PathMatcher {
private boolean prefixPattern;
@Nullable
private Integer length;
public PatternInfo(@Nullable String pattern) {
@@ -828,27 +831,29 @@ public class AntPathMatcher implements PathMatcher {
protected void initCounters() {
int pos = 0;
while (pos < this.pattern.length()) {
if (this.pattern.charAt(pos) == '{') {
this.uriVars++;
pos++;
}
else if (this.pattern.charAt(pos) == '*') {
if (pos + 1 < this.pattern.length() && this.pattern.charAt(pos + 1) == '*') {
this.doubleWildcards++;
pos += 2;
}
else if (pos > 0 && !this.pattern.substring(pos - 1).equals(".*")) {
this.singleWildcards++;
if (this.pattern != null) {
while (pos < this.pattern.length()) {
if (this.pattern.charAt(pos) == '{') {
this.uriVars++;
pos++;
}
else if (this.pattern.charAt(pos) == '*') {
if (pos + 1 < this.pattern.length() && this.pattern.charAt(pos + 1) == '*') {
this.doubleWildcards++;
pos += 2;
}
else if (pos > 0 && !this.pattern.substring(pos - 1).equals(".*")) {
this.singleWildcards++;
pos++;
}
else {
pos++;
}
}
else {
pos++;
}
}
else {
pos++;
}
}
}
@@ -881,7 +886,8 @@ public class AntPathMatcher implements PathMatcher {
*/
public int getLength() {
if (this.length == null) {
this.length = VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length();
this.length = (this.pattern != null ?
VARIABLE_PATTERN.matcher(this.pattern).replaceAll("#").length() : 0);
}
return this.length;
}

View File

@@ -116,9 +116,8 @@ public abstract class ClassUtils {
Set<Class<?>> primitiveTypes = new HashSet<>(32);
primitiveTypes.addAll(primitiveWrapperTypeMap.values());
primitiveTypes.addAll(Arrays.asList(new Class<?>[] {
boolean[].class, byte[].class, char[].class, double[].class,
float[].class, int[].class, long[].class, short[].class}));
primitiveTypes.addAll(Arrays.asList(boolean[].class, byte[].class, char[].class,
double[].class, float[].class, int[].class, long[].class, short[].class));
primitiveTypes.add(void.class);
for (Class<?> primitiveType : primitiveTypes) {
primitiveTypeNameMap.put(primitiveType.getName(), primitiveType);
@@ -374,7 +373,7 @@ public abstract class ClassUtils {
* @param clazz the class to analyze
* @param classLoader the ClassLoader to potentially cache metadata in
*/
public static boolean isCacheSafe(Class<?> clazz, ClassLoader classLoader) {
public static boolean isCacheSafe(Class<?> clazz, @Nullable ClassLoader classLoader) {
Assert.notNull(clazz, "Class must not be null");
try {
ClassLoader target = clazz.getClassLoader();
@@ -1222,6 +1221,7 @@ public abstract class ClassUtils {
/**
* Check whether the given object is a CGLIB proxy.
* @param object the object to check
* @see #isCglibProxyClass(Class)
* @see org.springframework.aop.support.AopUtils#isCglibProxy(Object)
*/
public static boolean isCglibProxy(Object object) {
@@ -1231,6 +1231,7 @@ public abstract class ClassUtils {
/**
* Check whether the specified class is a CGLIB-generated class.
* @param clazz the class to check
* @see #isCglibProxyClassName(String)
*/
public static boolean isCglibProxyClass(@Nullable Class<?> clazz) {
return (clazz != null && isCglibProxyClassName(clazz.getName()));

View File

@@ -96,6 +96,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
/**
* Late binding entry set.
*/
@Nullable
private Set<Map.Entry<K, V>> entrySet;
@@ -441,9 +442,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
private final int initialSize;
/**
* Array of references indexed using the low order bits from the hash. This
* property should only be set via {@link #setReferences} to ensure that the
* {@code resizeThreshold} is maintained.
* Array of references indexed using the low order bits from the hash.
* This property should only be set along with {@code resizeThreshold}.
*/
private volatile Reference<K, V>[] references;
@@ -462,7 +462,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public Segment(int initialCapacity) {
this.referenceManager = createReferenceManager();
this.initialSize = 1 << calculateShift(initialCapacity, MAXIMUM_SEGMENT_SIZE);
setReferences(createReferenceArray(this.initialSize));
this.references = createReferenceArray(this.initialSize);
this.resizeThreshold = (int) (this.references.length * getLoadFactor());
}
@Nullable
@@ -532,7 +533,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
}
lock();
try {
setReferences(createReferenceArray(this.initialSize));
this.references = createReferenceArray(this.initialSize);
this.resizeThreshold = (int) (this.references.length * getLoadFactor());
this.count = 0;
}
finally {
@@ -598,7 +600,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
// Replace volatile members
if (resizing) {
setReferences(restructured);
this.references = restructured;
this.resizeThreshold = (int) (this.references.length * getLoadFactor());
}
this.count = Math.max(countAfterRestructure, 0);
}
@@ -636,23 +639,14 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
}
/**
* Replace the references with a new value, recalculating the resizeThreshold.
* @param references the new references
*/
private void setReferences(Reference<K, V>[] references) {
this.references = references;
this.resizeThreshold = (int) (references.length * getLoadFactor());
}
/**
* @return the size of the current references array
* Return the size of the current references array.
*/
public final int getSize() {
return this.references.length;
}
/**
* @return the total number of references in this segment
* Return the total number of references in this segment.
*/
public final int getCount() {
return this.count;
@@ -865,12 +859,16 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
private int referenceIndex;
@Nullable
private Reference<K, V>[] references;
@Nullable
private Reference<K, V> reference;
@Nullable
private Entry<K, V> next;
@Nullable
private Entry<K, V> last;
public EntryIterator() {
@@ -990,9 +988,10 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
private final int hash;
@Nullable
private final Reference<K, V> nextReference;
public SoftEntryReference(Entry<K, V> entry, int hash, @Nullable Reference<K, V> next,
public SoftEntryReference(Entry<K, V> entry, int hash, @Nullable Reference<K, V> next,
ReferenceQueue<Entry<K, V>> queue) {
super(entry, queue);
@@ -1025,6 +1024,7 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
private final int hash;
@Nullable
private final Reference<K, V> nextReference;
public WeakEntryReference(Entry<K, V> entry, int hash, @Nullable Reference<K, V> next,

View File

@@ -23,6 +23,8 @@ import java.security.MessageDigest;
import java.util.Iterator;
import java.util.LinkedList;
import org.springframework.lang.Nullable;
/**
* A speedy alternative to {@link java.io.ByteArrayOutputStream}. Note that
* this variant does <i>not</i> extend {@code ByteArrayOutputStream}, unlike
@@ -329,6 +331,7 @@ public class FastByteArrayOutputStream extends OutputStream {
private final Iterator<byte[]> buffersIterator;
@Nullable
private byte[] currentBuffer;
private int currentBufferLength = 0;
@@ -350,7 +353,7 @@ public class FastByteArrayOutputStream extends OutputStream {
this.currentBufferLength = fastByteArrayOutputStream.index;
}
else {
this.currentBufferLength = this.currentBuffer.length;
this.currentBufferLength = (this.currentBuffer != null ? this.currentBuffer.length : 0);
}
}
}
@@ -369,12 +372,7 @@ public class FastByteArrayOutputStream extends OutputStream {
else {
if (this.buffersIterator.hasNext()) {
this.currentBuffer = this.buffersIterator.next();
if (this.currentBuffer == this.fastByteArrayOutputStream.buffers.getLast()) {
this.currentBufferLength = this.fastByteArrayOutputStream.index;
}
else {
this.currentBufferLength = this.currentBuffer.length;
}
updateCurrentBufferLength();
this.nextIndexInCurrentBuffer = 0;
}
else {
@@ -421,12 +419,7 @@ public class FastByteArrayOutputStream extends OutputStream {
else {
if (this.buffersIterator.hasNext()) {
this.currentBuffer = this.buffersIterator.next();
if (this.currentBuffer == this.fastByteArrayOutputStream.buffers.getLast()) {
this.currentBufferLength = this.fastByteArrayOutputStream.index;
}
else {
this.currentBufferLength = this.currentBuffer.length;
}
updateCurrentBufferLength();
this.nextIndexInCurrentBuffer = 0;
}
else {
@@ -464,12 +457,7 @@ public class FastByteArrayOutputStream extends OutputStream {
else {
if (this.buffersIterator.hasNext()) {
this.currentBuffer = this.buffersIterator.next();
if (this.currentBuffer == this.fastByteArrayOutputStream.buffers.getLast()) {
this.currentBufferLength = this.fastByteArrayOutputStream.index;
}
else {
this.currentBufferLength = this.currentBuffer.length;
}
updateCurrentBufferLength();
this.nextIndexInCurrentBuffer = 0;
}
else {
@@ -520,12 +508,7 @@ public class FastByteArrayOutputStream extends OutputStream {
else {
if (this.buffersIterator.hasNext()) {
this.currentBuffer = this.buffersIterator.next();
if (this.currentBuffer == this.fastByteArrayOutputStream.buffers.getLast()) {
this.currentBufferLength = this.fastByteArrayOutputStream.index;
}
else {
this.currentBufferLength = this.currentBuffer.length;
}
updateCurrentBufferLength();
this.nextIndexInCurrentBuffer = 0;
}
else {
@@ -535,6 +518,15 @@ public class FastByteArrayOutputStream extends OutputStream {
}
}
}
private void updateCurrentBufferLength() {
if (this.currentBuffer == this.fastByteArrayOutputStream.buffers.getLast()) {
this.currentBufferLength = this.fastByteArrayOutputStream.index;
}
else {
this.currentBufferLength = (this.currentBuffer != null ? this.currentBuffer.length : 0);
}
}
}
}

View File

@@ -38,17 +38,23 @@ import org.springframework.lang.Nullable;
*/
public class MethodInvoker {
@Nullable
protected Class<?> targetClass;
@Nullable
private Object targetObject;
@Nullable
private String targetMethod;
@Nullable
private String staticMethod;
@Nullable
private Object[] arguments = new Object[0];
/** The method we will call */
@Nullable
private Method methodObject;

View File

@@ -56,6 +56,7 @@ public class PropertyPlaceholderHelper {
private final String simplePrefix;
@Nullable
private final String valueSeparator;
private final boolean ignoreUnresolvablePlaceholders;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,12 +56,11 @@ public class StopWatch {
/** Start time of the current task */
private long startTimeMillis;
/** Is the stop watch currently running? */
private boolean running;
/** Name of the current task */
@Nullable
private String currentTaskName;
@Nullable
private TaskInfo lastTaskInfo;
private int taskCount;
@@ -125,10 +124,9 @@ public class StopWatch {
* @see #stop()
*/
public void start(String taskName) throws IllegalStateException {
if (this.running) {
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start StopWatch: it's already running");
}
this.running = true;
this.currentTaskName = taskName;
this.startTimeMillis = System.currentTimeMillis();
}
@@ -140,17 +138,16 @@ public class StopWatch {
* @see #start()
*/
public void stop() throws IllegalStateException {
if (!this.running) {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");
}
long lastTime = System.currentTimeMillis() - this.startTimeMillis;
this.totalTimeMillis += lastTime;
this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
if (this.keepTaskList) {
this.taskList.add(lastTaskInfo);
this.taskList.add(this.lastTaskInfo);
}
++this.taskCount;
this.running = false;
this.currentTaskName = null;
}
@@ -159,7 +156,7 @@ public class StopWatch {
* @see #currentTaskName()
*/
public boolean isRunning() {
return this.running;
return (this.currentTaskName != null);
}
/**

View File

@@ -38,7 +38,8 @@ public abstract class FutureAdapter<T, S> implements Future<T> {
private final Future<S> adaptee;
private Object result = null;
@Nullable
private Object result;
private State state = State.NEW;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.util.concurrent;
import java.util.LinkedList;
import java.util.Queue;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -40,7 +41,8 @@ public class ListenableFutureCallbackRegistry<T> {
private State state = State.NEW;
private Object result = null;
@Nullable
private Object result;
private final Object mutex = new Object();
@@ -78,6 +80,7 @@ public class ListenableFutureCallbackRegistry<T> {
}
private void notifyFailure(FailureCallback callback) {
Assert.state(this.result instanceof Throwable, "No Throwable result for failure state");
try {
callback.onFailure((Throwable) this.result);
}

View File

@@ -145,6 +145,7 @@ public class SettableListenableFuture<T> implements ListenableFuture<T> {
private static class SettableTask<T> extends ListenableFutureTask<T> {
@Nullable
private volatile Thread completingThread;
@SuppressWarnings("unchecked")

View File

@@ -56,6 +56,7 @@ abstract class AbstractStaxXMLReader extends AbstractXMLReader {
private boolean namespacePrefixesFeature = false;
@Nullable
private Boolean isStandalone;
private final Map<String, String> namespaces = new LinkedHashMap<>();