Browse Source

Ignore nested with NoUnboundElementsBindHandler

Update `NoUnboundElementsBindHandler` to also support ignoring
nested properties. This change is required to allow the
`NoUnboundElementsBindHandler` to be used alongside the
`IgnoreNestedPropertiesBindHandler`.

See gh-9000
pull/9050/merge
Phillip Webb 9 years ago
parent
commit
35a51e45d8
  1. 3
      spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java
  2. 20
      spring-boot/src/main/java/org/springframework/boot/context/properties/bind/handler/NoUnboundElementsBindHandler.java
  3. 31
      spring-boot/src/test/java/org/springframework/boot/context/properties/bind/handler/NoUnboundElementsBindHandlerTests.java

3
spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java

@ -411,7 +411,8 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc @@ -411,7 +411,8 @@ public class ConfigurationPropertiesBindingPostProcessor implements BeanPostProc
handler = new IgnoreErrorsBindHandler(handler);
}
if (!annotation.ignoreUnknownFields()) {
handler = new NoUnboundElementsBindHandler(handler);
handler = new NoUnboundElementsBindHandler(handler,
annotation.ignoreNestedProperties());
}
if (annotation.ignoreNestedProperties()) {
handler = new IgnoreNestedPropertiesBindHandler(handler);

20
spring-boot/src/main/java/org/springframework/boot/context/properties/bind/handler/NoUnboundElementsBindHandler.java

@ -40,14 +40,28 @@ import org.springframework.boot.context.properties.source.IterableConfigurationP @@ -40,14 +40,28 @@ import org.springframework.boot.context.properties.source.IterableConfigurationP
*/
public class NoUnboundElementsBindHandler extends AbstractBindHandler {
private final boolean ignoreNested;
private final Set<ConfigurationPropertyName> boundNames = new HashSet<>();
public NoUnboundElementsBindHandler() {
super();
this.ignoreNested = false;
}
public NoUnboundElementsBindHandler(boolean ignoreNested) {
super();
this.ignoreNested = ignoreNested;
}
public NoUnboundElementsBindHandler(BindHandler parent) {
super(parent);
this.ignoreNested = false;
}
public NoUnboundElementsBindHandler(BindHandler parent, boolean ignoreNested) {
super(parent);
this.ignoreNested = ignoreNested;
}
@Override
@ -96,7 +110,11 @@ public class NoUnboundElementsBindHandler extends AbstractBindHandler { @@ -96,7 +110,11 @@ public class NoUnboundElementsBindHandler extends AbstractBindHandler {
private boolean isUnbound(ConfigurationPropertyName name,
ConfigurationPropertyName candidate) {
return name.isAncestorOf(candidate) && !this.boundNames.contains(candidate);
boolean isParent = candidate.getParent() != null
&& name.equals(candidate.getParent());
boolean isAncestor = name.isAncestorOf(candidate);
return ((this.ignoreNested ? isParent : isAncestor)
&& !this.boundNames.contains(candidate));
}
}

31
spring-boot/src/test/java/org/springframework/boot/context/properties/bind/handler/NoUnboundElementsBindHandlerTests.java

@ -103,6 +103,37 @@ public class NoUnboundElementsBindHandlerTests { @@ -103,6 +103,37 @@ public class NoUnboundElementsBindHandlerTests {
assertThat(bound.getFoo()).isEqualTo("bar");
}
@Test
public void bindWhenUsingNoUnboundElementsHandlerIgnoreNestedAndUnboundChildShouldThrowException()
throws Exception {
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("example.foo", "bar");
source.put("example.baz", "bar");
this.sources.add(source);
this.binder = new Binder(this.sources);
try {
this.binder.bind("example", Bindable.of(Example.class),
new NoUnboundElementsBindHandler(true));
fail("did not throw");
}
catch (BindException ex) {
assertThat(ex.getCause().getMessage())
.contains("The elements [example.baz] were left unbound");
}
}
@Test
public void bindWhenUsingNoUnboundElementsHandlerIgnoreNestedAndUnboundGrandchildShouldBind()
throws Exception {
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("example.foo", "bar");
source.put("example.foo.baz", "bar");
this.sources.add(source);
this.binder = new Binder(this.sources);
this.binder.bind("example", Bindable.of(Example.class),
new NoUnboundElementsBindHandler(true));
}
public static class Example {
private String foo;

Loading…
Cancel
Save