Skip to content

Commit

Permalink
Fix validation when key matching the prefix is set
Browse files Browse the repository at this point in the history
  • Loading branch information
mbhave committed Jan 2, 2019
1 parent d1e1a82 commit 161635e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.util.ClassUtils;

/**
* {@link BindHandler} that can be used to ignore top-level
Expand All @@ -32,6 +33,11 @@
*/
public class IgnoreTopLevelConverterNotFoundBindHandler extends AbstractBindHandler {

/**
* Top-level exception type that can be ignored.
*/
public static final Class<?> IGNORABLE_EXCEPTION = ConverterNotFoundException.class;

/**
* Create a new {@link IgnoreTopLevelConverterNotFoundBindHandler} instance.
*/
Expand All @@ -49,7 +55,8 @@ public IgnoreTopLevelConverterNotFoundBindHandler(BindHandler parent) {
@Override
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target,
BindContext context, Exception error) throws Exception {
if (context.getDepth() == 0 && error instanceof ConverterNotFoundException) {
if (context.getDepth() == 0
&& ClassUtils.isAssignableValue(IGNORABLE_EXCEPTION, error)) {
return null;
}
throw error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
import org.springframework.boot.context.properties.bind.BindContext;
import org.springframework.boot.context.properties.bind.BindHandler;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.handler.IgnoreTopLevelConverterNotFoundBindHandler;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.util.ClassUtils;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
Expand Down Expand Up @@ -76,6 +78,19 @@ public void onFinish(ConfigurationPropertyName name, Bindable<?> target,
super.onFinish(name, target, context, result);
}

@Override
public Object onFailure(ConfigurationPropertyName name, Bindable<?> target,
BindContext context, Exception error) throws Exception {
if (context.getDepth() == 0 && ClassUtils.isAssignableValue(
IgnoreTopLevelConverterNotFoundBindHandler.IGNORABLE_EXCEPTION, error)) {
validate(name, target, context, null);
if (!this.exceptions.isEmpty()) {
throw this.exceptions.pop();
}
}
return super.onFailure(name, target, context, error);
}

private void validate(ConfigurationPropertyName name, Bindable<?> target,
BindContext context, Object result) {
Object validationTarget = getValidationTarget(target, context, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@ public void bindShouldNotValidateDepthGreaterThanZero() {
this.handler);
}

@Test
public void bindShouldValidateWhenTopLevelPropertyFailsWithIgnorableException() {
this.sources.add(new MockConfigurationPropertySource("foo", "hello"));
ExampleValidatedBean bean = new ExampleValidatedBean();
assertThatExceptionOfType(BindException.class)
.isThrownBy(
() -> this.binder.bind("foo",
Bindable.of(ExampleValidatedBean.class)
.withExistingValue(bean),
this.handler))
.withCauseInstanceOf(BindValidationException.class);
}

private BindValidationException bindAndExpectValidationError(Runnable action) {
try {
action.run();
Expand Down

0 comments on commit 161635e

Please sign in to comment.