summaryrefslogtreecommitdiff
path: root/spring-core/src
diff options
context:
space:
mode:
authorEmmanuel Bourg <ebourg@apache.org>2018-04-08 23:27:38 +0200
committerEmmanuel Bourg <ebourg@apache.org>2018-04-08 23:27:38 +0200
commite9dafb5ce16aa2faa4fee1019417cc0a7456af57 (patch)
treec38471d22f5c367a45673724d3a6571d5daf591b /spring-core/src
parent6dc3d6835b664af0d21e774a5342b90d4417f628 (diff)
New upstream version 4.3.15
Diffstat (limited to 'spring-core/src')
-rw-r--r--spring-core/src/main/java/org/springframework/asm/ClassWriter.java2
-rw-r--r--spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java5
-rw-r--r--spring-core/src/main/java/org/springframework/core/MethodParameter.java25
-rw-r--r--spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java13
-rw-r--r--spring-core/src/main/java/org/springframework/core/ResolvableType.java27
-rw-r--r--spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java42
-rw-r--r--spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java203
-rw-r--r--spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java74
-rw-r--r--spring-core/src/main/java/org/springframework/core/convert/Property.java6
-rw-r--r--spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java8
-rw-r--r--spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java4
-rw-r--r--spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java6
-rw-r--r--spring-core/src/main/java/org/springframework/core/io/VfsUtils.java36
-rw-r--r--spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java4
-rw-r--r--spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java4
-rw-r--r--spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java8
-rw-r--r--spring-core/src/main/java/org/springframework/core/type/filter/AnnotationTypeFilter.java11
-rw-r--r--spring-core/src/main/java/org/springframework/util/ClassUtils.java28
-rw-r--r--spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java32
-rw-r--r--spring-core/src/main/java/org/springframework/util/DigestUtils.java2
-rw-r--r--spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java2
-rw-r--r--spring-core/src/main/java/org/springframework/util/MimeType.java114
-rw-r--r--spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java9
-rw-r--r--spring-core/src/main/java/org/springframework/util/ReflectionUtils.java5
-rw-r--r--spring-core/src/main/java/org/springframework/util/StreamUtils.java2
-rw-r--r--spring-core/src/main/java/org/springframework/util/StringUtils.java27
-rw-r--r--spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java12
-rw-r--r--spring-core/src/main/java/org/springframework/util/xml/AbstractStaxHandler.java2
-rw-r--r--spring-core/src/main/java/org/springframework/util/xml/DomContentHandler.java4
-rw-r--r--spring-core/src/main/java/org/springframework/util/xml/TransformerUtils.java32
-rw-r--r--spring-core/src/test/java/org/springframework/core/ConventionsTests.java8
-rw-r--r--spring-core/src/test/java/org/springframework/core/LocalVariableTableParameterNameDiscovererTests.java33
-rw-r--r--spring-core/src/test/java/org/springframework/core/MethodParameterTests.java66
-rw-r--r--spring-core/src/test/java/org/springframework/core/NestedExceptionTests.java30
-rw-r--r--spring-core/src/test/java/org/springframework/core/PrioritizedParameterNameDiscovererTests.java2
-rw-r--r--spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java65
-rw-r--r--spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java52
-rw-r--r--spring-core/src/test/java/org/springframework/core/annotation/MapAnnotationAttributeExtractorTests.java50
-rw-r--r--spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java30
-rw-r--r--spring-core/src/test/java/org/springframework/core/type/AnnotationTypeFilterTests.java21
-rw-r--r--spring-core/src/test/java/org/springframework/core/type/ClassloadingAssertions.java11
-rw-r--r--spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java19
-rw-r--r--spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java168
-rw-r--r--spring-core/src/test/java/org/springframework/util/MimeTypeTests.java42
-rw-r--r--spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java19
-rw-r--r--spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java2
-rw-r--r--spring-core/src/test/java/org/springframework/util/StringUtilsTests.java3
47 files changed, 762 insertions, 608 deletions
diff --git a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java
index a024937d..513b2e5d 100644
--- a/spring-core/src/main/java/org/springframework/asm/ClassWriter.java
+++ b/spring-core/src/main/java/org/springframework/asm/ClassWriter.java
@@ -1699,7 +1699,7 @@ public class ClassWriter extends ClassVisitor {
*/
private Item addType(final Item item) {
++typeCount;
- Item result = new Item(typeCount, key);
+ Item result = new Item(typeCount, item);
put(result);
if (typeTable == null) {
typeTable = new Item[16];
diff --git a/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java b/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java
index dbbe1aff..ba321bf7 100644
--- a/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java
+++ b/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
/**
* Support class for {@link AttributeAccessor AttributeAccessors}, providing
@@ -70,7 +71,7 @@ public abstract class AttributeAccessorSupport implements AttributeAccessor, Ser
@Override
public String[] attributeNames() {
- return this.attributes.keySet().toArray(new String[this.attributes.size()]);
+ return StringUtils.toStringArray(this.attributes.keySet());
}
diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java
index 5bc50d97..7267704e 100644
--- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java
+++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -21,6 +21,7 @@ import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
@@ -47,6 +48,8 @@ import org.springframework.util.ClassUtils;
*/
public class MethodParameter {
+ private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
+
private static final Class<?> javaUtilOptionalClass;
static {
@@ -482,17 +485,27 @@ public class MethodParameter {
* Return the annotations associated with the specific method/constructor parameter.
*/
public Annotation[] getParameterAnnotations() {
- if (this.parameterAnnotations == null) {
+ Annotation[] paramAnns = this.parameterAnnotations;
+ if (paramAnns == null) {
Annotation[][] annotationArray = (this.method != null ?
this.method.getParameterAnnotations() : this.constructor.getParameterAnnotations());
- if (this.parameterIndex >= 0 && this.parameterIndex < annotationArray.length) {
- this.parameterAnnotations = adaptAnnotationArray(annotationArray[this.parameterIndex]);
+ int index = this.parameterIndex;
+ if (this.constructor != null && this.constructor.getDeclaringClass().isMemberClass() &&
+ !Modifier.isStatic(this.constructor.getDeclaringClass().getModifiers()) &&
+ annotationArray.length == this.constructor.getParameterTypes().length - 1) {
+ // Bug in javac in JDK <9: annotation array excludes enclosing instance parameter
+ // for inner classes, so access it with the actual parameter index lowered by 1
+ index = this.parameterIndex - 1;
+ }
+ if (index >= 0 && index < annotationArray.length) {
+ paramAnns = adaptAnnotationArray(annotationArray[index]);
}
else {
- this.parameterAnnotations = new Annotation[0];
+ paramAnns = EMPTY_ANNOTATION_ARRAY;
}
+ this.parameterAnnotations = paramAnns;
}
- return this.parameterAnnotations;
+ return paramAnns;
}
/**
diff --git a/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java b/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java
index 7f6d807f..5ed2e1ad 100644
--- a/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java
+++ b/spring-core/src/main/java/org/springframework/core/ParameterizedTypeReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -24,14 +24,14 @@ import org.springframework.util.Assert;
/**
* The purpose of this class is to enable capturing and passing a generic
* {@link Type}. In order to capture the generic type and retain it at runtime,
- * you need to create a subclass as follows:
+ * you need to create a subclass (ideally as anonymous inline class) as follows:
*
* <pre class="code">
* ParameterizedTypeReference&lt;List&lt;String&gt;&gt; typeRef = new ParameterizedTypeReference&lt;List&lt;String&gt;&gt;() {};
* </pre>
*
- * <p>The resulting {@code typeReference} instance can then be used to obtain a
- * {@link Type} instance that carries parameterized type information.
+ * <p>The resulting {@code typeRef} instance can then be used to obtain a {@link Type}
+ * instance that carries the captured parameterized type information at runtime.
* For more information on "super type tokens" see the link to Neal Gafter's blog post.
*
* @author Arjen Poutsma
@@ -49,8 +49,9 @@ public abstract class ParameterizedTypeReference<T> {
Type type = parameterizedTypeReferenceSubclass.getGenericSuperclass();
Assert.isInstanceOf(ParameterizedType.class, type, "Type must be a parameterized type");
ParameterizedType parameterizedType = (ParameterizedType) type;
- Assert.isTrue(parameterizedType.getActualTypeArguments().length == 1, "Number of type arguments must be 1");
- this.type = parameterizedType.getActualTypeArguments()[0];
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ Assert.isTrue(actualTypeArguments.length == 1, "Number of type arguments must be 1");
+ this.type = actualTypeArguments[0];
}
private ParameterizedTypeReference(Type type) {
diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java
index 35e6da4d..155236d5 100644
--- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java
+++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -34,6 +34,7 @@ import java.util.Map;
import org.springframework.core.SerializableTypeWrapper.FieldTypeProvider;
import org.springframework.core.SerializableTypeWrapper.MethodParameterTypeProvider;
import org.springframework.core.SerializableTypeWrapper.TypeProvider;
+import org.springframework.lang.UsesJava8;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
@@ -355,7 +356,7 @@ public class ResolvableType implements Serializable {
if (this == NONE) {
return false;
}
- return (((this.type instanceof Class && ((Class<?>) this.type).isArray())) ||
+ return ((this.type instanceof Class && ((Class<?>) this.type).isArray()) ||
this.type instanceof GenericArrayType || resolveType().isArray());
}
@@ -1427,8 +1428,9 @@ public class ResolvableType implements Serializable {
@Override
public ResolvableType resolveVariable(TypeVariable<?> variable) {
for (int i = 0; i < this.variables.length; i++) {
- if (SerializableTypeWrapper.unwrap(this.variables[i]).equals(
- SerializableTypeWrapper.unwrap(variable))) {
+ TypeVariable<?> v1 = SerializableTypeWrapper.unwrap(this.variables[i]);
+ TypeVariable<?> v2 = SerializableTypeWrapper.unwrap(variable);
+ if (ObjectUtils.nullSafeEquals(v1, v2)) {
return this.generics[i];
}
}
@@ -1453,6 +1455,23 @@ public class ResolvableType implements Serializable {
this.typeArguments = typeArguments;
}
+ @Override // on Java 8
+ @UsesJava8
+ public String getTypeName() {
+ StringBuilder result = new StringBuilder(this.rawType.getTypeName());
+ if (this.typeArguments.length > 0) {
+ result.append('<');
+ for (int i = 0; i < this.typeArguments.length; i++) {
+ if (i > 0) {
+ result.append(", ");
+ }
+ result.append(this.typeArguments[i].getTypeName());
+ }
+ result.append('>');
+ }
+ return result.toString();
+ }
+
@Override
public Type getOwnerType() {
return null;
diff --git a/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java b/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java
index 16c73b5f..fcfbd0f6 100644
--- a/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java
+++ b/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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,23 +45,25 @@ public class SimpleAliasRegistry implements AliasRegistry {
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
- if (alias.equals(name)) {
- this.aliasMap.remove(alias);
- }
- else {
- String registeredName = this.aliasMap.get(alias);
- if (registeredName != null) {
- if (registeredName.equals(name)) {
- // An existing alias - no need to re-register
- return;
- }
- if (!allowAliasOverriding()) {
- throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
- name + "': It is already registered for name '" + registeredName + "'.");
+ synchronized (this.aliasMap) {
+ if (alias.equals(name)) {
+ this.aliasMap.remove(alias);
+ }
+ else {
+ String registeredName = this.aliasMap.get(alias);
+ if (registeredName != null) {
+ if (registeredName.equals(name)) {
+ // An existing alias - no need to re-register
+ return;
+ }
+ if (!allowAliasOverriding()) {
+ throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
+ name + "': It is already registered for name '" + registeredName + "'.");
+ }
}
+ checkForAliasCircle(name, alias);
+ this.aliasMap.put(alias, name);
}
- checkForAliasCircle(name, alias);
- this.aliasMap.put(alias, name);
}
}
@@ -92,9 +94,11 @@ public class SimpleAliasRegistry implements AliasRegistry {
@Override
public void removeAlias(String alias) {
- String name = this.aliasMap.remove(alias);
- if (name == null) {
- throw new IllegalStateException("No alias '" + alias + "' registered");
+ synchronized (this.aliasMap) {
+ String name = this.aliasMap.remove(alias);
+ if (name == null) {
+ throw new IllegalStateException("No alias '" + alias + "' registered");
+ }
}
}
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java
index d83747fe..75f42f02 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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,6 +29,7 @@ import java.util.Set;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -59,10 +60,9 @@ import org.springframework.util.MultiValueMap;
* individual method for details on which search algorithm is used.
*
* <p><strong>Get semantics</strong> are limited to searching for annotations
- * that are either <em>present</em> on an {@code AnnotatedElement} (i.e.,
- * declared locally or {@linkplain java.lang.annotation.Inherited inherited})
- * or declared within the annotation hierarchy <em>above</em> the
- * {@code AnnotatedElement}.
+ * that are either <em>present</em> on an {@code AnnotatedElement} (i.e. declared
+ * locally or {@linkplain java.lang.annotation.Inherited inherited}) or declared
+ * within the annotation hierarchy <em>above</em> the {@code AnnotatedElement}.
*
* <p><strong>Find semantics</strong> are much more exhaustive, providing
* <em>get semantics</em> plus support for the following:
@@ -76,14 +76,13 @@ import org.springframework.util.MultiValueMap;
* </ul>
*
* <h3>Support for {@code @Inherited}</h3>
- * <p>Methods following <em>get semantics</em> will honor the contract of
- * Java's {@link java.lang.annotation.Inherited @Inherited} annotation except
- * that locally declared annotations (including custom composed annotations)
- * will be favored over inherited annotations. In contrast, methods following
- * <em>find semantics</em> will completely ignore the presence of
- * {@code @Inherited} since the <em>find</em> search algorithm manually
- * traverses type and method hierarchies and thereby implicitly supports
- * annotation inheritance without the need for {@code @Inherited}.
+ * <p>Methods following <em>get semantics</em> will honor the contract of Java's
+ * {@link java.lang.annotation.Inherited @Inherited} annotation except that locally
+ * declared annotations (including custom composed annotations) will be favored over
+ * inherited annotations. In contrast, methods following <em>find semantics</em>
+ * will completely ignore the presence of {@code @Inherited} since the <em>find</em>
+ * search algorithm manually traverses type and method hierarchies and thereby
+ * implicitly supports annotation inheritance without a need for {@code @Inherited}.
*
* @author Phillip Webb
* @author Juergen Hoeller
@@ -242,7 +241,6 @@ public class AnnotatedElementUtils {
return Boolean.TRUE.equals(
searchWithGetSemantics(element, annotationType, annotationName, new SimpleAnnotationProcessor<Boolean>() {
-
@Override
public Boolean process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
return (metaDepth > 0 ? Boolean.TRUE : CONTINUE);
@@ -272,7 +270,6 @@ public class AnnotatedElementUtils {
if (element.isAnnotationPresent(annotationType)) {
return true;
}
-
return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationType, null, alwaysTrueAnnotationProcessor));
}
@@ -617,7 +614,6 @@ public class AnnotatedElementUtils {
if (element.isAnnotationPresent(annotationType)) {
return true;
}
-
return Boolean.TRUE.equals(searchWithFindSemantics(element, annotationType, null, alwaysTrueAnnotationProcessor));
}
@@ -873,10 +869,10 @@ public class AnnotatedElementUtils {
* @param annotationName the fully qualified class name of the annotation
* type to find (as an alternative to {@code annotationType})
* @param processor the processor to delegate to
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
*/
- private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType,
- String annotationName, Processor<T> processor) {
+ private static <T> T searchWithGetSemantics(AnnotatedElement element,
+ Class<? extends Annotation> annotationType, String annotationName, Processor<T> processor) {
return searchWithGetSemantics(element, annotationType, annotationName, null, processor);
}
@@ -892,15 +888,16 @@ public class AnnotatedElementUtils {
* @param containerType the type of the container that holds repeatable
* annotations, or {@code null} if the annotation is not repeatable
* @param processor the processor to delegate to
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
* @since 4.3
*/
- private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType,
- String annotationName, Class<? extends Annotation> containerType, Processor<T> processor) {
+ private static <T> T searchWithGetSemantics(AnnotatedElement element,
+ Class<? extends Annotation> annotationType, String annotationName,
+ Class<? extends Annotation> containerType, Processor<T> processor) {
try {
- return searchWithGetSemantics(element, annotationType, annotationName, containerType, processor,
- new HashSet<AnnotatedElement>(), 0);
+ return searchWithGetSemantics(element, annotationType, annotationName,
+ containerType, processor, new HashSet<AnnotatedElement>(), 0);
}
catch (Throwable ex) {
AnnotationUtils.rethrowAnnotationConfigurationException(ex);
@@ -923,10 +920,11 @@ public class AnnotatedElementUtils {
* @param processor the processor to delegate to
* @param visited the set of annotated elements that have already been visited
* @param metaDepth the meta-depth of the annotation
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
*/
- private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType,
- String annotationName, Class<? extends Annotation> containerType, Processor<T> processor,
+ private static <T> T searchWithGetSemantics(AnnotatedElement element,
+ Class<? extends Annotation> annotationType, String annotationName,
+ Class<? extends Annotation> containerType, Processor<T> processor,
Set<AnnotatedElement> visited, int metaDepth) {
Assert.notNull(element, "AnnotatedElement must not be null");
@@ -941,7 +939,7 @@ public class AnnotatedElementUtils {
return result;
}
- if (element instanceof Class) { // otherwise getAnnotations doesn't return anything new
+ if (element instanceof Class) { // otherwise getAnnotations does not return anything new
List<Annotation> inheritedAnnotations = new ArrayList<Annotation>();
for (Annotation annotation : element.getAnnotations()) {
if (!declaredAnnotations.contains(annotation)) {
@@ -984,13 +982,13 @@ public class AnnotatedElementUtils {
* @param processor the processor to delegate to
* @param visited the set of annotated elements that have already been visited
* @param metaDepth the meta-depth of the annotation
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
* @since 4.2
*/
private static <T> T searchWithGetSemanticsInAnnotations(AnnotatedElement element,
- List<Annotation> annotations, Class<? extends Annotation> annotationType, String annotationName,
- Class<? extends Annotation> containerType, Processor<T> processor, Set<AnnotatedElement> visited,
- int metaDepth) {
+ List<Annotation> annotations, Class<? extends Annotation> annotationType,
+ String annotationName, Class<? extends Annotation> containerType,
+ Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {
// Search in annotations
for (Annotation annotation : annotations) {
@@ -1053,10 +1051,11 @@ public class AnnotatedElementUtils {
* @param annotationName the fully qualified class name of the annotation
* type to find (as an alternative to {@code annotationType})
* @param processor the processor to delegate to
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
* @since 4.2
*/
- private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType,
+ private static <T> T searchWithFindSemantics(AnnotatedElement element,
+ Class<? extends Annotation> annotationType,
String annotationName, Processor<T> processor) {
return searchWithFindSemantics(element, annotationType, annotationName, null, processor);
@@ -1073,11 +1072,12 @@ public class AnnotatedElementUtils {
* @param containerType the type of the container that holds repeatable
* annotations, or {@code null} if the annotation is not repeatable
* @param processor the processor to delegate to
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
* @since 4.3
*/
- private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType,
- String annotationName, Class<? extends Annotation> containerType, Processor<T> processor) {
+ private static <T> T searchWithFindSemantics(AnnotatedElement element,
+ Class<? extends Annotation> annotationType, String annotationName,
+ Class<? extends Annotation> containerType, Processor<T> processor) {
if (containerType != null && !processor.aggregates()) {
throw new IllegalArgumentException(
@@ -1085,8 +1085,8 @@ public class AnnotatedElementUtils {
}
try {
- return searchWithFindSemantics(
- element, annotationType, annotationName, containerType, processor, new HashSet<AnnotatedElement>(), 0);
+ return searchWithFindSemantics(element, annotationType, annotationName,
+ containerType, processor, new HashSet<AnnotatedElement>(), 0);
}
catch (Throwable ex) {
AnnotationUtils.rethrowAnnotationConfigurationException(ex);
@@ -1109,7 +1109,7 @@ public class AnnotatedElementUtils {
* @param processor the processor to delegate to
* @param visited the set of annotated elements that have already been visited
* @param metaDepth the meta-depth of the annotation
- * @return the result of the processor, potentially {@code null}
+ * @return the result of the processor (potentially {@code null})
* @since 4.2
*/
private static <T> T searchWithFindSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType,
@@ -1122,79 +1122,86 @@ public class AnnotatedElementUtils {
try {
// Locally declared annotations (ignoring @Inherited)
Annotation[] annotations = element.getDeclaredAnnotations();
- List<T> aggregatedResults = (processor.aggregates() ? new ArrayList<T>() : null);
-
- // Search in local annotations
- for (Annotation annotation : annotations) {
- Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
- if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
- if (currentAnnotationType == annotationType ||
- currentAnnotationType.getName().equals(annotationName) ||
- processor.alwaysProcesses()) {
- T result = processor.process(element, annotation, metaDepth);
- if (result != null) {
- if (processor.aggregates() && metaDepth == 0) {
- aggregatedResults.add(result);
- }
- else {
- return result;
+ if (annotations.length > 0) {
+ List<T> aggregatedResults = (processor.aggregates() ? new ArrayList<T>() : null);
+
+ // Search in local annotations
+ for (Annotation annotation : annotations) {
+ Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
+ if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
+ if (currentAnnotationType == annotationType ||
+ currentAnnotationType.getName().equals(annotationName) ||
+ processor.alwaysProcesses()) {
+ T result = processor.process(element, annotation, metaDepth);
+ if (result != null) {
+ if (aggregatedResults != null && metaDepth == 0) {
+ aggregatedResults.add(result);
+ }
+ else {
+ return result;
+ }
}
}
- }
- // Repeatable annotations in container?
- else if (currentAnnotationType == containerType) {
- for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
- T result = processor.process(element, contained, metaDepth);
- if (result != null) {
- // No need to post-process since repeatable annotations within a
- // container cannot be composed annotations.
- aggregatedResults.add(result);
+ // Repeatable annotations in container?
+ else if (currentAnnotationType == containerType) {
+ for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
+ T result = processor.process(element, contained, metaDepth);
+ if (aggregatedResults != null && result != null) {
+ // No need to post-process since repeatable annotations within a
+ // container cannot be composed annotations.
+ aggregatedResults.add(result);
+ }
}
}
}
}
- }
- // Search in meta annotations on local annotations
- for (Annotation annotation : annotations) {
- Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
- if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
- T result = searchWithFindSemantics(currentAnnotationType, annotationType, annotationName,
- containerType, processor, visited, metaDepth + 1);
- if (result != null) {
- processor.postProcess(currentAnnotationType, annotation, result);
- if (processor.aggregates() && metaDepth == 0) {
- aggregatedResults.add(result);
- }
- else {
- return result;
+ // Recursively search in meta-annotations
+ for (Annotation annotation : annotations) {
+ Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
+ if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
+ T result = searchWithFindSemantics(currentAnnotationType, annotationType, annotationName,
+ containerType, processor, visited, metaDepth + 1);
+ if (result != null) {
+ processor.postProcess(currentAnnotationType, annotation, result);
+ if (aggregatedResults != null && metaDepth == 0) {
+ aggregatedResults.add(result);
+ }
+ else {
+ return result;
+ }
}
}
}
- }
- if (processor.aggregates()) {
- // Prepend to support top-down ordering within class hierarchies
- processor.getAggregatedResults().addAll(0, aggregatedResults);
+ if (!CollectionUtils.isEmpty(aggregatedResults)) {
+ // Prepend to support top-down ordering within class hierarchies
+ processor.getAggregatedResults().addAll(0, aggregatedResults);
+ }
}
if (element instanceof Method) {
Method method = (Method) element;
+ T result;
// Search on possibly bridged method
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
- T result = searchWithFindSemantics(resolvedMethod, annotationType, annotationName, containerType,
- processor, visited, metaDepth);
- if (result != null) {
- return result;
+ if (resolvedMethod != method) {
+ result = searchWithFindSemantics(resolvedMethod, annotationType, annotationName,
+ containerType, processor, visited, metaDepth);
+ if (result != null) {
+ return result;
+ }
}
// Search on methods in interfaces declared locally
Class<?>[] ifcs = method.getDeclaringClass().getInterfaces();
- result = searchOnInterfaces(method, annotationType, annotationName, containerType, processor,
- visited, metaDepth, ifcs);
- if (result != null) {
- return result;
+ if (ifcs.length > 0) {
+ result = searchOnInterfaces(method, annotationType, annotationName,
+ containerType, processor, visited, metaDepth, ifcs);
+ if (result != null) {
+ return result;
+ }
}
// Search on methods in class hierarchy and interface hierarchy
@@ -1204,7 +1211,6 @@ public class AnnotatedElementUtils {
if (clazz == null || Object.class == clazz) {
break;
}
-
try {
Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
Method resolvedEquivalentMethod = BridgeMethodResolver.findBridgedMethod(equivalentMethod);
@@ -1217,10 +1223,9 @@ public class AnnotatedElementUtils {
catch (NoSuchMethodException ex) {
// No equivalent method found
}
-
// Search on interfaces declared on superclass
- result = searchOnInterfaces(method, annotationType, annotationName, containerType, processor,
- visited, metaDepth, clazz.getInterfaces());
+ result = searchOnInterfaces(method, annotationType, annotationName,
+ containerType, processor, visited, metaDepth, clazz.getInterfaces());
if (result != null) {
return result;
}
@@ -1231,8 +1236,8 @@ public class AnnotatedElementUtils {
// Search on interfaces
for (Class<?> ifc : clazz.getInterfaces()) {
- T result = searchWithFindSemantics(ifc, annotationType, annotationName, containerType,
- processor, visited, metaDepth);
+ T result = searchWithFindSemantics(ifc, annotationType, annotationName,
+ containerType, processor, visited, metaDepth);
if (result != null) {
return result;
}
@@ -1241,8 +1246,8 @@ public class AnnotatedElementUtils {
// Search on superclass
Class<?> superclass = clazz.getSuperclass();
if (superclass != null && Object.class != superclass) {
- T result = searchWithFindSemantics(superclass, annotationType, annotationName, containerType,
- processor, visited, metaDepth);
+ T result = searchWithFindSemantics(superclass, annotationType, annotationName,
+ containerType, processor, visited, metaDepth);
if (result != null) {
return result;
}
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
index 5e19db46..971568da 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -145,17 +145,17 @@ public abstract class AnnotationUtils {
* <p>Note that this method supports only a single level of meta-annotations.
* For support for arbitrary levels of meta-annotations, use one of the
* {@code find*()} methods instead.
- * @param ann the Annotation to check
+ * @param annotation the Annotation to check
* @param annotationType the annotation type to look for, both locally and as a meta-annotation
* @return the first matching annotation, or {@code null} if not found
* @since 4.0
*/
@SuppressWarnings("unchecked")
- public static <A extends Annotation> A getAnnotation(Annotation ann, Class<A> annotationType) {
- if (annotationType.isInstance(ann)) {
- return synthesizeAnnotation((A) ann);
+ public static <A extends Annotation> A getAnnotation(Annotation annotation, Class<A> annotationType) {
+ if (annotationType.isInstance(annotation)) {
+ return synthesizeAnnotation((A) annotation);
}
- Class<? extends Annotation> annotatedElement = ann.annotationType();
+ Class<? extends Annotation> annotatedElement = annotation.annotationType();
try {
return synthesizeAnnotation(annotatedElement.getAnnotation(annotationType), annotatedElement);
}
@@ -568,7 +568,6 @@ public abstract class AnnotationUtils {
if (result == null) {
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
result = findAnnotation((AnnotatedElement) resolvedMethod, annotationType);
-
if (result == null) {
result = searchOnInterfaces(method, annotationType, method.getDeclaringClass().getInterfaces());
}
@@ -603,10 +602,10 @@ public abstract class AnnotationUtils {
private static <A extends Annotation> A searchOnInterfaces(Method method, Class<A> annotationType, Class<?>... ifcs) {
A annotation = null;
- for (Class<?> iface : ifcs) {
- if (isInterfaceWithAnnotatedMethods(iface)) {
+ for (Class<?> ifc : ifcs) {
+ if (isInterfaceWithAnnotatedMethods(ifc)) {
try {
- Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
+ Method equivalentMethod = ifc.getMethod(method.getName(), method.getParameterTypes());
annotation = getAnnotation(equivalentMethod, annotationType);
}
catch (NoSuchMethodException ex) {
@@ -620,13 +619,13 @@ public abstract class AnnotationUtils {
return annotation;
}
- static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
- Boolean found = annotatedInterfaceCache.get(iface);
+ static boolean isInterfaceWithAnnotatedMethods(Class<?> ifc) {
+ Boolean found = annotatedInterfaceCache.get(ifc);
if (found != null) {
return found;
}
found = Boolean.FALSE;
- for (Method ifcMethod : iface.getMethods()) {
+ for (Method ifcMethod : ifc.getMethods()) {
try {
if (ifcMethod.getAnnotations().length > 0) {
found = Boolean.TRUE;
@@ -637,7 +636,7 @@ public abstract class AnnotationUtils {
handleIntrospectionFailure(ifcMethod, ex);
}
}
- annotatedInterfaceCache.put(iface, found);
+ annotatedInterfaceCache.put(ifc, found);
return found;
}
@@ -933,6 +932,32 @@ public abstract class AnnotationUtils {
}
/**
+ * Check the declared attributes of the given annotation, in particular covering
+ * Google App Engine's late arrival of {@code TypeNotPresentExceptionProxy} for
+ * {@code Class} values (instead of early {@code Class.getAnnotations() failure}.
+ * <p>This method not failing indicates that {@link #getAnnotationAttributes(Annotation)}
+ * won't failure either (when attempted later on).
+ * @param annotation the annotation to validate
+ * @throws IllegalStateException if a declared {@code Class} attribute could not be read
+ * @since 4.3.15
+ * @see Class#getAnnotations()
+ * @see #getAnnotationAttributes(Annotation)
+ */
+ public static void validateAnnotation(Annotation annotation) {
+ for (Method method : getAttributeMethods(annotation.annotationType())) {
+ Class<?> returnType = method.getReturnType();
+ if (returnType == Class.class || returnType == Class[].class) {
+ try {
+ method.invoke(annotation);
+ }
+ catch (Throwable ex) {
+ throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
+ }
+ }
+ }
+ }
+
+ /**
* Retrieve the given annotation's attributes as a {@link Map}, preserving all
* attribute types.
* <p>Equivalent to calling {@link #getAnnotationAttributes(Annotation, boolean, boolean)}
@@ -1260,15 +1285,12 @@ public abstract class AnnotationUtils {
}
Object value = attributes.get(attributeName);
boolean valuePresent = (value != null && !(value instanceof DefaultValueHolder));
-
for (String aliasedAttributeName : aliasMap.get(attributeName)) {
if (valuesAlreadyReplaced.contains(aliasedAttributeName)) {
continue;
}
-
Object aliasedValue = attributes.get(aliasedAttributeName);
boolean aliasPresent = (aliasedValue != null && !(aliasedValue instanceof DefaultValueHolder));
-
// Something to validate or replace with an alias?
if (valuePresent || aliasPresent) {
if (valuePresent && aliasPresent) {
@@ -1882,17 +1904,31 @@ public abstract class AnnotationUtils {
if (element instanceof Class && Annotation.class.isAssignableFrom((Class<?>) element)) {
// Meta-annotation or (default) value lookup on an annotation type
if (loggerToUse.isDebugEnabled()) {
- loggerToUse.debug("Failed to meta-introspect annotation [" + element + "]: " + ex);
+ loggerToUse.debug("Failed to meta-introspect annotation " + element + ": " + ex);
}
}
else {
// Direct annotation lookup on regular Class, Method, Field
if (loggerToUse.isInfoEnabled()) {
- loggerToUse.info("Failed to introspect annotations on [" + element + "]: " + ex);
+ loggerToUse.info("Failed to introspect annotations on " + element + ": " + ex);
}
}
}
+ /**
+ * Clear the internal annotation metadata cache.
+ * @since 4.3.15
+ */
+ public static void clearCache() {
+ findAnnotationCache.clear();
+ metaPresentCache.clear();
+ annotatedInterfaceCache.clear();
+ synthesizableCache.clear();
+ attributeAliasesCache.clear();
+ attributeMethodsCache.clear();
+ aliasDescriptorCache.clear();
+ }
+
/**
* Cache key for the AnnotatedElement cache.
diff --git a/spring-core/src/main/java/org/springframework/core/convert/Property.java b/spring-core/src/main/java/org/springframework/core/convert/Property.java
index 9c6db43c..c7c1bddc 100644
--- a/spring-core/src/main/java/org/springframework/core/convert/Property.java
+++ b/spring-core/src/main/java/org/springframework/core/convert/Property.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -36,8 +36,8 @@ import org.springframework.util.StringUtils;
* is not available in a number of environments (e.g. Android, Java ME), so this is
* desirable for portability of Spring's core conversion facility.
*
- * <p>Used to build a TypeDescriptor from a property location.
- * The built TypeDescriptor can then be used to convert from/to the property type.
+ * <p>Used to build a {@link TypeDescriptor} from a property location. The built
+ * {@code TypeDescriptor} can then be used to convert from/to the property type.
*
* @author Keith Donald
* @author Phillip Webb
diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
index 593687ef..03374f75 100644
--- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
+++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -54,12 +54,12 @@ public class TypeDescriptor implements Serializable {
private static final boolean streamAvailable = ClassUtils.isPresent(
"java.util.stream.Stream", TypeDescriptor.class.getClassLoader());
- private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<Class<?>, TypeDescriptor>(18);
+ private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<Class<?>, TypeDescriptor>(32);
private static final Class<?>[] CACHED_COMMON_TYPES = {
boolean.class, Boolean.class, byte.class, Byte.class, char.class, Character.class,
- double.class, Double.class, int.class, Integer.class, long.class, Long.class,
- float.class, Float.class, short.class, Short.class, String.class, Object.class};
+ double.class, Double.class, float.class, Float.class, int.class, Integer.class,
+ long.class, Long.class, short.class, Short.class, String.class, Object.class};
static {
for (Class<?> preCachedClass : CACHED_COMMON_TYPES) {
diff --git a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java
index b7ad3c42..d9e0afb6 100644
--- a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java
+++ b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java
@@ -65,8 +65,8 @@ class SimpleCommandLineArgsParser {
String optionName;
String optionValue = null;
if (optionText.contains("=")) {
- optionName = optionText.substring(0, optionText.indexOf("="));
- optionValue = optionText.substring(optionText.indexOf("=")+1, optionText.length());
+ optionName = optionText.substring(0, optionText.indexOf('='));
+ optionValue = optionText.substring(optionText.indexOf('=')+1, optionText.length());
}
else {
optionName = optionText;
diff --git a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java
index f1b1f8d7..36631a5a 100644
--- a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java
+++ b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -18,6 +18,8 @@ package org.springframework.core.env;
import java.util.List;
+import org.springframework.util.StringUtils;
+
/**
* {@link CommandLinePropertySource} implementation backed by a simple String array.
*
@@ -100,7 +102,7 @@ public class SimpleCommandLinePropertySource extends CommandLinePropertySource<C
*/
@Override
public String[] getPropertyNames() {
- return source.getOptionNames().toArray(new String[source.getOptionNames().size()]);
+ return StringUtils.toStringArray(this.source.getOptionNames());
}
@Override
diff --git a/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java b/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java
index d66b9a63..36c2019b 100644
--- a/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java
+++ b/spring-core/src/main/java/org/springframework/core/io/VfsUtils.java
@@ -46,24 +46,24 @@ 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;
- private static Method VFS_METHOD_GET_ROOT_URI;
-
- 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;
- private static Method VIRTUAL_FILE_METHOD_TO_URL;
- private static Method VIRTUAL_FILE_METHOD_TO_URI;
- private static Method VIRTUAL_FILE_METHOD_GET_NAME;
- private static Method VIRTUAL_FILE_METHOD_GET_PATH_NAME;
- private static Method VIRTUAL_FILE_METHOD_GET_CHILD;
-
- protected static Class<?> VIRTUAL_FILE_VISITOR_INTERFACE;
- protected static Method VIRTUAL_FILE_METHOD_VISIT;
-
- private static Field VISITOR_ATTRIBUTES_FIELD_RECURSE;
- private static Method GET_PHYSICAL_FILE;
+ private static final Method VFS_METHOD_GET_ROOT_URL;
+ private static final Method VFS_METHOD_GET_ROOT_URI;
+
+ private static final Method VIRTUAL_FILE_METHOD_EXISTS;
+ private static final Method VIRTUAL_FILE_METHOD_GET_INPUT_STREAM;
+ private static final Method VIRTUAL_FILE_METHOD_GET_SIZE;
+ private static final Method VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED;
+ private static final Method VIRTUAL_FILE_METHOD_TO_URL;
+ private static final Method VIRTUAL_FILE_METHOD_TO_URI;
+ private static final Method VIRTUAL_FILE_METHOD_GET_NAME;
+ private static final Method VIRTUAL_FILE_METHOD_GET_PATH_NAME;
+ private static final Method VIRTUAL_FILE_METHOD_GET_CHILD;
+
+ protected static final Class<?> VIRTUAL_FILE_VISITOR_INTERFACE;
+ protected static final Method VIRTUAL_FILE_METHOD_VISIT;
+
+ private static final Field VISITOR_ATTRIBUTES_FIELD_RECURSE;
+ private static final Method GET_PHYSICAL_FILE;
static {
ClassLoader loader = VfsUtils.class.getClassLoader();
diff --git a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
index f9ae32cf..131bb0a1 100644
--- a/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
+++ b/spring-core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.java
@@ -287,7 +287,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
// Generally only look for a pattern after a prefix here,
// and on Tomcat only after the "*/" separator for its "war:" protocol.
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
- locationPattern.indexOf(":") + 1);
+ locationPattern.indexOf(':') + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
@@ -525,7 +525,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
* @see #retrieveMatchingFiles
*/
protected String determineRootDir(String location) {
- int prefixEnd = location.indexOf(":") + 1;
+ int prefixEnd = location.indexOf(':') + 1;
int rootDirEnd = location.length();
while (rootDirEnd > prefixEnd && getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) {
rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1;
diff --git a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
index 908b54d3..fa378ed0 100644
--- a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
+++ b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -69,7 +69,7 @@ public abstract class SpringFactoriesLoader {
/**
* Load and instantiate the factory implementations of the given type from
* {@value #FACTORIES_RESOURCE_LOCATION}, using the given class loader.
- * <p>The returned factories are sorted in accordance with the {@link AnnotationAwareOrderComparator}.
+ * <p>The returned factories are sorted through {@link AnnotationAwareOrderComparator}.
* <p>If a custom instantiation strategy is required, use {@link #loadFactoryNames}
* to obtain all registered factory names.
* @param factoryClass the interface or abstract class representing the factory
diff --git a/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java b/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java
index 393ecee6..d666e7f3 100644
--- a/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java
+++ b/spring-core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -24,18 +24,18 @@ import org.springframework.core.task.TaskExecutor;
import org.springframework.util.Assert;
/**
- * Adapter that takes a Spring {@link org.springframework.core.task.TaskExecutor})
+ * Adapter that takes a Spring {@link org.springframework.core.task.TaskExecutor}
* and exposes a full {@code java.util.concurrent.ExecutorService} for it.
*
* <p>This is primarily for adapting to client components that communicate via the
* {@code java.util.concurrent.ExecutorService} API. It can also be used as
* common ground between a local Spring {@code TaskExecutor} backend and a
- * JNDI-located {@code ManagedExecutorService} in a Java EE 6 environment.
+ * JNDI-located {@code ManagedExecutorService} in a Java EE 7 environment.
*
* <p><b>NOTE:</b> This ExecutorService adapter does <em>not</em> support the
* lifecycle methods in the {@code java.util.concurrent.ExecutorService} API
* ("shutdown()" etc), similar to a server-wide {@code ManagedExecutorService}
- * in a Java EE 6 environment. The lifecycle is always up to the backend pool,
+ * in a Java EE 7 environment. The lifecycle is always up to the backend pool,
* with this adapter acting as an access-only proxy for that target pool.
*
* @author Juergen Hoeller
diff --git a/spring-core/src/main/java/org/springframework/core/type/filter/AnnotationTypeFilter.java b/spring-core/src/main/java/org/springframework/core/type/filter/AnnotationTypeFilter.java
index 2b2faa4d..9aaea290 100644
--- a/spring-core/src/main/java/org/springframework/core/type/filter/AnnotationTypeFilter.java
+++ b/spring-core/src/main/java/org/springframework/core/type/filter/AnnotationTypeFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -70,7 +70,9 @@ public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter
* @param considerMetaAnnotations whether to also match on meta-annotations
* @param considerInterfaces whether to also match interfaces
*/
- public AnnotationTypeFilter(Class<? extends Annotation> annotationType, boolean considerMetaAnnotations, boolean considerInterfaces) {
+ public AnnotationTypeFilter(
+ Class<? extends Annotation> annotationType, boolean considerMetaAnnotations, boolean considerInterfaces) {
+
super(annotationType.isAnnotationPresent(Inherited.class), considerInterfaces);
this.annotationType = annotationType;
this.considerMetaAnnotations = considerMetaAnnotations;
@@ -99,6 +101,11 @@ public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter
return false;
}
else if (typeName.startsWith("java")) {
+ if (!this.annotationType.getName().startsWith("java")) {
+ // Standard Java types do not have non-standard annotations on them ->
+ // skip any load attempt, in particular for Java language interfaces.
+ return false;
+ }
try {
Class<?> clazz = ClassUtils.forName(typeName, getClass().getClassLoader());
return ((this.considerMetaAnnotations ? AnnotationUtils.getAnnotation(clazz, this.annotationType) :
diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java
index 5a99de2e..89418ced 100644
--- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -112,7 +112,7 @@ public abstract class ClassUtils {
registerCommonClasses(entry.getKey());
}
- Set<Class<?>> primitiveTypes = new HashSet<Class<?>>(32);
+ Set<Class<?>> primitiveTypes = new HashSet<Class<?>>(64);
primitiveTypes.addAll(primitiveWrapperTypeMap.values());
primitiveTypes.addAll(Arrays.asList(new Class<?>[] {
boolean[].class, byte[].class, char[].class, double[].class,
@@ -125,9 +125,10 @@ public abstract class ClassUtils {
registerCommonClasses(Boolean[].class, Byte[].class, Character[].class, Double[].class,
Float[].class, Integer[].class, Long[].class, Short[].class);
registerCommonClasses(Number.class, Number[].class, String.class, String[].class,
- Object.class, Object[].class, Class.class, Class[].class);
+ Class.class, Class[].class, Object.class, Object[].class);
registerCommonClasses(Throwable.class, Exception.class, RuntimeException.class,
Error.class, StackTraceElement.class, StackTraceElement[].class);
+ registerCommonClasses(Enum.class, Iterable.class, Cloneable.class, Comparable.class);
}
@@ -1064,11 +1065,12 @@ public abstract class ClassUtils {
}
/**
- * Copy the given Collection into a Class array.
- * The Collection must contain Class elements only.
- * @param collection the Collection to copy
- * @return the Class array ({@code null} if the passed-in
- * Collection was {@code null})
+ * Copy the given {@code Collection} into a {@code Class} array.
+ * <p>The {@code Collection} must contain {@code Class} elements only.
+ * @param collection the {@code Collection} to copy
+ * @return the {@code Class} array
+ * @since 3.1
+ * @see StringUtils#toStringArray
*/
public static Class<?>[] toClassArray(Collection<Class<?>> collection) {
if (collection == null) {
@@ -1109,8 +1111,7 @@ public abstract class ClassUtils {
* @return all interfaces that the given object implements as an array
*/
public static Class<?>[] getAllInterfacesForClass(Class<?> clazz, ClassLoader classLoader) {
- Set<Class<?>> ifcs = getAllInterfacesForClassAsSet(clazz, classLoader);
- return ifcs.toArray(new Class<?>[ifcs.size()]);
+ return toClassArray(getAllInterfacesForClassAsSet(clazz, classLoader));
}
/**
@@ -1150,12 +1151,13 @@ public abstract class ClassUtils {
return Collections.<Class<?>>singleton(clazz);
}
Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
- while (clazz != null) {
- Class<?>[] ifcs = clazz.getInterfaces();
+ Class<?> current = clazz;
+ while (current != null) {
+ Class<?>[] ifcs = current.getInterfaces();
for (Class<?> ifc : ifcs) {
interfaces.addAll(getAllInterfacesForClassAsSet(ifc, classLoader));
}
- clazz = clazz.getSuperclass();
+ current = current.getSuperclass();
}
return interfaces;
}
diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java
index 17127f2e..cee33acd 100644
--- a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java
+++ b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -223,18 +223,27 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
@Override
public V get(Object key) {
- Reference<K, V> reference = getReference(key, Restructure.WHEN_NECESSARY);
- Entry<K, V> entry = (reference != null ? reference.get() : null);
+ Entry<K, V> entry = getEntryIfAvailable(key);
return (entry != null ? entry.getValue() : null);
}
@Override
+ public V getOrDefault(Object key, V defaultValue) {
+ Entry<K, V> entry = getEntryIfAvailable(key);
+ return (entry != null ? entry.getValue() : defaultValue);
+ }
+
+ @Override
public boolean containsKey(Object key) {
- Reference<K, V> reference = getReference(key, Restructure.WHEN_NECESSARY);
- Entry<K, V> entry = (reference != null ? reference.get() : null);
+ Entry<K, V> entry = getEntryIfAvailable(key);
return (entry != null && ObjectUtils.nullSafeEquals(entry.getKey(), key));
}
+ private Entry<K, V> getEntryIfAvailable(Object key) {
+ Reference<K, V> reference = getReference(key, Restructure.WHEN_NECESSARY);
+ return (reference != null ? reference.get() : null);
+ }
+
/**
* Return a {@link Reference} to the {@link Entry} for the specified {@code key},
* or {@code null} if not found.
@@ -582,17 +591,18 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
}
private Reference<K, V> findInChain(Reference<K, V> reference, Object key, int hash) {
- while (reference != null) {
- if (reference.getHash() == hash) {
- Entry<K, V> entry = reference.get();
+ Reference<K, V> currRef = reference;
+ while (currRef != null) {
+ if (currRef.getHash() == hash) {
+ Entry<K, V> entry = currRef.get();
if (entry != null) {
K entryKey = entry.getKey();
- if (entryKey == key || entryKey.equals(key)) {
- return reference;
+ if (ObjectUtils.nullSafeEquals(entryKey, key)) {
+ return currRef;
}
}
}
- reference = reference.getNext();
+ currRef = currRef.getNext();
}
return null;
}
diff --git a/spring-core/src/main/java/org/springframework/util/DigestUtils.java b/spring-core/src/main/java/org/springframework/util/DigestUtils.java
index 36b1a583..cc782565 100644
--- a/spring-core/src/main/java/org/springframework/util/DigestUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/DigestUtils.java
@@ -169,7 +169,7 @@ public abstract class DigestUtils {
}
private static char[] encodeHex(byte[] bytes) {
- char chars[] = new char[32];
+ char[] chars = new char[32];
for (int i = 0; i < chars.length; i = i + 2) {
byte b = bytes[i / 2];
chars[i] = HEX_CHARS[(b >>> 0x4) & 0xf];
diff --git a/spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java b/spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java
index 5e327797..886f92c0 100644
--- a/spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java
+++ b/spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java
@@ -489,6 +489,7 @@ public class FastByteArrayOutputStream extends OutputStream {
* Update the message digest with the remaining bytes in this stream.
* @param messageDigest The message digest to update
*/
+ @Override
public void updateMessageDigest(MessageDigest messageDigest) {
updateMessageDigest(messageDigest, available());
}
@@ -499,6 +500,7 @@ public class FastByteArrayOutputStream extends OutputStream {
* @param messageDigest The message digest to update
* @param len how many bytes to read from this stream and use to update the message digest
*/
+ @Override
public void updateMessageDigest(MessageDigest messageDigest, int len) {
if (this.currentBuffer == null) {
// This stream doesn't have any data in it...
diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java
index 23ceb3e3..26afb8ef 100644
--- a/spring-core/src/main/java/org/springframework/util/MimeType.java
+++ b/spring-core/src/main/java/org/springframework/util/MimeType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 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,15 +29,15 @@ import java.util.Map;
import java.util.TreeSet;
/**
- * Represents a MIME Type, as originally defined in RFC 2046 and subsequently used in
- * other Internet protocols including HTTP.
+ * Represents a MIME Type, as originally defined in RFC 2046 and subsequently
+ * used in other Internet protocols including HTTP.
*
* <p>This class, however, does not contain support for the q-parameters used
- * in HTTP content negotiation. Those can be found in the sub-class
+ * in HTTP content negotiation. Those can be found in the subclass
* {@code org.springframework.http.MediaType} in the {@code spring-web} module.
*
* <p>Consists of a {@linkplain #getType() type} and a {@linkplain #getSubtype() subtype}.
- * Also has functionality to parse media types from a string using
+ * Also has functionality to parse MIME Type values from a {@code String} using
* {@link #valueOf(String)}. For more parsing options see {@link MimeTypeUtils}.
*
* @author Arjen Poutsma
@@ -137,7 +137,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
/**
* Copy-constructor that copies the type, subtype, parameters of the given {@code MimeType},
* and allows to set the specified character set.
- * @param other the other media type
+ * @param other the other MimeType
* @param charset the character set
* @throws IllegalArgumentException if any of the parameters contains illegal characters
* @since 4.3
@@ -149,8 +149,8 @@ public class MimeType implements Comparable<MimeType>, Serializable {
/**
* Copy-constructor that copies the type and subtype of the given {@code MimeType},
* and allows for different parameter.
- * @param other the other media type
- * @param parameters the parameters, may be {@code null}
+ * @param other the other MimeType
+ * @param parameters the parameters (may be {@code null})
* @throws IllegalArgumentException if any of the parameters contains illegal characters
*/
public MimeType(MimeType other, Map<String, String> parameters) {
@@ -161,7 +161,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
* Create a new {@code MimeType} for the given type, subtype, and parameters.
* @param type the primary type
* @param subtype the subtype
- * @param parameters the parameters, may be {@code null}
+ * @param parameters the parameters (may be {@code null})
* @throws IllegalArgumentException if any of the parameters contains illegal characters
*/
public MimeType(String type, String subtype, Map<String, String> parameters) {
@@ -227,7 +227,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (s == null) {
return null;
}
- return isQuotedString(s) ? s.substring(1, s.length() - 1) : s;
+ return (isQuotedString(s) ? s.substring(1, s.length() - 1) : s);
}
/**
@@ -249,9 +249,9 @@ public class MimeType implements Comparable<MimeType>, Serializable {
}
/**
- * Indicates whether this media type is concrete, i.e. whether neither the type
+ * Indicates whether this MIME Type is concrete, i.e. whether neither the type
* nor the subtype is a wildcard character <code>&#42;</code>.
- * @return whether this media type is concrete
+ * @return whether this MIME Type is concrete
*/
public boolean isConcrete() {
return !isWildcardType() && !isWildcardSubtype();
@@ -310,19 +310,19 @@ public class MimeType implements Comparable<MimeType>, Serializable {
}
/**
- * Indicate whether this {@code MediaType} includes the given media type.
+ * Indicate whether this MIME Type includes the given MIME Type.
* <p>For instance, {@code text/*} includes {@code text/plain} and {@code text/html},
- * and {@code application/*+xml} includes {@code application/soap+xml}, etc. This
- * method is <b>not</b> symmetric.
- * @param other the reference media type with which to compare
- * @return {@code true} if this media type includes the given media type;
+ * and {@code application/*+xml} includes {@code application/soap+xml}, etc.
+ * This method is <b>not</b> symmetric.
+ * @param other the reference MIME Type with which to compare
+ * @return {@code true} if this MIME Type includes the given MIME Type;
* {@code false} otherwise
*/
public boolean includes(MimeType other) {
if (other == null) {
return false;
}
- if (this.isWildcardType()) {
+ if (isWildcardType()) {
// */* includes anything
return true;
}
@@ -330,9 +330,9 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (getSubtype().equals(other.getSubtype())) {
return true;
}
- if (this.isWildcardSubtype()) {
- // wildcard with suffix, e.g. application/*+xml
- int thisPlusIdx = getSubtype().indexOf('+');
+ if (isWildcardSubtype()) {
+ // Wildcard with suffix, e.g. application/*+xml
+ int thisPlusIdx = getSubtype().lastIndexOf('+');
if (thisPlusIdx == -1) {
return true;
}
@@ -354,12 +354,12 @@ public class MimeType implements Comparable<MimeType>, Serializable {
}
/**
- * Indicate whether this {@code MediaType} is compatible with the given media type.
+ * Indicate whether this MIME Type is compatible with the given MIME Type.
* <p>For instance, {@code text/*} is compatible with {@code text/plain},
* {@code text/html}, and vice versa. In effect, this method is similar to
* {@link #includes}, except that it <b>is</b> symmetric.
- * @param other the reference media type with which to compare
- * @return {@code true} if this media type is compatible with the given media type;
+ * @param other the reference MIME Type with which to compare
+ * @return {@code true} if this MIME Type is compatible with the given MIME Type;
* {@code false} otherwise
*/
public boolean isCompatibleWith(MimeType other) {
@@ -373,22 +373,18 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (getSubtype().equals(other.getSubtype())) {
return true;
}
- // wildcard with suffix? e.g. application/*+xml
- if (this.isWildcardSubtype() || other.isWildcardSubtype()) {
-
+ // Wildcard with suffix? e.g. application/*+xml
+ if (isWildcardSubtype() || other.isWildcardSubtype()) {
int thisPlusIdx = getSubtype().indexOf('+');
int otherPlusIdx = other.getSubtype().indexOf('+');
-
if (thisPlusIdx == -1 && otherPlusIdx == -1) {
return true;
}
else if (thisPlusIdx != -1 && otherPlusIdx != -1) {
String thisSubtypeNoSuffix = getSubtype().substring(0, thisPlusIdx);
String otherSubtypeNoSuffix = other.getSubtype().substring(0, otherPlusIdx);
-
String thisSubtypeSuffix = getSubtype().substring(thisPlusIdx + 1);
String otherSubtypeSuffix = other.getSubtype().substring(otherPlusIdx + 1);
-
if (thisSubtypeSuffix.equals(otherSubtypeSuffix) &&
(WILDCARD_TYPE.equals(thisSubtypeNoSuffix) || WILDCARD_TYPE.equals(otherSubtypeNoSuffix))) {
return true;
@@ -429,7 +425,6 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (!other.parameters.containsKey(key)) {
return false;
}
-
if (PARAM_CHARSET.equals(key)) {
if (!ObjectUtils.nullSafeEquals(getCharset(), other.getCharset())) {
return false;
@@ -475,8 +470,8 @@ public class MimeType implements Comparable<MimeType>, Serializable {
}
/**
- * Compares this {@code MediaType} to another alphabetically.
- * @param other media type to compare to
+ * Compares this MIME Type to another alphabetically.
+ * @param other the MIME Type to compare to
* @see MimeTypeUtils#sortBySpecificity(List)
*/
@Override
@@ -493,12 +488,14 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (comp != 0) {
return comp;
}
+
TreeSet<String> thisAttributes = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
thisAttributes.addAll(getParameters().keySet());
TreeSet<String> otherAttributes = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
otherAttributes.addAll(other.getParameters().keySet());
Iterator<String> thisAttributesIterator = thisAttributes.iterator();
Iterator<String> otherAttributesIterator = otherAttributes.iterator();
+
while (thisAttributesIterator.hasNext()) {
String thisAttribute = thisAttributesIterator.next();
String otherAttribute = otherAttributesIterator.next();
@@ -506,16 +503,35 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (comp != 0) {
return comp;
}
- String thisValue = getParameters().get(thisAttribute);
- String otherValue = other.getParameters().get(otherAttribute);
- if (otherValue == null) {
- otherValue = "";
+ if (PARAM_CHARSET.equals(thisAttribute)) {
+ Charset thisCharset = getCharset();
+ Charset otherCharset = other.getCharset();
+ if (thisCharset != otherCharset) {
+ if (thisCharset == null) {
+ return -1;
+ }
+ if (otherCharset == null) {
+ return 1;
+ }
+ comp = thisCharset.compareTo(otherCharset);
+ if (comp != 0) {
+ return comp;
+ }
+ }
}
- comp = thisValue.compareTo(otherValue);
- if (comp != 0) {
- return comp;
+ else {
+ String thisValue = getParameters().get(thisAttribute);
+ String otherValue = other.getParameters().get(otherAttribute);
+ if (otherValue == null) {
+ otherValue = "";
+ }
+ comp = thisValue.compareTo(otherValue);
+ if (comp != 0) {
+ return comp;
+ }
}
}
+
return 0;
}
@@ -541,26 +557,26 @@ public class MimeType implements Comparable<MimeType>, Serializable {
@Override
public int compare(T mimeType1, T mimeType2) {
- if (mimeType1.isWildcardType() && !mimeType2.isWildcardType()) { // */* < audio/*
+ if (mimeType1.isWildcardType() && !mimeType2.isWildcardType()) { // */* < audio/*
return 1;
}
- else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */*
+ else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */*
return -1;
}
- else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == text/html
+ else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == text/html
return 0;
}
- else { // mediaType1.getType().equals(mediaType2.getType())
- if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic
+ else { // mediaType1.getType().equals(mediaType2.getType())
+ if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic
return 1;
}
- else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/*
+ else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/*
return -1;
}
- else if (!mimeType1.getSubtype().equals(mimeType2.getSubtype())) { // audio/basic == audio/wave
+ else if (!mimeType1.getSubtype().equals(mimeType2.getSubtype())) { // audio/basic == audio/wave
return 0;
}
- else { // mediaType2.getSubtype().equals(mediaType2.getSubtype())
+ else { // mediaType2.getSubtype().equals(mediaType2.getSubtype())
return compareParameters(mimeType1, mimeType2);
}
}
@@ -569,7 +585,7 @@ public class MimeType implements Comparable<MimeType>, Serializable {
protected int compareParameters(T mimeType1, T mimeType2) {
int paramsSize1 = mimeType1.getParameters().size();
int paramsSize2 = mimeType2.getParameters().size();
- return (paramsSize2 < paramsSize1 ? -1 : (paramsSize2 == paramsSize1 ? 0 : 1)); // audio/basic;level=1 < audio/basic
+ return (paramsSize2 < paramsSize1 ? -1 : (paramsSize2 == paramsSize1 ? 0 : 1)); // audio/basic;level=1 < audio/basic
}
}
diff --git a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
index 5b3a7a0f..decf3918 100644
--- a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -18,6 +18,7 @@ package org.springframework.util;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -46,7 +47,7 @@ public abstract class MimeTypeUtils {
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z'};
- private static final Random RND = new Random();
+ private static final Random RND = new SecureRandom();
private static Charset US_ASCII = Charset.forName("US-ASCII");
@@ -287,8 +288,8 @@ public abstract class MimeTypeUtils {
}
int eqIndex = parameter.indexOf('=');
if (eqIndex >= 0) {
- String attribute = parameter.substring(0, eqIndex);
- String value = parameter.substring(eqIndex + 1, parameter.length());
+ String attribute = parameter.substring(0, eqIndex).trim();
+ String value = parameter.substring(eqIndex + 1, parameter.length()).trim();
parameters.put(attribute, value);
}
}
diff --git a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java
index 04f3e020..a43d016b 100644
--- a/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/ReflectionUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -645,8 +645,7 @@ public abstract class ReflectionUtils {
}
/**
- * Invoke the given callback on all fields in the target class, going up the
- * class hierarchy to get all declared fields.
+ * Invoke the given callback on all locally declared fields in the given class.
* @param clazz the target class to analyze
* @param fc the callback to invoke for each field
* @since 4.2
diff --git a/spring-core/src/main/java/org/springframework/util/StreamUtils.java b/spring-core/src/main/java/org/springframework/util/StreamUtils.java
index d3374bc3..8feb0f4e 100644
--- a/spring-core/src/main/java/org/springframework/util/StreamUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/StreamUtils.java
@@ -165,7 +165,7 @@ public abstract class StreamUtils {
}
long bytesToCopy = end - start + 1;
- byte buffer[] = new byte[StreamUtils.BUFFER_SIZE];
+ byte[] buffer = new byte[StreamUtils.BUFFER_SIZE];
while (bytesToCopy > 0) {
int bytesRead = in.read(buffer);
if (bytesRead == -1) {
diff --git a/spring-core/src/main/java/org/springframework/util/StringUtils.java b/spring-core/src/main/java/org/springframework/util/StringUtils.java
index 5e2fbfec..8dcef81e 100644
--- a/spring-core/src/main/java/org/springframework/util/StringUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -634,7 +634,7 @@ public abstract class StringUtils {
// first path element. This is necessary to correctly parse paths like
// "file:core/../core/io/Resource.class", where the ".." should just
// strip the first "core" directory while keeping the "file:" prefix.
- int prefixIndex = pathToUse.indexOf(":");
+ int prefixIndex = pathToUse.indexOf(':');
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
@@ -694,11 +694,11 @@ public abstract class StringUtils {
}
/**
- * Parse the given {@code localeString} value into a {@link Locale}.
+ * Parse the given {@code String} representation into a {@link Locale}.
* <p>This is the inverse operation of {@link Locale#toString Locale's toString}.
- * @param localeString the locale {@code String}, following {@code Locale's}
- * {@code toString()} format ("en", "en_UK", etc);
- * also accepts spaces as separators, as an alternative to underscores
+ * @param localeString the locale {@code String}: following {@code Locale's}
+ * {@code toString()} format ("en", "en_UK", etc), also accepting spaces as
+ * separators (as an alternative to underscores)
* @return a corresponding {@code Locale} instance, or {@code null} if none
* @throws IllegalArgumentException in case of an invalid locale specification
*/
@@ -815,7 +815,10 @@ public abstract class StringUtils {
* @param array1 the first array (can be {@code null})
* @param array2 the second array (can be {@code null})
* @return the new array ({@code null} if both given arrays were {@code null})
+ * @deprecated as of 4.3.15, in favor of manual merging via {@link LinkedHashSet}
+ * (with every entry included at most once, even entries within the first array)
*/
+ @Deprecated
public static String[] mergeStringArrays(String[] array1, String[] array2) {
if (ObjectUtils.isEmpty(array1)) {
return array2;
@@ -858,7 +861,6 @@ public abstract class StringUtils {
if (collection == null) {
return null;
}
-
return collection.toArray(new String[collection.size()]);
}
@@ -872,9 +874,7 @@ public abstract class StringUtils {
if (enumeration == null) {
return null;
}
-
- List<String> list = Collections.list(enumeration);
- return list.toArray(new String[list.size()]);
+ return toStringArray(Collections.list(enumeration));
}
/**
@@ -939,10 +939,9 @@ public abstract class StringUtils {
/**
* Take an array of strings and split each element based on the given delimiter.
- * A {@code Properties} instance is then generated, with the left of the
- * delimiter providing the key, and the right of the delimiter providing the value.
- * <p>Will trim both the key and value before adding them to the
- * {@code Properties} instance.
+ * A {@code Properties} instance is then generated, with the left of the delimiter
+ * providing the key, and the right of the delimiter providing the value.
+ * <p>Will trim both the key and value before adding them to the {@code Properties}.
* @param array the array to process
* @param delimiter to split each element using (typically the equals symbol)
* @return a {@code Properties} instance representing the array contents,
diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java
index 46eb746b..eca80014 100644
--- a/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java
+++ b/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -134,8 +134,9 @@ public class ListenableFutureCallbackRegistry<T> {
synchronized (this.mutex) {
this.state = State.SUCCESS;
this.result = result;
- while (!this.successCallbacks.isEmpty()) {
- notifySuccess(this.successCallbacks.poll());
+ SuccessCallback<? super T> callback;
+ while ((callback = this.successCallbacks.poll()) != null) {
+ notifySuccess(callback);
}
}
}
@@ -149,8 +150,9 @@ public class ListenableFutureCallbackRegistry<T> {
synchronized (this.mutex) {
this.state = State.FAILURE;
this.result = ex;
- while (!this.failureCallbacks.isEmpty()) {
- notifyFailure(this.failureCallbacks.poll());
+ FailureCallback callback;
+ while ((callback = this.failureCallbacks.poll()) != null) {
+ notifyFailure(callback);
}
}
}
diff --git a/spring-core/src/main/java/org/springframework/util/xml/AbstractStaxHandler.java b/spring-core/src/main/java/org/springframework/util/xml/AbstractStaxHandler.java
index e4294843..dbc0b700 100644
--- a/spring-core/src/main/java/org/springframework/util/xml/AbstractStaxHandler.java
+++ b/spring-core/src/main/java/org/springframework/util/xml/AbstractStaxHandler.java
@@ -100,7 +100,7 @@ abstract class AbstractStaxHandler implements ContentHandler, LexicalHandler {
}
@Override
- public final void characters(char ch[], int start, int length) throws SAXException {
+ public final void characters(char[] ch, int start, int length) throws SAXException {
try {
String data = new String(ch, start, length);
if (!this.inCData) {
diff --git a/spring-core/src/main/java/org/springframework/util/xml/DomContentHandler.java b/spring-core/src/main/java/org/springframework/util/xml/DomContentHandler.java
index 5a8d92aa..e7987ce0 100644
--- a/spring-core/src/main/java/org/springframework/util/xml/DomContentHandler.java
+++ b/spring-core/src/main/java/org/springframework/util/xml/DomContentHandler.java
@@ -94,7 +94,7 @@ class DomContentHandler implements ContentHandler {
}
@Override
- public void characters(char ch[], int start, int length) throws SAXException {
+ public void characters(char[] ch, int start, int length) throws SAXException {
String data = new String(ch, start, length);
Node parent = getParent();
Node lastChild = parent.getLastChild();
@@ -139,7 +139,7 @@ class DomContentHandler implements ContentHandler {
}
@Override
- public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
}
@Override
diff --git a/spring-core/src/main/java/org/springframework/util/xml/TransformerUtils.java b/spring-core/src/main/java/org/springframework/util/xml/TransformerUtils.java
index 4b48abd4..42d88149 100644
--- a/spring-core/src/main/java/org/springframework/util/xml/TransformerUtils.java
+++ b/spring-core/src/main/java/org/springframework/util/xml/TransformerUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2018 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,8 +22,8 @@ import javax.xml.transform.Transformer;
import org.springframework.util.Assert;
/**
- * Contains common behavior relating to {@link javax.xml.transform.Transformer Transformers}, and the
- * {@code javax.xml.transform} package in general.
+ * Contains common behavior relating to {@link javax.xml.transform.Transformer Transformers}
+ * and the {@code javax.xml.transform} package in general.
*
* @author Rick Evans
* @author Juergen Hoeller
@@ -32,16 +32,16 @@ import org.springframework.util.Assert;
public abstract class TransformerUtils {
/**
- * The indent amount of characters if {@link #enableIndenting(javax.xml.transform.Transformer) indenting is enabled}.
+ * The indent amount of characters if {@link #enableIndenting indenting is enabled}.
* <p>Defaults to "2".
*/
public static final int DEFAULT_INDENT_AMOUNT = 2;
+
/**
- * Enable indenting for the supplied {@link javax.xml.transform.Transformer}. <p>If the underlying XSLT engine is
- * Xalan, then the special output key {@code indent-amount} will be also be set to a value of {@link
- * #DEFAULT_INDENT_AMOUNT} characters.
- *
+ * Enable indenting for the supplied {@link javax.xml.transform.Transformer}.
+ * <p>If the underlying XSLT engine is Xalan, then the special output key {@code indent-amount}
+ * will be also be set to a value of {@link #DEFAULT_INDENT_AMOUNT} characters.
* @param transformer the target transformer
* @see javax.xml.transform.Transformer#setOutputProperty(String, String)
* @see javax.xml.transform.OutputKeys#INDENT
@@ -51,18 +51,19 @@ public abstract class TransformerUtils {
}
/**
- * Enable indenting for the supplied {@link javax.xml.transform.Transformer}. <p>If the underlying XSLT engine is
- * Xalan, then the special output key {@code indent-amount} will be also be set to a value of {@link
- * #DEFAULT_INDENT_AMOUNT} characters.
- *
- * @param transformer the target transformer
- * @param indentAmount the size of the indent (2 characters, 3 characters, etc.)
+ * Enable indenting for the supplied {@link javax.xml.transform.Transformer}.
+ * <p>If the underlying XSLT engine is Xalan, then the special output key {@code indent-amount}
+ * will be also be set to a value of {@link #DEFAULT_INDENT_AMOUNT} characters.
+ * @param transformer the target transformer
+ * @param indentAmount the size of the indent (2 characters, 3 characters, etc)
* @see javax.xml.transform.Transformer#setOutputProperty(String, String)
* @see javax.xml.transform.OutputKeys#INDENT
*/
public static void enableIndenting(Transformer transformer, int indentAmount) {
Assert.notNull(transformer, "Transformer must not be null");
- Assert.isTrue(indentAmount > -1, "The indent amount cannot be less than zero : got " + indentAmount);
+ if (indentAmount < 0) {
+ throw new IllegalArgumentException("Invalid indent amount (must not be less than zero): " + indentAmount);
+ }
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
try {
// Xalan-specific, but this is the most common XSLT engine in any case
@@ -74,7 +75,6 @@ public abstract class TransformerUtils {
/**
* Disable indenting for the supplied {@link javax.xml.transform.Transformer}.
- *
* @param transformer the target transformer
* @see javax.xml.transform.OutputKeys#INDENT
*/
diff --git a/spring-core/src/test/java/org/springframework/core/ConventionsTests.java b/spring-core/src/test/java/org/springframework/core/ConventionsTests.java
index 74d28bb7..87b43c50 100644
--- a/spring-core/src/test/java/org/springframework/core/ConventionsTests.java
+++ b/spring-core/src/test/java/org/springframework/core/ConventionsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -57,7 +57,7 @@ public class ConventionsTests {
@Test
public void emptyList() {
- exception.expect(IllegalArgumentException.class);
+ this.exception.expect(IllegalArgumentException.class);
Conventions.getVariableName(new ArrayList<>());
}
@@ -67,14 +67,14 @@ public class ConventionsTests {
}
@Test
- public void attributeNameToPropertyName() throws Exception {
+ public void attributeNameToPropertyName() {
assertEquals("transactionManager", Conventions.attributeNameToPropertyName("transaction-manager"));
assertEquals("pointcutRef", Conventions.attributeNameToPropertyName("pointcut-ref"));
assertEquals("lookupOnStartup", Conventions.attributeNameToPropertyName("lookup-on-startup"));
}
@Test
- public void getQualifiedAttributeName() throws Exception {
+ public void getQualifiedAttributeName() {
String baseName = "foo";
Class<String> cls = String.class;
String desiredResult = "java.lang.String.foo";
diff --git a/spring-core/src/test/java/org/springframework/core/LocalVariableTableParameterNameDiscovererTests.java b/spring-core/src/test/java/org/springframework/core/LocalVariableTableParameterNameDiscovererTests.java
index 31090c94..9c17e3d9 100644
--- a/spring-core/src/test/java/org/springframework/core/LocalVariableTableParameterNameDiscovererTests.java
+++ b/spring-core/src/test/java/org/springframework/core/LocalVariableTableParameterNameDiscovererTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -39,7 +39,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
@Test
public void methodParameterNameDiscoveryNoArgs() throws NoSuchMethodException {
- Method getName = TestObject.class.getMethod("getName", new Class[0]);
+ Method getName = TestObject.class.getMethod("getName");
String[] names = discoverer.getParameterNames(getName);
assertNotNull("should find method info", names);
assertEquals("no argument names", 0, names.length);
@@ -47,7 +47,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
@Test
public void methodParameterNameDiscoveryWithArgs() throws NoSuchMethodException {
- Method setName = TestObject.class.getMethod("setName", new Class[] { String.class });
+ Method setName = TestObject.class.getMethod("setName", String.class);
String[] names = discoverer.getParameterNames(setName);
assertNotNull("should find method info", names);
assertEquals("one argument", 1, names.length);
@@ -56,7 +56,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
@Test
public void consParameterNameDiscoveryNoArgs() throws NoSuchMethodException {
- Constructor<TestObject> noArgsCons = TestObject.class.getConstructor(new Class[0]);
+ Constructor<TestObject> noArgsCons = TestObject.class.getConstructor();
String[] names = discoverer.getParameterNames(noArgsCons);
assertNotNull("should find cons info", names);
assertEquals("no argument names", 0, names.length);
@@ -64,7 +64,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
@Test
public void consParameterNameDiscoveryArgs() throws NoSuchMethodException {
- Constructor<TestObject> twoArgCons = TestObject.class.getConstructor(new Class[] { String.class, int.class });
+ Constructor<TestObject> twoArgCons = TestObject.class.getConstructor(String.class, int.class);
String[] names = discoverer.getParameterNames(twoArgCons);
assertNotNull("should find cons info", names);
assertEquals("one argument", 2, names.length);
@@ -74,7 +74,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
@Test
public void staticMethodParameterNameDiscoveryNoArgs() throws NoSuchMethodException {
- Method m = getClass().getMethod("staticMethodNoLocalVars", new Class[0]);
+ Method m = getClass().getMethod("staticMethodNoLocalVars");
String[] names = discoverer.getParameterNames(m);
assertNotNull("should find method info", names);
assertEquals("no argument names", 0, names.length);
@@ -84,14 +84,14 @@ public class LocalVariableTableParameterNameDiscovererTests {
public void overloadedStaticMethod() throws Exception {
Class<? extends LocalVariableTableParameterNameDiscovererTests> clazz = this.getClass();
- Method m1 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE, Long.TYPE });
+ Method m1 = clazz.getMethod("staticMethod", Long.TYPE, Long.TYPE);
String[] names = discoverer.getParameterNames(m1);
assertNotNull("should find method info", names);
assertEquals("two arguments", 2, names.length);
assertEquals("x", names[0]);
assertEquals("y", names[1]);
- Method m2 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE, Long.TYPE, Long.TYPE });
+ Method m2 = clazz.getMethod("staticMethod", Long.TYPE, Long.TYPE, Long.TYPE);
names = discoverer.getParameterNames(m2);
assertNotNull("should find method info", names);
assertEquals("three arguments", 3, names.length);
@@ -104,13 +104,13 @@ public class LocalVariableTableParameterNameDiscovererTests {
public void overloadedStaticMethodInInnerClass() throws Exception {
Class<InnerClass> clazz = InnerClass.class;
- Method m1 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE });
+ Method m1 = clazz.getMethod("staticMethod", Long.TYPE);
String[] names = discoverer.getParameterNames(m1);
assertNotNull("should find method info", names);
assertEquals("one argument", 1, names.length);
assertEquals("x", names[0]);
- Method m2 = clazz.getMethod("staticMethod", new Class[] { Long.TYPE, Long.TYPE });
+ Method m2 = clazz.getMethod("staticMethod", Long.TYPE, Long.TYPE);
names = discoverer.getParameterNames(m2);
assertNotNull("should find method info", names);
assertEquals("two arguments", 2, names.length);
@@ -122,14 +122,14 @@ public class LocalVariableTableParameterNameDiscovererTests {
public void overloadedMethod() throws Exception {
Class<? extends LocalVariableTableParameterNameDiscovererTests> clazz = this.getClass();
- Method m1 = clazz.getMethod("instanceMethod", new Class[] { Double.TYPE, Double.TYPE });
+ Method m1 = clazz.getMethod("instanceMethod", Double.TYPE, Double.TYPE);
String[] names = discoverer.getParameterNames(m1);
assertNotNull("should find method info", names);
assertEquals("two arguments", 2, names.length);
assertEquals("x", names[0]);
assertEquals("y", names[1]);
- Method m2 = clazz.getMethod("instanceMethod", new Class[] { Double.TYPE, Double.TYPE, Double.TYPE });
+ Method m2 = clazz.getMethod("instanceMethod", Double.TYPE, Double.TYPE, Double.TYPE);
names = discoverer.getParameterNames(m2);
assertNotNull("should find method info", names);
assertEquals("three arguments", 3, names.length);
@@ -142,13 +142,13 @@ public class LocalVariableTableParameterNameDiscovererTests {
public void overloadedMethodInInnerClass() throws Exception {
Class<InnerClass> clazz = InnerClass.class;
- Method m1 = clazz.getMethod("instanceMethod", new Class[] { String.class });
+ Method m1 = clazz.getMethod("instanceMethod", String.class);
String[] names = discoverer.getParameterNames(m1);
assertNotNull("should find method info", names);
assertEquals("one argument", 1, names.length);
assertEquals("aa", names[0]);
- Method m2 = clazz.getMethod("instanceMethod", new Class[] { String.class, String.class });
+ Method m2 = clazz.getMethod("instanceMethod", String.class, String.class);
names = discoverer.getParameterNames(m2);
assertNotNull("should find method info", names);
assertEquals("two arguments", 2, names.length);
@@ -223,6 +223,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
assertNull(names);
}
+
public static void staticMethodNoLocalVars() {
}
@@ -246,6 +247,7 @@ public class LocalVariableTableParameterNameDiscovererTests {
return u;
}
+
public static class InnerClass {
public int waz = 0;
@@ -278,7 +280,9 @@ public class LocalVariableTableParameterNameDiscovererTests {
}
}
+
public static class GenerifiedClass<K, V> {
+
private static long date;
static {
@@ -317,4 +321,5 @@ public class LocalVariableTableParameterNameDiscovererTests {
return date;
}
}
+
}
diff --git a/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java b/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java
index c3c3e7d1..d7b01d52 100644
--- a/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java
+++ b/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -16,6 +16,11 @@
package org.springframework.core;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.junit.Before;
@@ -25,9 +30,13 @@ import static org.junit.Assert.*;
/**
* @author Arjen Poutsma
+ * @author Juergen Hoeller
+ * @author Sam Brannen
*/
public class MethodParameterTests {
+ private Method method;
+
private MethodParameter stringParameter;
private MethodParameter longParameter;
@@ -36,13 +45,14 @@ public class MethodParameterTests {
@Before
- public void setUp() throws NoSuchMethodException {
- Method method = getClass().getMethod("method", String.class, Long.TYPE);
+ public void setup() throws NoSuchMethodException {
+ method = getClass().getMethod("method", String.class, Long.TYPE);
stringParameter = new MethodParameter(method, 0);
longParameter = new MethodParameter(method, 1);
intReturnType = new MethodParameter(method, -1);
}
+
@Test
public void testEquals() throws NoSuchMethodException {
assertEquals(stringParameter, stringParameter);
@@ -60,8 +70,8 @@ public class MethodParameterTests {
MethodParameter methodParameter = new MethodParameter(method, 0);
assertEquals(stringParameter, methodParameter);
assertEquals(methodParameter, stringParameter);
- assertFalse(longParameter.equals(methodParameter));
- assertFalse(methodParameter.equals(longParameter));
+ assertNotEquals(longParameter, methodParameter);
+ assertNotEquals(methodParameter, longParameter);
}
@Test
@@ -73,7 +83,32 @@ public class MethodParameterTests {
Method method = getClass().getMethod("method", String.class, Long.TYPE);
MethodParameter methodParameter = new MethodParameter(method, 0);
assertEquals(stringParameter.hashCode(), methodParameter.hashCode());
- assertTrue(longParameter.hashCode() != methodParameter.hashCode());
+ assertNotEquals(longParameter.hashCode(), methodParameter.hashCode());
+ }
+
+ @Test
+ public void annotatedConstructorParameterInStaticNestedClass() throws Exception {
+ Constructor<?> constructor = NestedClass.class.getDeclaredConstructor(String.class);
+ MethodParameter methodParameter = MethodParameter.forMethodOrConstructor(constructor, 0);
+ assertEquals(String.class, methodParameter.getParameterType());
+ assertNotNull("Failed to find @Param annotation", methodParameter.getParameterAnnotation(Param.class));
+ }
+
+ @Test // SPR-16652
+ public void annotatedConstructorParameterInInnerClass() throws Exception {
+ Constructor<?> constructor = InnerClass.class.getConstructor(getClass(), String.class, Integer.class);
+
+ MethodParameter methodParameter = MethodParameter.forMethodOrConstructor(constructor, 0);
+ assertEquals(getClass(), methodParameter.getParameterType());
+ assertNull(methodParameter.getParameterAnnotation(Param.class));
+
+ methodParameter = MethodParameter.forMethodOrConstructor(constructor, 1);
+ assertEquals(String.class, methodParameter.getParameterType());
+ assertNotNull("Failed to find @Param annotation", methodParameter.getParameterAnnotation(Param.class));
+
+ methodParameter = MethodParameter.forMethodOrConstructor(constructor, 2);
+ assertEquals(Integer.class, methodParameter.getParameterType());
+ assertNull(methodParameter.getParameterAnnotation(Param.class));
}
@@ -81,4 +116,23 @@ public class MethodParameterTests {
return 42;
}
+ @SuppressWarnings("unused")
+ private static class NestedClass {
+
+ NestedClass(@Param String s) {
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private class InnerClass {
+
+ public InnerClass(@Param String s, Integer i) {
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.PARAMETER)
+ private @interface Param {
+ }
+
}
diff --git a/spring-core/src/test/java/org/springframework/core/NestedExceptionTests.java b/spring-core/src/test/java/org/springframework/core/NestedExceptionTests.java
index c0e60ad1..73376ccf 100644
--- a/spring-core/src/test/java/org/springframework/core/NestedExceptionTests.java
+++ b/spring-core/src/test/java/org/springframework/core/NestedExceptionTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -44,19 +44,19 @@ public class NestedExceptionTests {
nex.printStackTrace(pw);
pw.flush();
String stackTrace = new String(baos.toByteArray());
- assertFalse(stackTrace.indexOf(mesg) == -1);
+ assertTrue(stackTrace.contains(mesg));
}
@Test
public void nestedRuntimeExceptionWithRootCause() {
String myMessage = "mesg for this exception";
- String rootCauseMesg = "this is the obscure message of the root cause";
- Exception rootCause = new Exception(rootCauseMesg);
+ String rootCauseMsg = "this is the obscure message of the root cause";
+ Exception rootCause = new Exception(rootCauseMsg);
// Making a class abstract doesn't _really_ prevent instantiation :-)
NestedRuntimeException nex = new NestedRuntimeException(myMessage, rootCause) {};
assertEquals(nex.getCause(), rootCause);
- assertTrue(nex.getMessage().indexOf(myMessage) != -1);
- assertTrue(nex.getMessage().indexOf(rootCauseMesg) != -1);
+ assertTrue(nex.getMessage().contains(myMessage));
+ assertTrue(nex.getMessage().endsWith(rootCauseMsg));
// check PrintStackTrace
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -64,8 +64,8 @@ public class NestedExceptionTests {
nex.printStackTrace(pw);
pw.flush();
String stackTrace = new String(baos.toByteArray());
- assertFalse(stackTrace.indexOf(rootCause.getClass().getName()) == -1);
- assertFalse(stackTrace.indexOf(rootCauseMesg) == -1);
+ assertTrue(stackTrace.contains(rootCause.getClass().getName()));
+ assertTrue(stackTrace.contains(rootCauseMsg));
}
@Test
@@ -82,19 +82,19 @@ public class NestedExceptionTests {
nex.printStackTrace(pw);
pw.flush();
String stackTrace = new String(baos.toByteArray());
- assertFalse(stackTrace.indexOf(mesg) == -1);
+ assertTrue(stackTrace.contains(mesg));
}
@Test
public void nestedCheckedExceptionWithRootCause() {
String myMessage = "mesg for this exception";
- String rootCauseMesg = "this is the obscure message of the root cause";
- Exception rootCause = new Exception(rootCauseMesg);
+ String rootCauseMsg = "this is the obscure message of the root cause";
+ Exception rootCause = new Exception(rootCauseMsg);
// Making a class abstract doesn't _really_ prevent instantiation :-)
NestedCheckedException nex = new NestedCheckedException(myMessage, rootCause) {};
assertEquals(nex.getCause(), rootCause);
- assertTrue(nex.getMessage().indexOf(myMessage) != -1);
- assertTrue(nex.getMessage().indexOf(rootCauseMesg) != -1);
+ assertTrue(nex.getMessage().contains(myMessage));
+ assertTrue(nex.getMessage().endsWith(rootCauseMsg));
// check PrintStackTrace
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -102,8 +102,8 @@ public class NestedExceptionTests {
nex.printStackTrace(pw);
pw.flush();
String stackTrace = new String(baos.toByteArray());
- assertFalse(stackTrace.indexOf(rootCause.getClass().getName()) == -1);
- assertFalse(stackTrace.indexOf(rootCauseMesg) == -1);
+ assertTrue(stackTrace.contains(rootCause.getClass().getName()));
+ assertTrue(stackTrace.contains(rootCauseMsg));
}
}
diff --git a/spring-core/src/test/java/org/springframework/core/PrioritizedParameterNameDiscovererTests.java b/spring-core/src/test/java/org/springframework/core/PrioritizedParameterNameDiscovererTests.java
index 52209456..d2a1aa75 100644
--- a/spring-core/src/test/java/org/springframework/core/PrioritizedParameterNameDiscovererTests.java
+++ b/spring-core/src/test/java/org/springframework/core/PrioritizedParameterNameDiscovererTests.java
@@ -56,7 +56,7 @@ public class PrioritizedParameterNameDiscovererTests {
private final Method anyMethod;
public PrioritizedParameterNameDiscovererTests() throws SecurityException, NoSuchMethodException {
- anyMethod = TestObject.class.getMethod("getAge", (Class[]) null);
+ anyMethod = TestObject.class.getMethod("getAge");
}
@Test
diff --git a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java
index ab903fc6..68e5af3b 100644
--- a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java
+++ b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -42,7 +42,6 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Callable;
-import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -927,16 +926,6 @@ public class ResolvableTypeTests {
assertThat(ResolvableType.forClass(classType).getSuperType().getSource(), equalTo((Object) classType.getGenericSuperclass()));
}
- private void assertFieldToStringValue(String field, String expected) throws Exception {
- ResolvableType type = ResolvableType.forField(Fields.class.getField(field));
- assertThat("field " + field + " toString", type.toString(), equalTo(expected));
- }
-
- private void assertTypedFieldToStringValue(String field, String expected) throws Exception {
- ResolvableType type = ResolvableType.forField(Fields.class.getField(field), TypedFields.class);
- assertThat("field " + field + " toString", type.toString(), equalTo(expected));
- }
-
@Test
public void resolveFromOuterClass() throws Exception {
Field field = EnclosedInParameterizedType.InnerTyped.class.getField("field");
@@ -954,7 +943,6 @@ public class ResolvableTypeTests {
assertThat(type.asCollection().getGeneric().getGeneric().resolve(), equalTo((Type) String.class));
}
-
@Test
public void isAssignableFromMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
@@ -1189,18 +1177,17 @@ public class ResolvableTypeTests {
assertThat(forFieldDirect, not(equalTo(forFieldWithImplementation)));
}
- @SuppressWarnings("unused")
- private HashMap<Integer, List<String>> myMap;
-
@Test
public void javaDocSample() throws Exception {
ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
+ assertThat(t.toString(), equalTo("java.util.HashMap<java.lang.Integer, java.util.List<java.lang.String>>"));
+ assertThat(t.getType().getTypeName(), equalTo("java.util.HashMap<java.lang.Integer, java.util.List<java.lang.String>>"));
assertThat(t.getSuperType().toString(), equalTo("java.util.AbstractMap<java.lang.Integer, java.util.List<java.lang.String>>"));
assertThat(t.asMap().toString(), equalTo("java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>"));
- assertThat(t.getGeneric(0).resolve(), equalTo((Class)Integer.class));
- assertThat(t.getGeneric(1).resolve(), equalTo((Class)List.class));
+ assertThat(t.getGeneric(0).resolve(), equalTo(Integer.class));
+ assertThat(t.getGeneric(1).resolve(), equalTo(List.class));
assertThat(t.getGeneric(1).toString(), equalTo("java.util.List<java.lang.String>"));
- assertThat(t.resolveGeneric(1, 0), equalTo((Class) String.class));
+ assertThat(t.resolveGeneric(1, 0), equalTo(String.class));
}
@Test
@@ -1208,6 +1195,7 @@ public class ResolvableTypeTests {
ResolvableType elementType = ResolvableType.forClassWithGenerics(Map.class, Integer.class, String.class);
ResolvableType listType = ResolvableType.forClassWithGenerics(List.class, elementType);
assertThat(listType.toString(), equalTo("java.util.List<java.util.Map<java.lang.Integer, java.lang.String>>"));
+ assertThat(listType.getType().getTypeName(), equalTo("java.util.List<java.util.Map<java.lang.Integer, java.lang.String>>"));
}
@Test
@@ -1228,7 +1216,7 @@ public class ResolvableTypeTests {
ResolvableType elementType = ResolvableType.forField(Fields.class.getField("stringList"));
ResolvableType type = ResolvableType.forArrayComponent(elementType);
assertThat(type.toString(), equalTo("java.util.List<java.lang.String>[]"));
- assertThat(type.resolve(), equalTo((Class) List[].class));
+ assertThat(type.resolve(), equalTo(List[].class));
}
@Test
@@ -1248,14 +1236,14 @@ public class ResolvableTypeTests {
@Test
public void canResolveVoid() throws Exception {
ResolvableType type = ResolvableType.forClass(void.class);
- assertThat(type.resolve(), equalTo((Class) void.class));
+ assertThat(type.resolve(), equalTo(void.class));
}
@Test
public void narrow() throws Exception {
ResolvableType type = ResolvableType.forField(Fields.class.getField("stringList"));
ResolvableType narrow = ResolvableType.forType(ArrayList.class, type);
- assertThat(narrow.getGeneric().resolve(), equalTo((Class) String.class));
+ assertThat(narrow.getGeneric().resolve(), equalTo(String.class));
}
@Test
@@ -1330,23 +1318,30 @@ public class ResolvableTypeTests {
ResolvableType read = (ResolvableType) ois.readObject();
assertThat(read, equalTo(type));
assertThat(read.getType(), equalTo(type.getType()));
- assertThat(read.resolve(), equalTo((Class) type.resolve()));
+ assertThat(read.resolve(), equalTo(type.resolve()));
return read;
}
- private static AssertAssignbleMatcher assertAssignable(final ResolvableType type, final ResolvableType... fromTypes) {
- return new AssertAssignbleMatcher() {
- @Override
- public void equalTo(boolean... values) {
- for (int i = 0; i < fromTypes.length; i++) {
- assertThat(stringDesc(type) + " isAssignableFrom " + stringDesc(fromTypes[i]),
- type.isAssignableFrom(fromTypes[i]), Matchers.equalTo(values[i]));
- }
+ private void assertFieldToStringValue(String field, String expected) throws Exception {
+ ResolvableType type = ResolvableType.forField(Fields.class.getField(field));
+ assertThat("field " + field + " toString", type.toString(), equalTo(expected));
+ }
+
+ private void assertTypedFieldToStringValue(String field, String expected) throws Exception {
+ ResolvableType type = ResolvableType.forField(Fields.class.getField(field), TypedFields.class);
+ assertThat("field " + field + " toString", type.toString(), equalTo(expected));
+ }
+
+ private AssertAssignbleMatcher assertAssignable(final ResolvableType type, final ResolvableType... fromTypes) {
+ return values -> {
+ for (int i = 0; i < fromTypes.length; i++) {
+ assertThat(stringDesc(type) + " isAssignableFrom " + stringDesc(fromTypes[i]),
+ type.isAssignableFrom(fromTypes[i]), equalTo(values[i]));
}
};
}
- private static String stringDesc(ResolvableType type) {
+ private String stringDesc(ResolvableType type) {
if (type == ResolvableType.NONE) {
return "NONE";
}
@@ -1357,7 +1352,11 @@ public class ResolvableTypeTests {
}
- private static interface AssertAssignbleMatcher {
+ @SuppressWarnings("unused")
+ private HashMap<Integer, List<String>> myMap;
+
+
+ private interface AssertAssignbleMatcher {
void equalTo(boolean... values);
}
diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java
index ca033bb1..620668bf 100644
--- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java
+++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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,7 +22,6 @@ import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
@@ -38,7 +37,6 @@ import org.springframework.core.Ordered;
import org.springframework.core.annotation.subpackage.NonPublicAnnotatedClass;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
import static java.util.Arrays.*;
import static java.util.stream.Collectors.*;
@@ -63,23 +61,8 @@ public class AnnotationUtilsTests {
@Before
- public void clearCachesBeforeTests() {
- clearCaches();
- }
-
- static void clearCaches() {
- clearCache("findAnnotationCache", "annotatedInterfaceCache", "metaPresentCache", "synthesizableCache",
- "attributeAliasesCache", "attributeMethodsCache", "aliasDescriptorCache");
- }
-
- static void clearCache(String... cacheNames) {
- stream(cacheNames).forEach(cacheName -> getCache(cacheName).clear());
- }
-
- static Map<?, ?> getCache(String cacheName) {
- Field field = ReflectionUtils.findField(AnnotationUtils.class, cacheName);
- ReflectionUtils.makeAccessible(field);
- return (Map<?, ?>) ReflectionUtils.getField(field, null);
+ public void clearCacheBeforeTests() {
+ AnnotationUtils.clearCache();
}
@@ -727,7 +710,7 @@ public class AnnotationUtilsTests {
public void getAttributeOverrideNameFromWrongTargetAnnotation() throws Exception {
Method attribute = AliasedComposedContextConfig.class.getDeclaredMethod("xmlConfigFile");
assertThat("xmlConfigFile is not an alias for @Component.",
- getAttributeOverrideName(attribute, Component.class), is(nullValue()));
+ getAttributeOverrideName(attribute, Component.class), is(nullValue()));
}
@Test
@@ -861,12 +844,6 @@ public class AnnotationUtilsTests {
}
@Test
- public void synthesizeAnnotationsFromNullSources() throws Exception {
- assertNull("null annotation", synthesizeAnnotation(null, null));
- assertNull("null map", synthesizeAnnotation(null, WebMapping.class, null));
- }
-
- @Test
public void synthesizeAlreadySynthesizedAnnotation() throws Exception {
Method method = WebController.class.getMethod("handleMappedWithValueAttribute");
WebMapping webMapping = method.getAnnotation(WebMapping.class);
@@ -927,7 +904,6 @@ public class AnnotationUtilsTests {
public void synthesizeAnnotationWithAttributeAliasWithMirroredAliasForWrongAttribute() throws Exception {
AliasForWithMirroredAliasForWrongAttribute annotation =
AliasForWithMirroredAliasForWrongAttributeClass.class.getAnnotation(AliasForWithMirroredAliasForWrongAttribute.class);
-
exception.expect(AnnotationConfigurationException.class);
exception.expectMessage(startsWith("Attribute 'bar' in"));
exception.expectMessage(containsString(AliasForWithMirroredAliasForWrongAttribute.class.getName()));
@@ -1035,18 +1011,18 @@ public class AnnotationUtilsTests {
@Test
public void synthesizeAnnotationWithImplicitAliasesWithImpliedAliasNamesOmitted() throws Exception {
assertAnnotationSynthesisWithImplicitAliasesWithImpliedAliasNamesOmitted(
- ValueImplicitAliasesWithImpliedAliasNamesOmittedContextConfigClass.class, "value");
+ ValueImplicitAliasesWithImpliedAliasNamesOmittedContextConfigClass.class, "value");
assertAnnotationSynthesisWithImplicitAliasesWithImpliedAliasNamesOmitted(
- LocationsImplicitAliasesWithImpliedAliasNamesOmittedContextConfigClass.class, "location");
+ LocationsImplicitAliasesWithImpliedAliasNamesOmittedContextConfigClass.class, "location");
assertAnnotationSynthesisWithImplicitAliasesWithImpliedAliasNamesOmitted(
- XmlFilesImplicitAliasesWithImpliedAliasNamesOmittedContextConfigClass.class, "xmlFile");
+ XmlFilesImplicitAliasesWithImpliedAliasNamesOmittedContextConfigClass.class, "xmlFile");
}
- private void assertAnnotationSynthesisWithImplicitAliasesWithImpliedAliasNamesOmitted(Class<?> clazz,
- String expected) throws Exception {
+ private void assertAnnotationSynthesisWithImplicitAliasesWithImpliedAliasNamesOmitted(
+ Class<?> clazz, String expected) {
ImplicitAliasesWithImpliedAliasNamesOmittedContextConfig config = clazz.getAnnotation(
- ImplicitAliasesWithImpliedAliasNamesOmittedContextConfig.class);
+ ImplicitAliasesWithImpliedAliasNamesOmittedContextConfig.class);
assertNotNull(config);
ImplicitAliasesWithImpliedAliasNamesOmittedContextConfig synthesizedConfig = synthesizeAnnotation(config);
@@ -1241,9 +1217,11 @@ public class AnnotationUtilsTests {
assertEquals("location: ", "", contextConfig.location());
}
- @Test(expected = AnnotationConfigurationException.class)
- public void synthesizeAnnotationWithAttributeAliasesDifferentValues() throws Exception {
- getValue(synthesizeAnnotation(ContextConfigMismatch.class.getAnnotation(ContextConfig.class)));
+ @Test
+ public void synthesizeAnnotationWithAttributeAliasesWithDifferentValues() throws Exception {
+ ContextConfig contextConfig = synthesizeAnnotation(ContextConfigMismatch.class.getAnnotation(ContextConfig.class));
+ exception.expect(AnnotationConfigurationException.class);
+ getValue(contextConfig);
}
@Test
diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MapAnnotationAttributeExtractorTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MapAnnotationAttributeExtractorTests.java
index d3b45602..3fa90396 100644
--- a/spring-core/src/test/java/org/springframework/core/annotation/MapAnnotationAttributeExtractorTests.java
+++ b/spring-core/src/test/java/org/springframework/core/annotation/MapAnnotationAttributeExtractorTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -17,6 +17,7 @@
package org.springframework.core.annotation;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -25,9 +26,6 @@ import java.util.Map;
import org.junit.Before;
import org.junit.Test;
-import org.springframework.core.annotation.AnnotationUtilsTests.ImplicitAliasesContextConfig;
-import org.springframework.core.annotation.AnnotationUtilsTests.RequestMethod;
-import org.springframework.core.annotation.AnnotationUtilsTests.WebMapping;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -44,14 +42,21 @@ import static org.springframework.core.annotation.AnnotationUtilsTests.*;
@SuppressWarnings("serial")
public class MapAnnotationAttributeExtractorTests extends AbstractAliasAwareAnnotationAttributeExtractorTestCase {
+ @Override
+ protected AnnotationAttributeExtractor<?> createExtractorFor(Class<?> clazz, String expected, Class<? extends Annotation> annotationType) {
+ Map<String, Object> attributes = Collections.singletonMap(expected, expected);
+ return new MapAnnotationAttributeExtractor(attributes, annotationType, clazz);
+ }
+
@Before
- public void clearCachesBeforeTests() {
- AnnotationUtilsTests.clearCaches();
+ public void clearCacheBeforeTests() {
+ AnnotationUtils.clearCache();
}
+
@Test
- public void enrichAndValidateAttributesWithImplicitAliasesAndMinimalAttributes() {
- Map<String, Object> attributes = new HashMap<String, Object>();
+ public void enrichAndValidateAttributesWithImplicitAliasesAndMinimalAttributes() throws Exception {
+ Map<String, Object> attributes = new HashMap<>();
Map<String, Object> expectedAttributes = new HashMap<String, Object>() {{
put("groovyScript", "");
put("xmlFile", "");
@@ -67,7 +72,7 @@ public class MapAnnotationAttributeExtractorTests extends AbstractAliasAwareAnno
}
@Test
- public void enrichAndValidateAttributesWithImplicitAliases() {
+ public void enrichAndValidateAttributesWithImplicitAliases() throws Exception {
Map<String, Object> attributes = new HashMap<String, Object>() {{
put("groovyScript", "groovy!");
}};
@@ -88,7 +93,6 @@ public class MapAnnotationAttributeExtractorTests extends AbstractAliasAwareAnno
@Test
public void enrichAndValidateAttributesWithSingleElementThatOverridesAnArray() {
- // @formatter:off
Map<String, Object> attributes = new HashMap<String, Object>() {{
// Intentionally storing 'value' as a single String instead of an array.
// put("value", asArray("/foo"));
@@ -102,7 +106,6 @@ public class MapAnnotationAttributeExtractorTests extends AbstractAliasAwareAnno
put("name", "test");
put("method", new RequestMethod[0]);
}};
- // @formatter:on
MapAnnotationAttributeExtractor extractor = new MapAnnotationAttributeExtractor(attributes, WebMapping.class, null);
Map<String, Object> enriched = extractor.getSource();
@@ -112,22 +115,21 @@ public class MapAnnotationAttributeExtractorTests extends AbstractAliasAwareAnno
}
@SuppressWarnings("unchecked")
- private void assertEnrichAndValidateAttributes(Map<String, Object> sourceAttributes, Map<String, Object> expected) {
+ private void assertEnrichAndValidateAttributes(Map<String, Object> sourceAttributes, Map<String, Object> expected) throws Exception {
Class<? extends Annotation> annotationType = ImplicitAliasesContextConfig.class;
- // Since the ordering of attribute methods returned by the JVM is
- // non-deterministic, we have to rig the attributeAliasesCache in AnnotationUtils
- // so that the tests consistently fail in case enrichAndValidateAttributes() is
- // buggy.
- //
- // Otherwise, these tests would intermittently pass even for an invalid
- // implementation.
+ // Since the ordering of attribute methods returned by the JVM is non-deterministic,
+ // we have to rig the attributeAliasesCache in AnnotationUtils so that the tests
+ // consistently fail in case enrichAndValidateAttributes() is buggy.
+ // Otherwise, these tests would intermittently pass even for an invalid implementation.
+ Field cacheField = AnnotationUtils.class.getDeclaredField("attributeAliasesCache");
+ cacheField.setAccessible(true);
Map<Class<? extends Annotation>, MultiValueMap<String, String>> attributeAliasesCache =
- (Map<Class<? extends Annotation>, MultiValueMap<String, String>>) AnnotationUtilsTests.getCache("attributeAliasesCache");
+ (Map<Class<? extends Annotation>, MultiValueMap<String, String>>) cacheField.get(null);
// Declare aliases in an order that will cause enrichAndValidateAttributes() to
// fail unless it considers all aliases in the set of implicit aliases.
- MultiValueMap<String, String> aliases = new LinkedMultiValueMap<String, String>();
+ MultiValueMap<String, String> aliases = new LinkedMultiValueMap<>();
aliases.put("xmlFile", Arrays.asList("value", "groovyScript", "location1", "location2", "location3"));
aliases.put("groovyScript", Arrays.asList("value", "xmlFile", "location1", "location2", "location3"));
aliases.put("value", Arrays.asList("xmlFile", "groovyScript", "location1", "location2", "location3"));
@@ -144,10 +146,4 @@ public class MapAnnotationAttributeExtractorTests extends AbstractAliasAwareAnno
expected.forEach((attr, expectedValue) -> assertThat("for attribute '" + attr + "'", enriched.get(attr), is(expectedValue)));
}
- @Override
- protected AnnotationAttributeExtractor<?> createExtractorFor(Class<?> clazz, String expected, Class<? extends Annotation> annotationType) {
- Map<String, Object> attributes = Collections.singletonMap(expected, expected);
- return new MapAnnotationAttributeExtractor(attributes, annotationType, clazz);
- }
-
}
diff --git a/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java
index 2f377fc0..66aaf24f 100644
--- a/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java
+++ b/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -294,9 +294,9 @@ public class AnnotationMetadataTests {
assertEquals("direct", method.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"));
assertEquals("direct", method.getAnnotationAttributes(DirectAnnotation.class.getName()).get("myValue"));
List<Object> allMeta = method.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
- assertThat(new HashSet<Object>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
+ assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
allMeta = method.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("additional");
- assertThat(new HashSet<Object>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct")))));
+ assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct")))));
assertTrue(metadata.isAnnotated(IsAnnotatedAnnotation.class.getName()));
@@ -309,36 +309,36 @@ public class AnnotationMetadataTests {
AnnotationAttributes nestedAnno = specialAttrs.getAnnotation("nestedAnno");
assertThat("na", is(nestedAnno.getString("value")));
assertTrue(nestedAnno.getEnum("anEnum").equals(SomeEnum.LABEL1));
- assertArrayEquals(new Class[] { String.class }, (Class[]) nestedAnno.get("classArray"));
+ assertArrayEquals(new Class<?>[] {String.class}, (Class<?>[]) nestedAnno.get("classArray"));
AnnotationAttributes[] nestedAnnoArray = specialAttrs.getAnnotationArray("nestedAnnoArray");
assertThat(nestedAnnoArray.length, is(2));
assertThat(nestedAnnoArray[0].getString("value"), is("default"));
assertTrue(nestedAnnoArray[0].getEnum("anEnum").equals(SomeEnum.DEFAULT));
- assertArrayEquals(new Class[] { Void.class }, (Class[]) nestedAnnoArray[0].get("classArray"));
+ assertArrayEquals(new Class<?>[] {Void.class}, (Class<?>[]) nestedAnnoArray[0].get("classArray"));
assertThat(nestedAnnoArray[1].getString("value"), is("na1"));
assertTrue(nestedAnnoArray[1].getEnum("anEnum").equals(SomeEnum.LABEL2));
- assertArrayEquals(new Class[] { Number.class }, (Class[]) nestedAnnoArray[1].get("classArray"));
- assertArrayEquals(new Class[] { Number.class }, nestedAnnoArray[1].getClassArray("classArray"));
+ assertArrayEquals(new Class<?>[] {Number.class}, (Class<?>[]) nestedAnnoArray[1].get("classArray"));
+ assertArrayEquals(new Class<?>[] {Number.class}, nestedAnnoArray[1].getClassArray("classArray"));
AnnotationAttributes optional = specialAttrs.getAnnotation("optional");
assertThat(optional.getString("value"), is("optional"));
assertTrue(optional.getEnum("anEnum").equals(SomeEnum.DEFAULT));
- assertArrayEquals(new Class[] { Void.class }, (Class[]) optional.get("classArray"));
- assertArrayEquals(new Class[] { Void.class }, optional.getClassArray("classArray"));
+ assertArrayEquals(new Class<?>[] {Void.class}, (Class<?>[]) optional.get("classArray"));
+ assertArrayEquals(new Class<?>[] {Void.class}, optional.getClassArray("classArray"));
AnnotationAttributes[] optionalArray = specialAttrs.getAnnotationArray("optionalArray");
assertThat(optionalArray.length, is(1));
assertThat(optionalArray[0].getString("value"), is("optional"));
assertTrue(optionalArray[0].getEnum("anEnum").equals(SomeEnum.DEFAULT));
- assertArrayEquals(new Class[] { Void.class }, (Class[]) optionalArray[0].get("classArray"));
- assertArrayEquals(new Class[] { Void.class }, optionalArray[0].getClassArray("classArray"));
+ assertArrayEquals(new Class<?>[] {Void.class}, (Class<?>[]) optionalArray[0].get("classArray"));
+ assertArrayEquals(new Class<?>[] {Void.class}, optionalArray[0].getClassArray("classArray"));
assertEquals("direct", metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"));
allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
- assertThat(new HashSet<Object>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
+ assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("additional");
- assertThat(new HashSet<Object>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct")))));
+ assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct")))));
}
{ // perform tests with classValuesAsString = true
AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(
@@ -365,9 +365,9 @@ public class AnnotationMetadataTests {
assertArrayEquals(new String[] { Void.class.getName() }, (String[]) optionalArray[0].get("classArray"));
assertArrayEquals(new String[] { Void.class.getName() }, optionalArray[0].getStringArray("classArray"));
- assertEquals(metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"), "direct");
+ assertEquals("direct", metadata.getAnnotationAttributes(DirectAnnotation.class.getName()).get("value"));
allMeta = metadata.getAllAnnotationAttributes(DirectAnnotation.class.getName()).get("value");
- assertThat(new HashSet<Object>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
+ assertThat(new HashSet<>(allMeta), is(equalTo(new HashSet<Object>(Arrays.asList("direct", "meta")))));
}
}
diff --git a/spring-core/src/test/java/org/springframework/core/type/AnnotationTypeFilterTests.java b/spring-core/src/test/java/org/springframework/core/type/AnnotationTypeFilterTests.java
index 6dd6dace..01a679d6 100644
--- a/spring-core/src/test/java/org/springframework/core/type/AnnotationTypeFilterTests.java
+++ b/spring-core/src/test/java/org/springframework/core/type/AnnotationTypeFilterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -49,7 +49,7 @@ public class AnnotationTypeFilterTests {
@Test
public void testInheritedAnnotationFromInterfaceDoesNotMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
- String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeSubClassOfSomeComponentInterface";
+ String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeClassWithSomeComponentInterface";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
@@ -61,7 +61,7 @@ public class AnnotationTypeFilterTests {
@Test
public void testInheritedAnnotationFromBaseClassDoesMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
- String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeSubClassOfSomeComponent";
+ String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeSubclassOfSomeComponent";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
@@ -94,22 +94,21 @@ public class AnnotationTypeFilterTests {
@Test
public void testMatchesInterfacesIfConfigured() throws Exception {
-
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
- String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeComponentInterface";
+ String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeClassWithSomeComponentInterface";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class, false, true);
-
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
+
// We must use a standalone set of types to ensure that no one else is loading them
// and interfering with ClassloadingAssertions.assertClassNotLoaded()
@Inherited
- private static @interface InheritedAnnotation {
+ private @interface InheritedAnnotation {
}
@@ -119,21 +118,21 @@ public class AnnotationTypeFilterTests {
@InheritedAnnotation
- private static interface SomeComponentInterface {
+ private interface SomeComponentInterface {
}
@SuppressWarnings("unused")
- private static class SomeSubClassOfSomeComponentInterface implements SomeComponentInterface {
+ private static class SomeClassWithSomeComponentInterface implements Cloneable, SomeComponentInterface {
}
@SuppressWarnings("unused")
- private static class SomeSubClassOfSomeComponent extends SomeComponent {
+ private static class SomeSubclassOfSomeComponent extends SomeComponent {
}
- private static @interface NonInheritedAnnotation {
+ private @interface NonInheritedAnnotation {
}
diff --git a/spring-core/src/test/java/org/springframework/core/type/ClassloadingAssertions.java b/spring-core/src/test/java/org/springframework/core/type/ClassloadingAssertions.java
index 16a0e896..53dc8782 100644
--- a/spring-core/src/test/java/org/springframework/core/type/ClassloadingAssertions.java
+++ b/spring-core/src/test/java/org/springframework/core/type/ClassloadingAssertions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.core.type;
import java.lang.reflect.Method;
@@ -30,9 +31,9 @@ abstract class ClassloadingAssertions {
private static boolean isClassLoaded(String className) {
ClassLoader cl = ClassUtils.getDefaultClassLoader();
- Method findLoadeClassMethod = ReflectionUtils.findMethod(cl.getClass(), "findLoadedClass", new Class[] { String.class });
- ReflectionUtils.makeAccessible(findLoadeClassMethod);
- Class<?> loadedClass = (Class<?>) ReflectionUtils.invokeMethod(findLoadeClassMethod, cl, new Object[] { className });
+ Method findLoadedClassMethod = ReflectionUtils.findMethod(cl.getClass(), "findLoadedClass", String.class);
+ ReflectionUtils.makeAccessible(findLoadedClassMethod);
+ Class<?> loadedClass = (Class<?>) ReflectionUtils.invokeMethod(findLoadedClassMethod, cl, className);
return loadedClass != null;
}
@@ -40,4 +41,4 @@ abstract class ClassloadingAssertions {
assertFalse("Class [" + className + "] should not have been loaded", isClassLoaded(className));
}
-} \ No newline at end of file
+}
diff --git a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java
index 32978f57..8786363c 100644
--- a/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java
+++ b/spring-core/src/test/java/org/springframework/util/ClassUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -212,7 +212,7 @@ public class ClassUtilsTests {
assertNotNull(method);
assertEquals("size", method.getName());
- method = ClassUtils.getMethodIfAvailable(Collection.class, "remove", new Class[] {Object.class});
+ method = ClassUtils.getMethodIfAvailable(Collection.class, "remove", Object.class);
assertNotNull(method);
assertEquals("remove", method.getName());
@@ -239,7 +239,7 @@ public class ClassUtilsTests {
@Test
public void testNoArgsStaticMethod() throws IllegalAccessException, InvocationTargetException {
- Method method = ClassUtils.getStaticMethod(InnerClass.class, "staticMethod", (Class[]) null);
+ Method method = ClassUtils.getStaticMethod(InnerClass.class, "staticMethod");
method.invoke(null, (Object[]) null);
assertTrue("no argument method was not invoked.",
InnerClass.noArgCalled);
@@ -247,19 +247,16 @@ public class ClassUtilsTests {
@Test
public void testArgsStaticMethod() throws IllegalAccessException, InvocationTargetException {
- Method method = ClassUtils.getStaticMethod(InnerClass.class, "argStaticMethod",
- new Class[] {String.class});
- method.invoke(null, new Object[] {"test"});
+ Method method = ClassUtils.getStaticMethod(InnerClass.class, "argStaticMethod", String.class);
+ method.invoke(null, "test");
assertTrue("argument method was not invoked.", InnerClass.argCalled);
}
@Test
public void testOverloadedStaticMethod() throws IllegalAccessException, InvocationTargetException {
- Method method = ClassUtils.getStaticMethod(InnerClass.class, "staticMethod",
- new Class[] {String.class});
- method.invoke(null, new Object[] {"test"});
- assertTrue("argument method was not invoked.",
- InnerClass.overloadedCalled);
+ Method method = ClassUtils.getStaticMethod(InnerClass.class, "staticMethod", String.class);
+ method.invoke(null, "test");
+ assertTrue("argument method was not invoked.", InnerClass.overloadedCalled);
}
@Test
diff --git a/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java b/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java
index d585d0ae..5930a283 100644
--- a/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java
+++ b/spring-core/src/test/java/org/springframework/util/ConcurrentReferenceHashMapTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -50,50 +50,50 @@ import static org.junit.Assert.*;
*/
public class ConcurrentReferenceHashMapTests {
- private static final Comparator<? super String> NULL_SAFE_STRING_SORT = new NullSafeComparator<String>(
- new ComparableComparator<String>(), true);
+ private static final Comparator<? super String> NULL_SAFE_STRING_SORT =
+ new NullSafeComparator<String>(new ComparableComparator<String>(), true);
@Rule
public ExpectedException thrown = ExpectedException.none();
- private TestWeakConcurrentCache<Integer, String> map = new TestWeakConcurrentCache<Integer, String>();
+ private TestWeakConcurrentCache<Integer, String> map = new TestWeakConcurrentCache<>();
@Test
- public void shouldCreateWithDefaults() throws Exception {
- ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<Integer, String>();
+ public void shouldCreateWithDefaults() {
+ ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<>();
assertThat(map.getSegmentsSize(), is(16));
assertThat(map.getSegment(0).getSize(), is(1));
assertThat(map.getLoadFactor(), is(0.75f));
}
@Test
- public void shouldCreateWithInitialCapacity() throws Exception {
- ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<Integer, String>(32);
+ public void shouldCreateWithInitialCapacity() {
+ ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<>(32);
assertThat(map.getSegmentsSize(), is(16));
assertThat(map.getSegment(0).getSize(), is(2));
assertThat(map.getLoadFactor(), is(0.75f));
}
@Test
- public void shouldCreateWithInitialCapacityAndLoadFactor() throws Exception {
- ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<Integer, String>(32, 0.5f);
+ public void shouldCreateWithInitialCapacityAndLoadFactor() {
+ ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<>(32, 0.5f);
assertThat(map.getSegmentsSize(), is(16));
assertThat(map.getSegment(0).getSize(), is(2));
assertThat(map.getLoadFactor(), is(0.5f));
}
@Test
- public void shouldCreateWithInitialCapacityAndConcurrenyLevel() throws Exception {
- ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<Integer, String>(16, 2);
+ public void shouldCreateWithInitialCapacityAndConcurrenyLevel() {
+ ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<>(16, 2);
assertThat(map.getSegmentsSize(), is(2));
assertThat(map.getSegment(0).getSize(), is(8));
assertThat(map.getLoadFactor(), is(0.75f));
}
@Test
- public void shouldCreateFullyCustom() throws Exception {
- ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<Integer, String>(5, 0.5f, 3);
+ public void shouldCreateFullyCustom() {
+ ConcurrentReferenceHashMap<Integer, String> map = new ConcurrentReferenceHashMap<>(5, 0.5f, 3);
// concurrencyLevel of 3 ends up as 4 (nearest power of 2)
assertThat(map.getSegmentsSize(), is(4));
// initialCapacity is 5/4 (rounded up, to nearest power of 2)
@@ -102,7 +102,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldNeedNonNegativeInitialCapacity() throws Exception {
+ public void shouldNeedNonNegativeInitialCapacity() {
new ConcurrentReferenceHashMap<Integer, String>(0, 1);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Initial capacity must not be negative");
@@ -110,7 +110,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldNeedPositiveLoadFactor() throws Exception {
+ public void shouldNeedPositiveLoadFactor() {
new ConcurrentReferenceHashMap<Integer, String>(0, 0.1f, 1);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Load factor must be positive");
@@ -118,7 +118,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldNeedPositiveConcurrencyLevel() throws Exception {
+ public void shouldNeedPositiveConcurrencyLevel() {
new ConcurrentReferenceHashMap<Integer, String>(1, 1);
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Concurrency level must be positive");
@@ -126,7 +126,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldPutAndGet() throws Exception {
+ public void shouldPutAndGet() {
// NOTE we are using mock references so we don't need to worry about GC
assertThat(this.map.size(), is(0));
this.map.put(123, "123");
@@ -139,32 +139,40 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldReplaceOnDoublePut() throws Exception {
+ public void shouldReplaceOnDoublePut() {
this.map.put(123, "321");
this.map.put(123, "123");
assertThat(this.map.get(123), is("123"));
}
@Test
- public void shouldPutNullKey() throws Exception {
+ public void shouldPutNullKey() {
+ assertThat(this.map.get(null), is(nullValue()));
+ assertThat(this.map.getOrDefault(null, "456"), is("456"));
this.map.put(null, "123");
assertThat(this.map.get(null), is("123"));
+ assertThat(this.map.getOrDefault(null, "456"), is("123"));
}
@Test
- public void shouldPutNullValue() throws Exception {
+ public void shouldPutNullValue() {
+ assertThat(this.map.get(123), is(nullValue()));
+ assertThat(this.map.getOrDefault(123, "456"), is("456"));
this.map.put(123, "321");
+ assertThat(this.map.get(123), is("321"));
+ assertThat(this.map.getOrDefault(123, "456"), is("321"));
this.map.put(123, null);
assertThat(this.map.get(123), is(nullValue()));
+ assertThat(this.map.getOrDefault(123, "456"), is(nullValue()));
}
@Test
- public void shouldGetWithNoItems() throws Exception {
+ public void shouldGetWithNoItems() {
assertThat(this.map.get(123), is(nullValue()));
}
@Test
- public void shouldApplySupplimentalHash() throws Exception {
+ public void shouldApplySupplimentalHash() {
Integer key = 123;
this.map.put(key, "123");
assertThat(this.map.getSupplimentalHash(), is(not(key.hashCode())));
@@ -172,9 +180,9 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldGetFollowingNexts() throws Exception {
+ public void shouldGetFollowingNexts() {
// Use loadFactor to disable resize
- this.map = new TestWeakConcurrentCache<Integer, String>(1, 10.0f, 1);
+ this.map = new TestWeakConcurrentCache<>(1, 10.0f, 1);
this.map.put(1, "1");
this.map.put(2, "2");
this.map.put(3, "3");
@@ -186,8 +194,8 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldResize() throws Exception {
- this.map = new TestWeakConcurrentCache<Integer, String>(1, 0.75f, 1);
+ public void shouldResize() {
+ this.map = new TestWeakConcurrentCache<>(1, 0.75f, 1);
this.map.put(1, "1");
assertThat(this.map.getSegment(0).getSize(), is(1));
assertThat(this.map.get(1), is("1"));
@@ -216,8 +224,8 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldPurgeOnGet() throws Exception {
- this.map = new TestWeakConcurrentCache<Integer, String>(1, 0.75f, 1);
+ public void shouldPurgeOnGet() {
+ this.map = new TestWeakConcurrentCache<>(1, 0.75f, 1);
for (int i = 1; i <= 5; i++) {
this.map.put(i, String.valueOf(i));
}
@@ -231,8 +239,8 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldPergeOnPut() throws Exception {
- this.map = new TestWeakConcurrentCache<Integer, String>(1, 0.75f, 1);
+ public void shouldPergeOnPut() {
+ this.map = new TestWeakConcurrentCache<>(1, 0.75f, 1);
for (int i = 1; i <= 5; i++) {
this.map.put(i, String.valueOf(i));
}
@@ -247,28 +255,28 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldPutIfAbsent() throws Exception {
+ public void shouldPutIfAbsent() {
assertThat(this.map.putIfAbsent(123, "123"), is(nullValue()));
assertThat(this.map.putIfAbsent(123, "123b"), is("123"));
assertThat(this.map.get(123), is("123"));
}
@Test
- public void shouldPutIfAbsentWithNullValue() throws Exception {
+ public void shouldPutIfAbsentWithNullValue() {
assertThat(this.map.putIfAbsent(123, null), is(nullValue()));
assertThat(this.map.putIfAbsent(123, "123"), is(nullValue()));
assertThat(this.map.get(123), is(nullValue()));
}
@Test
- public void shouldPutIfAbsentWithNullKey() throws Exception {
+ public void shouldPutIfAbsentWithNullKey() {
assertThat(this.map.putIfAbsent(null, "123"), is(nullValue()));
assertThat(this.map.putIfAbsent(null, "123b"), is("123"));
assertThat(this.map.get(null), is("123"));
}
@Test
- public void shouldRemoveKeyAndValue() throws Exception {
+ public void shouldRemoveKeyAndValue() {
this.map.put(123, "123");
assertThat(this.map.remove(123, "456"), is(false));
assertThat(this.map.get(123), is("123"));
@@ -278,7 +286,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldRemoveKeyAndValueWithExistingNull() throws Exception {
+ public void shouldRemoveKeyAndValueWithExistingNull() {
this.map.put(123, null);
assertThat(this.map.remove(123, "456"), is(false));
assertThat(this.map.get(123), is(nullValue()));
@@ -288,7 +296,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldReplaceOldValueWithNewValue() throws Exception {
+ public void shouldReplaceOldValueWithNewValue() {
this.map.put(123, "123");
assertThat(this.map.replace(123, "456", "789"), is(false));
assertThat(this.map.get(123), is("123"));
@@ -297,7 +305,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldReplaceOldNullValueWithNewValue() throws Exception {
+ public void shouldReplaceOldNullValueWithNewValue() {
this.map.put(123, null);
assertThat(this.map.replace(123, "456", "789"), is(false));
assertThat(this.map.get(123), is(nullValue()));
@@ -306,21 +314,21 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldReplaceValue() throws Exception {
+ public void shouldReplaceValue() {
this.map.put(123, "123");
assertThat(this.map.replace(123, "456"), is("123"));
assertThat(this.map.get(123), is("456"));
}
@Test
- public void shouldReplaceNullValue() throws Exception {
+ public void shouldReplaceNullValue() {
this.map.put(123, null);
assertThat(this.map.replace(123, "456"), is(nullValue()));
assertThat(this.map.get(123), is("456"));
}
@Test
- public void shouldGetSize() throws Exception {
+ public void shouldGetSize() {
assertThat(this.map.size(), is(0));
this.map.put(123, "123");
this.map.put(123, null);
@@ -329,7 +337,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldSupportIsEmpty() throws Exception {
+ public void shouldSupportIsEmpty() {
assertThat(this.map.isEmpty(), is(true));
this.map.put(123, "123");
this.map.put(123, null);
@@ -338,7 +346,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldContainKey() throws Exception {
+ public void shouldContainKey() {
assertThat(this.map.containsKey(123), is(false));
assertThat(this.map.containsKey(456), is(false));
this.map.put(123, "123");
@@ -348,7 +356,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldContainValue() throws Exception {
+ public void shouldContainValue() {
assertThat(this.map.containsValue("123"), is(false));
assertThat(this.map.containsValue(null), is(false));
this.map.put(123, "123");
@@ -358,7 +366,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldRemoveWhenKeyIsInMap() throws Exception {
+ public void shouldRemoveWhenKeyIsInMap() {
this.map.put(123, null);
this.map.put(456, "456");
this.map.put(null, "789");
@@ -369,15 +377,15 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldRemoveWhenKeyIsNotInMap() throws Exception {
+ public void shouldRemoveWhenKeyIsNotInMap() {
assertThat(this.map.remove(123), is(nullValue()));
assertThat(this.map.remove(null), is(nullValue()));
assertThat(this.map.isEmpty(), is(true));
}
@Test
- public void shouldPutAll() throws Exception {
- Map<Integer, String> m = new HashMap<Integer, String>();
+ public void shouldPutAll() {
+ Map<Integer, String> m = new HashMap<>();
m.put(123, "123");
m.put(456, null);
m.put(null, "789");
@@ -389,7 +397,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldClear() throws Exception {
+ public void shouldClear() {
this.map.put(123, "123");
this.map.put(456, null);
this.map.put(null, "789");
@@ -401,11 +409,11 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldGetKeySet() throws Exception {
+ public void shouldGetKeySet() {
this.map.put(123, "123");
this.map.put(456, null);
this.map.put(null, "789");
- Set<Integer> expected = new HashSet<Integer>();
+ Set<Integer> expected = new HashSet<>();
expected.add(123);
expected.add(456);
expected.add(null);
@@ -413,26 +421,26 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldGetValues() throws Exception {
+ public void shouldGetValues() {
this.map.put(123, "123");
this.map.put(456, null);
this.map.put(null, "789");
- List<String> actual = new ArrayList<String>(this.map.values());
- List<String> expected = new ArrayList<String>();
+ List<String> actual = new ArrayList<>(this.map.values());
+ List<String> expected = new ArrayList<>();
expected.add("123");
expected.add(null);
expected.add("789");
- Collections.sort(actual, NULL_SAFE_STRING_SORT);
- Collections.sort(expected, NULL_SAFE_STRING_SORT);
+ actual.sort(NULL_SAFE_STRING_SORT);
+ expected.sort(NULL_SAFE_STRING_SORT);
assertThat(actual, is(expected));
}
@Test
- public void shouldGetEntrySet() throws Exception {
+ public void shouldGetEntrySet() {
this.map.put(123, "123");
this.map.put(456, null);
this.map.put(null, "789");
- HashMap<Integer, String> expected = new HashMap<Integer, String>();
+ HashMap<Integer, String> expected = new HashMap<>();
expected.put(123, "123");
expected.put(456, null);
expected.put(null, "789");
@@ -440,13 +448,13 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldGetEntrySetFollowingNext() throws Exception {
+ public void shouldGetEntrySetFollowingNext() {
// Use loadFactor to disable resize
- this.map = new TestWeakConcurrentCache<Integer, String>(1, 10.0f, 1);
+ this.map = new TestWeakConcurrentCache<>(1, 10.0f, 1);
this.map.put(1, "1");
this.map.put(2, "2");
this.map.put(3, "3");
- HashMap<Integer, String> expected = new HashMap<Integer, String>();
+ HashMap<Integer, String> expected = new HashMap<>();
expected.put(1, "1");
expected.put(2, "2");
expected.put(3, "3");
@@ -454,7 +462,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldRemoveViaEntrySet() throws Exception {
+ public void shouldRemoveViaEntrySet() {
this.map.put(1, "1");
this.map.put(2, "2");
this.map.put(3, "3");
@@ -469,7 +477,7 @@ public class ConcurrentReferenceHashMapTests {
}
@Test
- public void shouldSetViaEntrySet() throws Exception {
+ public void shouldSetViaEntrySet() {
this.map.put(1, "1");
this.map.put(2, "2");
this.map.put(3, "3");
@@ -484,36 +492,21 @@ public class ConcurrentReferenceHashMapTests {
@Test
@Ignore("Intended for use during development only")
- public void shouldBeFasterThanSynchronizedMap() throws Exception {
+ public void shouldBeFasterThanSynchronizedMap() throws InterruptedException {
Map<Integer, WeakReference<String>> synchronizedMap = Collections.synchronizedMap(new WeakHashMap<Integer, WeakReference<String>>());
- StopWatch mapTime = timeMultiThreaded("SynchronizedMap", synchronizedMap,
- new ValueFactory<WeakReference<String>>() {
-
- @Override
- public WeakReference<String> newValue(int v) {
- return new WeakReference<String>(String.valueOf(v));
- }
- });
+ StopWatch mapTime = timeMultiThreaded("SynchronizedMap", synchronizedMap, v -> new WeakReference<>(String.valueOf(v)));
System.out.println(mapTime.prettyPrint());
this.map.setDisableTestHooks(true);
- StopWatch cacheTime = timeMultiThreaded("WeakConcurrentCache", this.map,
- new ValueFactory<String>() {
-
- @Override
- public String newValue(int v) {
- return String.valueOf(v);
- }
- });
+ StopWatch cacheTime = timeMultiThreaded("WeakConcurrentCache", this.map, String::valueOf);
System.out.println(cacheTime.prettyPrint());
// We should be at least 4 time faster
- assertThat(cacheTime.getTotalTimeSeconds(),
- is(lessThan(mapTime.getTotalTimeSeconds() / 4.0)));
+ assertThat(cacheTime.getTotalTimeSeconds(), is(lessThan(mapTime.getTotalTimeSeconds() / 4.0)));
}
@Test
- public void shouldSupportNullReference() throws Exception {
+ public void shouldSupportNullReference() {
// GC could happen during restructure so we must be able to create a reference for a null entry
map.createReferenceManager().createReference(null, 1234, null);
}
@@ -557,7 +550,7 @@ public class ConcurrentReferenceHashMapTests {
}
- private static interface ValueFactory<V> {
+ private interface ValueFactory<V> {
V newValue(int k);
}
@@ -567,7 +560,7 @@ public class ConcurrentReferenceHashMapTests {
private int supplimentalHash;
- private final LinkedList<MockReference<K, V>> queue = new LinkedList<MockReference<K, V>>();
+ private final LinkedList<MockReference<K, V>> queue = new LinkedList<>();
private boolean disableTestHooks;
@@ -605,12 +598,11 @@ public class ConcurrentReferenceHashMapTests {
protected ReferenceManager createReferenceManager() {
return new ReferenceManager() {
@Override
- public Reference<K, V> createReference(Entry<K, V> entry, int hash,
- Reference<K, V> next) {
+ public Reference<K, V> createReference(Entry<K, V> entry, int hash, Reference<K, V> next) {
if (TestWeakConcurrentCache.this.disableTestHooks) {
return super.createReference(entry, hash, next);
}
- return new MockReference<K, V>(entry, hash, next, TestWeakConcurrentCache.this.queue);
+ return new MockReference<>(entry, hash, next, TestWeakConcurrentCache.this.queue);
}
@Override
public Reference<K, V> pollForPurge() {
diff --git a/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java b/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java
index 43420d36..f855a5f2 100644
--- a/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java
+++ b/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -27,7 +27,7 @@ import org.junit.Test;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
-import static java.util.Collections.singletonMap;
+import static java.util.Collections.*;
import static org.junit.Assert.*;
/**
@@ -70,7 +70,7 @@ public class MimeTypeTests {
}
@Test
- public void parseCharset() throws Exception {
+ public void parseCharset() {
String s = "text/html; charset=iso-8859-1";
MimeType mimeType = MimeType.valueOf(s);
assertEquals("Invalid type", "text", mimeType.getType());
@@ -106,7 +106,7 @@ public class MimeTypeTests {
}
@Test
- public void includes() throws Exception {
+ public void includes() {
MimeType textPlain = MimeTypeUtils.TEXT_PLAIN;
assertTrue("Equal types is not inclusive", textPlain.includes(textPlain));
MimeType allText = new MimeType("text");
@@ -133,7 +133,7 @@ public class MimeTypeTests {
}
@Test
- public void isCompatible() throws Exception {
+ public void isCompatible() {
MimeType textPlain = MimeTypeUtils.TEXT_PLAIN;
assertTrue("Equal types is not compatible", textPlain.isCompatibleWith(textPlain));
MimeType allText = new MimeType("text");
@@ -160,14 +160,14 @@ public class MimeTypeTests {
}
@Test
- public void testToString() throws Exception {
+ public void testToString() {
MimeType mimeType = new MimeType("text", "plain");
String result = mimeType.toString();
assertEquals("Invalid toString() returned", "text/plain", result);
}
@Test
- public void parseMimeType() throws Exception {
+ public void parseMimeType() {
String s = "audio/*";
MimeType mimeType = MimeTypeUtils.parseMimeType(s);
assertEquals("Invalid type", "audio", mimeType.getType());
@@ -200,7 +200,7 @@ public class MimeTypeTests {
}
@Test(expected = InvalidMimeTypeException.class)
- public void parseMimeTypeMissingTypeAndSubtype() throws Exception {
+ public void parseMimeTypeMissingTypeAndSubtype() {
MimeTypeUtils.parseMimeType(" ;a=b");
}
@@ -229,31 +229,37 @@ public class MimeTypeTests {
MimeTypeUtils.parseMimeType("text/html; charset=foo-bar");
}
- /**
- * SPR-8917
- */
- @Test
+ @Test // SPR-8917
public void parseMimeTypeQuotedParameterValue() {
MimeType mimeType = MimeTypeUtils.parseMimeType("audio/*;attr=\"v>alue\"");
assertEquals("\"v>alue\"", mimeType.getParameter("attr"));
}
- /**
- * SPR-8917
- */
- @Test
+ @Test // SPR-8917
public void parseMimeTypeSingleQuotedParameterValue() {
MimeType mimeType = MimeTypeUtils.parseMimeType("audio/*;attr='v>alue'");
assertEquals("'v>alue'", mimeType.getParameter("attr"));
}
+ @Test // SPR-16630
+ public void parseMimeTypeWithSpacesAroundEquals() {
+ MimeType mimeType = MimeTypeUtils.parseMimeType("multipart/x-mixed-replace;boundary = --myboundary");
+ assertEquals("--myboundary", mimeType.getParameter("boundary"));
+ }
+
+ @Test // SPR-16630
+ public void parseMimeTypeWithSpacesAroundEqualsAndQuotedValue() {
+ MimeType mimeType = MimeTypeUtils.parseMimeType("text/plain; foo = \" bar \" ");
+ assertEquals("\" bar \"", mimeType.getParameter("foo"));
+ }
+
@Test(expected = InvalidMimeTypeException.class)
public void parseMimeTypeIllegalQuotedParameterValue() {
MimeTypeUtils.parseMimeType("audio/*;attr=\"");
}
@Test
- public void parseMimeTypes() throws Exception {
+ public void parseMimeTypes() {
String s = "text/plain, text/html, text/x-dvi, text/x-c";
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes(s);
assertNotNull("No mime types returned", mimeTypes);
@@ -325,6 +331,8 @@ public class MimeTypeTests {
MimeType m2 = new MimeType("text", "plain", singletonMap("charset", "utf-8"));
assertEquals(m1, m2);
assertEquals(m2, m1);
+ assertEquals(0, m1.compareTo(m2));
+ assertEquals(0, m2.compareTo(m1));
}
}
diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java
index 07bc3a0d..d11ea1f7 100644
--- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java
+++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -60,10 +60,10 @@ public class ObjectUtilsTests {
@Test
public void isCompatibleWithThrowsClause() {
- Class<?>[] empty = new Class[0];
- Class<?>[] exception = new Class[] {Exception.class};
- Class<?>[] sqlAndIO = new Class[] {SQLException.class, IOException.class};
- Class<?>[] throwable = new Class[] {Throwable.class};
+ Class<?>[] empty = new Class<?>[0];
+ Class<?>[] exception = new Class<?>[] {Exception.class};
+ Class<?>[] sqlAndIO = new Class<?>[] {SQLException.class, IOException.class};
+ Class<?>[] throwable = new Class<?>[] {Throwable.class};
assertTrue(ObjectUtils.isCompatibleWithThrowsClause(new RuntimeException()));
assertTrue(ObjectUtils.isCompatibleWithThrowsClause(new RuntimeException(), empty));
@@ -110,7 +110,7 @@ public class ObjectUtilsTests {
assertTrue(isEmpty(Collections.emptyList()));
assertTrue(isEmpty(Collections.emptySet()));
- Set<String> set = new HashSet<String>();
+ Set<String> set = new HashSet<>();
set.add("foo");
assertFalse(isEmpty(set));
assertFalse(isEmpty(Arrays.asList("foo")));
@@ -120,7 +120,7 @@ public class ObjectUtilsTests {
public void isEmptyMap() {
assertTrue(isEmpty(Collections.emptyMap()));
- HashMap<String, Object> map = new HashMap<String, Object>();
+ HashMap<String, Object> map = new HashMap<>();
map.put("foo", 42L);
assertFalse(isEmpty(map));
}
@@ -239,18 +239,21 @@ public class ObjectUtilsTests {
}
@Test
+ @Deprecated
public void hashCodeWithBooleanFalse() {
int expected = Boolean.FALSE.hashCode();
assertEquals(expected, ObjectUtils.hashCode(false));
}
@Test
+ @Deprecated
public void hashCodeWithBooleanTrue() {
int expected = Boolean.TRUE.hashCode();
assertEquals(expected, ObjectUtils.hashCode(true));
}
@Test
+ @Deprecated
public void hashCodeWithDouble() {
double dbl = 9830.43;
int expected = (new Double(dbl)).hashCode();
@@ -258,6 +261,7 @@ public class ObjectUtilsTests {
}
@Test
+ @Deprecated
public void hashCodeWithFloat() {
float flt = 34.8f;
int expected = (new Float(flt)).hashCode();
@@ -265,6 +269,7 @@ public class ObjectUtilsTests {
}
@Test
+ @Deprecated
public void hashCodeWithLong() {
long lng = 883l;
int expected = (new Long(lng)).hashCode();
diff --git a/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java
index 3c0c8f84..5cd04e36 100644
--- a/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java
+++ b/spring-core/src/test/java/org/springframework/util/ReflectionUtilsTests.java
@@ -86,7 +86,7 @@ public class ReflectionUtilsTests {
TestObject bean = new TestObject();
bean.setName(rob);
- Method getName = TestObject.class.getMethod("getName", (Class[]) null);
+ Method getName = TestObject.class.getMethod("getName");
Method setName = TestObject.class.getMethod("setName", String.class);
Object name = ReflectionUtils.invokeMethod(getName, bean);
diff --git a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java
index 8ccffe38..61e996b4 100644
--- a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java
+++ b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -443,6 +443,7 @@ public class StringUtilsTests {
}
@Test
+ @Deprecated
public void testMergeStringArrays() {
String[] input1 = new String[] {"myString2"};
String[] input2 = new String[] {"myString1", "myString2"};