aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka <pekka@vaadin.com>2019-04-08 09:42:31 +0300
committerPekka <pekka@vaadin.com>2019-04-08 09:42:31 +0300
commit89c9bc96e561068f14855869bfd824c7f9827416 (patch)
tree33e8e1aa008beeee693d1a74fca2027cb4b78a26
parent2833876dac2aea5f5bea824303750d3f8b025231 (diff)
downloadvaadin-framework-pr/11306.tar.gz
vaadin-framework-pr/11306.zip
wip 2: revisited designpr/11306
Still missing tests and example
-rw-r--r--server/src/main/java/com/vaadin/data/Binder.java103
-rw-r--r--server/src/main/java/com/vaadin/data/ConverterFactory.java (renamed from server/src/main/java/com/vaadin/data/BindingConverterFactory.java)19
-rw-r--r--server/src/main/java/com/vaadin/data/DefaultConverterFactory.java (renamed from server/src/main/java/com/vaadin/data/DefaultBindingConverterFactory.java)33
3 files changed, 91 insertions, 64 deletions
diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java
index 5393a8389c..af3c70e2d3 100644
--- a/server/src/main/java/com/vaadin/data/Binder.java
+++ b/server/src/main/java/com/vaadin/data/Binder.java
@@ -99,8 +99,8 @@ import com.vaadin.util.ReflectTools;
*/
public class Binder<BEAN> implements Serializable {
- // TODO get default factory from session / ui like in V7 ?
- private BindingConverterFactory defaultConverter;
+ private final DefaultConverterFactory defaultConverterFactory = new DefaultConverterFactory();
+ private ConverterFactory customConverterFactory;
/**
* Represents the binding between a field and a data property.
@@ -2639,28 +2639,26 @@ public class Binder<BEAN> implements Serializable {
memberField.getName(),
objectWithMemberFields.getClass().getName()));
}
+ HasValue<?> field;
+ // Get the field from the object
+ try {
+ field = (HasValue<?>) ReflectTools.getJavaFieldValue(
+ objectWithMemberFields, memberField, HasValue.class);
+ } catch (IllegalArgumentException | IllegalAccessException
+ | InvocationTargetException e) {
+ // If we cannot determine the value, just skip the field
+ return false;
+ }
+ if (field == null) {
+ field = makeFieldInstance(
+ (Class<? extends HasValue<?>>) memberField.getType());
+ initializeField(objectWithMemberFields, memberField, field);
+ }
+ BindingBuilder builder = forField(field);
+
Class<?> fieldClass = GenericTypeReflector.erase(valueType);
- if (propertyType.equals(fieldClass) || (defaultConverter != null
- && defaultConverter.isSupported(fieldClass, propertyType))) {
- HasValue<?> field;
- // Get the field from the object
- try {
- field = (HasValue<?>) ReflectTools.getJavaFieldValue(
- objectWithMemberFields, memberField, HasValue.class);
- } catch (IllegalArgumentException | IllegalAccessException
- | InvocationTargetException e) {
- // If we cannot determine the value, just skip the field
- return false;
- }
- if (field == null) {
- field = makeFieldInstance(
- (Class<? extends HasValue<?>>) memberField.getType());
- initializeField(objectWithMemberFields, memberField, field);
- }
- BindingBuilder builder = forField(field);
- if (defaultConverter != null)
- builder = defaultConverter.buildBindingConverter(builder, fieldClass,
- propertyType);
+ if (propertyType.equals(fieldClass)
+ || applyConverterFactory(builder, propertyType, fieldClass)) {
builder.bind(property);
return true;
} else {
@@ -2672,27 +2670,13 @@ public class Binder<BEAN> implements Serializable {
}
}
- /**
- * @return the current default binding converter
- */
- public BindingConverterFactory getDefaultConverter() {
- return defaultConverter;
- }
-
- /**
- * Set at default binding converter. If this is set, it is used when
- * {@link #bindInstanceFields(Object)} is called. The default converter is
- * able to convert a set of input classes to a given range of output
- * classes. This is typically used for automatically binding Integer,
- * Double, Long or Float to a TextField (which use String as a return
- * value). It may also be used to convert {@link java.time.LocalDateTime}
- * (or LocalDate) to the old {@link java.util.Date}
- *
- * @param defaultConverter
- * an interface for converting values
- */
- public void setDefaultConverter(DefaultBindingConverterFactory defaultConverter) {
- this.defaultConverter = defaultConverter;
+ private boolean applyConverterFactory(BindingBuilder bindingBuilder,
+ Class<?> modelType, Class<?> presentationType) {
+ return customConverterFactory != null
+ && customConverterFactory.applyConverter(bindingBuilder,
+ presentationType, modelType)
+ || getDefaultConverterFactory().applyConverter(bindingBuilder,
+ presentationType, modelType);
}
/**
@@ -2923,6 +2907,37 @@ public class Binder<BEAN> implements Serializable {
.ifPresent(Binding::unbind);
}
+ /**
+ * TODO
+ *
+ * @return
+ * @since
+ */
+ public ConverterFactory getCustomConverterFactory() {
+ return customConverterFactory;
+ }
+
+ /**
+ * TODO
+ *
+ * @param customConverterFactory
+ * @since
+ */
+ public void setCustomConverterFactory(
+ ConverterFactory customConverterFactory) {
+ this.customConverterFactory = customConverterFactory;
+ }
+
+ /**
+ * TODO
+ *
+ * @return
+ * @since
+ */
+ public DefaultConverterFactory getDefaultConverterFactory() {
+ return defaultConverterFactory;
+ }
+
private static final Logger getLogger() {
return Logger.getLogger(Binder.class.getName());
}
diff --git a/server/src/main/java/com/vaadin/data/BindingConverterFactory.java b/server/src/main/java/com/vaadin/data/ConverterFactory.java
index 1cd78a4fef..c3ac4cd7f9 100644
--- a/server/src/main/java/com/vaadin/data/BindingConverterFactory.java
+++ b/server/src/main/java/com/vaadin/data/ConverterFactory.java
@@ -23,12 +23,20 @@ import java.io.Serializable;
* Binder when creating bindings with {@link Binder#bindInstanceFields(Object)}.
* <p>
* The framework default implementation is
- * {@link DefaultBindingConverterFactory}.
+ * {@link DefaultConverterFactory}.
*
* @author Vaadin Ltd.
* @since
*/
-public interface BindingConverterFactory extends Serializable {
+public interface ConverterFactory extends Serializable {
+
+ <PRESENTATION, MODEL> boolean applyConverter(
+ Binder.BindingBuilder<MODEL, PRESENTATION> bindingBuilder,
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType);
+
+// <MODEL, PRESENTATION> Optional<Consumer<Binder.BindingBuilder<MODEL,
+// PRESENTATION>>> getConverterApplier(
+// Class<PRESENTATION> presentationType, Class<MODEL> modelType);
/**
* Builds converter to the given binding to convert between the presentation
@@ -43,8 +51,9 @@ public interface BindingConverterFactory extends Serializable {
* the bean property type
* @return the binder builder with converter applied if possible
*/
- Binder.BindingBuilder buildBindingConverter(Binder.BindingBuilder builder,
- Class<?> presentationType, Class<?> modelType);
+ // Binder.BindingBuilder buildBindingConverter(Binder.BindingBuilder
+ // builder,
+ // Class<?> presentationType, Class<?> modelType);
/**
* Returns whether this factory has a converter to convert between the
@@ -57,6 +66,6 @@ public interface BindingConverterFactory extends Serializable {
* class of the property type in the entity
* @return {@code true} if conversion possible, {@code false} if not
*/
- boolean isSupported(Class<?> presentationType, Class<?> modelType);
+ // boolean isSupported(Class<?> presentationType, Class<?> modelType);
}
diff --git a/server/src/main/java/com/vaadin/data/DefaultBindingConverterFactory.java b/server/src/main/java/com/vaadin/data/DefaultConverterFactory.java
index d7aae39b8a..1b7efcd47f 100644
--- a/server/src/main/java/com/vaadin/data/DefaultBindingConverterFactory.java
+++ b/server/src/main/java/com/vaadin/data/DefaultConverterFactory.java
@@ -45,7 +45,7 @@ import com.vaadin.server.SerializableFunction;
/**
* TODO
*/
-public class DefaultBindingConverterFactory implements BindingConverterFactory {
+public class DefaultConverterFactory implements ConverterFactory {
private static final Map<Class<?>, Set<Class<?>>> SUPPORTED_PRESENTATION_TO_MODEL_CONVERTERS_MAP = new HashMap<>();
static {
@@ -60,6 +60,8 @@ public class DefaultBindingConverterFactory implements BindingConverterFactory {
new HashSet<>(Collections.singletonList(Date.class)));
}
+ // TODO: provide setters for customizing default behavior
+
private static final SerializableFunction<Class, ErrorMessageProvider> TYPE_BASED_ERROR_MESSAGE_PROVIDER = clazz -> context -> String
.format("Invalid value, expected ${0}", clazz.getSimpleName());
@@ -68,34 +70,36 @@ public class DefaultBindingConverterFactory implements BindingConverterFactory {
}
@Override
- public Binder.BindingBuilder buildBindingConverter(
- Binder.BindingBuilder builder, Class<?> presentationType,
- Class<?> modelType) {
+ public <PRESENTATION, MODEL> boolean applyConverter(
+ Binder.BindingBuilder<MODEL, PRESENTATION> builder,
+ Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
if (isSupported(presentationType, modelType)) {
- Supplier<?> nullRepresentationProvider = getNullRepresentationProvider(
+ Supplier<PRESENTATION> nullRepresentationProvider = getNullRepresentationProvider(
presentationType, modelType);
if (nullRepresentationProvider != null) {
- builder = builder.withNullRepresentation(
+ builder.withNullRepresentation(
nullRepresentationProvider.get());
}
if (presentationType == String.class) {
- builder = builder
+ ((Binder.BindingBuilder<MODEL, String>)builder)
.withConverter(createStringConverter(modelType));
} else if (presentationType == LocalDateTime.class) {
if (modelType == Date.class) {
- builder = builder
+ ((Binder.BindingBuilder<Date, LocalDateTime>)builder)
.withConverter(new LocalDateTimeToDateConverter(
getZoneIdForDateConverters()));
}
} else if (presentationType == LocalDate.class) {
if (modelType == Date.class) {
- builder = builder
+ ((Binder.BindingBuilder<Date, LocalDate>)builder)
.withConverter(new LocalDateToDateConverter(
getZoneIdForDateConverters()));
}
}
+ return true;
+ } else {
+ return false;
}
- return builder;
}
/**
@@ -147,10 +151,10 @@ public class DefaultBindingConverterFactory implements BindingConverterFactory {
* @return the null representation provider, or {@code null} to prevent
* conversion of {@code null} model value
*/
- protected Supplier<?> getNullRepresentationProvider(
- Class<?> presentationType, Class<?> modelType) {
+ protected <PRESENTATION> Supplier<PRESENTATION> getNullRepresentationProvider(
+ Class<PRESENTATION> presentationType, Class<?> modelType) {
if (presentationType.equals(String.class)) {
- return () -> "";
+ return () -> (PRESENTATION) "";
}
return null;
}
@@ -172,8 +176,7 @@ public class DefaultBindingConverterFactory implements BindingConverterFactory {
return ZoneId.systemDefault();
}
- @Override
- public boolean isSupported(Class<?> presentationType, Class<?> modelType) {
+ private boolean isSupported(Class<?> presentationType, Class<?> modelType) {
Set<Class<?>> supported = SUPPORTED_PRESENTATION_TO_MODEL_CONVERTERS_MAP
.get(presentationType);
return supported != null && supported.size() > 0