diff options
author | Denis <denis@vaadin.com> | 2017-01-25 16:34:02 +0200 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2017-01-25 16:34:02 +0200 |
commit | fb2ceee075473e10eb94f0c49bc5f4b36836174d (patch) | |
tree | b3a8c02eb1d45958f54b58f311ddc91e1d50c774 /server | |
parent | 0b67c1c9c93d6db3dabf52fc4e7d43f8edabb31f (diff) | |
download | vaadin-framework-fb2ceee075473e10eb94f0c49bc5f4b36836174d.tar.gz vaadin-framework-fb2ceee075473e10eb94f0c49bc5f4b36836174d.zip |
Extract Bean validation logic from Binder to BeanValidationBinder
Fixes #8253
Diffstat (limited to 'server')
8 files changed, 94 insertions, 43 deletions
diff --git a/server/src/main/java/com/vaadin/data/BeanBinderPropertySet.java b/server/src/main/java/com/vaadin/data/BeanBinderPropertySet.java index f28873438e..d5fb2b4f5d 100644 --- a/server/src/main/java/com/vaadin/data/BeanBinderPropertySet.java +++ b/server/src/main/java/com/vaadin/data/BeanBinderPropertySet.java @@ -30,9 +30,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.util.BeanUtil; -import com.vaadin.data.validator.BeanValidator; import com.vaadin.server.Setter; import com.vaadin.util.ReflectTools; @@ -153,17 +151,6 @@ public class BeanBinderPropertySet<T> implements BinderPropertySet<T> { } @Override - public BindingBuilder<T, V> beforeBind( - BindingBuilder<T, V> originalBuilder) { - if (BeanUtil.checkBeanValidationAvailable()) { - return originalBuilder.withValidator(new BeanValidator( - getPropertySet().beanType, descriptor.getName())); - } else { - return originalBuilder; - } - } - - @Override public String getName() { return descriptor.getName(); } diff --git a/server/src/main/java/com/vaadin/data/BeanValidationBinder.java b/server/src/main/java/com/vaadin/data/BeanValidationBinder.java new file mode 100644 index 0000000000..5e3b220ffd --- /dev/null +++ b/server/src/main/java/com/vaadin/data/BeanValidationBinder.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data; + +import com.vaadin.data.util.BeanUtil; +import com.vaadin.data.validator.BeanValidator; + +/** + * @author Vaadin Ltd + * @see Binder + * @see HasValue + * + * @since 8.0 + */ +public class BeanValidationBinder<BEAN> extends Binder<BEAN> { + + private final Class<BEAN> beanType; + + /** + * Creates a new binder that uses reflection based on the provided bean type + * to resolve bean properties. It assumes that JSR-303 bean validation + * implementation is present on the classpath. If there is no such + * implementation available then {@link Binder} class should be used instead + * (this constructor will throw an exception). Otherwise + * {@link BeanValidator} is added to each binding that is defined using a + * property name. + * + * @param beanType + * the bean type to use, not <code>null</code> + */ + public BeanValidationBinder(Class<BEAN> beanType) { + super(beanType); + if (!BeanUtil.checkBeanValidationAvailable()) { + throw new IllegalStateException( + BeanValidationBinder.class.getSimpleName() + + " cannot be used because a JSR-303 Bean Validation " + + "implementation not found on the classpath. Use " + + Binder.class.getSimpleName() + " instead"); + } + this.beanType = beanType; + } + + @Override + protected BindingBuilder<BEAN, ?> configureBinding( + BindingBuilder<BEAN, ?> binding, + BinderPropertyDefinition<BEAN, ?> definition) { + return binding.withValidator( + new BeanValidator(beanType, definition.getName())); + } +} diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index 7451c004ed..4cbcd18eb1 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -619,13 +619,14 @@ public class Binder<BEAN> implements Serializable { // Setter ignores value }); - BindingBuilder finalBinding = withConverter( + BindingBuilder<BEAN, ?> finalBinding = withConverter( createConverter(definition.getType()), false); - finalBinding = definition.beforeBind(finalBinding); + finalBinding = getBinder().configureBinding(finalBinding, + definition); try { - return finalBinding.bind(getter, setter); + return ((BindingBuilder) finalBinding).bind(getter, setter); } finally { getBinder().boundProperties.add(propertyName); getBinder().incompleteMemberFieldBindings.remove(getField()); @@ -1085,9 +1086,7 @@ public class Binder<BEAN> implements Serializable { /** * Creates a new binder that uses reflection based on the provided bean type - * to resolve bean properties. If a JSR-303 bean validation implementation - * is present on the classpath, a {@link BeanValidator} is added to each - * binding that is defined using a property name. + * to resolve bean properties. * * @param beanType * the bean type to use, not <code>null</code> @@ -1937,6 +1936,22 @@ public class Binder<BEAN> implements Serializable { return eventRouter; } + /** + * Configures the {@code binding} with the property definition + * {@code definition} before it's being bound. + * + * @param binding + * a binding to configure + * @param definition + * a property definition information + * @return the new configured binding + */ + protected BindingBuilder<BEAN, ?> configureBinding( + BindingBuilder<BEAN, ?> binding, + BinderPropertyDefinition<BEAN, ?> definition) { + return binding; + } + private void doRemoveBean(boolean fireStatusEvent) { setHasChanges(false); if (bean != null) { diff --git a/server/src/main/java/com/vaadin/data/BinderPropertyDefinition.java b/server/src/main/java/com/vaadin/data/BinderPropertyDefinition.java index 7ab7e1ccec..b4145a8c4f 100644 --- a/server/src/main/java/com/vaadin/data/BinderPropertyDefinition.java +++ b/server/src/main/java/com/vaadin/data/BinderPropertyDefinition.java @@ -18,7 +18,6 @@ package com.vaadin.data; import java.io.Serializable; import java.util.Optional; -import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.server.Setter; /** @@ -56,20 +55,6 @@ public interface BinderPropertyDefinition<T, V> extends Serializable { public Class<V> getType(); /** - * Hook for modifying a binding before it is being bound to this property. - * This method can return the provided {@link BindingBuilder} as-is if no - * modifications are necessary. - * - * @param originalBuilder - * the original binding builder that is being bound, not - * <code>null</code> - * @return the binding builder to use for creating the binding, not - * <code>null</code> - */ - public BindingBuilder<T, V> beforeBind( - BindingBuilder<T, V> originalBuilder); - - /** * Gets the name of this property. * * @return the property name, not <code>null</code> diff --git a/server/src/main/java/com/vaadin/data/validator/BeanValidator.java b/server/src/main/java/com/vaadin/data/validator/BeanValidator.java index 3d7baa05a0..097b47cb0f 100644 --- a/server/src/main/java/com/vaadin/data/validator/BeanValidator.java +++ b/server/src/main/java/com/vaadin/data/validator/BeanValidator.java @@ -91,7 +91,7 @@ public class BeanValidator implements Validator<Object> { if (!BeanUtil.checkBeanValidationAvailable()) { throw new IllegalStateException("Cannot create a " + BeanValidator.class.getSimpleName() - + ": a JSR-303 Bean Validation implementation not found on theclasspath"); + + ": a JSR-303 Bean Validation implementation not found on the classpath"); } Objects.requireNonNull(beanType, "bean class cannot be null"); Objects.requireNonNull(propertyName, "property name cannot be null"); diff --git a/server/src/test/java/com/vaadin/data/BeanBinderTest.java b/server/src/test/java/com/vaadin/data/BeanBinderTest.java index 6bd53044b7..2103c2b132 100644 --- a/server/src/test/java/com/vaadin/data/BeanBinderTest.java +++ b/server/src/test/java/com/vaadin/data/BeanBinderTest.java @@ -48,7 +48,7 @@ public class BeanBinderTest @Before public void setUp() { - binder = new Binder<>(BeanToValidate.class); + binder = new BeanValidationBinder<>(BeanToValidate.class); item = new BeanToValidate(); item.setFirstname("Johannes"); item.setAge(32); diff --git a/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java b/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java index 3d85084bc6..d8ebf4da10 100644 --- a/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java +++ b/server/src/test/java/com/vaadin/data/BinderCustomPropertySetTest.java @@ -23,7 +23,6 @@ import java.util.stream.Stream; import org.junit.Assert; import org.junit.Test; -import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.server.Setter; import com.vaadin.ui.TextField; @@ -61,12 +60,6 @@ public class BinderCustomPropertySetTest { } @Override - public BindingBuilder<Map<String, String>, String> beforeBind( - BindingBuilder<Map<String, String>, String> originalBuilder) { - return originalBuilder; - } - - @Override public String getName() { return name; } diff --git a/server/src/test/java/com/vaadin/data/Jsr303Test.java b/server/src/test/java/com/vaadin/data/Jsr303Test.java index 43b03feb97..c907bd2af0 100644 --- a/server/src/test/java/com/vaadin/data/Jsr303Test.java +++ b/server/src/test/java/com/vaadin/data/Jsr303Test.java @@ -98,6 +98,14 @@ public class Jsr303Test { // BeanToValidate : @Size(min = 3, max = 16) for the firstName nameField.setValue("a"); assertEquals(nameField.getValue(), item.getFirstname()); + + try { + BeanValidationBinder<BeanToValidate> beanValidationBinder = new BeanValidationBinder<>( + BeanToValidate.class); + Assert.fail(); + } catch (IllegalStateException ignore) { + // an exception has to be thrown + } } } |