From dd5597d9014032cc366d4b70405e007b1876c350 Mon Sep 17 00:00:00 2001 From: Ahmed Ashour Date: Fri, 13 Oct 2017 08:53:17 +0200 Subject: Convert AbstractDateField not to be a LegacyComponent (#10148) --- .../main/java/com/vaadin/ui/AbstractDateField.java | 314 +++++++++------------ .../datefield/DateFieldListenersTest.java | 24 +- 2 files changed, 152 insertions(+), 186 deletions(-) (limited to 'server/src') diff --git a/server/src/main/java/com/vaadin/ui/AbstractDateField.java b/server/src/main/java/com/vaadin/ui/AbstractDateField.java index b5f11f7122..bfe3119f26 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractDateField.java +++ b/server/src/main/java/com/vaadin/ui/AbstractDateField.java @@ -48,12 +48,10 @@ import com.vaadin.event.FieldEvents.BlurNotifier; import com.vaadin.event.FieldEvents.FocusEvent; import com.vaadin.event.FieldEvents.FocusListener; import com.vaadin.event.FieldEvents.FocusNotifier; -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; import com.vaadin.server.UserError; import com.vaadin.shared.Registration; +import com.vaadin.shared.ui.datefield.AbstractDateFieldServerRpc; import com.vaadin.shared.ui.datefield.AbstractDateFieldState; -import com.vaadin.shared.ui.datefield.DateFieldConstants; import com.vaadin.shared.ui.datefield.DateResolution; import com.vaadin.ui.declarative.DesignAttributeHandler; import com.vaadin.ui.declarative.DesignContext; @@ -73,8 +71,86 @@ import com.vaadin.util.TimeZoneUtil; * */ public abstract class AbstractDateField, R extends Enum> - extends AbstractField - implements LegacyComponent, FocusNotifier, BlurNotifier { + extends AbstractField implements FocusNotifier, BlurNotifier { + + private AbstractDateFieldServerRpc rpc = new AbstractDateFieldServerRpc() { + + @Override + public void update(String newDateString, boolean invalidDateString, + Map resolutions) { + Set resolutionNames = getResolutions() + .map(AbstractDateField.this::getResolutionVariable) + .collect(Collectors.toSet()); + resolutionNames.retainAll(resolutions.keySet()); + if (!isReadOnly() + && (!resolutionNames.isEmpty() || newDateString != null)) { + + // Old and new dates + final T oldDate = getValue(); + + T newDate; + + boolean hasChanges = false; + + if ("".equals(newDateString)) { + + newDate = null; + // TODO check if the following 3 lines are necessary + hasChanges = !getState(false).parsable; + getState().parsable = true; + currentParseErrorMessage = null; + } else { + newDate = reconstructDateFromFields(resolutions, oldDate); + } + + hasChanges |= !Objects.equals(dateString, newDateString) + || !Objects.equals(oldDate, newDate); + + if (hasChanges) { + dateString = newDateString; + if (newDateString == null || newDateString.isEmpty()) { + getState().parsable = true; + currentParseErrorMessage = null; + setComponentError(null); + setValue(newDate, true); + } else { + if (invalidDateString) { + Result parsedDate = handleUnparsableDateString( + dateString); + parsedDate.ifOk(v -> { + getState().parsable = true; + currentParseErrorMessage = null; + setValue(v, true); + }); + if (parsedDate.isError()) { + dateString = null; + getState().parsable = false; + currentParseErrorMessage = parsedDate + .getMessage().orElse("Parsing error"); + setComponentError( + new UserError(getParseErrorMessage())); + setValue(null, true); + } + } else { + getState().parsable = true; + currentParseErrorMessage = null; + setValue(newDate, true); + } + } + } + } + } + + @Override + public void focus() { + fireEvent(new FocusEvent(AbstractDateField.this)); + } + + @Override + public void blur() { + fireEvent(new BlurEvent(AbstractDateField.this)); + } + }; /** * Value of the field. @@ -86,36 +162,19 @@ public abstract class AbstractDateField variables) { - Set resolutionNames = getResolutions() - .map(this::getResolutionVariable).collect(Collectors.toSet()); - resolutionNames.retainAll(variables.keySet()); - if (!isReadOnly() && (!resolutionNames.isEmpty() - || variables.containsKey("dateString"))) { - - // Old and new dates - final T oldDate = getValue(); - - // this enables analyzing invalid input on the server - // this variable is null if the date was chosen with popup calendar - // or contains user-typed string - final String newDateString = (String) variables.get("dateString"); - - T newDate; - - boolean hasChanges = false; - - if ("".equals(newDateString)) { - - newDate = null; - // TODO check if the following 3 lines are necessary - hasChanges = !uiHasValidDateString; - uiHasValidDateString = true; - currentParseErrorMessage = null; - } else { - newDate = reconstructDateFromFields(variables, oldDate); - } - - hasChanges |= !Objects.equals(dateString, newDateString) - || !Objects.equals(oldDate, newDate); - - if (hasChanges) { - dateString = newDateString; - if (newDateString == null || newDateString.isEmpty()) { - uiHasValidDateString = true; - currentParseErrorMessage = null; - setComponentError(null); - setValue(newDate, true); - } else { - if (variables.get("lastInvalidDateString") != null) { - Result parsedDate = handleUnparsableDateString( - dateString); - parsedDate.ifOk(v -> { - uiHasValidDateString = true; - currentParseErrorMessage = null; - setValue(v, true); - }); - if (parsedDate.isError()) { - dateString = null; - uiHasValidDateString = false; - currentParseErrorMessage = parsedDate.getMessage() - .orElse("Parsing error"); - setComponentError( - new UserError(getParseErrorMessage())); - setValue(null, true); - } - } else { - uiHasValidDateString = true; - currentParseErrorMessage = null; - setValue(newDate, true); - } - } - markAsDirty(); - } - } - - if (variables.containsKey(FocusEvent.EVENT_ID)) { - fireEvent(new FocusEvent(this)); - } - - if (variables.containsKey(BlurEvent.EVENT_ID)) { - fireEvent(new BlurEvent(this)); - } + Locale locale = getLocale(); + getState().locale = locale == null ? null : locale.toString(); } /** * Construct a date object from the individual field values received from * the client. * - * @since 8.1.1 + * @since */ - protected T reconstructDateFromFields(Map variables, + protected T reconstructDateFromFields(Map variables, T oldDate) { Map calendarFields = new HashMap<>(); @@ -307,8 +247,8 @@ public abstract class AbstractDateField= 0) { + Integer newValue = variables.get(variableName); + if (newValue != null) { calendarFields.put(resolution, newValue); } else { calendarFields.put(resolution, @@ -378,7 +318,7 @@ public abstract class AbstractDateField resolutions = getState().resolutions; + resolutions.clear(); + + // Only paint variables for the resolution and up, e.g. Resolution DAY + // paints DAY,MONTH,YEAR + for (R res : getResolutionsHigherOrEqualTo(getResolution())) { + String variableName = getResolutionVariable(res); + + Integer value = getValuePart(currentDate, res); + resolutions.put(variableName, value); + + Integer defaultValuePart = getValuePart(defaultValue, res); + resolutions.put("default-" + variableName, defaultValuePart); + } + } + + private Integer getValuePart(T date, R resolution) { + if (date == null) { + return null; + } + return getDatePart(date, resolution); + } + /** * Returns the {@link ZoneId}, which is used when {@code z} is included * inside the {@link #setDateFormat(String)}. @@ -507,20 +473,19 @@ public abstract class AbstractDateField, R extends Enum> - extends AbstractDateField { + public static class TestDateField + extends AbstractDateField { public TestDateField() { - super(null); + super(DateTimeResolution.DAY); } @Override - protected int getDatePart(T date, R resolution) { + protected int getDatePart(LocalDateTime date, + DateTimeResolution resolution) { return 0; } @Override - protected T buildDate(Map resolutionValues) { + protected LocalDateTime buildDate( + Map resolutionValues) { return null; } @Override - protected RangeValidator getRangeValidator() { + protected RangeValidator getRangeValidator() { return null; } @Override - protected T convertFromDate(Date date) { + protected LocalDateTime convertFromDate(Date date) { return null; } @Override - protected Date convertToDate(T date) { + protected Date convertToDate(LocalDateTime date) { return null; } - } @Test -- cgit v1.2.3