summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <legioth@gmail.com>2016-12-05 13:15:08 +0200
committerPekka Hyvönen <pekka@vaadin.com>2016-12-05 13:15:08 +0200
commitc7b84bf51d343867cb82a34b81cfdf0461d0919c (patch)
tree5f7e4c0cd989350121a382422e8267f7159bdc62
parent0cef38513b58f4b486dfb1c0e3c154eed6039743 (diff)
downloadvaadin-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()
-rw-r--r--server/src/main/java/com/vaadin/data/BeanBinder.java129
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java239
-rw-r--r--server/src/main/java/com/vaadin/data/BinderValidationStatus.java8
-rw-r--r--server/src/main/java/com/vaadin/data/StatusChangeEvent.java5
-rw-r--r--server/src/main/java/com/vaadin/data/ValidationStatus.java8
-rw-r--r--server/src/main/java/com/vaadin/data/ValidationStatusHandler.java6
-rw-r--r--server/src/main/java/com/vaadin/data/util/converter/Converter.java4
-rw-r--r--server/src/test/java/com/vaadin/data/BeanBinderTest.java12
-rw-r--r--server/src/test/java/com/vaadin/data/BinderBookOfVaadinTest.java18
-rw-r--r--server/src/test/java/com/vaadin/data/BinderConverterValidatorTest.java29
-rw-r--r--server/src/test/java/com/vaadin/data/BinderStatusChangeTest.java11
-rw-r--r--server/src/test/java/com/vaadin/data/BinderTest.java6
-rw-r--r--server/src/test/java/com/vaadin/data/BinderValidationStatusTest.java41
-rw-r--r--server/src/test/java/com/vaadin/data/validator/NotEmptyValidator.java6
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
*