Merge pull request #23146 from otaconix

* pr/23146:
  Polish 'Support nested @PropertyMapping annotations'
  Support nested @PropertyMapping annotations

Closes gh-23146
pull/28993/head
Phillip Webb 4 years ago
commit 10ab477426

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -73,10 +73,10 @@ public class AnnotationsPropertySource extends EnumerablePropertySource<Class<?>
return properties; return properties;
} }
private void collectProperties(String prefix, SkipPropertyMapping defaultSkip, MergedAnnotation<?> annotation, private void collectProperties(String prefix, SkipPropertyMapping skip, MergedAnnotation<?> annotation,
Method attribute, Map<String, Object> properties) { Method attribute, Map<String, Object> properties) {
MergedAnnotation<?> attributeMapping = MergedAnnotations.from(attribute).get(PropertyMapping.class); MergedAnnotation<?> attributeMapping = MergedAnnotations.from(attribute).get(PropertyMapping.class);
SkipPropertyMapping skip = attributeMapping.getValue("skip", SkipPropertyMapping.class).orElse(defaultSkip); skip = attributeMapping.getValue("skip", SkipPropertyMapping.class).orElse(skip);
if (skip == SkipPropertyMapping.YES) { if (skip == SkipPropertyMapping.YES) {
return; return;
} }
@ -90,7 +90,7 @@ public class AnnotationsPropertySource extends EnumerablePropertySource<Class<?>
} }
} }
String name = getName(prefix, attributeMapping, attribute); String name = getName(prefix, attributeMapping, attribute);
putProperties(name, value.get(), properties); putProperties(name, skip, value.get(), properties);
} }
private String getName(String prefix, MergedAnnotation<?> attributeMapping, Method attribute) { private String getName(String prefix, MergedAnnotation<?> attributeMapping, Method attribute) {
@ -118,11 +118,18 @@ public class AnnotationsPropertySource extends EnumerablePropertySource<Class<?>
return postfix; return postfix;
} }
private void putProperties(String name, Object value, Map<String, Object> properties) { private void putProperties(String name, SkipPropertyMapping defaultSkip, Object value,
Map<String, Object> properties) {
if (ObjectUtils.isArray(value)) { if (ObjectUtils.isArray(value)) {
Object[] array = ObjectUtils.toObjectArray(value); Object[] array = ObjectUtils.toObjectArray(value);
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
properties.put(name + "[" + i + "]", array[i]); putProperties(name + "[" + i + "]", defaultSkip, array[i], properties);
}
}
else if (value instanceof MergedAnnotation<?>) {
MergedAnnotation<?> annotation = (MergedAnnotation<?>) value;
for (Method attribute : annotation.getType().getDeclaredMethods()) {
collectProperties(name, defaultSkip, (MergedAnnotation<?>) value, attribute, properties);
} }
} }
else { else {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,9 @@ import java.lang.annotation.RetentionPolicy;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.properties.AnnotationsPropertySourceTests.DeeplyNestedAnnotations.Level1;
import org.springframework.boot.test.autoconfigure.properties.AnnotationsPropertySourceTests.DeeplyNestedAnnotations.Level2;
import org.springframework.boot.test.autoconfigure.properties.AnnotationsPropertySourceTests.NestedAnnotations.Entry;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -172,6 +175,26 @@ class AnnotationsPropertySourceTests {
assertThat(source.containsProperty("testenum.value")).isFalse(); assertThat(source.containsProperty("testenum.value")).isFalse();
} }
@Test
void nestedAnnotationsMapped() {
AnnotationsPropertySource source = new AnnotationsPropertySource(PropertyMappedWithNestedAnnotations.class);
assertThat(source.getProperty("testnested")).isNull();
assertThat(source.getProperty("testnested.entries[0]")).isNull();
assertThat(source.getProperty("testnested.entries[0].value")).isEqualTo("one");
assertThat(source.getProperty("testnested.entries[1]")).isNull();
assertThat(source.getProperty("testnested.entries[1].value")).isEqualTo("two");
}
@Test
void deeplyNestedAnnotationsMapped() {
AnnotationsPropertySource source = new AnnotationsPropertySource(
PropertyMappedWithDeeplyNestedAnnotations.class);
assertThat(source.getProperty("testdeeplynested")).isNull();
assertThat(source.getProperty("testdeeplynested.level1")).isNull();
assertThat(source.getProperty("testdeeplynested.level1.level2")).isNull();
assertThat(source.getProperty("testdeeplynested.level1.level2.value")).isEqualTo("level2");
}
static class NoAnnotation { static class NoAnnotation {
} }
@ -396,4 +419,51 @@ class AnnotationsPropertySourceTests {
} }
@Retention(RetentionPolicy.RUNTIME)
@PropertyMapping("testnested")
@interface NestedAnnotations {
Entry[] entries();
@Retention(RetentionPolicy.RUNTIME)
@interface Entry {
String value();
}
}
@NestedAnnotations(entries = { @Entry("one"), @Entry("two") })
static class PropertyMappedWithNestedAnnotations {
}
@Retention(RetentionPolicy.RUNTIME)
@PropertyMapping("testdeeplynested")
@interface DeeplyNestedAnnotations {
Level1 level1();
@Retention(RetentionPolicy.RUNTIME)
@interface Level1 {
Level2 level2();
}
@Retention(RetentionPolicy.RUNTIME)
@interface Level2 {
String value();
}
}
@DeeplyNestedAnnotations(level1 = @Level1(level2 = @Level2("level2")))
static class PropertyMappedWithDeeplyNestedAnnotations {
}
} }

Loading…
Cancel
Save