Skip to content

Commit

Permalink
Simplify Binding API by removing the FIELDTYPE type parameter
Browse files Browse the repository at this point in the history
The type parameter is mainly used internally, the only externally facing
use is to define the exact type of Binding.getField. Code that has
access to a typed instance of Binding does typically also have direct
access to the field instance, so there's no real use for the type
parameter.

Change-Id: Idf2ab18a79ec5f0a7cef83705b8084fbf7014c10
  • Loading branch information
Legioth authored and Vaadin Code Review committed Nov 29, 2016
1 parent 9aee6e6 commit 3fd7537
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 100 deletions.
44 changes: 20 additions & 24 deletions server/src/main/java/com/vaadin/data/BeanBinder.java
Expand Up @@ -23,6 +23,7 @@
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
Expand All @@ -40,7 +41,6 @@
import com.vaadin.server.SerializableFunction; import com.vaadin.server.SerializableFunction;
import com.vaadin.server.SerializablePredicate; import com.vaadin.server.SerializablePredicate;
import com.vaadin.util.ReflectTools; import com.vaadin.util.ReflectTools;
import java.util.Arrays;


/** /**
* A {@code Binder} subclass specialized for binding <em>beans</em>: classes * A {@code Binder} subclass specialized for binding <em>beans</em>: classes
Expand All @@ -62,44 +62,41 @@ public class BeanBinder<BEAN> extends Binder<BEAN> {
* *
* @param <BEAN> * @param <BEAN>
* the bean type * the bean type
* @param <FIELDVALUE>
* the field value type
* @param <TARGET> * @param <TARGET>
* the target property type * the target property type
*/ */
public interface BeanBinding<BEAN, FIELDVALUE, TARGET> public interface BeanBinding<BEAN, TARGET> extends Binding<BEAN, TARGET> {
extends Binding<BEAN, FIELDVALUE, TARGET> {


@Override @Override
public BeanBinding<BEAN, FIELDVALUE, TARGET> withValidator( public BeanBinding<BEAN, TARGET> withValidator(
Validator<? super TARGET> validator); Validator<? super TARGET> validator);


@Override @Override
public default BeanBinding<BEAN, FIELDVALUE, TARGET> withValidator( public default BeanBinding<BEAN, TARGET> withValidator(
SerializablePredicate<? super TARGET> predicate, SerializablePredicate<? super TARGET> predicate,
String message) { String message) {
return (BeanBinding<BEAN, FIELDVALUE, TARGET>) Binding.super.withValidator( return (BeanBinding<BEAN, TARGET>) Binding.super.withValidator(
predicate, message); predicate, message);
} }


@Override @Override
public <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter(
Converter<TARGET, NEWTARGET> converter); Converter<TARGET, NEWTARGET> converter);


@Override @Override
public default <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public default <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter(
SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation) { SerializableFunction<NEWTARGET, TARGET> toPresentation) {
return (BeanBinding<BEAN, FIELDVALUE, NEWTARGET>) Binding.super.withConverter( return (BeanBinding<BEAN, NEWTARGET>) Binding.super.withConverter(
toModel, toPresentation); toModel, toPresentation);
} }


@Override @Override
public default <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public default <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter(
SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation, SerializableFunction<NEWTARGET, TARGET> toPresentation,
String errorMessage) { String errorMessage) {
return (BeanBinding<BEAN, FIELDVALUE, NEWTARGET>) Binding.super.withConverter( return (BeanBinding<BEAN, NEWTARGET>) Binding.super.withConverter(
toModel, toPresentation, errorMessage); toModel, toPresentation, errorMessage);
} }


Expand Down Expand Up @@ -141,7 +138,7 @@ public default <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverte
*/ */
protected static class BeanBindingImpl<BEAN, FIELDVALUE, TARGET> protected static class BeanBindingImpl<BEAN, FIELDVALUE, TARGET>
extends BindingImpl<BEAN, FIELDVALUE, TARGET> extends BindingImpl<BEAN, FIELDVALUE, TARGET>
implements BeanBinding<BEAN, FIELDVALUE, TARGET> { implements BeanBinding<BEAN, TARGET> {


private Method getter; private Method getter;
private Method setter; private Method setter;
Expand All @@ -166,24 +163,23 @@ protected BeanBindingImpl(BeanBinder<BEAN> binder,
} }


@Override @Override
public BeanBinding<BEAN, FIELDVALUE, TARGET> withValidator( public BeanBinding<BEAN, TARGET> withValidator(
Validator<? super TARGET> validator) { Validator<? super TARGET> validator) {
return (BeanBinding<BEAN, FIELDVALUE, TARGET>) super.withValidator( return (BeanBinding<BEAN, TARGET>) super.withValidator(validator);
validator);
} }


@Override @Override
public <NEWTARGET> BeanBinding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public <NEWTARGET> BeanBinding<BEAN, NEWTARGET> withConverter(
Converter<TARGET, NEWTARGET> converter) { Converter<TARGET, NEWTARGET> converter) {
return (BeanBinding<BEAN, FIELDVALUE, NEWTARGET>) super.withConverter( return (BeanBinding<BEAN, NEWTARGET>) super.withConverter(
converter); converter);
} }


@Override @Override
public void bind(String propertyName) { public void bind(String propertyName) {
checkUnbound(); checkUnbound();


Binding<BEAN, FIELDVALUE, Object> finalBinding; Binding<BEAN, Object> finalBinding;


finalBinding = withConverter(createConverter(), false); finalBinding = withConverter(createConverter(), false);


Expand Down Expand Up @@ -281,10 +277,9 @@ public BeanBinder(Class<? extends BEAN> beanType) {
} }


@Override @Override
public <FIELDVALUE> BeanBinding<BEAN, FIELDVALUE, FIELDVALUE> forField( public <FIELDVALUE> BeanBinding<BEAN, FIELDVALUE> forField(
HasValue<FIELDVALUE> field) { HasValue<FIELDVALUE> field) {
return (BeanBinding<BEAN, FIELDVALUE, FIELDVALUE>) super.forField( return (BeanBinding<BEAN, FIELDVALUE>) super.forField(field);
field);
} }


/** /**
Expand Down Expand Up @@ -481,7 +476,8 @@ protected List<Field> getFieldsInDeclareOrder(Class<?> searchClass) {
ArrayList<Field> memberFieldInOrder = new ArrayList<>(); ArrayList<Field> memberFieldInOrder = new ArrayList<>();


while (searchClass != null) { while (searchClass != null) {
memberFieldInOrder.addAll(Arrays.asList(searchClass.getDeclaredFields())); memberFieldInOrder
.addAll(Arrays.asList(searchClass.getDeclaredFields()));
searchClass = searchClass.getSuperclass(); searchClass = searchClass.getSuperclass();
} }
return memberFieldInOrder; return memberFieldInOrder;
Expand Down
48 changes: 22 additions & 26 deletions server/src/main/java/com/vaadin/data/Binder.java
Expand Up @@ -92,15 +92,13 @@ public class Binder<BEAN> implements Serializable {
* *
* @param <BEAN> * @param <BEAN>
* the bean type * the bean type
* @param <FIELDVALUE>
* the value type of the field
* @param <TARGET> * @param <TARGET>
* the target data type of the binding, matches the field type * the target data type of the binding, matches the field type
* until a converter has been set * until a converter has been set
* *
* @see Binder#forField(HasValue) * @see Binder#forField(HasValue)
*/ */
public interface Binding<BEAN, FIELDVALUE, TARGET> extends Serializable { public interface Binding<BEAN, TARGET> extends Serializable {


/** /**
* Completes this binding using the given getter and setter functions * Completes this binding using the given getter and setter functions
Expand Down Expand Up @@ -159,7 +157,7 @@ public void bind(SerializableFunction<BEAN, TARGET> getter,
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
public Binding<BEAN, FIELDVALUE, TARGET> withValidator( public Binding<BEAN, TARGET> withValidator(
Validator<? super TARGET> validator); Validator<? super TARGET> validator);


/** /**
Expand All @@ -182,7 +180,7 @@ public Binding<BEAN, FIELDVALUE, TARGET> withValidator(
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
public default Binding<BEAN, FIELDVALUE, TARGET> withValidator( public default Binding<BEAN, TARGET> withValidator(
SerializablePredicate<? super TARGET> predicate, SerializablePredicate<? super TARGET> predicate,
String message) { String message) {
return withValidator(Validator.from(predicate, message)); return withValidator(Validator.from(predicate, message));
Expand All @@ -209,7 +207,7 @@ public default Binding<BEAN, FIELDVALUE, TARGET> withValidator(
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
public default Binding<BEAN, FIELDVALUE, TARGET> withValidator( public default Binding<BEAN, TARGET> withValidator(
SerializablePredicate<? super TARGET> predicate, SerializablePredicate<? super TARGET> predicate,
ErrorMessageProvider errorMessageProvider) { ErrorMessageProvider errorMessageProvider) {
return withValidator( return withValidator(
Expand Down Expand Up @@ -239,7 +237,7 @@ public default Binding<BEAN, FIELDVALUE, TARGET> withValidator(
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
public <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter(
Converter<TARGET, NEWTARGET> converter); Converter<TARGET, NEWTARGET> converter);


/** /**
Expand Down Expand Up @@ -269,7 +267,7 @@ public <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public default <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter(
SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation) { SerializableFunction<NEWTARGET, TARGET> toPresentation) {
return withConverter(Converter.from(toModel, toPresentation, return withConverter(Converter.from(toModel, toPresentation,
Expand Down Expand Up @@ -307,7 +305,7 @@ public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public default <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter(
SerializableFunction<TARGET, NEWTARGET> toModel, SerializableFunction<TARGET, NEWTARGET> toModel,
SerializableFunction<NEWTARGET, TARGET> toPresentation, SerializableFunction<NEWTARGET, TARGET> toPresentation,
String errorMessage) { String errorMessage) {
Expand All @@ -323,7 +321,7 @@ public default <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter(
* the value to use instead of {@code null} * the value to use instead of {@code null}
* @return a new binding with null representation handling. * @return a new binding with null representation handling.
*/ */
public default Binding<BEAN, FIELDVALUE, TARGET> withNullRepresentation( public default Binding<BEAN, TARGET> withNullRepresentation(
TARGET nullRepresentation) { TARGET nullRepresentation) {
return withConverter( return withConverter(
fieldValue -> Objects.equals(fieldValue, nullRepresentation) fieldValue -> Objects.equals(fieldValue, nullRepresentation)
Expand All @@ -337,7 +335,7 @@ public default Binding<BEAN, FIELDVALUE, TARGET> withNullRepresentation(
* *
* @return the field for the binding * @return the field for the binding
*/ */
public HasValue<FIELDVALUE> getField(); public HasValue<?> getField();


/** /**
* Sets the given {@code label} to show an error message if validation * Sets the given {@code label} to show an error message if validation
Expand Down Expand Up @@ -371,8 +369,7 @@ public default Binding<BEAN, FIELDVALUE, TARGET> withNullRepresentation(
* label to show validation status for the field * label to show validation status for the field
* @return this binding, for chaining * @return this binding, for chaining
*/ */
public default Binding<BEAN, FIELDVALUE, TARGET> withStatusLabel( public default Binding<BEAN, TARGET> withStatusLabel(Label label) {
Label label) {
return withValidationStatusHandler(status -> { return withValidationStatusHandler(status -> {
label.setValue(status.getMessage().orElse("")); label.setValue(status.getMessage().orElse(""));
// Only show the label when validation has failed // Only show the label when validation has failed
Expand Down Expand Up @@ -409,7 +406,7 @@ public default Binding<BEAN, FIELDVALUE, TARGET> withStatusLabel(
* status change handler * status change handler
* @return this binding, for chaining * @return this binding, for chaining
*/ */
public Binding<BEAN, FIELDVALUE, TARGET> withValidationStatusHandler( public Binding<BEAN, TARGET> withValidationStatusHandler(
ValidationStatusHandler handler); ValidationStatusHandler handler);


/** /**
Expand Down Expand Up @@ -442,8 +439,7 @@ public Binding<BEAN, FIELDVALUE, TARGET> withValidationStatusHandler(
* the error message to show for the invalid value * the error message to show for the invalid value
* @return this binding, for chaining * @return this binding, for chaining
*/ */
public default Binding<BEAN, FIELDVALUE, TARGET> setRequired( public default Binding<BEAN, TARGET> setRequired(String errorMessage) {
String errorMessage) {
return setRequired(context -> errorMessage); return setRequired(context -> errorMessage);
} }


Expand All @@ -462,7 +458,7 @@ public default Binding<BEAN, FIELDVALUE, TARGET> setRequired(
* the provider for localized validation error message * the provider for localized validation error message
* @return this binding, for chaining * @return this binding, for chaining
*/ */
public Binding<BEAN, FIELDVALUE, TARGET> setRequired( public Binding<BEAN, TARGET> setRequired(
ErrorMessageProvider errorMessageProvider); ErrorMessageProvider errorMessageProvider);
} }


Expand All @@ -478,7 +474,7 @@ public Binding<BEAN, FIELDVALUE, TARGET> setRequired(
* until a converter has been set * until a converter has been set
*/ */
protected static class BindingImpl<BEAN, FIELDVALUE, TARGET> protected static class BindingImpl<BEAN, FIELDVALUE, TARGET>
implements Binding<BEAN, FIELDVALUE, TARGET> { implements Binding<BEAN, TARGET> {


private final Binder<BEAN> binder; private final Binder<BEAN> binder;


Expand Down Expand Up @@ -534,7 +530,7 @@ public void bind(SerializableFunction<BEAN, TARGET> getter,
} }


@Override @Override
public Binding<BEAN, FIELDVALUE, TARGET> withValidator( public Binding<BEAN, TARGET> withValidator(
Validator<? super TARGET> validator) { Validator<? super TARGET> validator) {
checkUnbound(); checkUnbound();
Objects.requireNonNull(validator, "validator cannot be null"); Objects.requireNonNull(validator, "validator cannot be null");
Expand All @@ -545,13 +541,13 @@ public Binding<BEAN, FIELDVALUE, TARGET> withValidator(
} }


@Override @Override
public <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter( public <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter(
Converter<TARGET, NEWTARGET> converter) { Converter<TARGET, NEWTARGET> converter) {
return withConverter(converter, true); return withConverter(converter, true);
} }


@Override @Override
public Binding<BEAN, FIELDVALUE, TARGET> withValidationStatusHandler( public Binding<BEAN, TARGET> withValidationStatusHandler(
ValidationStatusHandler handler) { ValidationStatusHandler handler) {
checkUnbound(); checkUnbound();
Objects.requireNonNull(handler, "handler cannot be null"); Objects.requireNonNull(handler, "handler cannot be null");
Expand All @@ -566,7 +562,7 @@ public Binding<BEAN, FIELDVALUE, TARGET> withValidationStatusHandler(
} }


@Override @Override
public Binding<BEAN, FIELDVALUE, TARGET> setRequired( public Binding<BEAN, TARGET> setRequired(
ErrorMessageProvider errorMessageProvider) { ErrorMessageProvider errorMessageProvider) {
checkUnbound(); checkUnbound();


Expand Down Expand Up @@ -601,7 +597,7 @@ public HasValue<FIELDVALUE> getField() {
* @throws IllegalStateException * @throws IllegalStateException
* if {@code bind} has already been called * if {@code bind} has already been called
*/ */
protected <NEWTARGET> Binding<BEAN, FIELDVALUE, NEWTARGET> withConverter( protected <NEWTARGET> Binding<BEAN, NEWTARGET> withConverter(
Converter<TARGET, NEWTARGET> converter, Converter<TARGET, NEWTARGET> converter,
boolean resetNullRepresentation) { boolean resetNullRepresentation) {
checkUnbound(); checkUnbound();
Expand Down Expand Up @@ -920,7 +916,7 @@ public Optional<BEAN> getBean() {
* *
* @see #bind(HasValue, SerializableFunction, SerializableBiConsumer) * @see #bind(HasValue, SerializableFunction, SerializableBiConsumer)
*/ */
public <FIELDVALUE> Binding<BEAN, FIELDVALUE, FIELDVALUE> forField( public <FIELDVALUE> Binding<BEAN, FIELDVALUE> forField(
HasValue<FIELDVALUE> field) { HasValue<FIELDVALUE> field) {
Objects.requireNonNull(field, "field cannot be null"); Objects.requireNonNull(field, "field cannot be null");
// clear previous errors for this field and any bean level validation // clear previous errors for this field and any bean level validation
Expand Down Expand Up @@ -1139,7 +1135,7 @@ private BinderValidationStatus<BEAN> doWriteIfValid(BEAN bean) {
} }


// Store old bean values so we can restore them if validators fail // Store old bean values so we can restore them if validators fail
Map<Binding<BEAN, ?, ?>, Object> oldValues = new HashMap<>(); Map<Binding<BEAN, ?>, Object> oldValues = new HashMap<>();
bindings.forEach( bindings.forEach(
binding -> oldValues.put(binding, binding.getter.apply(bean))); binding -> oldValues.put(binding, binding.getter.apply(bean)));


Expand Down Expand Up @@ -1435,7 +1431,7 @@ public Registration addStatusChangeListener(StatusChangeListener listener) {
* the handler to notify of status changes, not null * the handler to notify of status changes, not null
* @return the new incomplete binding * @return the new incomplete binding
*/ */
protected <FIELDVALUE, TARGET> Binding<BEAN, FIELDVALUE, TARGET> createBinding( protected <FIELDVALUE, TARGET> Binding<BEAN, TARGET> createBinding(
HasValue<FIELDVALUE> field, Converter<FIELDVALUE, TARGET> converter, HasValue<FIELDVALUE> field, Converter<FIELDVALUE, TARGET> converter,
ValidationStatusHandler handler) { ValidationStatusHandler handler) {
return new BindingImpl<>(this, field, converter, handler); return new BindingImpl<>(this, field, converter, handler);
Expand Down
10 changes: 5 additions & 5 deletions server/src/main/java/com/vaadin/data/ValidationStatus.java
Expand Up @@ -69,7 +69,7 @@ public enum Status {


private final Status status; private final Status status;
private final ValidationResult result; private final ValidationResult result;
private final Binding<?, ?, TARGET> binding; private final Binding<?, TARGET> binding;


/** /**
* Convenience method for creating a {@link Status#UNRESOLVED} validation * Convenience method for creating a {@link Status#UNRESOLVED} validation
Expand All @@ -83,7 +83,7 @@ public enum Status {
* status was reset * status was reset
*/ */
public static <TARGET> ValidationStatus<TARGET> createUnresolvedStatus( public static <TARGET> ValidationStatus<TARGET> createUnresolvedStatus(
Binding<?, ?, TARGET> source) { Binding<?, TARGET> source) {
return new ValidationStatus<>(source, Status.UNRESOLVED, null); return new ValidationStatus<>(source, Status.UNRESOLVED, null);
} }


Expand All @@ -96,7 +96,7 @@ public static <TARGET> ValidationStatus<TARGET> createUnresolvedStatus(
* @param result * @param result
* the result of the validation * the result of the validation
*/ */
public ValidationStatus(Binding<?, ?, TARGET> source, public ValidationStatus(Binding<?, TARGET> source,
ValidationResult result) { ValidationResult result) {
this(source, result.isError() ? Status.ERROR : Status.OK, result); this(source, result.isError() ? Status.ERROR : Status.OK, result);
} }
Expand All @@ -114,7 +114,7 @@ public ValidationStatus(Binding<?, ?, TARGET> source,
* @param result * @param result
* the related result, may be {@code null} * the related result, may be {@code null}
*/ */
public ValidationStatus(Binding<?, ?, TARGET> source, Status status, public ValidationStatus(Binding<?, TARGET> source, Status status,
ValidationResult result) { ValidationResult result) {
Objects.requireNonNull(source, "Event source may not be null"); Objects.requireNonNull(source, "Event source may not be null");
Objects.requireNonNull(status, "Status may not be null"); Objects.requireNonNull(status, "Status may not be null");
Expand Down Expand Up @@ -177,7 +177,7 @@ public Optional<ValidationResult> getResult() {
* *
* @return the source binding * @return the source binding
*/ */
public Binding<?, ?, TARGET> getBinding() { public Binding<?, TARGET> getBinding() {
return binding; return binding;
} }


Expand Down

0 comments on commit 3fd7537

Please sign in to comment.