diff options
author | Leif Åstrand <legioth@gmail.com> | 2016-12-05 13:15:08 +0200 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2016-12-05 13:15:08 +0200 |
commit | c7b84bf51d343867cb82a34b81cfdf0461d0919c (patch) | |
tree | 5f7e4c0cd989350121a382422e8267f7159bdc62 | |
parent | 0cef38513b58f4b486dfb1c0e3c154eed6039743 (diff) | |
download | vaadin-framework-c7b84bf51d343867cb82a34b81cfdf0461d0919c.tar.gz vaadin-framework-c7b84bf51d343867cb82a34b81cfdf0461d0919c.zip |
Separate Binding and BindingBuilder (#80)
BindingBinder is API that is used before calling bind()
Binding is API that is used after calling bind()
14 files changed, 306 insertions, 216 deletions
diff --git a/server/src/main/java/com/vaadin/data/BeanBinder.java b/server/src/main/java/com/vaadin/data/BeanBinder.java index 068b681d9c..22761c2cd7 100644 --- a/server/src/main/java/com/vaadin/data/BeanBinder.java +++ b/server/src/main/java/com/vaadin/data/BeanBinder.java @@ -66,74 +66,76 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * @param <TARGET> * the target property type */ - public interface BeanBinding<BEAN, TARGET> extends Binding<BEAN, TARGET> { + public interface BeanBindingBuilder<BEAN, TARGET> + extends BindingBuilder<BEAN, TARGET> { @Override - public BeanBinding<BEAN, TARGET> withValidator( + public BeanBindingBuilder<BEAN, TARGET> withValidator( Validator<? super TARGET> validator); @Override - public default BeanBinding<BEAN, TARGET> withValidator( + public default BeanBindingBuilder<BEAN, TARGET> withValidator( SerializablePredicate<? super TARGET> predicate, String message) { - return (BeanBinding<BEAN, TARGET>) Binding.super.withValidator( + return (BeanBindingBuilder<BEAN, TARGET>) BindingBuilder.super.withValidator( predicate, message); } @Override - default BeanBinding<BEAN, TARGET> withValidator( + default BeanBindingBuilder<BEAN, TARGET> withValidator( SerializablePredicate<? super TARGET> predicate, ErrorMessageProvider errorMessageProvider) { - return (BeanBinding<BEAN, TARGET>) Binding.super.withValidator( + return (BeanBindingBuilder<BEAN, TARGET>) BindingBuilder.super.withValidator( predicate, errorMessageProvider); } @Override - default BeanBinding<BEAN, TARGET> withNullRepresentation( + default BeanBindingBuilder<BEAN, TARGET> withNullRepresentation( TARGET nullRepresentation) { - return (BeanBinding<BEAN, TARGET>) Binding.super.withNullRepresentation( + return (BeanBindingBuilder<BEAN, TARGET>) BindingBuilder.super.withNullRepresentation( nullRepresentation); } @Override - public BeanBinding<BEAN, TARGET> setRequired( + public BeanBindingBuilder<BEAN, TARGET> setRequired( ErrorMessageProvider errorMessageProvider); @Override - public default BeanBinding<BEAN, TARGET> setRequired( + public default BeanBindingBuilder<BEAN, TARGET> setRequired( String errorMessage) { - return (BeanBinding<BEAN, TARGET>) Binding.super.setRequired( + return (BeanBindingBuilder<BEAN, TARGET>) BindingBuilder.super.setRequired( errorMessage); } @Override - public <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter( + public <NEWTARGET> BeanBindingBuilder<BEAN, NEWTARGET> withConverter( Converter<TARGET, NEWTARGET> converter); @Override - public default <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter( + public default <NEWTARGET> BeanBindingBuilder<BEAN, NEWTARGET> withConverter( SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<NEWTARGET, TARGET> toPresentation) { - return (BeanBinding<BEAN, NEWTARGET>) Binding.super.withConverter( + return (BeanBindingBuilder<BEAN, NEWTARGET>) BindingBuilder.super.withConverter( toModel, toPresentation); } @Override - public default <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter( + public default <NEWTARGET> BeanBindingBuilder<BEAN, NEWTARGET> withConverter( SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<NEWTARGET, TARGET> toPresentation, String errorMessage) { - return (BeanBinding<BEAN, NEWTARGET>) Binding.super.withConverter( + return (BeanBindingBuilder<BEAN, NEWTARGET>) BindingBuilder.super.withConverter( toModel, toPresentation, errorMessage); } @Override - public BeanBinding<BEAN, TARGET> withValidationStatusHandler( + public BeanBindingBuilder<BEAN, TARGET> withValidationStatusHandler( ValidationStatusHandler handler); @Override - public default BeanBinding<BEAN, TARGET> withStatusLabel(Label label) { - return (BeanBinding<BEAN, TARGET>) Binding.super.withStatusLabel( + public default BeanBindingBuilder<BEAN, TARGET> withStatusLabel( + Label label) { + return (BeanBindingBuilder<BEAN, TARGET>) BindingBuilder.super.withStatusLabel( label); } @@ -152,19 +154,21 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * * @param propertyName * the name of the property to bind, not null + * @return the newly created binding * * @throws IllegalArgumentException * if the property name is invalid * @throws IllegalArgumentException * if the property has no accessible getter * - * @see Binding#bind(SerializableFunction, SerializableBiConsumer) + * @see BindingBuilder#bind(SerializableFunction, + * SerializableBiConsumer) */ - public void bind(String propertyName); + public Binding<BEAN, TARGET> bind(String propertyName); } /** - * An internal implementation of {@link BeanBinding}. + * An internal implementation of {@link BeanBindingBuilder}. * * @param <BEAN> * the bean type @@ -174,11 +178,8 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * the target property type */ protected static class BeanBindingImpl<BEAN, FIELDVALUE, TARGET> - extends BindingImpl<BEAN, FIELDVALUE, TARGET> - implements BeanBinding<BEAN, TARGET> { - - private Method getter; - private Method setter; + extends BindingBuilderImpl<BEAN, FIELDVALUE, TARGET> + implements BeanBindingBuilder<BEAN, TARGET> { /** * Creates a new bean binding. @@ -200,50 +201,60 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { } @Override - public BeanBinding<BEAN, TARGET> withValidator( + public BeanBindingBuilder<BEAN, TARGET> withValidator( Validator<? super TARGET> validator) { - return (BeanBinding<BEAN, TARGET>) super.withValidator(validator); + return (BeanBindingBuilder<BEAN, TARGET>) super.withValidator( + validator); } @Override - public <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter( + public <NEWTARGET> BeanBindingBuilder<BEAN, NEWTARGET> withConverter( Converter<TARGET, NEWTARGET> converter) { - return (BeanBinding<BEAN, NEWTARGET>) super.withConverter( + return (BeanBindingBuilder<BEAN, NEWTARGET>) super.withConverter( converter); } @Override - public BeanBinding<BEAN, TARGET> withValidationStatusHandler( + public BeanBindingBuilder<BEAN, TARGET> withValidationStatusHandler( ValidationStatusHandler handler) { - return (BeanBinding<BEAN, TARGET>) super.withValidationStatusHandler( + return (BeanBindingBuilder<BEAN, TARGET>) super.withValidationStatusHandler( handler); } @Override - public BeanBinding<BEAN, TARGET> setRequired( + public BeanBindingBuilder<BEAN, TARGET> setRequired( ErrorMessageProvider errorMessageProvider) { - return (BeanBinding<BEAN, TARGET>) super.setRequired( + return (BeanBindingBuilder<BEAN, TARGET>) super.setRequired( errorMessageProvider); } @Override - public void bind(String propertyName) { + public Binding<BEAN, TARGET> bind(String propertyName) { checkUnbound(); - Binding<BEAN, Object> finalBinding; + BindingBuilder<BEAN, Object> finalBinding; + + PropertyDescriptor descriptor = getDescriptor(propertyName); + + Method getter = descriptor.getReadMethod(); + Method setter = descriptor.getWriteMethod(); - finalBinding = withConverter(createConverter(), false); + finalBinding = withConverter( + createConverter(getter.getReturnType()), false); if (BeanUtil.checkBeanValidationAvailable()) { finalBinding = finalBinding.withValidator( new BeanValidator(getBinder().beanType, propertyName)); } - PropertyDescriptor descriptor = getDescriptor(propertyName); - getter = descriptor.getReadMethod(); - setter = descriptor.getWriteMethod(); - finalBinding.bind(this::getValue, this::setValue); - getBinder().boundProperties.add(propertyName); + try { + return (Binding<BEAN, TARGET>) finalBinding.bind( + bean -> invokeWrapExceptions(getter, bean), + (bean, value) -> invokeWrapExceptions(setter, bean, + value)); + } finally { + getBinder().boundProperties.add(propertyName); + } } @Override @@ -251,19 +262,13 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { return (BeanBinder<BEAN>) super.getBinder(); } - private void setValue(BEAN bean, Object value) { - try { - if (setter != null) { - setter.invoke(bean, value); - } - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); + private static Object invokeWrapExceptions(Method method, Object target, + Object... parameters) { + if (method == null) { + return null; } - } - - private Object getValue(BEAN bean) { try { - return getter.invoke(bean); + return method.invoke(target, parameters); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } @@ -295,9 +300,8 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { } @SuppressWarnings("unchecked") - private Converter<TARGET, Object> createConverter() { - return Converter.from( - fieldValue -> cast(fieldValue, getter.getReturnType()), + private Converter<TARGET, Object> createConverter(Class<?> getterType) { + return Converter.from(fieldValue -> cast(fieldValue, getterType), propertyValue -> (TARGET) propertyValue, exception -> { throw new RuntimeException(exception); }); @@ -328,9 +332,9 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { } @Override - public <FIELDVALUE> BeanBinding<BEAN, FIELDVALUE> forField( + public <FIELDVALUE> BeanBindingBuilder<BEAN, FIELDVALUE> forField( HasValue<FIELDVALUE> field) { - return (BeanBinding<BEAN, FIELDVALUE>) super.forField(field); + return (BeanBindingBuilder<BEAN, FIELDVALUE>) super.forField(field); } /** @@ -351,6 +355,7 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * the field to bind, not null * @param propertyName * the name of the property to bind, not null + * @return the newly created binding * * @throws IllegalArgumentException * if the property name is invalid @@ -359,9 +364,9 @@ public class BeanBinder<BEAN> extends Binder<BEAN> { * * @see #bind(HasValue, SerializableFunction, SerializableBiConsumer) */ - public <FIELDVALUE> void bind(HasValue<FIELDVALUE> field, - String propertyName) { - forField(field).bind(propertyName); + public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( + HasValue<FIELDVALUE> field, String propertyName) { + return forField(field).bind(propertyName); } @Override diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index da65b6600d..da52cfd116 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -42,7 +42,6 @@ import com.vaadin.server.SerializablePredicate; import com.vaadin.server.UserError; import com.vaadin.shared.Registration; import com.vaadin.ui.AbstractComponent; -import com.vaadin.ui.AbstractMultiSelect; import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.UI; @@ -80,6 +79,7 @@ import com.vaadin.ui.UI; * @param <BEAN> * the bean type * + * @see BindingBuilder * @see Binding * @see HasValue * @@ -94,13 +94,46 @@ public class Binder<BEAN> implements Serializable { * the bean type * @param <TARGET> * the target data type of the binding, matches the field type - * until a converter has been set + * unless a converter has been set * * @see Binder#forField(HasValue) */ public interface Binding<BEAN, TARGET> extends Serializable { /** + * Gets the field the binding uses. + * + * @return the field for the binding + */ + public HasValue<?> getField(); + + /** + * Validates the field value and returns a {@code ValidationStatus} + * instance representing the outcome of the validation. + * + * @see Binder#validate() + * @see Validator#apply(Object) + * + * @return the validation result. + */ + public ValidationStatus<TARGET> validate(); + + } + + /** + * Creates a binding between a field and a data property. + * + * @param <BEAN> + * the bean type + * @param <TARGET> + * the target data type of the binding, matches the field type + * until a converter has been set + * + * @see Binder#forField(HasValue) + */ + public interface BindingBuilder<BEAN, TARGET> extends Serializable { + + /** * Completes this binding using the given getter and setter functions * representing a backing bean property. The functions are used to * update the field value from the property and to store the field value @@ -136,10 +169,12 @@ public class Binder<BEAN> implements Serializable { * @param setter * the function to write the field value to the property or * null if read-only + * @return the newly created binding * @throws IllegalStateException * if {@code bind} has already been called on this binding */ - public void bind(SerializableFunction<BEAN, TARGET> getter, + public Binding<BEAN, TARGET> bind( + SerializableFunction<BEAN, TARGET> getter, com.vaadin.server.SerializableBiConsumer<BEAN, TARGET> setter); /** @@ -157,7 +192,7 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - public Binding<BEAN, TARGET> withValidator( + public BindingBuilder<BEAN, TARGET> withValidator( Validator<? super TARGET> validator); /** @@ -180,7 +215,7 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - public default Binding<BEAN, TARGET> withValidator( + public default BindingBuilder<BEAN, TARGET> withValidator( SerializablePredicate<? super TARGET> predicate, String message) { return withValidator(Validator.from(predicate, message)); @@ -207,7 +242,7 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - public default Binding<BEAN, TARGET> withValidator( + public default BindingBuilder<BEAN, TARGET> withValidator( SerializablePredicate<? super TARGET> predicate, ErrorMessageProvider errorMessageProvider) { return withValidator( @@ -237,7 +272,7 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - public <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter( + public <NEWTARGET> BindingBuilder<BEAN, NEWTARGET> withConverter( Converter<TARGET, NEWTARGET> converter); /** @@ -267,7 +302,7 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - public default <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter( + public default <NEWTARGET> BindingBuilder<BEAN, NEWTARGET> withConverter( SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<NEWTARGET, TARGET> toPresentation) { return withConverter(Converter.from(toModel, toPresentation, @@ -305,7 +340,7 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - public default <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter( + public default <NEWTARGET> BindingBuilder<BEAN, NEWTARGET> withConverter( SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<NEWTARGET, TARGET> toPresentation, String errorMessage) { @@ -321,7 +356,7 @@ public class Binder<BEAN> implements Serializable { * the value to use instead of {@code null} * @return a new binding with null representation handling. */ - public default Binding<BEAN, TARGET> withNullRepresentation( + public default BindingBuilder<BEAN, TARGET> withNullRepresentation( TARGET nullRepresentation) { return withConverter( fieldValue -> Objects.equals(fieldValue, nullRepresentation) @@ -331,13 +366,6 @@ public class Binder<BEAN> implements Serializable { } /** - * Gets the field the binding uses. - * - * @return the field for the binding - */ - public HasValue<?> getField(); - - /** * Sets the given {@code label} to show an error message if validation * fails. * <p> @@ -369,7 +397,8 @@ public class Binder<BEAN> implements Serializable { * label to show validation status for the field * @return this binding, for chaining */ - public default Binding<BEAN, TARGET> withStatusLabel(Label label) { + public default BindingBuilder<BEAN, TARGET> withStatusLabel( + Label label) { return withValidationStatusHandler(status -> { label.setValue(status.getMessage().orElse("")); // Only show the label when validation has failed @@ -406,21 +435,10 @@ public class Binder<BEAN> implements Serializable { * status change handler * @return this binding, for chaining */ - public Binding<BEAN, TARGET> withValidationStatusHandler( + public BindingBuilder<BEAN, TARGET> withValidationStatusHandler( ValidationStatusHandler handler); /** - * Validates the field value and returns a {@code ValidationStatus} - * instance representing the outcome of the validation. - * - * @see Binder#validate() - * @see Validator#apply(Object) - * - * @return the validation result. - */ - public ValidationStatus<TARGET> validate(); - - /** * Sets the field to be required. This means two things: * <ol> * <li>the required indicator is visible</li> @@ -439,7 +457,8 @@ public class Binder<BEAN> implements Serializable { * the error message to show for the invalid value * @return this binding, for chaining */ - public default Binding<BEAN, TARGET> setRequired(String errorMessage) { + public default BindingBuilder<BEAN, TARGET> setRequired( + String errorMessage) { return setRequired(context -> errorMessage); } @@ -458,12 +477,12 @@ public class Binder<BEAN> implements Serializable { * the provider for localized validation error message * @return this binding, for chaining */ - public Binding<BEAN, TARGET> setRequired( + public BindingBuilder<BEAN, TARGET> setRequired( ErrorMessageProvider errorMessageProvider); } /** - * An internal implementation of {@code Binding}. + * An internal implementation of {@code BindingBuilder}. * * @param <BEAN> * the bean type, must match the Binder bean type @@ -473,18 +492,16 @@ public class Binder<BEAN> implements Serializable { * the target data type of the binding, matches the field type * until a converter has been set */ - protected static class BindingImpl<BEAN, FIELDVALUE, TARGET> - implements Binding<BEAN, TARGET> { + protected static class BindingBuilderImpl<BEAN, FIELDVALUE, TARGET> + implements BindingBuilder<BEAN, TARGET> { private final Binder<BEAN> binder; private final HasValue<FIELDVALUE> field; - private Registration onValueChange; private ValidationStatusHandler statusHandler; private boolean isStatusHandlerChanged; - private SerializableFunction<BEAN, TARGET> getter; - private SerializableBiConsumer<BEAN, TARGET> setter; + private boolean bound; /** * Contains all converters and validators chained together in the @@ -493,8 +510,9 @@ public class Binder<BEAN> implements Serializable { private Converter<FIELDVALUE, TARGET> converterValidatorChain; /** - * Creates a new binding associated with the given field. Initializes - * the binding with the given converter chain and status change handler. + * Creates a new binding builder associated with the given field. + * Initializes the builder with the given converter chain and status + * change handler. * * @param binder * the binder this instance is connected to, not null @@ -505,7 +523,8 @@ public class Binder<BEAN> implements Serializable { * @param statusHandler * the handler to track validation status, not null */ - protected BindingImpl(Binder<BEAN> binder, HasValue<FIELDVALUE> field, + protected BindingBuilderImpl(Binder<BEAN> binder, + HasValue<FIELDVALUE> field, Converter<FIELDVALUE, TARGET> converterValidatorChain, ValidationStatusHandler statusHandler) { this.field = field; @@ -515,22 +534,26 @@ public class Binder<BEAN> implements Serializable { } @Override - public void bind(SerializableFunction<BEAN, TARGET> getter, + public Binding<BEAN, TARGET> bind( + SerializableFunction<BEAN, TARGET> getter, SerializableBiConsumer<BEAN, TARGET> setter) { checkUnbound(); Objects.requireNonNull(getter, "getter cannot be null"); - this.getter = getter; - this.setter = setter; - onValueChange = getField() - .addValueChangeListener(this::handleFieldValueChange); - getBinder().bindings.add(this); - getBinder().getBean().ifPresent(this::initFieldValue); + BindingImpl<BEAN, FIELDVALUE, TARGET> binding = new BindingImpl<>( + this, getter, setter); + + getBinder().bindings.add(binding); + getBinder().getBean().ifPresent(binding::initFieldValue); getBinder().fireStatusChangeEvent(false); + + bound = true; + + return binding; } @Override - public Binding<BEAN, TARGET> withValidator( + public BindingBuilder<BEAN, TARGET> withValidator( Validator<? super TARGET> validator) { checkUnbound(); Objects.requireNonNull(validator, "validator cannot be null"); @@ -541,13 +564,13 @@ public class Binder<BEAN> implements Serializable { } @Override - public <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter( + public <NEWTARGET> BindingBuilder<BEAN, NEWTARGET> withConverter( Converter<TARGET, NEWTARGET> converter) { return withConverter(converter, true); } @Override - public Binding<BEAN, TARGET> withValidationStatusHandler( + public BindingBuilder<BEAN, TARGET> withValidationStatusHandler( ValidationStatusHandler handler) { checkUnbound(); Objects.requireNonNull(handler, "handler cannot be null"); @@ -562,21 +585,15 @@ public class Binder<BEAN> implements Serializable { } @Override - public Binding<BEAN, TARGET> setRequired( + public BindingBuilder<BEAN, TARGET> setRequired( ErrorMessageProvider errorMessageProvider) { checkUnbound(); - - getField().setRequiredIndicatorVisible(true); + field.setRequiredIndicatorVisible(true); return withValidator( - value -> !Objects.equals(value, getField().getEmptyValue()), + value -> !Objects.equals(value, field.getEmptyValue()), errorMessageProvider); } - @Override - public HasValue<FIELDVALUE> getField() { - return field; - } - /** * Implements {@link #withConverter(Converter)} method with additional * possibility to disable (reset) default null representation converter. @@ -597,17 +614,17 @@ public class Binder<BEAN> implements Serializable { * @throws IllegalStateException * if {@code bind} has already been called */ - protected <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter( + protected <NEWTARGET> BindingBuilder<BEAN, NEWTARGET> withConverter( Converter<TARGET, NEWTARGET> converter, boolean resetNullRepresentation) { checkUnbound(); Objects.requireNonNull(converter, "converter cannot be null"); if (resetNullRepresentation) { - getBinder().initialConverters.get(getField()).setIdentity(); + getBinder().initialConverters.get(field).setIdentity(); } - return getBinder().createBinding(getField(), + return getBinder().createBinding(field, converterValidatorChain.chain(converter), statusHandler); } @@ -629,11 +646,63 @@ public class Binder<BEAN> implements Serializable { * if this binding is already bound */ protected void checkUnbound() { - if (getter != null) { + if (bound) { throw new IllegalStateException( "cannot modify binding: already bound to a property"); } } + } + + /** + * An internal implementation of {@code Binding}. + * + * @param <BEAN> + * the bean type, must match the Binder bean type + * @param <FIELDVALUE> + * the value type of the field + * @param <TARGET> + * the target data type of the binding, matches the field type + * unless a converter has been set + */ + protected static class BindingImpl<BEAN, FIELDVALUE, TARGET> + implements Binding<BEAN, TARGET> { + + private final Binder<BEAN> binder; + + private final HasValue<FIELDVALUE> field; + private final ValidationStatusHandler statusHandler; + + private final SerializableFunction<BEAN, TARGET> getter; + private final SerializableBiConsumer<BEAN, TARGET> setter; + + // Not final since we temporarily remove listener while changing values + private Registration onValueChange; + + /** + * Contains all converters and validators chained together in the + * correct order. + */ + private final Converter<FIELDVALUE, TARGET> converterValidatorChain; + + public BindingImpl(BindingBuilderImpl<BEAN, FIELDVALUE, TARGET> builder, + SerializableFunction<BEAN, TARGET> getter, + SerializableBiConsumer<BEAN, TARGET> setter) { + this.binder = builder.getBinder(); + this.field = builder.field; + this.statusHandler = builder.statusHandler; + converterValidatorChain = builder.converterValidatorChain; + + onValueChange = getField() + .addValueChangeListener(this::handleFieldValueChange); + + this.getter = getter; + this.setter = setter; + } + + @Override + public HasValue<FIELDVALUE> getField() { + return field; + } /** * Finds an appropriate locale to be used in conversion and validation. @@ -783,6 +852,16 @@ public class Binder<BEAN> implements Serializable { return toValidationStatus(result); } + /** + * Returns the {@code Binder} connected to this {@code Binding} + * instance. + * + * @return the binder + */ + protected Binder<BEAN> getBinder() { + return binder; + } + private void notifyStatusHandler(ValidationStatus<?> status) { statusHandler.accept(status); } @@ -895,18 +974,18 @@ public class Binder<BEAN> implements Serializable { } /** - * Creates a new binding for the given field. The returned binding may be + * Creates a new binding for the given field. The returned builder may be * further configured before invoking - * {@link Binding#bind(SerializableFunction, SerializableBiConsumer)} which - * completes the binding. Until {@code Binding.bind} is called, the binding - * has no effect. + * {@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)} + * which completes the binding. Until {@code Binding.bind} is called, the + * binding has no effect. * <p> * <strong>Note:</strong> Not all {@link HasValue} implementations support * passing {@code null} as the value. For these the Binder will * automatically change {@code null} to a null representation provided by * {@link HasValue#getEmptyValue()}. This conversion is one-way only, if you * want to have a two-way mapping back to {@code null}, use - * {@link Binding#withNullRepresentation(Object))}. + * {@link BindingBuilder#withNullRepresentation(Object)}. * * @param <FIELDVALUE> * the value type of the field @@ -916,7 +995,7 @@ public class Binder<BEAN> implements Serializable { * * @see #bind(HasValue, SerializableFunction, SerializableBiConsumer) */ - public <FIELDVALUE> Binding<BEAN, FIELDVALUE> forField( + public <FIELDVALUE> BindingBuilder<BEAN, FIELDVALUE> forField( HasValue<FIELDVALUE> field) { Objects.requireNonNull(field, "field cannot be null"); // clear previous errors for this field and any bean level validation @@ -977,11 +1056,13 @@ public class Binder<BEAN> implements Serializable { * @param setter * the function to write the field value to the property or null * if read-only + * @return the newly created binding */ - public <FIELDVALUE> void bind(HasValue<FIELDVALUE> field, + public <FIELDVALUE> Binding<BEAN, FIELDVALUE> bind( + HasValue<FIELDVALUE> field, SerializableFunction<BEAN, FIELDVALUE> getter, SerializableBiConsumer<BEAN, FIELDVALUE> setter) { - forField(field).bind(getter, setter); + return forField(field).bind(getter, setter); } /** @@ -1311,7 +1392,7 @@ public class Binder<BEAN> implements Serializable { * @param statusLabel * the status label to set * @see #setValidationStatusHandler(BinderStatusHandler) - * @see Binding#withStatusLabel(Label) + * @see BindingBuilder#withStatusLabel(Label) */ public void setStatusLabel(Label statusLabel) { if (statusHandler != null) { @@ -1349,7 +1430,7 @@ public class Binder<BEAN> implements Serializable { * @throws NullPointerException * for <code>null</code> status handler * @see #setStatusLabel(Label) - * @see Binding#withValidationStatusHandler(ValidationStatusHandler) + * @see BindingBuilder#withValidationStatusHandler(ValidationStatusHandler) */ public void setValidationStatusHandler( BinderValidationStatusHandler<BEAN> statusHandler) { @@ -1390,8 +1471,8 @@ public class Binder<BEAN> implements Serializable { * <li>{@link #readBean(Object)} is called * <li>{@link #setBean(Object)} is called * <li>{@link #removeBean()} is called - * <li>{@link Binding#bind(SerializableFunction, SerializableBiConsumer)} is - * called + * <li>{@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)} + * is called * <li>{@link Binder#validate()} or {@link Binding#validate()} is called * </ul> * @@ -1401,10 +1482,8 @@ public class Binder<BEAN> implements Serializable { * @see #setBean(Object) * @see #removeBean() * @see #forField(HasValue) - * @see #forSelect(AbstractMultiSelect) * @see #validate() * @see Binding#validate() - * @see Binding#bind(Object) * * @param listener * status change listener to add, not null @@ -1431,10 +1510,10 @@ public class Binder<BEAN> implements Serializable { * the handler to notify of status changes, not null * @return the new incomplete binding */ - protected <FIELDVALUE, TARGET> Binding<BEAN, TARGET> createBinding( + protected <FIELDVALUE, TARGET> BindingBuilder<BEAN, TARGET> createBinding( HasValue<FIELDVALUE> field, Converter<FIELDVALUE, TARGET> converter, ValidationStatusHandler handler) { - return new BindingImpl<>(this, field, converter, handler); + return new BindingBuilderImpl<>(this, field, converter, handler); } /** diff --git a/server/src/main/java/com/vaadin/data/BinderValidationStatus.java b/server/src/main/java/com/vaadin/data/BinderValidationStatus.java index 41a181dacf..983745c89a 100644 --- a/server/src/main/java/com/vaadin/data/BinderValidationStatus.java +++ b/server/src/main/java/com/vaadin/data/BinderValidationStatus.java @@ -22,13 +22,13 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.validator.BeanValidator; /** * Binder validation status change. Represents the outcome of binder level * validation. Has information about the validation results for the - * {@link Binding#withValidator(Validator) field level} and + * {@link BindingBuilder#withValidator(Validator) field level} and * {@link Binder#withValidator(Validator)binder level} validation. * <p> * Note: if there are any field level validation errors, the bean level @@ -149,7 +149,7 @@ public class BinderValidationStatus<BEAN> implements Serializable { * Gets the field level validation statuses. * <p> * The field level validtors have been added with - * {@link Binding#withValidator(Validator)}. + * {@link BindingBuilder#withValidator(Validator)}. * * @return the field validation statuses */ @@ -175,7 +175,7 @@ public class BinderValidationStatus<BEAN> implements Serializable { * Gets the failed field level validation statuses. * <p> * The field level validtors have been added with - * {@link Binding#withValidator(Validator)}. + * {@link BindingBuilder#withValidator(Validator)}. * * @return a list of failed field level validation statuses */ diff --git a/server/src/main/java/com/vaadin/data/StatusChangeEvent.java b/server/src/main/java/com/vaadin/data/StatusChangeEvent.java index 076b4a4a4d..ded3ed7955 100644 --- a/server/src/main/java/com/vaadin/data/StatusChangeEvent.java +++ b/server/src/main/java/com/vaadin/data/StatusChangeEvent.java @@ -18,6 +18,7 @@ package com.vaadin.data; import java.util.EventObject; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.server.SerializableBiConsumer; import com.vaadin.server.SerializableFunction; @@ -32,8 +33,8 @@ import com.vaadin.server.SerializableFunction; * <li>{@link Binder#readBean(Object)} is called * <li>{@link Binder#setBean(Object)} is called * <li>{@link Binder#removeBean()} is called - * <li>{@link Binding#bind(SerializableFunction, SerializableBiConsumer)} is - * called + * <li>{@link BindingBuilder#bind(SerializableFunction, SerializableBiConsumer)} + * is called * <li>{@link Binder#validate()} or {@link Binding#validate()} is called * </ul> * diff --git a/server/src/main/java/com/vaadin/data/ValidationStatus.java b/server/src/main/java/com/vaadin/data/ValidationStatus.java index bbc4326b60..a5ff3896aa 100644 --- a/server/src/main/java/com/vaadin/data/ValidationStatus.java +++ b/server/src/main/java/com/vaadin/data/ValidationStatus.java @@ -20,14 +20,16 @@ import java.util.Objects; import java.util.Optional; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; /** * Represents the status of field validation. Status can be {@code Status.OK}, * {@code Status.ERROR} or {@code Status.RESET}. Status OK and ERROR are always * associated with a ValidationResult {@link #getResult}. * <p> - * Use {@link Binding#withValidationStatusHandler(ValidationStatusHandler)} to - * register a handler for field level validation status changes. + * Use + * {@link BindingBuilder#withValidationStatusHandler(ValidationStatusHandler)} + * to register a handler for field level validation status changes. * * @author Vaadin Ltd * @@ -36,7 +38,7 @@ import com.vaadin.data.Binder.Binding; * status changed, matches the field type unless a converter has been * set * - * @see Binding#withValidationStatusHandler(ValidationStatusHandler) + * @see BindingBuilder#withValidationStatusHandler(ValidationStatusHandler) * @see Binding#validate() * @see ValidationStatusHandler * @see BinderValidationStatus diff --git a/server/src/main/java/com/vaadin/data/ValidationStatusHandler.java b/server/src/main/java/com/vaadin/data/ValidationStatusHandler.java index eb38e044f4..9cf20b92ea 100644 --- a/server/src/main/java/com/vaadin/data/ValidationStatusHandler.java +++ b/server/src/main/java/com/vaadin/data/ValidationStatusHandler.java @@ -18,13 +18,13 @@ package com.vaadin.data; import java.io.Serializable; import java.util.function.Consumer; -import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.ui.AbstractComponent; /** * Handler for {@link ValidationStatus} changes. * <p> - * {@link Binding#withValidationStatusHandler(withValidationStatusHandler) + * {@link BindingBuilder#withValidationStatusHandler(withValidationStatusHandler) * Register} an instance of this class to be able to override the default * handling, which is to show * {@link AbstractComponent#setComponentError(com.vaadin.server.ErrorMessage) an @@ -32,7 +32,7 @@ import com.vaadin.ui.AbstractComponent; * * @author Vaadin Ltd * - * @see Binding#withValidationStatusHandler(withValidationStatusHandler) + * @see BindingBuilder#withValidationStatusHandler(withValidationStatusHandler) * @see ValidationStatus * * @since 8.0 diff --git a/server/src/main/java/com/vaadin/data/util/converter/Converter.java b/server/src/main/java/com/vaadin/data/util/converter/Converter.java index 9c46469f22..6d58e54613 100644 --- a/server/src/main/java/com/vaadin/data/util/converter/Converter.java +++ b/server/src/main/java/com/vaadin/data/util/converter/Converter.java @@ -19,7 +19,7 @@ package com.vaadin.data.util.converter; import java.io.Serializable; import java.util.function.Function; -import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.Result; import com.vaadin.server.SerializableFunction; @@ -149,7 +149,7 @@ public interface Converter<PRESENTATION, MODEL> extends Serializable { * <p> * In most typical cases you should not need this method but instead only * need to define one converter for a binding using - * {@link Binding#withConverter(Converter)}. + * {@link BindingBuilder#withConverter(Converter)}. * * @param <T> * the model type of the resulting converter diff --git a/server/src/test/java/com/vaadin/data/BeanBinderTest.java b/server/src/test/java/com/vaadin/data/BeanBinderTest.java index 08cdf38426..fd15d3981c 100644 --- a/server/src/test/java/com/vaadin/data/BeanBinderTest.java +++ b/server/src/test/java/com/vaadin/data/BeanBinderTest.java @@ -10,8 +10,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import com.vaadin.data.BeanBinder.BeanBinding; -import com.vaadin.data.Binder.Binding; +import com.vaadin.data.BeanBinder.BeanBindingBuilder; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.tests.data.bean.BeanToValidate; public class BeanBinderTest @@ -178,18 +178,18 @@ public class BeanBinderTest @Test public void beanBindingChainingMethods() { - Method[] methods = BeanBinding.class.getMethods(); + Method[] methods = BeanBindingBuilder.class.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; try { - Method actualMethod = BeanBinding.class.getMethod( + Method actualMethod = BeanBindingBuilder.class.getMethod( method.getName(), method.getParameterTypes()); Assert.assertNotSame( actualMethod + " should be overridden in " - + BeanBinding.class + + BeanBindingBuilder.class + " with more specific return type ", - Binding.class, actualMethod.getReturnType()); + BindingBuilder.class, actualMethod.getReturnType()); } catch (NoSuchMethodException | SecurityException e) { throw new RuntimeException(e); } diff --git a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java index 5aafc475ef..8f61fb5f16 100644 --- a/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java +++ b/server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java @@ -26,6 +26,7 @@ import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.ValidationStatus.Status; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.StringToIntegerConverter; @@ -249,14 +250,15 @@ public class BinderBookOfVaadinTest { // Slider for integers between 1 and 10 Slider salaryLevelField = new Slider("Salary level", 1, 10); - Binding<BookPerson, String> b1 = binder.forField(yearOfBirthField); - Binding<BookPerson, Integer> b2 = b1.withConverter( + BindingBuilder<BookPerson, String> b1 = binder + .forField(yearOfBirthField); + BindingBuilder<BookPerson, Integer> b2 = b1.withConverter( new StringToIntegerConverter("Must enter a number")); b2.bind(BookPerson::getYearOfBirth, BookPerson::setYearOfBirth); - Binding<BookPerson, Double> salaryBinding1 = binder + BindingBuilder<BookPerson, Double> salaryBinding1 = binder .forField(salaryLevelField); - Binding<BookPerson, Integer> salaryBinding2 = salaryBinding1 + BindingBuilder<BookPerson, Integer> salaryBinding2 = salaryBinding1 .withConverter(Double::intValue, Integer::doubleValue); salaryBinding2.bind(BookPerson::getSalaryLevel, BookPerson::setSalaryLevel); @@ -308,9 +310,9 @@ public class BinderBookOfVaadinTest { .withValidator( returnDate -> !returnDate .isBefore(departing.getValue()), - "Cannot return before departing"); + "Cannot return before departing") + .bind(Trip::getReturnDate, Trip::setReturnDate); - returnBinding.bind(Trip::getReturnDate, Trip::setReturnDate); departing.addValueChangeListener(event -> returnBinding.validate()); LocalDate past = LocalDate.now(); @@ -361,9 +363,9 @@ public class BinderBookOfVaadinTest { .withValidator( returnDate -> !returnDate .isBefore(departing.getValue()), - "Cannot return before departing"); + "Cannot return before departing") + .bind(Trip::getReturnDate, Trip::setReturnDate); - returnBinding.bind(Trip::getReturnDate, Trip::setReturnDate); departing.addValueChangeListener(event -> returnBinding.validate()); LocalDate past = LocalDate.now(); diff --git a/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java b/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java index 9ad8dca2c3..f6a7463a12 100644 --- a/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java +++ b/server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java @@ -29,6 +29,7 @@ import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.util.converter.ValueContext; import com.vaadin.data.validator.NotEmptyValidator; @@ -73,7 +74,7 @@ public class BinderConverterValidatorTest @Test public void bound_validatorsAreOK_noErrors() { - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.withValidator(Validator.alwaysPass()).bind(Person::getFirstName, Person::setFirstName); @@ -87,7 +88,7 @@ public class BinderConverterValidatorTest @SuppressWarnings("serial") @Test public void bound_validatorsFail_errors() { - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.withValidator(Validator.alwaysPass()); String msg1 = "foo"; String msg2 = "bar"; @@ -221,7 +222,7 @@ public class BinderConverterValidatorTest bean.setStatus("1"); Binder<StatusBean> binder = new Binder<>(); - Binding<StatusBean, String> binding = binder.forField(field) + BindingBuilder<StatusBean, String> binding = binder.forField(field) .withConverter(presentation -> { if (presentation.equals("OK")) { return "1"; @@ -266,7 +267,7 @@ public class BinderConverterValidatorTest public void validate_failedBeanValidatorWithFieldValidator() { String msg = "foo"; - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(new NotEmptyValidator<>(msg)); binding.bind(Person::getFirstName, Person::setFirstName); @@ -286,7 +287,7 @@ public class BinderConverterValidatorTest public void validate_failedBothBeanValidatorAndFieldValidator() { String msg1 = "foo"; - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(new NotEmptyValidator<>(msg1)); binding.bind(Person::getFirstName, Person::setFirstName); @@ -322,7 +323,7 @@ public class BinderConverterValidatorTest @Test public void binder_saveIfValid() { String msg1 = "foo"; - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(new NotEmptyValidator<>(msg1)); binding.bind(Person::getFirstName, Person::setFirstName); @@ -554,11 +555,11 @@ public class BinderConverterValidatorTest public void save_validationErrors_exceptionContainsErrors() throws ValidationException { String msg = "foo"; - Binding<Person, String> nameBinding = binder.forField(nameField) + BindingBuilder<Person, String> nameBinding = binder.forField(nameField) .withValidator(new NotEmptyValidator<>(msg)); nameBinding.bind(Person::getFirstName, Person::setFirstName); - Binding<Person, Integer> ageBinding = binder.forField(ageField) + BindingBuilder<Person, Integer> ageBinding = binder.forField(ageField) .withConverter(stringToInteger).withValidator(notNegative); ageBinding.bind(Person::getAge, Person::setAge); @@ -585,7 +586,7 @@ public class BinderConverterValidatorTest @Test public void binderBindAndLoad_clearsErrors() { - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); binder.withValidator(bean -> !bean.getFirstName().contains("error"), @@ -621,7 +622,7 @@ public class BinderConverterValidatorTest // bind a new field that has invalid value in bean TextField lastNameField = new TextField(); person.setLastName(""); - Binding<Person, String> binding2 = binder.forField(lastNameField) + BindingBuilder<Person, String> binding2 = binder.forField(lastNameField) .withValidator(notEmpty); binding2.bind(Person::getLastName, Person::setLastName); @@ -663,15 +664,15 @@ public class BinderConverterValidatorTest final SerializablePredicate<String> lengthPredicate = v -> v .length() > 2; - Binding<Person, String> firstNameBinding = binder.forField(nameField) - .withValidator(lengthPredicate, "length"); + BindingBuilder<Person, String> firstNameBinding = binder + .forField(nameField).withValidator(lengthPredicate, "length"); firstNameBinding.bind(Person::getFirstName, Person::setFirstName); Binding<Person, String> lastNameBinding = binder.forField(lastNameField) .withValidator(v -> !nameField.getValue().isEmpty() || lengthPredicate.test(v), "err") - .withValidator(lengthPredicate, "length"); - lastNameBinding.bind(Person::getLastName, Person::setLastName); + .withValidator(lengthPredicate, "length") + .bind(Person::getLastName, Person::setLastName); // this will be triggered as a new bean is bound with binder.bind(), // causing a validation error to be visible until reset is done diff --git a/server/src/test/java/com/vaadin/data/BinderStatusChangeTest.java b/server/src/test/java/com/vaadin/data/BinderStatusChangeTest.java index e453e68482..4f46a78a5b 100644 --- a/server/src/test/java/com/vaadin/data/BinderStatusChangeTest.java +++ b/server/src/test/java/com/vaadin/data/BinderStatusChangeTest.java @@ -22,6 +22,7 @@ import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.tests.data.bean.Person; @@ -45,7 +46,7 @@ public class BinderStatusChangeTest public void bindBinding_unbound_eventWhenBoundEndnoEventsBeforeBound() { binder.addStatusChangeListener(this::statusChanged); - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); nameField.setValue(""); Assert.assertNull(event.get()); @@ -377,8 +378,8 @@ public class BinderStatusChangeTest @Test public void validateBinding_noValidationErrors_statusEventWithoutErrors() { - Binding<Person, String> binding = binder.forField(nameField); - binding.bind(Person::getFirstName, Person::setFirstName); + Binding<Person, String> binding = binder.forField(nameField) + .bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); @@ -394,8 +395,8 @@ public class BinderStatusChangeTest @Test public void validateBinding_validationErrors_statusEventWithError() { Binding<Person, String> binding = binder.forField(nameField) - .withValidator(name -> false, ""); - binding.bind(Person::getFirstName, Person::setFirstName); + .withValidator(name -> false, "") + .bind(Person::getFirstName, Person::setFirstName); binder.forField(ageField) .withConverter(new StringToIntegerConverter("")) .bind(Person::getAge, Person::setAge); diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index 7f2353a448..d1f831003b 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -13,7 +13,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.validator.NotEmptyValidator; import com.vaadin.server.ErrorMessage; @@ -331,7 +331,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { TextField textField = new TextField(); Assert.assertFalse(textField.isRequiredIndicatorVisible()); - Binding<Person, String> binding = binder.forField(textField); + BindingBuilder<Person, String> binding = binder.forField(textField); Assert.assertFalse(textField.isRequiredIndicatorVisible()); binding.setRequired("foobar"); @@ -357,7 +357,7 @@ public class BinderTest extends BinderTestBase<Binder<Person>, Person> { textField.setLocale(Locale.CANADA); Assert.assertFalse(textField.isRequiredIndicatorVisible()); - Binding<Person, String> binding = binder.forField(textField); + BindingBuilder<Person, String> binding = binder.forField(textField); Assert.assertFalse(textField.isRequiredIndicatorVisible()); AtomicInteger invokes = new AtomicInteger(); diff --git a/server/src/test/java/com/vaadin/data/BinderValidationStatusTest.java b/server/src/test/java/com/vaadin/data/BinderValidationStatusTest.java index d901ee00d8..bb4052cc8d 100644 --- a/server/src/test/java/com/vaadin/data/BinderValidationStatusTest.java +++ b/server/src/test/java/com/vaadin/data/BinderValidationStatusTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.ValidationStatus.Status; import com.vaadin.tests.data.bean.Person; import com.vaadin.ui.Label; @@ -48,7 +49,7 @@ public class BinderValidationStatusTest @Test public void bindingWithStatusHandler_handlerGetsEvents() { AtomicReference<ValidationStatus<?>> statusCapture = new AtomicReference<>(); - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty).withValidationStatusHandler(evt -> { Assert.assertNull(statusCapture.get()); statusCapture.set(evt); @@ -86,8 +87,7 @@ public class BinderValidationStatusTest public void bindingWithStatusHandler_defaultStatusHandlerIsReplaced() { Binding<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty).withValidationStatusHandler(evt -> { - }); - binding.bind(Person::getFirstName, Person::setFirstName); + }).bind(Person::getFirstName, Person::setFirstName); Assert.assertNull(nameField.getComponentError()); @@ -106,8 +106,8 @@ public class BinderValidationStatusTest Label label = new Label(); Binding<Person, String> binding = binder.forField(nameField) - .withValidator(notEmpty).withStatusLabel(label); - binding.bind(Person::getFirstName, Person::setFirstName); + .withValidator(notEmpty).withStatusLabel(label) + .bind(Person::getFirstName, Person::setFirstName); nameField.setValue(""); @@ -133,8 +133,8 @@ public class BinderValidationStatusTest Label label = new Label(); Binding<Person, String> binding = binder.forField(nameField) - .withValidator(notEmpty).withStatusLabel(label); - binding.bind(Person::getFirstName, Person::setFirstName); + .withValidator(notEmpty).withStatusLabel(label) + .bind(Person::getFirstName, Person::setFirstName); Assert.assertNull(nameField.getComponentError()); @@ -150,7 +150,7 @@ public class BinderValidationStatusTest @Test(expected = IllegalStateException.class) public void bindingWithStatusHandler_addAfterBound() { - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); @@ -161,7 +161,7 @@ public class BinderValidationStatusTest public void bindingWithStatusLabel_addAfterBound() { Label label = new Label(); - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); @@ -172,7 +172,7 @@ public class BinderValidationStatusTest public void bindingWithStatusLabel_setAfterHandler() { Label label = new Label(); - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.withValidationStatusHandler(NOOP); @@ -183,7 +183,7 @@ public class BinderValidationStatusTest public void bindingWithStatusHandler_setAfterLabel() { Label label = new Label(); - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.withStatusLabel(label); @@ -193,7 +193,7 @@ public class BinderValidationStatusTest @Test(expected = IllegalStateException.class) public void bindingWithStatusHandler_setAfterOtherHandler() { - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.withValidationStatusHandler(NOOP); @@ -394,8 +394,7 @@ public class BinderValidationStatusTest public void binderWithStatusHandler_defaultStatusHandlerIsReplaced() { Binding<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty).withValidationStatusHandler(evt -> { - }); - binding.bind(Person::getFirstName, Person::setFirstName); + }).bind(Person::getFirstName, Person::setFirstName); Assert.assertNull(nameField.getComponentError()); @@ -414,8 +413,8 @@ public class BinderValidationStatusTest Label label = new Label(); Binding<Person, String> binding = binder.forField(nameField) - .withValidator(notEmpty).withStatusLabel(label); - binding.bind(Person::getFirstName, Person::setFirstName); + .withValidator(notEmpty).withStatusLabel(label) + .bind(Person::getFirstName, Person::setFirstName); Assert.assertNull(nameField.getComponentError()); @@ -431,7 +430,7 @@ public class BinderValidationStatusTest @Test(expected = IllegalStateException.class) public void binderWithStatusHandler_addAfterBound() { - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); @@ -442,7 +441,7 @@ public class BinderValidationStatusTest public void binderWithStatusLabel_addAfterBound() { Label label = new Label(); - Binding<Person, String> binding = binder.forField(nameField) + BindingBuilder<Person, String> binding = binder.forField(nameField) .withValidator(notEmpty); binding.bind(Person::getFirstName, Person::setFirstName); @@ -453,7 +452,7 @@ public class BinderValidationStatusTest public void binderWithStatusLabel_setAfterHandler() { Label label = new Label(); - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.bind(Person::getFirstName, Person::setFirstName); binder.setValidationStatusHandler(event -> { @@ -466,7 +465,7 @@ public class BinderValidationStatusTest public void binderWithStatusHandler_setAfterLabel() { Label label = new Label(); - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.bind(Person::getFirstName, Person::setFirstName); binder.setStatusLabel(label); @@ -484,7 +483,7 @@ public class BinderValidationStatusTest public void binderWithStatusHandler_replaceHandler() { AtomicReference<BinderValidationStatus<?>> capture = new AtomicReference<>(); - Binding<Person, String> binding = binder.forField(nameField); + BindingBuilder<Person, String> binding = binder.forField(nameField); binding.bind(Person::getFirstName, Person::setFirstName); binder.setValidationStatusHandler(results -> { diff --git a/server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java b/server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java index 61cacf8b51..3a358b7097 100644 --- a/server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java +++ b/server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java @@ -17,7 +17,7 @@ package com.vaadin.data.validator; import java.util.Objects; -import com.vaadin.data.Binder.Binding; +import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.data.HasValue; import com.vaadin.data.ValidationResult; import com.vaadin.data.Validator; @@ -33,13 +33,13 @@ import com.vaadin.data.util.converter.ValueContext; * This validator can be suitable for fields that have been marked as required * with {@link HasValue#setRequiredIndicatorVisible(boolean)}. * <p> - * Note that {@link Binding#setRequired(com.vaadin.data.ErrorMessageProvider)} + * Note that {@link BindingBuilder#setRequired(com.vaadin.data.ErrorMessageProvider)} * does almost the same thing, but verifies against the value NOT being equal to * what {@link HasValue#getEmptyValue()} returns and sets the required indicator * visible with {@link HasValue#setRequiredIndicatorVisible(boolean)}. * * @see HasValue#setRequiredIndicatorVisible(boolean) - * @see Binding#setRequired(com.vaadin.data.ErrorMessageProvider) + * @see BindingBuilder#setRequired(com.vaadin.data.ErrorMessageProvider) * @author Vaadin Ltd * @since 8.0 * |