package com.constellio.app.ui.framework.components; import com.constellio.app.ui.framework.buttons.AddButton; import com.vaadin.data.Property; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.data.util.NestedMethodProperty; import com.vaadin.server.Resource; import com.vaadin.server.ThemeResource; import com.vaadin.ui.*; import com.vaadin.ui.themes.ValoTheme; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.joda.time.Duration; import java.util.*; import static com.constellio.app.ui.i18n.i18n.$; public class ScheduleComponent extends HorizontalLayout implements Property.ValueChangeListener { private static final String DELETE = "delete"; private static final String ADD = "add"; private static final Resource DELETE_ICON_RESOURCE = new ThemeResource("images/commun/supprimer.gif"); private static final String HOUR_ROUNDED_SUFFIX = ":00"; private static final String HALF_HOUR_ROUNDED_SUFFIX = ":30"; private static final List<String> options = Arrays.asList(new String[] {"ldap.syncConfiguration.schedule.time", "ldap.syncConfiguration.durationBetweenExecution"}); private BeanItemContainer<TimeBean> timeBeanContainer = new BeanItemContainer<>(TimeBean.class); private TextField daysComponent; private TextField hoursComponent; private TextField minComponent; private Layout scheduleTimeLayout; private Layout periodLayout; public ScheduleComponent(final List<String> timeList, final Duration period) { setSizeFull(); addStyleName(ValoTheme.PANEL_BORDERLESS); final OptionGroup scheduleOptions = buildOptionsComponent(); scheduleTimeLayout = buildTimeListTableComponent(timeList); addComponent(scheduleTimeLayout); periodLayout = buildPeriodComponent(period); addComponent(periodLayout); if (CollectionUtils.isEmpty(timeList)) { scheduleOptions.unselect(options.get(0)); scheduleTimeLayout.setVisible(false); } else { scheduleOptions.select(options.get(0)); } if (period == null) { scheduleOptions.unselect(options.get(1)); periodLayout .setVisible(false); } else { scheduleOptions.select(options.get(1)); } } private OptionGroup buildOptionsComponent() { final OptionGroup scheduleOptions = new OptionGroup($("ldap.syncConfiguration.schedule"), options); for (final String option : options) { scheduleOptions.setItemCaption(option, $(option)); } scheduleOptions.setNullSelectionAllowed(true); scheduleOptions.setImmediate(true); scheduleOptions.addValueChangeListener(this); addComponent(scheduleOptions); return scheduleOptions; } private Layout buildTimeListTableComponent(final List<String> timeList) { final Layout horizontalLayout = new HorizontalLayout(); horizontalLayout.setSizeFull(); final Table table = new Table(); timeBeanContainer = new BeanItemContainer<>(TimeBean.class); setTimeList(timeList); table.setContainerDataSource(timeBeanContainer); table.setSizeFull(); table.setPageLength(table.size()); table.setEditable(true); table.setColumnHeaderMode(Table.ColumnHeaderMode.HIDDEN); table.addGeneratedColumn(TimeBean.TIME_PROPERTY_NAME, new Table.ColumnGenerator() { public Object generateCell(Table source, Object itemId, Object columnId) { final ComboBox comboBox = new ComboBox(); for (int scheduleTime = 0; scheduleTime < 24; scheduleTime++) { comboBox.addItem(scheduleTime + HOUR_ROUNDED_SUFFIX); comboBox.addItem(scheduleTime + HALF_HOUR_ROUNDED_SUFFIX); } comboBox.setPropertyDataSource(new NestedMethodProperty<String>(itemId, TimeBean.TIME_PROPERTY_NAME)); return comboBox; } }); table.addGeneratedColumn(DELETE, new Table.ColumnGenerator() { public Object generateCell(final Table source, final Object itemId, Object columnId) { final Button removeButton = new Button(); removeButton.setIcon(DELETE_ICON_RESOURCE); removeButton.setEnabled(source.size() > 1); removeButton.addClickListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { timeBeanContainer.removeItem(itemId); source.setPageLength(source.size()); } }); return removeButton; } }); horizontalLayout.addComponent(table); horizontalLayout.addComponent(new AddButton($(ADD)) { @Override protected void buttonClick(ClickEvent event) { timeBeanContainer.addItem(new TimeBean()); table.setPageLength(table.size()); } }); return horizontalLayout; } private void setTimeList(final List<String> timeList) { timeBeanContainer.removeAllItems(); if (CollectionUtils.isEmpty(timeList)) { timeBeanContainer.addItem(new TimeBean()); } else { for (final String time : timeList) { timeBeanContainer.addItem(new TimeBean(time)); } } } private Layout buildPeriodComponent(final Duration peroid) { final Layout horizontalLayout = new HorizontalLayout(); daysComponent = new TextField($("days")); //daysComponent.addValidator(new IntegerRangeValidator($("com.vaadin.data.validator.IntegerRangeValidator_withMinValue"), 0, 100)); horizontalLayout.addComponent(daysComponent); hoursComponent = new TextField($("hours")); //hoursComponent.addValidator(new IntegerRangeValidator($("com.vaadin.data.validator.IntegerRangeValidator"), 0, 23)); horizontalLayout.addComponent(hoursComponent); minComponent = new TextField($("mns")); //minComponent.addValidator(new IntegerRangeValidator($("com.vaadin.data.validator.IntegerRangeValidator"), 0, 59)); horizontalLayout.addComponent(minComponent); setPeriod(peroid); return horizontalLayout; } public void setPeriod(Duration period) { long days = 0, hours = 0, mns = 0; if (period != null) { days = period.getStandardDays(); hours = period.getStandardHours() % 24; mns = period.getStandardMinutes() % 60; } daysComponent.setValue(days + ""); hoursComponent.setValue(hours + ""); minComponent.setValue(mns + ""); } @Override public void valueChange(Property.ValueChangeEvent event) { if (options.get(0).equals(event.getProperty().getValue())) { scheduleTimeLayout.setVisible(true); periodLayout.setVisible(false); setPeriod(null); } else { scheduleTimeLayout.setVisible(false); setTimeList(null); periodLayout.setVisible(true); } } public List<String> getTimeList() { final List<String> timeList = new ArrayList<>(timeBeanContainer.size()); for (final TimeBean timeBean : timeBeanContainer.getItemIds()) { if ((timeBean == null) || (timeBean.getTime() == null) || (timeBean.getTime().isEmpty()) || (timeList.contains(timeBean.getTime()))) { continue; } timeList.add(timeBean.getTime()); } Collections.sort(timeList); return timeList; } public Duration getPeriod() { Integer days = 0, hours = 0, mns = 0; if (StringUtils.isNotBlank(daysComponent.getValue())) { days = Integer.valueOf(daysComponent.getValue()); } if (StringUtils.isNotBlank(hoursComponent.getValue())) { hours = Integer.valueOf(hoursComponent.getValue()); } if (StringUtils.isNotBlank(minComponent.getValue())) { mns = Integer.valueOf(minComponent.getValue()); } long durationInMilliSeconds = ((((days * 24) + hours) * 60) + mns) * 60 * 1000; return new Duration(durationInMilliSeconds); } protected static class TimeBean { public static final String TIME_PROPERTY_NAME = "time"; private String time; public TimeBean() { time = ""; } public TimeBean(String time) { this.time = time; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } @Override public String toString() { return time; } } }