| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.xtext.datamart.common; |
| |
| import java.text.DateFormat; |
| import java.text.ParseException; |
| import java.text.SimpleDateFormat; |
| import java.time.DayOfWeek; |
| import java.time.LocalDate; |
| import java.time.LocalDateTime; |
| import java.time.ZoneId; |
| import java.util.Arrays; |
| import java.util.Date; |
| import java.util.Locale; |
| |
| import org.eclipse.osbp.ui.api.datamart.DatamartFilter; |
| import org.eclipse.osbp.ui.api.datamart.IDatamartBetweenInput; |
| import org.eclipse.osbp.ui.api.themes.EnumCssClass; |
| import org.slf4j.Logger; |
| |
| import com.vaadin.data.Property.ReadOnlyException; |
| import com.vaadin.data.Property.ValueChangeListener; |
| import com.vaadin.data.util.converter.Converter.ConversionException; |
| import com.vaadin.shared.ui.datefield.Resolution; |
| import com.vaadin.ui.ComboBox; |
| import com.vaadin.ui.DateField; |
| import com.vaadin.ui.HorizontalLayout; |
| import com.vaadin.ui.UI; |
| |
| public class DatamartBetweenDate extends HorizontalLayout implements IDatamartBetweenInput { |
| |
| private static Logger LOGGER = org.slf4j.LoggerFactory.getLogger(DatamartBetweenDate.class.getName()); |
| |
| private static final long serialVersionUID = -5673052113801450589L; |
| |
| private DateField fromInput; |
| |
| private DateField untilInput; |
| |
| private ComboBox defaultDatesCombo; |
| |
| private boolean defaultDateUpdateFlagFrom = false; |
| private boolean defaultDateUpdateFlagUntil = false; |
| |
| private enum DefaultTime { |
| MANUALLY, TODAY, YESTERDAY, THIS_WEEK, LAST_WEEK, THIS_MONTH |
| } |
| |
| |
| // private DateFormat formatter = DateFormat.getDateTimeInstance(); |
| private SimpleDateFormat formatter = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, UI.getCurrent().getLocale()); |
| |
| public static long getSerialversionuid() { |
| return serialVersionUID; |
| } |
| |
| public DatamartBetweenDate() { |
| fromInput = new DateField(); |
| untilInput = new DateField(); |
| fromInput.setDateFormat(formatter.toPattern()); |
| untilInput.setDateFormat(formatter.toPattern()); |
| fromInput.setResolution(Resolution.SECOND); |
| untilInput.setResolution(Resolution.SECOND); |
| createDefaultDatesCombo(); |
| addComponent(fromInput); |
| addComponent(untilInput); |
| addComponent(defaultDatesCombo); |
| addStyleName(EnumCssClass.RANGE_SELECTION.styleName()); |
| } |
| |
| public DatamartBetweenDate(DatamartFilter.DateTimeFormat filterFormat, DatamartFilter.DateResolution filterResolution) { |
| fromInput = new DateField(); |
| untilInput = new DateField(); |
| String dateFormat = formatter.toPattern(); |
| Resolution resolution = Resolution.MINUTE; |
| if (filterFormat != null && filterResolution != null) { |
| dateFormat = getFormat(filterFormat, filterResolution); |
| resolution = mapToVaadin(filterResolution); |
| } |
| fromInput.setDateFormat(dateFormat); |
| untilInput.setDateFormat(dateFormat); |
| fromInput.setResolution(resolution); |
| untilInput.setResolution(resolution); |
| createDefaultDatesCombo(); |
| addComponent(fromInput); |
| addComponent(untilInput); |
| addComponent(defaultDatesCombo); |
| addStyleName(EnumCssClass.RANGE_SELECTION.styleName()); |
| } |
| |
| private void createDefaultDatesCombo() { |
| defaultDatesCombo = new ComboBox(); |
| defaultDatesCombo.setStyleName(EnumCssClass.DEFAULT_TIMES.styleName()); |
| fromInput.addValueChangeListener(e -> { |
| fromInput.setValue((Date) e.getProperty().getValue()); |
| if (!isDefaultDateUpdateFlagFrom()) { |
| defaultDatesCombo.setValue(DefaultTime.MANUALLY); |
| } |
| setDefaultDateUpdateFlagFrom(false); |
| }); |
| untilInput.addValueChangeListener(e -> { |
| untilInput.setValue((Date) e.getProperty().getValue()); |
| if (!isDefaultDateUpdateFlagUntil()) { |
| defaultDatesCombo.setValue(DefaultTime.MANUALLY); |
| } |
| setDefaultDateUpdateFlagUntil(false); |
| }); |
| |
| defaultDatesCombo.addItems(Arrays.asList(DefaultTime.values())); |
| defaultDatesCombo.addValueChangeListener(e -> { |
| DefaultTime dt = (DefaultTime)e.getProperty().getValue(); |
| if (!DefaultTime.MANUALLY.equals(dt)) { |
| setDefaultDateUpdateFlagFrom(true); |
| setDefaultDateUpdateFlagUntil(true); |
| fromInput.setValue(getDateFromDefaultTime(dt)[0]); |
| untilInput.setValue(getDateFromDefaultTime(dt)[1]); |
| } |
| }); |
| |
| } |
| |
| private Date[] getDateFromDefaultTime(DefaultTime dt){ |
| Date[] dateArray = new Date[2]; |
| LocalDate today = LocalDate.now(); |
| switch (dt) { |
| case TODAY: |
| dateArray[0] = convertToDate(today.atTime(0, 0, 0)); |
| dateArray[1] = convertToDate(today.atTime(23, 59, 59)); |
| return dateArray; |
| case YESTERDAY: |
| LocalDate yesterday = today.minusDays(1); |
| dateArray[0] = convertToDate(yesterday.atTime(0, 0, 0)); |
| dateArray[1] = convertToDate(yesterday.atTime(23, 59, 59)); |
| return dateArray; |
| case THIS_WEEK: |
| DayOfWeek dayOfWeek = today.getDayOfWeek(); |
| dateArray[0] = convertToDate(today.minusDays(dayOfWeek.getValue()-1)); |
| dateArray[1] = convertToDate(today.plusDays(7-dayOfWeek.getValue()).atTime(23, 59, 59)); |
| return dateArray; |
| case LAST_WEEK: |
| LocalDate lastWeekDate = today.minusWeeks(1); |
| DayOfWeek dayOfLastWeek = lastWeekDate.getDayOfWeek(); |
| dateArray[0] = convertToDate(lastWeekDate.minusDays(dayOfLastWeek.getValue()-1)); |
| dateArray[1] = convertToDate(lastWeekDate.plusDays(7-dayOfLastWeek.getValue()).atTime(23, 59, 59)); |
| return dateArray; |
| case THIS_MONTH: |
| dateArray[0] = convertToDate(today.withDayOfMonth(1)); |
| dateArray[1] = convertToDate(today.withDayOfMonth(1).plusMonths(1).minusDays(1).atTime(23, 59, 59)); |
| return dateArray; |
| case MANUALLY: |
| default: |
| dateArray[0] = convertToDate(today.atTime(0, 0, 0)); |
| dateArray[1] = convertToDate(today.atTime(0, 0, 0)); |
| return dateArray; |
| } |
| } |
| |
| private Date convertToDate(LocalDate value) { |
| |
| if (value != null) { |
| return Date.from(value.atStartOfDay() |
| .atZone(ZoneId.systemDefault()) |
| .toInstant()); |
| } |
| |
| return null; |
| } |
| |
| private Date convertToDate(LocalDateTime value) { |
| |
| if (value != null) { |
| return Date.from(value.atZone(ZoneId.systemDefault()) |
| .toInstant()); |
| } |
| |
| return null; |
| } |
| |
| private boolean isDefaultDateUpdateFlagFrom() { |
| return defaultDateUpdateFlagFrom; |
| } |
| |
| private boolean isDefaultDateUpdateFlagUntil() { |
| return defaultDateUpdateFlagUntil; |
| } |
| |
| private void setDefaultDateUpdateFlagFrom(boolean defaultDateUpdateFlagFrom) { |
| this.defaultDateUpdateFlagFrom = defaultDateUpdateFlagFrom; |
| } |
| |
| private void setDefaultDateUpdateFlagUntil(boolean defaultDateUpdateFlagUntil) { |
| this.defaultDateUpdateFlagUntil = defaultDateUpdateFlagUntil; |
| } |
| |
| private String getFormat(DatamartFilter.DateTimeFormat format, DatamartFilter.DateResolution resolution) { |
| DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT); |
| String pattern = ((SimpleDateFormat)formatter).toPattern(); |
| String dateFormat = null; |
| if (format != null) { |
| switch (format) { |
| case DATE: |
| switch (resolution) { |
| case YEAR: |
| dateFormat = filterFormat(pattern, "yyyy"); |
| break; |
| case MONTH: |
| dateFormat = filterFormat(pattern, "yyyy.MM"); |
| break; |
| case DAY: |
| dateFormat = filterFormat(pattern, "yyyy.MM.dd"); |
| break; |
| default: |
| throw new IllegalArgumentException(resolution |
| + " is not a valid resolution for " + format); |
| } |
| break; |
| case DATE_TIME: |
| switch (resolution) { |
| case YEAR: |
| dateFormat = filterFormat(pattern, "yyyy"); |
| break; |
| case MONTH: |
| dateFormat = filterFormat(pattern, "yyyy.MM"); |
| break; |
| case DAY: |
| dateFormat = filterFormat(pattern, "yyyy.MM.dd"); |
| break; |
| case HOUR: |
| dateFormat = filterFormat(pattern, "yyyy.MM.dd hhHH"); |
| break; |
| case MINUTE: |
| dateFormat = filterFormat(pattern, "yyyy.MM.dd hhHH:mm"); |
| break; |
| case SECOND: |
| dateFormat = filterFormat(pattern, "yyyy.MM.dd hhHH:mm:ss"); |
| break; |
| default: |
| throw new IllegalArgumentException(resolution |
| + " is not a valid resolution for " + format); |
| } |
| break; |
| case TIME: |
| switch (resolution) { |
| case HOUR: |
| dateFormat = filterFormat(pattern, "HH"); |
| break; |
| case MINUTE: |
| dateFormat = filterFormat(pattern, "HH:mm"); |
| break; |
| case SECOND: |
| dateFormat = filterFormat(pattern, "HH:mm:ss"); |
| break; |
| default: |
| throw new IllegalArgumentException(resolution |
| + " is not a valid resolution for " + format); |
| } |
| break; |
| } |
| } |
| return dateFormat; |
| } |
| |
| /** |
| * filters from any localized date-time pattern the desired subset |
| * defined by filterPattern without destroying the original localized |
| * pattern . |
| * |
| * @param localizedPattern |
| * the localized full date-time pattern |
| * @param filterPattern |
| * the subset of desired date-time formatter patterns |
| * @return the string |
| */ |
| private String filterFormat(String localizedPattern, String filterPattern) { |
| // remove any multiple characters sequences and remove all separator signs from filterPattern |
| String filter = filterPattern.replaceAll("(.)\\1+", "$1").replaceAll("[^\\w\\s]", "")+","; |
| // create a replacement pattern to remove unnecessary blanks disturbing the recognition of orphaned separators |
| // rule: each blank must be surrounded by any filter-letter to be valid |
| String invalidBlanks = "(?!["+filter+"])( )(?!["+filter+"])"; |
| // create a replacement pattern to remove remaining separators without formatting function |
| // rule: each separator must be surrounded by any filter-letter or blank to be valid |
| String invalidSeparators = "(?!["+filter+" ])([.:])(?!["+filter+" ])"; |
| return localizedPattern.replaceAll("[^"+filter+",.: ]", "").replaceAll(invalidBlanks, "").trim().replaceAll(invalidSeparators, ""); |
| } |
| |
| /** |
| * Map to vaadin. |
| * |
| * @param resolution |
| * the resolution |
| * @return the resolution |
| */ |
| private Resolution mapToVaadin(DatamartFilter.DateResolution resolution) { |
| switch (resolution) { |
| case YEAR: |
| return Resolution.YEAR; |
| case MONTH: |
| return Resolution.MONTH; |
| case DAY: |
| return Resolution.DAY; |
| case HOUR: |
| return Resolution.HOUR; |
| case MINUTE: |
| return Resolution.MINUTE; |
| case SECOND: |
| return Resolution.SECOND; |
| case UNDEFINED: |
| return Resolution.DAY; |
| } |
| |
| return Resolution.DAY; |
| } |
| |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.xtext.datamart.common.IDatamartBetweenInput#getFrom() |
| */ |
| @Override |
| public String getFrom() { |
| return fromInput.getValue() != null ? formatter.format(fromInput.getValue()) : ""; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.xtext.datamart.common.IDatamartBetweenInput#setFrom(java |
| * .lang.String) |
| */ |
| @Override |
| public void setFrom(String from) { |
| try { |
| fromInput.setValue(formatter.parse(from)); |
| } catch (ReadOnlyException | ConversionException | ParseException e) { |
| LOGGER.error("DateParseError on setFrom method!", e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.xtext.datamart.common.IDatamartBetweenInput#getUntil() |
| */ |
| @Override |
| public String getUntil() { |
| return untilInput.getValue() != null ? formatter.format(untilInput.getValue()) : ""; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.xtext.datamart.common.IDatamartBetweenInput#setUntil( |
| * java.lang.String) |
| */ |
| @Override |
| public void setUntil(String until) { |
| try { |
| untilInput.setValue(formatter.parse(until)); |
| } catch (ReadOnlyException | ConversionException | ParseException e) { |
| LOGGER.error("DateParseError on setUntil method!", e); |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| public DateField getFromInput() { |
| return fromInput; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public DateField getUntilInput() { |
| return untilInput; |
| } |
| |
| @Override |
| public void addValueChangeListener(ValueChangeListener listener) { |
| fromInput.addValueChangeListener(listener); |
| untilInput.addValueChangeListener(listener); |
| } |
| |
| @Override |
| public void removeValueChangeListener(ValueChangeListener listener) { |
| fromInput.removeValueChangeListener(listener); |
| untilInput.removeValueChangeListener(listener); |
| } |
| |
| @Override |
| public void setDescription(String description) { |
| fromInput.setDescription("[" + description); |
| untilInput.setDescription(description + "]"); |
| } |
| |
| public void setLocale(Locale locale){ |
| formatter = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale); |
| fromInput.setDateFormat(formatter.toPattern()); |
| untilInput.setDateFormat(formatter.toPattern()); |
| } |
| |
| public SimpleDateFormat getFormatter() { |
| return formatter; |
| } |
| |
| } |