The {@link MapValues options} may be used to change the way that values are added.
- * @param options map value options
+ * Create a new mutable {@link AnnotationAttributes} instance from this
+ * merged annotation.
+ *
The {@link Adapt adaptations} may be used to change the way that values
+ * are added.
+ * @param adaptations adaptations that should be applied to the annotation values
* @return an immutable map containing the attributes and values
*/
- Map asMap(MapValues... options);
+ AnnotationAttributes asAnnotationAttributes(Adapt... adaptations);
/**
- * Create a {@link Map} of the given type that contains all the annotation attributes.
- * The {@link MapValues options} may be used to change the way that values are added.
+ * Return an immutable {@link Map} that contains all the annotation attributes.
+ *
The {@link Adapt adaptations} may be used to change the way that values are added.
+ * @param adaptations adaptations that should be applied to the annotation values
+ * @return an immutable map containing the attributes and values
+ */
+ Map asMap(Adapt... adaptations);
+
+ /**
+ * Create a new {@link Map} instance of the given type that contains all the annotation
+ * attributes.
+ * The {@link Adapt adaptations} may be used to change the way that values are added.
* @param factory a map factory
- * @param options map value options
+ * @param adaptations adaptations that should be applied to the annotation values
* @return a map containing the attributes and values
*/
- > T asMap(Function, T> factory, MapValues... options);
+ > T asMap(Function, T> factory, Adapt... adaptations);
/**
* Create a type-safe synthesized version of this annotation that can be
@@ -539,24 +550,25 @@ public interface MergedAnnotation {
/**
- * Options that effect the way map values are
- * {@linkplain MergedAnnotation#asMap(MapValues...) converted}.
+ * Adaptations that can be applied to attributes values when creating
+ * {@linkplain MergedAnnotation#asMap(Adapt...) Maps} or
+ * {@link MergedAnnotation#asAnnotationAttributes(Adapt...) AnnotationAttributes}.
*/
- enum MapValues {
+ enum Adapt {
/**
- * Add class or class array attributes as strings.
+ * Adapt class or class array attributes to strings.
*/
CLASS_TO_STRING,
/**
- * Convert any nested annotation or annotation arrays to maps rather
+ * Adapt nested annotation or annotation arrays to maps rather
* than synthesizing the values.
*/
ANNOTATION_TO_MAP;
- protected final boolean isIn(MapValues... options) {
- for (MapValues candidate : options) {
+ protected final boolean isIn(Adapt... adaptations) {
+ for (Adapt candidate : adaptations) {
if (candidate == this) {
return true;
}
@@ -565,16 +577,16 @@ public interface MergedAnnotation {
}
/**
- * Factory method to create a {@link MapValues} array from a set of boolean flags.
- * @param classToString if {@link MapValues#CLASS_TO_STRING} is included
- * @param annotationsToMap if {@link MapValues#ANNOTATION_TO_MAP} is included
- * @return a new {@link MapValues} array
+ * Factory method to create a {@link Adapt} array from a set of boolean flags.
+ * @param classToString if {@link Adapt#CLASS_TO_STRING} is included
+ * @param annotationsToMap if {@link Adapt#ANNOTATION_TO_MAP} is included
+ * @return a new {@link Adapt} array
*/
- public static MapValues[] of(boolean classToString, boolean annotationsToMap) {
- EnumSet result = EnumSet.noneOf(MapValues.class);
- addIfTrue(result, MapValues.CLASS_TO_STRING, classToString);
- addIfTrue(result, MapValues.ANNOTATION_TO_MAP, annotationsToMap);
- return result.toArray(new MapValues[0]);
+ public static Adapt[] values(boolean classToString, boolean annotationsToMap) {
+ EnumSet result = EnumSet.noneOf(Adapt.class);
+ addIfTrue(result, Adapt.CLASS_TO_STRING, classToString);
+ addIfTrue(result, Adapt.ANNOTATION_TO_MAP, annotationsToMap);
+ return result.toArray(new Adapt[0]);
}
private static void addIfTrue(Set result, T value, boolean test) {
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationCollectors.java b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationCollectors.java
index 242932c61d..c448f1cd29 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationCollectors.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationCollectors.java
@@ -26,7 +26,7 @@ import java.util.function.IntFunction;
import java.util.stream.Collector;
import java.util.stream.Collector.Characteristics;
-import org.springframework.core.annotation.MergedAnnotation.MapValues;
+import org.springframework.core.annotation.MergedAnnotation.Adapt;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -97,39 +97,39 @@ public abstract class MergedAnnotationCollectors {
* Create a new {@link Collector} that accumulates merged annotations to an
* {@link MultiValueMap} with items {@linkplain MultiValueMap#add(Object, Object)
* added} from each merged annotation
- * {@link MergedAnnotation#asMap(MapValues...) as a map}.
+ * {@link MergedAnnotation#asMap(Adapt...) as a map}.
* @param the annotation type
- * @param options the map conversion options
+ * @param adaptations adaptations that should be applied to the annotation values
* @return a {@link Collector} which collects and synthesizes the
* annotations into a {@link LinkedMultiValueMap}
- * @see #toMultiValueMap(Function, MergedAnnotation.MapValues...)
+ * @see #toMultiValueMap(Function, MergedAnnotation.Adapt...)
*/
public static Collector, ?, MultiValueMap> toMultiValueMap(
- MapValues... options) {
+ Adapt... adaptations) {
- return toMultiValueMap(Function.identity(), options);
+ return toMultiValueMap(Function.identity(), adaptations);
}
/**
* Create a new {@link Collector} that accumulates merged annotations to an
* {@link MultiValueMap} with items {@linkplain MultiValueMap#add(Object, Object)
* added} from each merged annotation
- * {@link MergedAnnotation#asMap(MapValues...) as a map}.
+ * {@link MergedAnnotation#asMap(Adapt...) as a map}.
* @param the annotation type
- * @param options the map conversion options
+ * @param adaptations adaptations that should be applied to the annotation values
* @param finisher the finisher function for the new {@link MultiValueMap}
* @return a {@link Collector} which collects and synthesizes the
* annotations into a {@link LinkedMultiValueMap}
- * @see #toMultiValueMap(MergedAnnotation.MapValues...)
+ * @see #toMultiValueMap(MergedAnnotation.Adapt...)
*/
public static Collector, ?, MultiValueMap> toMultiValueMap(
Function, MultiValueMap> finisher,
- MapValues... options) {
+ Adapt... adaptations) {
Characteristics[] characteristics = (isSameInstance(finisher, Function.identity()) ?
IDENTITY_FINISH_CHARACTERISTICS : NO_CHARACTERISTICS);
return Collector.of(LinkedMultiValueMap::new,
- (map, annotation) -> annotation.asMap(options).forEach(map::add),
+ (map, annotation) -> annotation.asMap(adaptations).forEach(map::add),
MergedAnnotationCollectors::merge, finisher, characteristics);
}
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/MissingMergedAnnotation.java b/spring-core/src/main/java/org/springframework/core/annotation/MissingMergedAnnotation.java
index 46b32b99de..0c780e1c23 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/MissingMergedAnnotation.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/MissingMergedAnnotation.java
@@ -108,12 +108,17 @@ final class MissingMergedAnnotation extends AbstractMerged
}
@Override
- public Map asMap(MapValues... options) {
+ public AnnotationAttributes asAnnotationAttributes(Adapt... adaptations) {
+ return new AnnotationAttributes();
+ }
+
+ @Override
+ public Map asMap(Adapt... adaptations) {
return Collections.emptyMap();
}
@Override
- public > T asMap(Function, T> factory, MapValues... options) {
+ public > T asMap(Function, T> factory, Adapt... adaptations) {
return factory.apply(this);
}
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java b/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java
index 83c8e029c0..645a66e2bc 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java
@@ -233,50 +233,50 @@ final class TypeMappedAnnotation extends AbstractMergedAnn
}
@Override
- public Map asMap(MapValues... options) {
- return Collections.unmodifiableMap(asMap(mergedAnnotation -> new LinkedHashMap<>(), options));
+ public Map asMap(Adapt... adaptations) {
+ return Collections.unmodifiableMap(asMap(mergedAnnotation -> new LinkedHashMap<>(), adaptations));
}
@Override
- public > T asMap(Function, T> factory, MapValues... options) {
+ public > T asMap(Function, T> factory, Adapt... adaptations) {
T map = factory.apply(this);
Assert.state(map != null, "Factory used to create MergedAnnotation Map must not return null");
AttributeMethods attributes = this.mapping.getAttributes();
for (int i = 0; i < attributes.size(); i++) {
Method attribute = attributes.get(i);
Object value = (isFiltered(attribute.getName()) ? null :
- getValue(i, getTypeForMapOptions(attribute, options)));
+ getValue(i, getTypeForMapOptions(attribute, adaptations)));
if (value != null) {
map.put(attribute.getName(),
- adaptValueForMapOptions(attribute, value, map.getClass(), factory, options));
+ adaptValueForMapOptions(attribute, value, map.getClass(), factory, adaptations));
}
}
return map;
}
- private Class> getTypeForMapOptions(Method attribute, MapValues[] options) {
+ private Class> getTypeForMapOptions(Method attribute, Adapt[] adaptations) {
Class> attributeType = attribute.getReturnType();
Class> componentType = (attributeType.isArray() ? attributeType.getComponentType() : attributeType);
- if (MapValues.CLASS_TO_STRING.isIn(options) && componentType == Class.class) {
+ if (Adapt.CLASS_TO_STRING.isIn(adaptations) && componentType == Class.class) {
return (attributeType.isArray() ? String[].class : String.class);
}
return Object.class;
}
private > Object adaptValueForMapOptions(Method attribute, Object value,
- Class> mapType, Function, T> factory, MapValues[] options) {
+ Class> mapType, Function, T> factory, Adapt[] adaptations) {
if (value instanceof MergedAnnotation) {
MergedAnnotation> annotation = (MergedAnnotation>) value;
- return (MapValues.ANNOTATION_TO_MAP.isIn(options) ?
- annotation.asMap(factory, options) : annotation.synthesize());
+ return (Adapt.ANNOTATION_TO_MAP.isIn(adaptations) ?
+ annotation.asMap(factory, adaptations) : annotation.synthesize());
}
if (value instanceof MergedAnnotation[]) {
MergedAnnotation>[] annotations = (MergedAnnotation>[]) value;
- if (MapValues.ANNOTATION_TO_MAP.isIn(options)) {
+ if (Adapt.ANNOTATION_TO_MAP.isIn(adaptations)) {
Object result = Array.newInstance(mapType, annotations.length);
for (int i = 0; i < annotations.length; i++) {
- Array.set(result, i, annotations[i].asMap(factory, options));
+ Array.set(result, i, annotations[i].asMap(factory, adaptations));
}
return result;
}
diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationCollectorsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationCollectorsTests.java
index b8d547b202..ee2af352ff 100644
--- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationCollectorsTests.java
+++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationCollectorsTests.java
@@ -27,7 +27,7 @@ import java.util.stream.Stream;
import org.junit.Test;
-import org.springframework.core.annotation.MergedAnnotation.MapValues;
+import org.springframework.core.annotation.MergedAnnotation.Adapt;
import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.*;
@@ -72,7 +72,7 @@ public class MergedAnnotationCollectorsTests {
MultiValueMap map = stream().map(
MergedAnnotation::filterDefaultValues).collect(
MergedAnnotationCollectors.toMultiValueMap(
- MapValues.CLASS_TO_STRING));
+ Adapt.CLASS_TO_STRING));
assertThat(map.get("value")).containsExactly("a", "b", "c");
assertThat(map.get("extra")).containsExactly("java.lang.String",
"java.lang.Integer");
diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java
index 3533aba940..595f510717 100644
--- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java
+++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java
@@ -40,7 +40,7 @@ import org.junit.Test;
import org.junit.internal.ArrayComparisonFailure;
import org.springframework.core.Ordered;
-import org.springframework.core.annotation.MergedAnnotation.MapValues;
+import org.springframework.core.annotation.MergedAnnotation.Adapt;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.annotation.subpackage.NonPublicAnnotatedClass;
import org.springframework.lang.Nullable;
@@ -1665,7 +1665,7 @@ public class MergedAnnotationsTests {
assertThat(componentScan.value().pattern()).isEqualTo("*Foo");
Map map = MergedAnnotation.from(componentScan).asMap(
annotation -> new LinkedHashMap(),
- MapValues.ANNOTATION_TO_MAP);
+ Adapt.ANNOTATION_TO_MAP);
Map filterMap = (Map) map.get("value");
assertThat(filterMap.get("pattern")).isEqualTo("*Foo");
filterMap.put("pattern", "newFoo");
@@ -1685,7 +1685,7 @@ public class MergedAnnotationsTests {
assertThat(componentScan).isNotNull();
Map map = MergedAnnotation.from(componentScan).asMap(
annotation -> new LinkedHashMap(),
- MapValues.ANNOTATION_TO_MAP);
+ Adapt.ANNOTATION_TO_MAP);
Map[] filters = (Map[]) map.get("excludeFilters");
List patterns = Arrays.stream(filters).map(
m -> (String) m.get("pattern")).collect(Collectors.toList());
@@ -2053,6 +2053,17 @@ public class MergedAnnotationsTests {
"FromValueAttributeMeta");
}
+ @Test
+ public void asAnnotationAttributesReturnsPopulatedAnnotationAttributes() {
+ MergedAnnotation> annotation = MergedAnnotations.from(
+ SpringApplicationConfigurationClass.class).get(
+ SpringApplicationConfiguration.class);
+ AnnotationAttributes attributes = annotation.asAnnotationAttributes(
+ Adapt.CLASS_TO_STRING);
+ assertThat(attributes).containsEntry("classes", new String[] { Number.class.getName() });
+ assertThat(attributes.annotationType()).isEqualTo(SpringApplicationConfiguration.class);
+ }
+
// @formatter:off
@Retention(RetentionPolicy.RUNTIME)
diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MissingMergedAnnotationTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MissingMergedAnnotationTests.java
index aeac3813dc..8fee0117c0 100644
--- a/spring-core/src/test/java/org/springframework/core/annotation/MissingMergedAnnotationTests.java
+++ b/spring-core/src/test/java/org/springframework/core/annotation/MissingMergedAnnotationTests.java
@@ -264,6 +264,13 @@ public class MissingMergedAnnotationTests {
assertThat(this.missing.toString()).isEqualTo("(missing)");
}
+ @Test
+ public void asAnnotationAttributesReturnsNewAnnotationAttributes() {
+ AnnotationAttributes attributes = this.missing.asAnnotationAttributes();
+ assertThat(attributes).isEmpty();
+ assertThat(this.missing.asAnnotationAttributes()).isNotSameAs(attributes);
+ }
+
@Test
public void asMapReturnsEmptyMap() {
Map map = this.missing.asMap();