Nullability refinements on private and static methods

Based on IntelliJ IDEA 2017.3 introspection results.

Issue: SPR-15756
This commit is contained in:
Juergen Hoeller 2017-09-22 18:22:12 +02:00
parent 60f47f4489
commit 7ae59d0c2a
88 changed files with 319 additions and 300 deletions

View File

@ -48,6 +48,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@ -543,6 +544,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* @see #setInterceptorNames
*/
private Advisor[] resolveInterceptorNames() {
Assert.state(this.beanFactory != null, "BeanFactory required for resolving interceptor names");
ConfigurableBeanFactory cbf = (this.beanFactory instanceof ConfigurableBeanFactory ?
(ConfigurableBeanFactory) this.beanFactory : null);
List<Advisor> advisors = new ArrayList<>();

View File

@ -205,7 +205,7 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
* @throws TypeMismatchException if type conversion failed
*/
@Nullable
public Object convertForProperty(Object value, String propertyName) throws TypeMismatchException {
public Object convertForProperty(@Nullable Object value, String propertyName) throws TypeMismatchException {
CachedIntrospectionResults cachedIntrospectionResults = getCachedIntrospectionResults();
PropertyDescriptor pd = cachedIntrospectionResults.getPropertyDescriptor(propertyName);
if (pd == null) {

View File

@ -541,6 +541,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
return this.registeredType;
}
@Nullable
private PropertyEditor getPropertyEditor(@Nullable Class<?> requiredType) {
// Special case: If no required type specified, which usually only happens for
// Collection elements, or required type is not assignable to registered type,

View File

@ -97,7 +97,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
* @param original the PropertyValue to link to (never {@code null})
* @param newValue the new value to apply
*/
public PropertyValue(PropertyValue original, Object newValue) {
public PropertyValue(PropertyValue original, @Nullable Object newValue) {
Assert.notNull(original, "Original must not be null");
this.name = original.getName();
this.value = newValue;
@ -172,7 +172,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
* Set the converted value of the constructor argument,
* after processed type conversion.
*/
public synchronized void setConvertedValue(Object value) {
public synchronized void setConvertedValue(@Nullable Object value) {
this.converted = true;
this.convertedValue = value;
}

View File

@ -459,21 +459,18 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
boolean hasClosureArgument = (args[args.length - 1] instanceof Closure);
if (args[0] instanceof Class) {
Class<?> beanClass = (Class<?>) args[0];
if (args.length >= 1) {
if (hasClosureArgument) {
if (args.length - 1 != 1) {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
beanName, beanClass, resolveConstructorArguments(args, 1, args.length - 1));
}
else {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, beanClass);
}
}
else {
if (hasClosureArgument) {
if (args.length - 1 != 1) {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
beanName, beanClass, resolveConstructorArguments(args, 1, args.length));
beanName, beanClass, resolveConstructorArguments(args, 1, args.length - 1));
}
else {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, beanClass);
}
}
else {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
beanName, beanClass, resolveConstructorArguments(args, 1, args.length));
}
}
else if (args[0] instanceof RuntimeBeanReference) {

View File

@ -1556,7 +1556,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param pvs the new property values
*/
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
if (pvs.isEmpty()) {
return;
}
@ -1649,7 +1649,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* Convert the given value for the specified target property.
*/
@Nullable
private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
private Object convertForProperty(
@Nullable Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
if (converter instanceof BeanWrapperImpl) {
return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
}

View File

@ -145,7 +145,6 @@ abstract class AutowireUtils {
* @param requiredType the type to assign the result to
* @return the resolved value
*/
@Nullable
public static Object resolveAutowiringValue(Object autowiringValue, Class<?> requiredType) {
if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue)) {
ObjectFactory<?> factory = (ObjectFactory<?>) autowiringValue;

View File

@ -93,6 +93,7 @@ public final class ParserContext {
return this.readerContext.extractSource(sourceCandidate);
}
@Nullable
public CompositeComponentDefinition getContainingComponent() {
return (!this.containingComponents.isEmpty() ?
(CompositeComponentDefinition) this.containingComponents.lastElement() : null);

View File

@ -205,7 +205,9 @@ public class EhCacheFactoryBean extends CacheConfiguration implements FactoryBea
String cacheName = getName();
if (cacheName == null) {
cacheName = this.beanName;
setName(cacheName);
if (cacheName != null) {
setName(cacheName);
}
}
// If no CacheManager given, fetch the default.

View File

@ -597,7 +597,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
else if (embeddedValueResolver != null) {
resourceName = embeddedValueResolver.resolveStringValue(resourceName);
}
if (resourceType != null && Object.class != resourceType) {
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
@ -642,7 +642,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
resourceName = Introspector.decapitalize(resourceName.substring(3));
}
}
if (resourceType != null && Object.class != resourceType) {
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
@ -726,7 +726,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
}
Class<?> resourceType = resource.beanInterface();
if (resourceType != null && Object.class != resourceType) {
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {

View File

@ -364,7 +364,6 @@ class ConfigurationClassEnhancer {
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
@Nullable
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {

View File

@ -35,6 +35,7 @@ import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
/**
@ -205,6 +206,7 @@ abstract class ConfigurationClassUtils {
* or {@link Ordered#LOWEST_PRECEDENCE} if none declared
* @since 5.0
*/
@Nullable
public static Integer getOrder(AnnotationMetadata metadata) {
Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null);

View File

@ -766,6 +766,7 @@ public class ResolvableType implements Serializable {
return (this.resolved != null ? this.resolved : fallback);
}
@Nullable
private Class<?> resolveClass() {
if (this.type == EmptyType.INSTANCE) {
return null;
@ -1474,6 +1475,7 @@ public class ResolvableType implements Serializable {
}
@Override
@Nullable
public Type getOwnerType() {
return null;
}

View File

@ -153,7 +153,6 @@ public class AnnotatedElementUtils {
* @see #getMetaAnnotationTypes(AnnotatedElement, String)
* @see #hasMetaAnnotationTypes
*/
@Nullable
public static Set<String> getMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "'annotationType' must not be null");
@ -1114,7 +1113,7 @@ public class AnnotatedElementUtils {
processor.alwaysProcesses()) {
T result = processor.process(element, annotation, metaDepth);
if (result != null) {
if (processor.aggregates() && metaDepth == 0) {
if (aggregatedResults != null && metaDepth == 0) {
aggregatedResults.add(result);
}
else {
@ -1126,7 +1125,7 @@ public class AnnotatedElementUtils {
else if (currentAnnotationType == containerType) {
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
T result = processor.process(element, contained, metaDepth);
if (result != null) {
if (aggregatedResults != null && result != null) {
// No need to post-process since repeatable annotations within a
// container cannot be composed annotations.
aggregatedResults.add(result);
@ -1144,7 +1143,7 @@ public class AnnotatedElementUtils {
containerType, processor, visited, metaDepth + 1);
if (result != null) {
processor.postProcess(currentAnnotationType, annotation, result);
if (processor.aggregates() && metaDepth == 0) {
if (aggregatedResults != null && metaDepth == 0) {
aggregatedResults.add(result);
}
else {
@ -1154,7 +1153,7 @@ public class AnnotatedElementUtils {
}
}
if (processor.aggregates()) {
if (aggregatedResults != null) {
// Prepend to support top-down ordering within class hierarchies
processor.getAggregatedResults().addAll(0, aggregatedResults);
}
@ -1237,9 +1236,10 @@ public class AnnotatedElementUtils {
return null;
}
private static <T> T searchOnInterfaces(Method method, Class<? extends Annotation> annotationType,
String annotationName, Class<? extends Annotation> containerType, Processor<T> processor,
Set<AnnotatedElement> visited, int metaDepth, Class<?>[] ifcs) {
@Nullable
private static <T> T searchOnInterfaces(Method method, @Nullable Class<? extends Annotation> annotationType,
@Nullable String annotationName, @Nullable Class<? extends Annotation> containerType,
Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth, Class<?>[] ifcs) {
for (Class<?> iface : ifcs) {
if (AnnotationUtils.isInterfaceWithAnnotatedMethods(iface)) {
@ -1495,7 +1495,6 @@ public class AnnotatedElementUtils {
static class AlwaysTrueBooleanAnnotationProcessor extends SimpleAnnotationProcessor<Boolean> {
@Override
@Nullable
public final Boolean process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
return Boolean.TRUE;
}

View File

@ -292,7 +292,6 @@ public abstract class AnnotationUtils {
* @see java.lang.annotation.Repeatable
* @see java.lang.reflect.AnnotatedElement#getAnnotationsByType
*/
@Nullable
public static <A extends Annotation> Set<A> getRepeatableAnnotations(AnnotatedElement annotatedElement,
Class<A> annotationType) {
@ -1524,7 +1523,6 @@ public abstract class AnnotationUtils {
* @see #synthesizeAnnotation(Map, Class, AnnotatedElement)
* @see #synthesizeAnnotation(Annotation, AnnotatedElement)
*/
@Nullable
public static <A extends Annotation> A synthesizeAnnotation(Class<A> annotationType) {
return synthesizeAnnotation(Collections.<String, Object> emptyMap(), annotationType, null);
}

View File

@ -129,6 +129,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
return (getValidatedMember(targetClass, sourceClass) != null);
}
@Nullable
private static Member getValidatedMember(Class<?> targetClass, Class<?> sourceClass) {
Member member = conversionMemberCache.get(targetClass);
if (isApplicable(member, sourceClass)) {
@ -166,6 +167,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
}
}
@Nullable
private static Method determineToMethod(Class<?> targetClass, Class<?> sourceClass) {
if (String.class == targetClass || String.class == sourceClass) {
// Do not accept a toString() method or any to methods on String itself
@ -177,6 +179,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
ClassUtils.isAssignable(targetClass, method.getReturnType()) ? method : null);
}
@Nullable
private static Method determineFactoryMethod(Class<?> targetClass, Class<?> sourceClass) {
if (String.class == targetClass) {
// Do not accept the String.valueOf(Object) method

View File

@ -30,9 +30,8 @@ import javax.annotation.meta.TypeQualifierNickname;
* Leverages JSR 305 meta-annotations to indicate nullability in Java to common tools with
* JSR 305 support and used by Kotlin to infer nullability of Spring API.
*
* <p>Should be used at parameter, return value, and field level.
* Methods overrides should repeat parent {@code @NonNull} annotations unless they behave
* differently.
* <p>Should be used at parameter, return value, and field level. Method overrides should
* repeat parent {@code @NonNull} annotations unless they behave differently.
*
* <p>Use {@code @NonNullApi} (scope = parameters + return values) and/or {@code @NonNullFields}
* (scope = fields) to set the default behavior to non-nullable in order to avoid annotating

View File

@ -27,8 +27,9 @@ 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.
* Leverages JSR 305 meta-annotations to indicate nullability in Java to common tools with
* JSR 305 support and used by Kotlin to infer nullability of Spring API.
*
* <p>Leverages JSR-305 meta-annotations to indicate nullability in Java to common
* tools with JSR-305 support and used by Kotlin to infer nullability of Spring API.
*
* <p>Should be used at package level in association with {@link Nullable}
* annotations at parameter and return value level.

View File

@ -21,15 +21,15 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
/**
* A common Spring annotation to declare that fields are to be considered as
* non-nullable by default for a given package. Leverages JSR 305 meta-annotations to
* indicate nullability in Java to common tools with JSR 305 support and used by Kotlin
* to infer nullability of Spring API.
* non-nullable by default for a given package.
*
* <p>Leverages JSR-305 meta-annotations to indicate nullability in Java to common
* tools with JSR-305 support and used by Kotlin to infer nullability of Spring API.
*
* <p>Should be used at package level in association with {@link Nullable}
* annotations at field level.

View File

@ -30,9 +30,8 @@ import javax.annotation.meta.When;
* some circumstance. Leverages JSR 305 meta-annotations to indicate nullability in Java
* to common tools with JSR 305 support and used by Kotlin to infer nullability of Spring API.
*
* <p>Should be used at parameter, return value, and field level.
* Methods overrides should repeat parent {@code @Nullable} annotations unless they behave
* differently.
* <p>Should be used at parameter, return value, and field level. Methods override should
* repeat parent {@code @Nullable} annotations unless they behave differently.
*
* <p>Can be used in association with {@code NonNullApi} or {@code @NonNullFields} to
* override the default non-nullable semantic to nullable.

View File

@ -20,8 +20,6 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.springframework.lang.Nullable;
/**
* A simple utility class for Base64 encoding and decoding.
*
@ -90,9 +88,8 @@ public abstract class Base64Utils {
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
* @since 4.2.4
*/
@Nullable
public static byte[] decodeUrlSafe(@Nullable byte[] src) {
if (src == null || src.length == 0) {
public static byte[] decodeUrlSafe(byte[] src) {
if (src.length == 0) {
return src;
}
return Base64.getUrlDecoder().decode(src);
@ -130,7 +127,6 @@ public abstract class Base64Utils {
* @throws IllegalStateException if Base64 encoding between byte arrays is not
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
*/
@Nullable
public static String encodeToUrlSafeString(byte[] src) {
return new String(encodeUrlSafe(src), DEFAULT_CHARSET);
}
@ -143,7 +139,6 @@ public abstract class Base64Utils {
* @throws IllegalStateException if Base64 encoding between byte arrays is not
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
*/
@Nullable
public static byte[] decodeFromUrlSafeString(String src) {
return decodeUrlSafe(src.getBytes(DEFAULT_CHARSET));
}

View File

@ -306,7 +306,6 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public boolean remove(Object key, final Object value) {
Boolean result = doTask(key, new Task<Boolean>(TaskOption.RESTRUCTURE_AFTER, TaskOption.SKIP_IF_EMPTY) {
@Override
@Nullable
protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
if (entry != null && ObjectUtils.nullSafeEquals(entry.getValue(), value)) {
if (reference != null) {
@ -324,7 +323,6 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public boolean replace(K key, final V oldValue, final V newValue) {
Boolean result = doTask(key, new Task<Boolean>(TaskOption.RESTRUCTURE_BEFORE, TaskOption.SKIP_IF_EMPTY) {
@Override
@Nullable
protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
if (entry != null && ObjectUtils.nullSafeEquals(entry.getValue(), oldValue)) {
entry.setValue(newValue);

View File

@ -396,12 +396,6 @@ public class FastByteArrayOutputStream extends OutputStream {
else if (len == 0) {
return 0;
}
else if (len < 0) {
throw new IllegalArgumentException("len must be 0 or greater: " + len);
}
else if (off < 0) {
throw new IllegalArgumentException("off must be 0 or greater: " + off);
}
else {
if (this.currentBuffer == null) {
// This stream doesn't have any data in it...

View File

@ -51,7 +51,7 @@ public abstract class FutureAdapter<T, S> implements Future<T> {
* @param adaptee the future to delegate to
*/
protected FutureAdapter(Future<S> adaptee) {
Assert.notNull(adaptee, "'delegate' must not be null");
Assert.notNull(adaptee, "Delegate must not be null");
this.adaptee = adaptee;
}
@ -98,6 +98,7 @@ public abstract class FutureAdapter<T, S> implements Future<T> {
case SUCCESS:
return (T) this.result;
case FAILURE:
Assert.state(this.result instanceof ExecutionException, "Failure without exception");
throw (ExecutionException) this.result;
case NEW:
try {

View File

@ -165,6 +165,7 @@ public class XmlValidationModeDetector {
* Consume the next comment token, update the "inComment" flag
* and return the remaining content.
*/
@Nullable
private String consume(String line) {
int index = (this.inComment ? endComment(line) : startComment(line));
return (index == -1 ? null : line.substring(index));

View File

@ -32,7 +32,7 @@ import org.springframework.lang.Nullable;
*/
public class CompoundExpression extends SpelNodeImpl {
public CompoundExpression(int pos,SpelNodeImpl... expressionComponents) {
public CompoundExpression(int pos, SpelNodeImpl... expressionComponents) {
super(pos, expressionComponents);
if (expressionComponents.length < 2) {
throw new IllegalStateException("Do not build compound expressions with less than two entries: " +

View File

@ -61,7 +61,6 @@ public class Selection extends SpelNodeImpl {
public Selection(boolean nullSafe, int variant, int pos, SpelNodeImpl expression) {
super(pos, expression);
Assert.notNull(expression, "Expression must not be null");
this.nullSafe = nullSafe;
this.variant = variant;
}

View File

@ -72,8 +72,9 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
Assert.isTrue(pos != 0, "Pos must not be 0");
if (!ObjectUtils.isEmpty(operands)) {
this.children = operands;
for (SpelNodeImpl childNode : operands) {
childNode.parent = this;
for (SpelNodeImpl operand : operands) {
Assert.notNull(operand, "Operand must not be null");
operand.parent = this;
}
}
}

View File

@ -329,13 +329,11 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
if (t.kind == TokenKind.NOT) {
return new OperatorNot(toPos(t), expr);
}
if (t.kind == TokenKind.PLUS) {
return new OpPlus(toPos(t), expr);
}
Assert.isTrue(t.kind == TokenKind.MINUS, "Minus token expected");
return new OpMinus(toPos(t), expr);
}
if (peekToken(TokenKind.INC, TokenKind.DEC)) {
Token t = takeToken();
@ -345,48 +343,40 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
}
return new OpDec(toPos(t), false, expr);
}
return eatPrimaryExpression();
}
// primaryExpression : startNode (node)? -> ^(EXPRESSION startNode (node)?);
@Nullable
private SpelNodeImpl eatPrimaryExpression() {
List<SpelNodeImpl> nodes = new ArrayList<>();
SpelNodeImpl start = eatStartNode(); // always a start node
nodes.add(start);
while (maybeEatNode()) {
nodes.add(pop());
List<SpelNodeImpl> nodes = null;
SpelNodeImpl node = eatNode();
while (node != null) {
if (nodes == null) {
nodes = new ArrayList<>(4);
nodes.add(start);
}
nodes.add(node);
node = eatNode();
}
if (nodes.size() == 1) {
return nodes.get(0);
if (start == null || nodes == null) {
return start;
}
return new CompoundExpression(toPos((start != null ? start.getStartPosition() : 0),
return new CompoundExpression(toPos(start.getStartPosition(),
nodes.get(nodes.size() - 1).getEndPosition()),
nodes.toArray(new SpelNodeImpl[nodes.size()]));
}
// node : ((DOT dottedNode) | (SAFE_NAVI dottedNode) | nonDottedNode)+;
private boolean maybeEatNode() {
SpelNodeImpl expr = null;
if (peekToken(TokenKind.DOT, TokenKind.SAFE_NAVI)) {
expr = eatDottedNode();
}
else {
expr = maybeEatNonDottedNode();
}
if (expr == null) {
return false;
}
else {
push(expr);
return true;
}
@Nullable
private SpelNodeImpl eatNode() {
return (peekToken(TokenKind.DOT, TokenKind.SAFE_NAVI) ? eatDottedNode() : eatNonDottedNode());
}
// nonDottedNode: indexer;
@Nullable
private SpelNodeImpl maybeEatNonDottedNode() {
private SpelNodeImpl eatNonDottedNode() {
if (peekToken(TokenKind.LSQUARE)) {
if (maybeEatIndexer()) {
return pop();
@ -404,7 +394,6 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
// | lastSelection
// ))
// ;
@Nullable
private SpelNodeImpl eatDottedNode() {
Token t = takeToken(); // it was a '.' or a '?.'
boolean nullSafeNavigation = (t.kind == TokenKind.SAFE_NAVI);
@ -414,12 +403,11 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
}
if (peekToken() == null) {
// unexpectedly ran out of data
raiseInternalException(t.startPos, SpelMessage.OOD);
throw internalException(t.startPos, SpelMessage.OOD);
}
else {
raiseInternalException(t.startPos, SpelMessage.UNEXPECTED_DATA_AFTER_DOT, toString(peekToken()));
throw internalException(t.startPos, SpelMessage.UNEXPECTED_DATA_AFTER_DOT, toString(peekToken()));
}
return null;
}
// functionOrVar
@ -479,7 +467,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
nextToken(); // consume (first time through) or comma (subsequent times)
t = peekToken();
if (t == null) {
raiseInternalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS);
throw internalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS);
}
if (t.kind != TokenKind.RPAREN) {
accumulatedArguments.add(eatExpression());
@ -489,7 +477,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
while (next != null && next.kind == TokenKind.COMMA);
if (next == null) {
raiseInternalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS);
throw internalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS);
}
}
@ -556,10 +544,8 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
beanName = beanName.substring(1, beanName.length() - 1);
}
else {
raiseInternalException(beanRefToken.startPos,
SpelMessage.INVALID_BEAN_REFERENCE);
throw internalException(beanRefToken.startPos, SpelMessage.INVALID_BEAN_REFERENCE);
}
BeanReference beanReference;
if (beanRefToken.getKind() == TokenKind.FACTORY_BEAN_REF) {
String beanNameString = String.valueOf(TokenKind.FACTORY_BEAN_REF.tokenChars) + beanName;
@ -692,7 +678,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
mapElements.toArray(new SpelNodeImpl[mapElements.size()]));
}
else {
raiseInternalException(t.startPos, SpelMessage.OOD);
throw internalException(t.startPos, SpelMessage.OOD);
}
}
this.constructedNodes.push(expr);
@ -721,7 +707,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
nextToken();
SpelNodeImpl expr = eatExpression();
if (expr == null) {
raiseInternalException(toPos(t), SpelMessage.MISSING_SELECTION_EXPRESSION);
throw internalException(toPos(t), SpelMessage.MISSING_SELECTION_EXPRESSION);
}
eatToken(TokenKind.RSQUARE);
if (t.kind == TokenKind.SELECT_FIRST) {
@ -752,9 +738,9 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
}
if (qualifiedIdPieces.isEmpty()) {
if (node == null) {
raiseInternalException( this.expressionString.length(), SpelMessage.OOD);
throw internalException( this.expressionString.length(), SpelMessage.OOD);
}
raiseInternalException(node.startPos, SpelMessage.NOT_EXPECTED_TOKEN,
throw internalException(node.startPos, SpelMessage.NOT_EXPECTED_TOKEN,
"qualified ID", node.getKind().toString().toLowerCase());
}
int pos = toPos(qualifiedIdPieces.getFirst().getStartPosition(),
@ -942,10 +928,10 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
Token t = nextToken();
if (t == null) {
int pos = this.expressionString.length();
raiseInternalException(pos, SpelMessage.OOD);
throw internalException(pos, SpelMessage.OOD);
}
if (t.kind != expectedKind) {
raiseInternalException(t.startPos, SpelMessage.NOT_EXPECTED_TOKEN,
throw internalException(t.startPos, SpelMessage.NOT_EXPECTED_TOKEN,
expectedKind.toString().toLowerCase(), t.getKind().toString().toLowerCase());
}
return t;
@ -1035,10 +1021,6 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
return this.tokenStream.get(this.tokenStreamPointer);
}
private void raiseInternalException(int pos, SpelMessage message, Object... inserts) {
throw new InternalParseException(new SpelParseException(this.expressionString, pos, message, inserts));
}
public String toString(@Nullable Token t) {
if (t == null) {
return "";
@ -1056,23 +1038,27 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
private void checkLeftOperand(Token token, @Nullable SpelNodeImpl operandExpression) {
if (operandExpression == null) {
raiseInternalException(token.startPos, SpelMessage.LEFT_OPERAND_PROBLEM);
throw internalException(token.startPos, SpelMessage.LEFT_OPERAND_PROBLEM);
}
}
private void checkRightOperand(Token token, @Nullable SpelNodeImpl operandExpression) {
if (operandExpression == null) {
raiseInternalException(token.startPos, SpelMessage.RIGHT_OPERAND_PROBLEM);
throw internalException(token.startPos, SpelMessage.RIGHT_OPERAND_PROBLEM);
}
}
private InternalParseException internalException(int pos, SpelMessage message, Object... inserts) {
return new InternalParseException(new SpelParseException(this.expressionString, pos, message, inserts));
}
private int toPos(Token t) {
// Compress the start and end of a token into a single int
return (t.startPos<<16) + t.endPos;
return (t.startPos << 16) + t.endPos;
}
private int toPos(int start, int end) {
return (start<<16) + end;
return (start << 16) + end;
}
}

View File

@ -381,7 +381,6 @@ public class SpelParserTests {
checkNumber("22", 22, Integer.class);
checkNumber("+22", 22, Integer.class);
checkNumber("-22", -22, Integer.class);
checkNumber("2L", 2L, Long.class);
checkNumber("22l", 22L, Long.class);
@ -392,13 +391,10 @@ public class SpelParserTests {
checkNumberError("0x", SpelMessage.NOT_AN_INTEGER);
checkNumberError("0xL", SpelMessage.NOT_A_LONG);
checkNumberError(".324", SpelMessage.UNEXPECTED_DATA_AFTER_DOT);
checkNumberError("3.4L", SpelMessage.REAL_CANNOT_BE_LONG);
checkNumber("3.5f", 3.5f, Float.class);
checkNumber("1.2e3", 1.2e3d, Double.class);
checkNumber("1.2e+3", 1.2e3d, Double.class);
checkNumber("1.2e-3", 1.2e-3d, Double.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.jdbc;
import java.sql.SQLException;
import org.springframework.dao.UncategorizedDataAccessException;
import org.springframework.lang.Nullable;
/**
* Exception thrown when we can't classify a SQLException into
@ -31,6 +32,7 @@ import org.springframework.dao.UncategorizedDataAccessException;
public class UncategorizedSQLException extends UncategorizedDataAccessException {
/** SQL that led to the problem */
@Nullable
private final String sql;
@ -40,9 +42,10 @@ public class UncategorizedSQLException extends UncategorizedDataAccessException
* @param sql the offending SQL statement
* @param ex the root cause
*/
public UncategorizedSQLException(String task, String sql, SQLException ex) {
super(task + "; uncategorized SQLException for SQL [" + sql + "]; SQL state [" +
ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex);
public UncategorizedSQLException(String task, @Nullable String sql, SQLException ex) {
super(task + "; uncategorized SQLException" + (sql != null ? " for SQL [" + sql + "]" : "") +
"; SQL state [" + ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " +
ex.getMessage(), ex);
this.sql = sql;
}
@ -55,8 +58,9 @@ public class UncategorizedSQLException extends UncategorizedDataAccessException
}
/**
* Return the SQL that led to the problem.
* Return the SQL that led to the problem (if known).
*/
@Nullable
public String getSql() {
return this.sql;
}

View File

@ -41,6 +41,7 @@ import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.SQLWarningException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.jdbc.datasource.ConnectionProxy;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcAccessor;
@ -329,9 +330,10 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
String sql = getSql(action);
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
throw translateException("ConnectionCallback", sql, ex);
}
finally {
DataSourceUtils.releaseConnection(con, getDataSource());
@ -378,11 +380,12 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
String sql = getSql(action);
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
throw translateException("StatementCallback", sql, ex);
}
finally {
JdbcUtils.closeStatement(stmt);
@ -446,12 +449,12 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
@Override
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
return nonNull(query(sql, new RowMapperResultSetExtractor<>(rowMapper)));
return result(query(sql, new RowMapperResultSetExtractor<>(rowMapper)));
}
@Override
public Map<String, Object> queryForMap(String sql) throws DataAccessException {
return nonNull(queryForObject(sql, getColumnMapRowMapper()));
return result(queryForObject(sql, getColumnMapRowMapper()));
}
@Override
@ -479,7 +482,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
@Override
public SqlRowSet queryForRowSet(String sql) throws DataAccessException {
return nonNull(query(sql, new SqlRowSetResultSetExtractor()));
return result(query(sql, new SqlRowSetResultSetExtractor()));
}
@Override
@ -612,7 +615,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
ps = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);
throw translateException("PreparedStatementCallback", sql, ex);
}
finally {
if (psc instanceof ParameterDisposer) {
@ -728,27 +731,27 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
@Override
public <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
return nonNull(query(psc, new RowMapperResultSetExtractor<>(rowMapper)));
return result(query(psc, new RowMapperResultSetExtractor<>(rowMapper)));
}
@Override
public <T> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException {
return nonNull(query(sql, pss, new RowMapperResultSetExtractor<>(rowMapper)));
return result(query(sql, pss, new RowMapperResultSetExtractor<>(rowMapper)));
}
@Override
public <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException {
return nonNull(query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper)));
return result(query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper)));
}
@Override
public <T> List<T> query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) throws DataAccessException {
return nonNull(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
}
@Override
public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args) throws DataAccessException {
return nonNull(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
}
@Override
@ -794,12 +797,12 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
@Override
public Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes) throws DataAccessException {
return nonNull(queryForObject(sql, args, argTypes, getColumnMapRowMapper()));
return result(queryForObject(sql, args, argTypes, getColumnMapRowMapper()));
}
@Override
public Map<String, Object> queryForMap(String sql, @Nullable Object... args) throws DataAccessException {
return nonNull(queryForObject(sql, args, getColumnMapRowMapper()));
return result(queryForObject(sql, args, getColumnMapRowMapper()));
}
@Override
@ -829,12 +832,12 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
@Override
public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes) throws DataAccessException {
return nonNull(query(sql, args, argTypes, new SqlRowSetResultSetExtractor()));
return result(query(sql, args, argTypes, new SqlRowSetResultSetExtractor()));
}
@Override
public SqlRowSet queryForRowSet(String sql, @Nullable Object... args) throws DataAccessException {
return nonNull(query(sql, args, new SqlRowSetResultSetExtractor()));
return result(query(sql, args, new SqlRowSetResultSetExtractor()));
}
protected int update(final PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss)
@ -882,7 +885,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
try {
RowMapperResultSetExtractor<Map<String, Object>> rse =
new RowMapperResultSetExtractor<>(getColumnMapRowMapper(), 1);
generatedKeys.addAll(nonNull(rse.extractData(keys)));
generatedKeys.addAll(result(rse.extractData(keys)));
}
finally {
JdbcUtils.closeResultSet(keys);
@ -1057,7 +1060,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
cs = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("CallableStatementCallback", sql, ex);
throw translateException("CallableStatementCallback", sql, ex);
}
finally {
if (csc instanceof ParameterDisposer) {
@ -1384,6 +1387,20 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
}
}
/**
* Translate the given {@link SQLException} into a generic {@link DataAccessException}.
* @param task readable text describing the task being attempted
* @param sql SQL query or update that caused the problem (may be {@code null})
* @param ex the offending {@code SQLException}
* @return a DataAccessException wrapping the {@code SQLException} (never {@code null})
* @since 5.0
* @see #getExceptionTranslator()
*/
protected DataAccessException translateException(String task, @Nullable String sql, SQLException ex) {
DataAccessException dae = getExceptionTranslator().translate(task, sql, ex);
return (dae != null ? dae : new UncategorizedSQLException(task, sql, ex));
}
/**
* Determine SQL from potential provider object.
@ -1401,7 +1418,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
}
}
private static <T> T nonNull(@Nullable T result) {
private static <T> T result(@Nullable T result) {
Assert.state(result != null, "No result");
return result;
}

View File

@ -26,7 +26,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.util.Assert;
/**
* Factory used to create a {@link CallMetaDataProvider} implementation
@ -130,7 +129,6 @@ public class CallMetaDataProviderFactory {
}
return provider;
});
Assert.state(result != null, "No CallMetaDataProvider");
return result;
}
catch (MetaDataAccessException ex) {

View File

@ -24,7 +24,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.util.Assert;
/**
* Factory used to create a {@link TableMetaDataProvider} implementation
@ -77,7 +76,6 @@ public class TableMetaDataProviderFactory {
}
return provider;
});
Assert.state(result != null, "No TableMetaDataProvider");
return result;
}
catch (MetaDataAccessException ex) {

View File

@ -76,6 +76,7 @@ public abstract class JdbcDaoSupport extends DaoSupport {
/**
* Return the JDBC DataSource used by this DAO.
*/
@Nullable
public final DataSource getDataSource() {
return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null);
}

View File

@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@ -64,26 +65,26 @@ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExcep
* {@link #getFallbackTranslator() fallback translator} if necessary.
*/
@Override
@Nullable
public DataAccessException translate(@Nullable String task, @Nullable String sql, SQLException ex) {
@NonNull
public DataAccessException translate(String task, @Nullable String sql, SQLException ex) {
Assert.notNull(ex, "Cannot translate a null SQLException");
if (task == null) {
task = "";
}
if (sql == null) {
sql = "";
DataAccessException dae = doTranslate(task, sql, ex);
if (dae != null) {
// Specific exception match found.
return dae;
}
DataAccessException dex = doTranslate(task, sql, ex);
if (dex != null) {
// Specific exception match found.
return dex;
}
// Looking for a fallback...
SQLExceptionTranslator fallback = getFallbackTranslator();
if (fallback != null) {
return fallback.translate(task, sql, ex);
dae = fallback.translate(task, sql, ex);
if (dae != null) {
// Fallback exception match found.
return dae;
}
}
// We couldn't identify it more precisely.
return new UncategorizedSQLException(task, sql, ex);
}
@ -94,13 +95,13 @@ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExcep
* is allowed to return {@code null} to indicate that no exception match has
* been found and that fallback translation should kick in.
* @param task readable text describing the task being attempted
* @param sql SQL query or update that caused the problem
* @param sql SQL query or update that caused the problem (if known)
* @param ex the offending {@code SQLException}
* @return the DataAccessException, wrapping the {@code SQLException};
* or {@code null} if no exception match found
*/
@Nullable
protected abstract DataAccessException doTranslate(String task, String sql, SQLException ex);
protected abstract DataAccessException doTranslate(String task, @Nullable String sql, SQLException ex);
/**
@ -112,8 +113,8 @@ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExcep
* @param ex the offending {@code SQLException}
* @return the message {@code String} to use
*/
protected String buildMessage(String task, String sql, SQLException ex) {
return task + "; SQL [" + sql + "]; " + ex.getMessage();
protected String buildMessage(String task, @Nullable String sql, SQLException ex) {
return task + "; " + (sql != null ? "SQL [" + sql : "]; " + "") + ex.getMessage();
}
}

View File

@ -97,11 +97,12 @@ public class DatabaseStartupValidator implements InitializingBean {
*/
@Override
public void afterPropertiesSet() {
if (this.dataSource == null) {
throw new IllegalArgumentException("dataSource is required");
DataSource dataSource = this.dataSource;
if (dataSource == null) {
throw new IllegalArgumentException("Property 'dataSource' is required");
}
if (this.validationQuery == null) {
throw new IllegalArgumentException("validationQuery is required");
throw new IllegalArgumentException("Property 'validationQuery' is required");
}
try {
@ -114,10 +115,10 @@ public class DatabaseStartupValidator implements InitializingBean {
Connection con = null;
Statement stmt = null;
try {
con = this.dataSource.getConnection();
con = dataSource.getConnection();
if (con == null) {
throw new CannotGetJdbcConnectionException("Failed to execute validation query: " +
"DataSource returned null from getConnection(): " + this.dataSource);
"DataSource returned null from getConnection(): " + dataSource);
}
stmt = con.createStatement();
stmt.execute(this.validationQuery);

View File

@ -132,6 +132,7 @@ public abstract class JdbcUtils {
* @throws SQLException if thrown by the JDBC API
* @see #getResultSetValue(ResultSet, int)
*/
@Nullable
public static Object getResultSetValue(ResultSet rs, int index, @Nullable Class<?> requiredType) throws SQLException {
if (requiredType == null) {
return getResultSetValue(rs, index);
@ -310,7 +311,6 @@ public abstract class JdbcUtils {
* the DatabaseMetaDataCallback's {@code processMetaData} method
* @throws MetaDataAccessException if meta data access failed
*/
@Nullable
public static Object extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback action)
throws MetaDataAccessException {
@ -350,7 +350,6 @@ public abstract class JdbcUtils {
* @see java.sql.DatabaseMetaData
*/
@SuppressWarnings("unchecked")
@Nullable
public static <T> T extractDatabaseMetaData(DataSource dataSource, final String metaDataMethodName)
throws MetaDataAccessException {

View File

@ -169,7 +169,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
@Override
@Nullable
protected DataAccessException doTranslate(String task, String sql, SQLException ex) {
protected DataAccessException doTranslate(String task, @Nullable String sql, SQLException ex) {
SQLException sqlEx = ex;
if (sqlEx instanceof BatchUpdateException && sqlEx.getNextException() != null) {
SQLException nestedSqlEx = sqlEx.getNextException();
@ -232,11 +232,11 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
// Next, look for grouped error codes.
if (Arrays.binarySearch(this.sqlErrorCodes.getBadSqlGrammarCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new BadSqlGrammarException(task, sql, sqlEx);
return new BadSqlGrammarException(task, (sql != null ? sql : ""), sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getInvalidResultSetAccessCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new InvalidResultSetAccessException(task, sql, sqlEx);
return new InvalidResultSetAccessException(task, (sql != null ? sql : ""), sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getDuplicateKeyCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
@ -397,12 +397,12 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
}
}
private void logTranslation(String task, String sql, SQLException sqlEx, boolean custom) {
private void logTranslation(String task, @Nullable String sql, SQLException sqlEx, boolean custom) {
if (logger.isDebugEnabled()) {
String intro = custom ? "Custom translation of" : "Translating";
logger.debug(intro + " SQLException with SQL state '" + sqlEx.getSQLState() +
"', error code '" + sqlEx.getErrorCode() + "', message [" + sqlEx.getMessage() +
"]; SQL was [" + sql + "] for task [" + task + "]");
"', error code '" + sqlEx.getErrorCode() + "', message [" + sqlEx.getMessage() + "]" +
(sql != null ? "; SQL was [" + sql + "]": "") + " for task [" + task + "]");
}
}

View File

@ -32,6 +32,7 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
/**
* Factory for creating {@link SQLErrorCodes} based on the
@ -211,7 +212,7 @@ public class SQLErrorCodesFactory {
// We could not find it - got to look it up.
try {
String name = JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductName");
if (name != null) {
if (StringUtils.hasLength(name)) {
return registerDatabase(dataSource, name);
}
}

View File

@ -64,7 +64,7 @@ public class SQLExceptionSubclassTranslator extends AbstractFallbackSQLException
@Override
@Nullable
protected DataAccessException doTranslate(String task, String sql, SQLException ex) {
protected DataAccessException doTranslate(String task, @Nullable String sql, SQLException ex) {
if (ex instanceof SQLTransientException) {
if (ex instanceof SQLTransientConnectionException) {
return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex);
@ -90,7 +90,7 @@ public class SQLExceptionSubclassTranslator extends AbstractFallbackSQLException
return new PermissionDeniedDataAccessException(buildMessage(task, sql, ex), ex);
}
else if (ex instanceof SQLSyntaxErrorException) {
return new BadSqlGrammarException(task, sql, ex);
return new BadSqlGrammarException(task, (sql != null ? sql : ""), ex);
}
else if (ex instanceof SQLFeatureNotSupportedException) {
return new InvalidDataAccessApiUsageException(buildMessage(task, sql, ex), ex);

View File

@ -46,12 +46,15 @@ public interface SQLExceptionTranslator {
* check (and subsequent cast) is considered reliable when expecting JDBC-based
* access to have happened.
* @param task readable text describing the task being attempted
* @param sql SQL query or update that caused the problem (may be {@code null})
* @param sql SQL query or update that caused the problem (if known)
* @param ex the offending {@code SQLException}
* @return the DataAccessException, wrapping the {@code SQLException}
* @return the DataAccessException wrapping the {@code SQLException},
* or {@code null} if no translation could be applied
* (in a custom translator; the default translators always throw an
* {@link org.springframework.jdbc.UncategorizedSQLException} in such a case)
* @see org.springframework.dao.DataAccessException#getRootCause()
*/
@Nullable
DataAccessException translate(@Nullable String task, @Nullable String sql, SQLException ex);
DataAccessException translate(String task, @Nullable String sql, SQLException ex);
}

View File

@ -89,7 +89,7 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
@Override
@Nullable
protected DataAccessException doTranslate(String task, String sql, SQLException ex) {
protected DataAccessException doTranslate(String task, @Nullable String sql, SQLException ex) {
// First, the getSQLState check...
String sqlState = getSqlState(ex);
if (sqlState != null && sqlState.length() >= 2) {
@ -98,7 +98,7 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
logger.debug("Extracted SQL state class '" + classCode + "' from value '" + sqlState + "'");
}
if (BAD_SQL_GRAMMAR_CODES.contains(classCode)) {
return new BadSqlGrammarException(task, sql, ex);
return new BadSqlGrammarException(task, (sql != null ? sql : ""), ex);
}
else if (DATA_INTEGRITY_VIOLATION_CODES.contains(classCode)) {
return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex);

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.
@ -688,14 +688,10 @@ public class StoredProcedureTests {
setDataSource(ds);
setSql(SQL);
getJdbcTemplate().setExceptionTranslator(new SQLExceptionTranslator() {
@Override
@Nullable
public DataAccessException translate(String task, @Nullable String sql,
SQLException sqlex) {
return new CustomDataException(sql, sqlex);
public DataAccessException translate(String task, @Nullable String sql, SQLException ex) {
return new CustomDataException(sql, ex);
}
});
compile();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@ -28,6 +28,7 @@ import org.springframework.lang.Nullable;
* @author Thomas Risberg
*/
public class CustomSqlExceptionTranslator implements SQLExceptionTranslator {
@Override
public DataAccessException translate(String task, @Nullable String sql, SQLException ex) {
if (ex.getErrorCode() == 2) {
@ -35,4 +36,5 @@ public class CustomSqlExceptionTranslator implements SQLExceptionTranslator {
}
return null;
}
}

View File

@ -345,7 +345,9 @@ public class JmsListenerAnnotationBeanPostProcessor
private MessageHandlerMethodFactory createDefaultJmsHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory defaultFactory = new DefaultMessageHandlerMethodFactory();
defaultFactory.setBeanFactory(beanFactory);
if (beanFactory != null) {
defaultFactory.setBeanFactory(beanFactory);
}
defaultFactory.afterPropertiesSet();
return defaultFactory;
}

View File

@ -76,6 +76,7 @@ public abstract class JmsGatewaySupport implements InitializingBean {
/**
* Return the JMS ConnectionFactory used by the gateway.
*/
@Nullable
public final ConnectionFactory getConnectionFactory() {
return (this.jmsTemplate != null ? this.jmsTemplate.getConnectionFactory() : 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.
@ -25,6 +25,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.ValueConstants;
import org.springframework.util.Assert;
/**
* Resolves method parameters annotated with
@ -52,6 +53,7 @@ public class DestinationVariableMethodArgumentResolver extends AbstractNamedValu
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
DestinationVariable annotation = parameter.getParameterAnnotation(DestinationVariable.class);
Assert.state(annotation != null, "No DestinationVariable annotation");
return new DestinationVariableNamedValueInfo(annotation);
}

View File

@ -30,6 +30,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.support.NativeMessageHeaderAccessor;
import org.springframework.util.Assert;
/**
* Resolves method parameters annotated with {@link Header @Header}.
@ -55,6 +56,7 @@ public class HeaderMethodArgumentResolver extends AbstractNamedValueMethodArgume
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
Header annotation = parameter.getParameterAnnotation(Header.class);
Assert.state(annotation != null, "No Header annotation");
return new HeaderNamedValueInfo(annotation);
}

View File

@ -522,6 +522,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
return (credentials != null ? credentials.passcode : null);
}
@Nullable
public static Integer getContentLength(Map<String, List<String>> nativeHeaders) {
List<String> values = nativeHeaders.get(STOMP_CONTENT_LENGTH_HEADER);
return (!CollectionUtils.isEmpty(values) ? Integer.valueOf(values.get(0)) : null);

View File

@ -161,6 +161,7 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
return null;
}
@Nullable
private ParseResult parseSubscriptionMessage(Message<?> message, String sourceDestination) {
MessageHeaders headers = message.getHeaders();
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);

View File

@ -17,7 +17,6 @@
package org.springframework.orm.jpa;
import java.util.Map;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@ -481,12 +480,14 @@ public abstract class EntityManagerFactoryUtils {
em.flush();
}
catch (RuntimeException ex) {
DataAccessException dae;
if (this.jpaDialect != null) {
throw this.jpaDialect.translateExceptionIfPossible(ex);
dae = this.jpaDialect.translateExceptionIfPossible(ex);
}
else {
throw convertJpaAccessExceptionIfPossible(ex);
dae = convertJpaAccessExceptionIfPossible(ex);
}
throw (dae != null ? dae : ex);
}
}

View File

@ -490,7 +490,7 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
if (context == null) {
try {
if (StringUtils.hasLength(this.contextPath)) {
context = createJaxbContextFromContextPath();
context = createJaxbContextFromContextPath(this.contextPath);
}
else if (!ObjectUtils.isEmpty(this.classesToBeBound)) {
context = createJaxbContextFromClasses(this.classesToBeBound);
@ -511,26 +511,26 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
}
}
private JAXBContext createJaxbContextFromContextPath() throws JAXBException {
private JAXBContext createJaxbContextFromContextPath(String contextPath) throws JAXBException {
if (logger.isInfoEnabled()) {
logger.info("Creating JAXBContext with context path [" + this.contextPath + "]");
}
if (this.jaxbContextProperties != null) {
if (this.beanClassLoader != null) {
return JAXBContext.newInstance(this.contextPath, this.beanClassLoader, this.jaxbContextProperties);
return JAXBContext.newInstance(contextPath, this.beanClassLoader, this.jaxbContextProperties);
}
else {
// analogous to the JAXBContext.newInstance(String) implementation
return JAXBContext.newInstance(this.contextPath, Thread.currentThread().getContextClassLoader(),
return JAXBContext.newInstance(contextPath, Thread.currentThread().getContextClassLoader(),
this.jaxbContextProperties);
}
}
else {
if (this.beanClassLoader != null) {
return JAXBContext.newInstance(this.contextPath, this.beanClassLoader);
return JAXBContext.newInstance(contextPath, this.beanClassLoader);
}
else {
return JAXBContext.newInstance(this.contextPath);
return JAXBContext.newInstance(contextPath);
}
}
}

View File

@ -68,7 +68,6 @@ public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEval
public Object evaluate(String expression, Class expectedType, javax.servlet.jsp.el.VariableResolver variableResolver,
javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException {
Assert.isNull(variableResolver, "Custom VariableResolver not supported");
return doEvaluate(expression, expectedType, functionMapper);
}
@ -76,7 +75,6 @@ public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEval
protected Object doEvaluate(String expression, Class expectedType, javax.servlet.jsp.el.FunctionMapper functionMapper)
throws javax.servlet.jsp.el.ELException {
Assert.isNull(functionMapper, "Custom FunctionMapper not supported");
try {
return ExpressionEvaluatorManager.evaluate("JSP EL expression", expression, expectedType, this.pageContext);
}

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.
@ -30,6 +30,7 @@ import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.lang.Nullable;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
import org.springframework.test.context.jdbc.SqlConfig.ErrorMode;
@ -231,6 +232,7 @@ public class SqlScriptsTestExecutionListener extends AbstractTestExecutionListen
}
}
@Nullable
private DataSource getDataSourceFromTransactionManager(PlatformTransactionManager transactionManager) {
try {
Method getDataSourceMethod = transactionManager.getClass().getMethod("getDataSource");

View File

@ -23,7 +23,6 @@ import java.util.function.Function;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.extension.ExtensionContext;
@ -69,7 +68,6 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
/**
* Evaluate the expression configured via the supplied annotation type on
* the {@link AnnotatedElement} for the supplied {@link ExtensionContext}.
*
* @param annotationType the type of annotation to process
* @param expressionExtractor a function that extracts the expression from
* the annotation
@ -88,6 +86,7 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
Function<A, String> expressionExtractor, Function<A, String> reasonExtractor,
Function<A, Boolean> loadContextExtractor, boolean enabledOnTrue, ExtensionContext context) {
Assert.state(context.getElement().isPresent(), "No AnnotatedElement");
AnnotatedElement element = context.getElement().get();
Optional<A> annotation = findMergedAnnotation(element, annotationType);
@ -100,13 +99,11 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
return ConditionEvaluationResult.enabled(reason);
}
// @formatter:off
String expression = annotation.map(expressionExtractor).map(String::trim).filter(StringUtils::hasLength)
.orElseThrow(() -> new IllegalStateException(String.format(
"The expression in @%s on [%s] must not be blank", annotationType.getSimpleName(), element)));
// @formatter:on
boolean loadContext = annotation.map(loadContextExtractor).get();
boolean loadContext = loadContextExtractor.apply(annotation.get());
boolean evaluatedToTrue = evaluateExpression(expression, loadContext, annotationType, context);
if (evaluatedToTrue) {
@ -127,20 +124,21 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
if (logger.isDebugEnabled()) {
logger.debug(reason);
}
return (enabledOnTrue ? ConditionEvaluationResult.disabled(reason)
: ConditionEvaluationResult.enabled(reason));
return (enabledOnTrue ? ConditionEvaluationResult.disabled(reason) :
ConditionEvaluationResult.enabled(reason));
}
}
private <A extends Annotation> boolean evaluateExpression(String expression, boolean loadContext,
Class<A> annotationType, ExtensionContext extensionContext) {
Class<A> annotationType, ExtensionContext context) {
AnnotatedElement element = extensionContext.getElement().get();
Assert.state(context.getElement().isPresent(), "No AnnotatedElement");
AnnotatedElement element = context.getElement().get();
GenericApplicationContext gac = null;
ApplicationContext applicationContext;
if (loadContext) {
applicationContext = SpringExtension.getApplicationContext(extensionContext);
applicationContext = SpringExtension.getApplicationContext(context);
}
else {
gac = new GenericApplicationContext();
@ -191,8 +189,9 @@ abstract class AbstractExpressionEvaluatingCondition implements ExecutionConditi
}
}
private static <A extends Annotation> Optional<A> findMergedAnnotation(AnnotatedElement element,
Class<A> annotationType) {
private static <A extends Annotation> Optional<A> findMergedAnnotation(
AnnotatedElement element, Class<A> annotationType) {
return Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(element, annotationType));
}

View File

@ -20,9 +20,9 @@ import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExtensionContext;
/**
* {@code DisabledIfCondition} is an {@link ExecutionCondition} that supports the
* {@link DisabledIf @DisabledIf} annotation when using the <em>Spring TestContext
* Framework</em> in conjunction with JUnit 5's <em>Jupiter</em> programming model.
* {@code DisabledIfCondition} is an {@link org.junit.jupiter.api.extension.ExecutionCondition}
* that supports the {@link DisabledIf @DisabledIf} annotation when using the <em>Spring
* TestContext Framework</em> in conjunction with JUnit 5's <em>Jupiter</em> programming model.
*
* <p>Any attempt to use the {@code DisabledIfCondition} without the presence of
* {@link DisabledIf @DisabledIf} will result in an <em>enabled</em>
@ -43,8 +43,8 @@ public class DisabledIfCondition extends AbstractExpressionEvaluatingCondition {
*/
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
return evaluateAnnotation(DisabledIf.class, DisabledIf::expression, DisabledIf::reason, DisabledIf::loadContext,
false, context);
return evaluateAnnotation(DisabledIf.class, DisabledIf::expression, DisabledIf::reason,
DisabledIf::loadContext, false, context);
}
}

View File

@ -20,9 +20,9 @@ import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExtensionContext;
/**
* {@code EnabledIfCondition} is an {@link ExecutionCondition} that supports the
* {@link EnabledIf @EnabledIf} annotation when using the <em>Spring TestContext
* Framework</em> in conjunction with JUnit 5's <em>Jupiter</em> programming model.
* {@code EnabledIfCondition} is an {@link org.junit.jupiter.api.extension.ExecutionCondition}
* that supports the {@link EnabledIf @EnabledIf} annotation when using the <em>Spring
* TestContext Framework</em> in conjunction with JUnit 5's <em>Jupiter</em> programming model.
*
* <p>Any attempt to use the {@code EnabledIfCondition} without the presence of
* {@link EnabledIf @EnabledIf} will result in an <em>enabled</em>
@ -43,8 +43,8 @@ public class EnabledIfCondition extends AbstractExpressionEvaluatingCondition {
*/
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
return evaluateAnnotation(EnabledIf.class, EnabledIf::expression, EnabledIf::reason, EnabledIf::loadContext,
true, context);
return evaluateAnnotation(EnabledIf.class, EnabledIf::expression, EnabledIf::reason,
EnabledIf::loadContext, true, context);
}
}

View File

@ -115,7 +115,6 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
/**
* Set the {@link ApplicationContext} to be used by this test instance,
* provided via {@link ApplicationContextAware} semantics.
*
* @param applicationContext the ApplicationContext that this test runs in
*/
@Override
@ -123,13 +122,11 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
this.applicationContext = applicationContext;
}
/**
* Delegates to the configured {@link TestContextManager} to call
* {@linkplain TestContextManager#beforeTestClass() 'before test class'}
* callbacks.
*
* @throws Exception if a registered TestExecutionListener throws an
* exception
* {@linkplain TestContextManager#beforeTestClass() 'before test class'} callbacks.
* @throws Exception if a registered TestExecutionListener throws an exception
*/
@BeforeClass(alwaysRun = true)
protected void springTestContextBeforeTestClass() throws Exception {
@ -141,9 +138,7 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
* {@linkplain TestContextManager#prepareTestInstance(Object) prepare} this test
* instance prior to execution of any individual tests, for example for
* injecting dependencies, etc.
*
* @throws Exception if a registered TestExecutionListener throws an
* exception
* @throws Exception if a registered TestExecutionListener throws an exception
*/
@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextBeforeTestClass")
protected void springTestContextPrepareTestInstance() throws Exception {
@ -154,7 +149,6 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
* Delegates to the configured {@link TestContextManager} to
* {@linkplain TestContextManager#beforeTestMethod(Object,Method) pre-process}
* the test method before the actual test is executed.
*
* @param testMethod the test method which is about to be executed
* @throws Exception allows all exceptions to propagate
*/
@ -167,7 +161,6 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
* Delegates to the {@linkplain IHookCallBack#runTestMethod(ITestResult) test
* method} in the supplied {@code callback} to execute the actual test
* and then tracks the exception thrown during test execution, if any.
*
* @see org.testng.IHookable#run(IHookCallBack, ITestResult)
*/
@Override
@ -224,15 +217,14 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
/**
* Delegates to the configured {@link TestContextManager} to call
* {@linkplain TestContextManager#afterTestClass() 'after test class'} callbacks.
*
* @throws Exception if a registered TestExecutionListener throws an
* exception
* @throws Exception if a registered TestExecutionListener throws an exception
*/
@AfterClass(alwaysRun = true)
protected void springTestContextAfterTestClass() throws Exception {
this.testContextManager.afterTestClass();
}
private Throwable getTestResultException(ITestResult testResult) {
Throwable testResultException = testResult.getThrowable();
if (testResultException instanceof InvocationTargetException) {
@ -241,12 +233,10 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
return testResultException;
}
@Nullable
private RuntimeException throwAsUncheckedException(Throwable t) {
throwAs(t);
// Appeasing the compiler: the following line will never be executed.
return null;
throw new IllegalStateException(t);
}
@SuppressWarnings("unchecked")

View File

@ -95,7 +95,7 @@ public final class MockMvc {
* A default request builder merged into every performed request.
* @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#defaultRequest(RequestBuilder)
*/
void setDefaultRequest(RequestBuilder requestBuilder) {
void setDefaultRequest(@Nullable RequestBuilder requestBuilder) {
this.defaultRequestBuilder = requestBuilder;
}
@ -104,7 +104,7 @@ public final class MockMvc {
* @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#alwaysExpect(ResultMatcher)
*/
void setGlobalResultMatchers(List<ResultMatcher> resultMatchers) {
Assert.notNull(resultMatchers, "resultMatchers is required");
Assert.notNull(resultMatchers, "ResultMatcher List is required");
this.defaultResultMatchers = resultMatchers;
}
@ -113,7 +113,7 @@ public final class MockMvc {
* @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#alwaysDo(ResultHandler)
*/
void setGlobalResultHandlers(List<ResultHandler> resultHandlers) {
Assert.notNull(resultHandlers, "resultHandlers is required");
Assert.notNull(resultHandlers, "ResultHandler List is required");
this.defaultResultHandlers = resultHandlers;
}

View File

@ -41,7 +41,7 @@ import org.springframework.web.context.WebApplicationContext;
public abstract class MockMvcBuilderSupport {
protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
WebApplicationContext webAppContext, @Nullable RequestBuilder defaultRequestBuilder,
List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers,
@Nullable List<DispatcherServletCustomizer> dispatcherServletCustomizers) {

View File

@ -448,7 +448,6 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
@Nullable
public String getName() {
return joinpointIdentification;
}

View File

@ -26,7 +26,7 @@ dependencies {
optional("javax.faces:javax.faces-api:2.2")
optional("javax.validation:validation-api:1.1.0.Final")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("com.caucho:hessian:4.0.38")
optional("com.caucho:hessian:4.0.51")
optional("commons-fileupload:commons-fileupload:1.3.3")
optional("org.synchronoss.cloud:nio-multipart-parser:1.1.0")
optional("io.projectreactor.ipc:reactor-netty")

View File

@ -30,6 +30,7 @@ import okhttp3.RequestBody;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@ -145,6 +146,7 @@ public class OkHttp3ClientHttpRequestFactory
return builder.build();
}
@Nullable
private static okhttp3.MediaType getContentType(HttpHeaders headers) {
String rawContentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
return (StringUtils.hasText(rawContentType) ? okhttp3.MediaType.parse(rawContentType) : null);

View File

@ -79,6 +79,7 @@ class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements Cl
return result;
}
@Nullable
private Decoder<?> getSseDecoder() {
if (this.sseDecoder != null) {
return this.sseDecoder;

View File

@ -91,6 +91,7 @@ class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements Se
return result;
}
@Nullable
private Encoder<?> getSseEncoder() {
if (this.sseEncoder != null) {
return this.sseEncoder;

View File

@ -67,6 +67,7 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
this.defaultMediaType = initDefaultMediaType(this.mediaTypes);
}
@Nullable
private static MediaType initDefaultMediaType(List<MediaType> mediaTypes) {
return mediaTypes.stream().filter(MediaType::isConcrete).findFirst().orElse(null);
}

View File

@ -145,6 +145,7 @@ public abstract class RequestContextHolder {
*/
private static class FacesRequestAttributesFactory {
@Nullable
public static RequestAttributes getFacesRequestAttributes() {
FacesContext facesContext = FacesContext.getCurrentInstance();
return (facesContext != null ? new FacesRequestAttributes(facesContext) : null);

View File

@ -146,6 +146,10 @@ public abstract class CommonsFileUploadSupport {
this.fileUpload.setHeaderEncoding(defaultEncoding);
}
/**
* Determine the default encoding to use for parsing requests.
* @see #setDefaultEncoding
*/
protected String getDefaultEncoding() {
String encoding = getFileUpload().getHeaderEncoding();
if (encoding == null) {
@ -167,6 +171,10 @@ public abstract class CommonsFileUploadSupport {
this.uploadTempDirSpecified = true;
}
/**
* Return the temporary directory where uploaded files get stored.
* @see #setUploadTempDir
*/
protected boolean isUploadTempDirSpecified() {
return this.uploadTempDirSpecified;
}
@ -247,19 +255,14 @@ public abstract class CommonsFileUploadSupport {
if (fileItem.isFormField()) {
String value;
String partEncoding = determineEncoding(fileItem.getContentType(), encoding);
if (partEncoding != null) {
try {
value = fileItem.getString(partEncoding);
}
catch (UnsupportedEncodingException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Could not decode multipart item '" + fileItem.getFieldName() +
"' with encoding '" + partEncoding + "': using platform default");
}
value = fileItem.getString();
}
try {
value = fileItem.getString(partEncoding);
}
else {
catch (UnsupportedEncodingException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Could not decode multipart item '" + fileItem.getFieldName() +
"' with encoding '" + partEncoding + "': using platform default");
}
value = fileItem.getString();
}
String[] curParam = multipartParameters.get(fileItem.getFieldName());
@ -324,7 +327,6 @@ public abstract class CommonsFileUploadSupport {
}
}
@Nullable
private String determineEncoding(String contentTypeHeader, String defaultEncoding) {
if (!StringUtils.hasText(contentTypeHeader)) {
return defaultEncoding;

View File

@ -28,6 +28,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@ -135,6 +136,7 @@ final class HierarchicalUriComponents extends UriComponents {
}
@Override
@NonNull
public String getPath() {
return this.path.getPath();
}

View File

@ -299,7 +299,6 @@ public abstract class WebUtils {
* @return the value of the session attribute, or {@code null} if not found
* @throws IllegalStateException if the session attribute could not be found
*/
@Nullable
public static Object getRequiredSessionAttribute(HttpServletRequest request, String name)
throws IllegalStateException {

View File

@ -334,15 +334,12 @@ class DefaultWebClient implements WebClient {
}
private HttpHeaders initHeaders() {
if (CollectionUtils.isEmpty(defaultHeaders) && CollectionUtils.isEmpty(this.headers)) {
return new HttpHeaders();
if (CollectionUtils.isEmpty(this.headers)) {
return (defaultHeaders != null ? defaultHeaders : new HttpHeaders());
}
else if (CollectionUtils.isEmpty(defaultHeaders)) {
return this.headers;
}
else if (CollectionUtils.isEmpty(this.headers)) {
return defaultHeaders;
}
else {
HttpHeaders result = new HttpHeaders();
result.putAll(this.headers);
@ -356,15 +353,12 @@ class DefaultWebClient implements WebClient {
}
private MultiValueMap<String, String> initCookies() {
if (CollectionUtils.isEmpty(defaultCookies) && CollectionUtils.isEmpty(this.cookies)) {
return new LinkedMultiValueMap<>(0);
if (CollectionUtils.isEmpty(this.cookies)) {
return (defaultCookies != null ? defaultCookies : new LinkedMultiValueMap<>(0));
}
else if (CollectionUtils.isEmpty(defaultCookies)) {
return this.cookies;
}
else if (CollectionUtils.isEmpty(this.cookies)) {
return defaultCookies;
}
else {
MultiValueMap<String, String> result = new LinkedMultiValueMap<>();
result.putAll(this.cookies);
@ -379,9 +373,11 @@ class DefaultWebClient implements WebClient {
}
}
private static class DefaultResponseSpec implements ResponseSpec {
private static final StatusHandler DEFAULT_STATUS_HANDLER = new StatusHandler(HttpStatus::isError, DefaultResponseSpec::createResponseException);
private static final StatusHandler DEFAULT_STATUS_HANDLER =
new StatusHandler(HttpStatus::isError, DefaultResponseSpec::createResponseException);
private final Mono<ClientResponse> responseMono;

View File

@ -50,7 +50,7 @@ public class CompositeRequestCondition extends AbstractRequestCondition<Composit
* same number of conditions so they may be compared and combined.
* It is acceptable to provide {@code null} conditions.
*/
public CompositeRequestCondition(@Nullable RequestCondition<?>... requestConditions) {
public CompositeRequestCondition(RequestCondition<?>... requestConditions) {
this.requestConditions = wrap(requestConditions);
}

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.
@ -38,12 +38,13 @@ import org.springframework.web.server.ServerWebExchange;
*/
public final class RequestConditionHolder extends AbstractRequestCondition<RequestConditionHolder> {
@Nullable
private final RequestCondition<Object> condition;
/**
* Create a new holder to wrap the given request condition.
* @param requestCondition the condition to hold, may be {@code null}
* @param requestCondition the condition to hold (may be {@code null})
*/
@SuppressWarnings("unchecked")
public RequestConditionHolder(@Nullable RequestCondition<?> requestCondition) {
@ -86,23 +87,12 @@ public final class RequestConditionHolder extends AbstractRequestCondition<Reque
return this;
}
else {
assertEqualConditionTypes(other);
assertEqualConditionTypes(this.condition, other.condition);
RequestCondition<?> combined = (RequestCondition<?>) this.condition.combine(other.condition);
return new RequestConditionHolder(combined);
}
}
/**
* Ensure the held request conditions are of the same type.
*/
private void assertEqualConditionTypes(RequestConditionHolder other) {
Class<?> clazz = this.condition.getClass();
Class<?> otherClazz = other.condition.getClass();
if (!clazz.equals(otherClazz)) {
throw new ClassCastException("Incompatible request conditions: " + clazz + " and " + otherClazz);
}
}
/**
* Get the matching condition for the held request condition wrap it in a
* new RequestConditionHolder instance. Or otherwise if this is an empty
@ -134,9 +124,20 @@ public final class RequestConditionHolder extends AbstractRequestCondition<Reque
return -1;
}
else {
assertEqualConditionTypes(other);
assertEqualConditionTypes(this.condition, other.condition);
return this.condition.compareTo(other.condition, exchange);
}
}
/**
* Ensure the held request conditions are of the same type.
*/
private void assertEqualConditionTypes(RequestCondition<?> cond1, RequestCondition<?> cond2) {
Class<?> clazz = cond1.getClass();
Class<?> otherClazz = cond2.getClass();
if (!clazz.equals(otherClazz)) {
throw new ClassCastException("Incompatible request conditions: " + clazz + " vs " + otherClazz);
}
}
}

View File

@ -124,6 +124,7 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
* @see #getCustomTypeCondition(Class)
* @see #getCustomMethodCondition(Method)
*/
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = (element instanceof Class ?

View File

@ -467,6 +467,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
}
}
@Nullable
private String getAsyncTimeout(Element element) {
Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");
return (asyncElement != null) ? asyncElement.getAttribute("default-timeout") : null;
@ -555,6 +556,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
return result;
}
@Nullable
private ManagedList<?> getReturnValueHandlers(Element element, ParserContext parserContext) {
Element handlers = DomUtils.getChildElementByTagName(element, "return-value-handlers");
return (handlers != null ? extractBeanSubElements(handlers, parserContext) : null);

View File

@ -154,6 +154,7 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser {
}
}
@Nullable
private String registerResourceHandler(ParserContext parserContext, Element element, @Nullable Object source) {
String locationAttr = element.getAttribute("location");
if (!StringUtils.hasText(locationAttr)) {

View File

@ -123,19 +123,19 @@ public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser {
compositeResolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
names = new String[] {"content-negotiation"};
List<Element> contentnNegotiationElements = DomUtils.getChildElementsByTagName(element, names);
if (contentnNegotiationElements.isEmpty()) {
List<Element> contentNegotiationElements = DomUtils.getChildElementsByTagName(element, names);
if (contentNegotiationElements.isEmpty()) {
compositeResolverBeanDef.getPropertyValues().add("viewResolvers", resolvers);
}
else if (contentnNegotiationElements.size() == 1) {
BeanDefinition beanDef = createContentNegotiatingViewResolver(contentnNegotiationElements.get(0), context);
else if (contentNegotiationElements.size() == 1) {
BeanDefinition beanDef = createContentNegotiatingViewResolver(contentNegotiationElements.get(0), context);
beanDef.getPropertyValues().add("viewResolvers", resolvers);
ManagedList<Object> list = new ManagedList<>(1);
list.add(beanDef);
compositeResolverBeanDef.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
compositeResolverBeanDef.getPropertyValues().add("viewResolvers", list);
}
else if (contentnNegotiationElements.size() > 1) {
else {
throw new IllegalArgumentException("Only one <content-negotiation> element is allowed.");
}

View File

@ -232,6 +232,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
return matches;
}
@Nullable
private String getMatchingPattern(String pattern, String lookupPath) {
if (pattern.equals(lookupPath)) {
return pattern;

View File

@ -130,6 +130,7 @@ public final class RequestMethodsRequestCondition extends AbstractRequestConditi
return matchRequestMethod(expectedMethod);
}
@Nullable
private RequestMethodsRequestCondition matchRequestMethod(String httpMethodValue) {
HttpMethod httpMethod = HttpMethod.resolve(httpMethodValue);
if (httpMethod != null) {

View File

@ -189,6 +189,7 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
methods, params, headers, consumes, produces, custom.getCondition());
}
@Nullable
private String combineNames(RequestMappingInfo other) {
if (this.name != null && other.name != null) {
String separator = RequestMappingInfoHandlerMethodMappingNamingStrategy.SEPARATOR;

View File

@ -552,6 +552,7 @@ public class MvcUriComponentsBuilder {
}
}
@Nullable
private static WebApplicationContext getWebApplicationContext() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {

View File

@ -81,6 +81,7 @@ class DefaultResourceResolverChain implements ResourceResolverChain {
}
}
@Nullable
private ResourceResolver getNext() {
Assert.state(this.index <= this.resolvers.size(),
"Current index exceeds the number of configured ResourceResolvers");

View File

@ -111,11 +111,13 @@ public class JspAwareRequestContext extends RequestContext {
*/
private static class JstlPageLocaleResolver {
@Nullable
public static Locale getJstlLocale(PageContext pageContext) {
Object localeObject = Config.find(pageContext, Config.FMT_LOCALE);
return (localeObject instanceof Locale ? (Locale) localeObject : null);
}
@Nullable
public static TimeZone getJstlTimeZone(PageContext pageContext) {
Object timeZoneObject = Config.find(pageContext, Config.FMT_TIME_ZONE);
return (timeZoneObject instanceof TimeZone ? (TimeZone) timeZoneObject : null);

View File

@ -904,6 +904,7 @@ public class RequestContext {
*/
private static class JstlLocaleResolver {
@Nullable
public static Locale getJstlLocale(HttpServletRequest request, @Nullable ServletContext servletContext) {
Object localeObject = Config.get(request, Config.FMT_LOCALE);
if (localeObject == null) {
@ -918,6 +919,7 @@ public class RequestContext {
return (localeObject instanceof Locale ? (Locale) localeObject : null);
}
@Nullable
public static TimeZone getJstlTimeZone(HttpServletRequest request, @Nullable ServletContext servletContext) {
Object timeZoneObject = Config.get(request, Config.FMT_TIME_ZONE);
if (timeZoneObject == null) {

View File

@ -198,6 +198,7 @@ public class EvalTag extends HtmlEscapingAwareTag {
throw new UnsupportedOperationException();
}
@Nullable
private Object resolveImplicitVariable(String name) throws AccessException {
if (this.variableResolver == null) {
return null;

View File

@ -411,6 +411,7 @@ public class SubProtocolWebSocketHandler
return handler;
}
@Nullable
private String resolveSessionId(Message<?> message) {
for (SubProtocolHandler handler : this.protocolHandlerLookup.values()) {
String sessionId = handler.resolveSessionId(message);

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.
@ -26,6 +26,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@ -97,6 +98,7 @@ public class SpringConfigurator extends Configurator {
return wac.getAutowireCapableBeanFactory().createBean(endpointClass);
}
@Nullable
private String getBeanNameByType(WebApplicationContext wac, Class<?> endpointClass) {
String wacId = wac.getId();