dhbw.clippinggorilla.userinterface.windows.PreferencesWindow.java Source code

Java tutorial

Introduction

Here is the source code for dhbw.clippinggorilla.userinterface.windows.PreferencesWindow.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dhbw.clippinggorilla.userinterface.windows;

import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.AbstractErrorMessage;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Page;
import com.vaadin.server.UserError;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.shared.ui.datefield.DateTimeResolution;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.InlineDateTimeField;
import com.vaadin.ui.Label;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.ProgressBar;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.ValoTheme;
import dhbw.clippinggorilla.external.mailserver.Mail;
import dhbw.clippinggorilla.objects.user.User;
import dhbw.clippinggorilla.objects.user.UserUtils;
import dhbw.clippinggorilla.utilities.language.Language;
import dhbw.clippinggorilla.utilities.language.Word;
import dhbw.clippinggorilla.utilities.log.Log;
import dhbw.clippinggorilla.utilities.ressources.Props;
import dhbw.clippinggorilla.utilities.ui.VaadinUtils;
import java.time.Clock;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;

/**
 * This is the preferences window
 *
 * @author frank
 */
public class PreferencesWindow extends Window {

    public static Window get(User user) {
        return new PreferencesWindow(user);
    }

    public PreferencesWindow(User user) {
        //setHeight("480px");
        //setWidth("720px");

        VerticalLayout windowContent = new VerticalLayout();
        windowContent.setWidth("100%");
        windowContent.setHeight("100%");
        windowContent.setMargin(new MarginInfo(true, false, false, false));

        TabSheet preferencesCategories = new TabSheet();
        preferencesCategories.setWidth("100%");
        preferencesCategories.setHeight("100%");
        preferencesCategories.addStyleName(ValoTheme.TABSHEET_PADDED_TABBAR);
        preferencesCategories.addStyleName(ValoTheme.TABSHEET_ICONS_ON_TOP);
        preferencesCategories.addStyleName(ValoTheme.TABSHEET_CENTERED_TABS);
        windowContent.addComponent(preferencesCategories);
        windowContent.setExpandRatio(preferencesCategories, 1f);

        preferencesCategories.addComponent(buildUserTab(user));
        preferencesCategories.addComponent(buildClippingsTab(user));
        preferencesCategories.addComponent(buildSupportTab(user));
        preferencesCategories.setSelectedTab(0);

        windowContent.addComponent(buildFooter(user));

        setContent(windowContent);
        setModal(true);
        addCloseShortcut(KeyCode.ENTER, null);
        setResizable(false);
        setClosable(false);
        setHeight("480px");
        setWidth("720px");
    }

    TextField firstNameField;
    TextField lastNameField;
    TextField usernameField;
    TextField emailField;
    PasswordField oldPasswordField;
    PasswordField password1Field;
    PasswordField password2Field;

    private Component buildUserTab(User user) {
        HorizontalLayout root = new HorizontalLayout();
        root.setCaption(Language.get(Word.PROFILE));
        root.setIcon(VaadinIcons.USER);
        root.setWidth("100%");
        root.setSpacing(true);
        root.setMargin(true);

        FormLayout details = new FormLayout();
        details.addStyleName(ValoTheme.FORMLAYOUT_LIGHT);
        root.addComponent(details);

        firstNameField = new TextField(Language.get(Word.FIRST_NAME));
        firstNameField.setValue(user.getFirstName());
        firstNameField.setMaxLength(20);
        firstNameField.addValueChangeListener(event -> {
            String firstNameError = UserUtils.checkName(event.getValue());
            if (!firstNameError.isEmpty()) {
                firstNameField.setComponentError(new UserError(firstNameError,
                        AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION));
                VaadinUtils.infoNotification(firstNameError);
                saveButton.setEnabled(setError(firstNameField, true));
            } else {
                firstNameField.setComponentError(null);
                boolean enabled = setError(firstNameField, false);
                saveButton.setEnabled(enabled);
            }
        });
        setError(firstNameField, false);

        lastNameField = new TextField(Language.get(Word.LAST_NAME));
        lastNameField.setValue(user.getLastName());
        lastNameField.setMaxLength(20);
        lastNameField.addValueChangeListener(event -> {
            String lastNameError = UserUtils.checkName(event.getValue());
            if (!lastNameError.isEmpty()) {
                lastNameField.setComponentError(new UserError(lastNameError, AbstractErrorMessage.ContentMode.HTML,
                        ErrorMessage.ErrorLevel.INFORMATION));
                VaadinUtils.infoNotification(lastNameError);
                saveButton.setEnabled(setError(lastNameField, true));
            } else {
                lastNameField.setComponentError(null);
                saveButton.setEnabled(setError(lastNameField, false));
            }
        });
        setError(lastNameField, false);

        usernameField = new TextField(Language.get(Word.USERNAME));
        usernameField.setValue(user.getUsername());
        usernameField.setMaxLength(20);
        usernameField.addValueChangeListener(event -> {
            if (!event.getValue().equals(user.getUsername())) {
                String userNameError = UserUtils.checkUsername(event.getValue());
                if (!userNameError.isEmpty()) {
                    usernameField.setComponentError(new UserError(userNameError,
                            AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION));
                    VaadinUtils.infoNotification(userNameError);
                    saveButton.setEnabled(setError(usernameField, true));
                } else {
                    usernameField.setComponentError(null);
                    saveButton.setEnabled(setError(usernameField, false));
                }
            } else {
                usernameField.setComponentError(null);
                saveButton.setEnabled(setError(usernameField, false));
            }
        });
        setError(usernameField, false);

        emailField = new TextField(Language.get(Word.EMAIL));
        emailField.setValue(user.getEmail());
        emailField.setMaxLength(256);
        emailField.addValueChangeListener(event -> {
            if (!event.getValue().equals(user.getEmail())) {
                String email1Error = UserUtils.checkEmail(event.getValue().toLowerCase());
                if (!email1Error.isEmpty()) {
                    emailField.setComponentError(new UserError(email1Error, AbstractErrorMessage.ContentMode.HTML,
                            ErrorMessage.ErrorLevel.INFORMATION));
                    VaadinUtils.infoNotification(email1Error);
                    saveButton.setEnabled(setError(emailField, true));
                } else {
                    emailField.setComponentError(null);
                    saveButton.setEnabled(setError(emailField, false));
                }
            } else {
                emailField.setComponentError(null);
                saveButton.setEnabled(setError(emailField, false));
            }
        });
        setError(emailField, false);

        oldPasswordField = new PasswordField(Language.get(Word.OLD_PASSWORD));
        oldPasswordField.setValue("");
        oldPasswordField.setMaxLength(51);
        oldPasswordField.addValueChangeListener(event -> {
            if (!event.getValue().isEmpty()) {
                String password1Error = UserUtils.checkPassword(event.getValue());
                if (!password1Error.isEmpty()) {
                    oldPasswordField.setComponentError(new UserError(password1Error,
                            AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION));
                    VaadinUtils.infoNotification(password1Error);
                    saveButton.setEnabled(setError(oldPasswordField, true));
                } else {
                    oldPasswordField.setComponentError(null);
                    saveButton.setEnabled(setError(oldPasswordField, false));
                }
            } else {
                oldPasswordField.setComponentError(null);
                saveButton.setEnabled(setError(oldPasswordField, false));
            }
        });
        setError(oldPasswordField, false);

        ProgressBar strength = new ProgressBar();

        password1Field = new PasswordField(Language.get(Word.PASSWORD));
        password1Field.setValue("");
        password1Field.setMaxLength(51);
        password1Field.addValueChangeListener(event -> {
            if (!event.getValue().isEmpty()) {
                String password1Error = UserUtils.checkPassword(event.getValue());
                strength.setValue(UserUtils.calculatePasswordStrength(event.getValue()));
                if (!password1Error.isEmpty()) {
                    password1Field.setComponentError(new UserError(password1Error,
                            AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION));
                    VaadinUtils.infoNotification(password1Error);
                    saveButton.setEnabled(setError(password1Field, true));
                } else {
                    password1Field.setComponentError(null);
                    saveButton.setEnabled(setError(password1Field, false));
                }
            } else {
                password1Field.setComponentError(null);
                saveButton.setEnabled(setError(password1Field, false));
            }
        });
        setError(password1Field, false);

        strength.setWidth("184px");
        strength.setHeight("1px");

        password2Field = new PasswordField(Language.get(Word.PASSWORD_AGAIN));
        password2Field.setValue("");
        password2Field.setMaxLength(51);
        password2Field.addValueChangeListener(event -> {
            if (!event.getValue().isEmpty()) {
                String password2Error = UserUtils.checkPassword(event.getValue())
                        + UserUtils.checkSecondPassword(password1Field.getValue(), event.getValue());
                if (!password2Error.isEmpty()) {
                    password2Field.setComponentError(new UserError(password2Error,
                            AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION));
                    VaadinUtils.infoNotification(password2Error);
                    saveButton.setEnabled(setError(password2Field, true));
                } else {
                    password2Field.setComponentError(null);
                    saveButton.setEnabled(setError(password2Field, false));
                }
            } else {
                password2Field.setComponentError(null);
                saveButton.setEnabled(setError(password2Field, false));
            }
        });
        setError(password2Field, false);

        details.addComponents(firstNameField, lastNameField, usernameField, emailField, oldPasswordField,
                password1Field, strength, password2Field);

        return root;
    }

    private VerticalLayout layoutClippingTimes;
    //    private final int offsetInSec = Page.getCurrent().getWebBrowser().getTimezoneOffset() / 1000;
    //    private final ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetInSec);

    private Component buildClippingsTab(User user) {
        HorizontalLayout root = new HorizontalLayout();
        root.setCaption(Language.get(Word.CLIPPINGS));
        root.setIcon(VaadinIcons.NEWSPAPER);
        root.setWidth("100%");
        root.setSpacing(true);
        root.setMargin(true);

        FormLayout formLayoutClippingDetails = new FormLayout();
        formLayoutClippingDetails.addStyleName(ValoTheme.FORMLAYOUT_LIGHT);
        root.addComponent(formLayoutClippingDetails);

        CheckBox checkBoxReceiveEmails = new CheckBox();
        checkBoxReceiveEmails.setValue(UserUtils.getEmailNewsletter(user));
        checkBoxReceiveEmails.addValueChangeListener(v -> UserUtils.setEmailNewsletter(user, v.getValue()));
        HorizontalLayout layoutCheckBoxReceiveEmails = new HorizontalLayout(checkBoxReceiveEmails);
        layoutCheckBoxReceiveEmails.setCaption(Language.get(Word.EMAIL_SUBSCRIPTION));
        layoutCheckBoxReceiveEmails.setMargin(false);
        layoutCheckBoxReceiveEmails.setSpacing(false);

        HorizontalLayout layoutAddNewClippingTime = new HorizontalLayout();
        layoutAddNewClippingTime.setMargin(false);
        layoutAddNewClippingTime.setCaption(Language.get(Word.ADD_CLIPPING_TIME));
        layoutAddNewClippingTime.setWidth("100%");

        InlineDateTimeField dateFieldNewClippingTime = new InlineDateTimeField();
        LocalDateTime value = LocalDateTime.now(ZoneId.of("Europe/Berlin"));
        dateFieldNewClippingTime.setValue(value);
        dateFieldNewClippingTime.setLocale(VaadinSession.getCurrent().getLocale());
        dateFieldNewClippingTime.setResolution(DateTimeResolution.MINUTE);
        dateFieldNewClippingTime.addStyleName("time-only");

        Button buttonAddClippingTime = new Button();
        buttonAddClippingTime.setIcon(VaadinIcons.PLUS);
        buttonAddClippingTime.addStyleName(ValoTheme.BUTTON_PRIMARY);
        buttonAddClippingTime.setClickShortcut(ShortcutAction.KeyCode.ENTER, null);
        buttonAddClippingTime.addClickListener(e -> {
            LocalTime generalTime = dateFieldNewClippingTime.getValue().toLocalTime();
            layoutClippingTimes.addComponent(getTimeRow(user, generalTime));
            UserUtils.addClippingSendTime(user, generalTime);
        });
        layoutAddNewClippingTime.addComponents(dateFieldNewClippingTime, buttonAddClippingTime);
        layoutAddNewClippingTime.setComponentAlignment(dateFieldNewClippingTime, Alignment.MIDDLE_LEFT);
        layoutAddNewClippingTime.setComponentAlignment(buttonAddClippingTime, Alignment.MIDDLE_CENTER);
        layoutAddNewClippingTime.setExpandRatio(dateFieldNewClippingTime, 5);

        layoutClippingTimes = new VerticalLayout();
        layoutClippingTimes.setMargin(new MarginInfo(true, false, false, true));
        layoutClippingTimes.setCaption(Language.get(Word.CLIPPING_TIMES));
        layoutClippingTimes.setWidth("100%");
        layoutClippingTimes.addStyleName("times");

        Set<LocalTime> userTimes = user.getClippingTime();
        userTimes.forEach(t -> layoutClippingTimes.addComponent(getTimeRow(user, t)));

        formLayoutClippingDetails.addComponents(layoutCheckBoxReceiveEmails, layoutAddNewClippingTime,
                layoutClippingTimes);

        return root;
    }

    private Component getTimeRow(User user, LocalTime time) {
        HorizontalLayout layoutTimeRow = new HorizontalLayout();
        layoutTimeRow.setWidth("100%");

        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
        Label labelTime = new Label(time.format(formatter));

        Button buttonDelete = new Button(VaadinIcons.TRASH);
        buttonDelete.addStyleName(ValoTheme.BUTTON_DANGER);
        buttonDelete.setWidth("80px");
        buttonDelete.addClickListener(e -> {
            if (layoutClippingTimes.getComponentCount() > 1) {
                layoutClippingTimes.removeComponent(layoutTimeRow);
                UserUtils.removeClippingSendTime(user, time);
            } else {
                VaadinUtils.errorNotification(Language.get(Word.AT_LREAST_ONE_TIME));
            }
        });

        layoutTimeRow.addComponents(labelTime, buttonDelete);
        layoutTimeRow.setComponentAlignment(labelTime, Alignment.MIDDLE_LEFT);
        layoutTimeRow.setComponentAlignment(buttonDelete, Alignment.MIDDLE_CENTER);
        layoutTimeRow.setExpandRatio(labelTime, 5);

        return layoutTimeRow;
    }

    private Button saveButton = new Button();

    private Component buildFooter(User user) {
        HorizontalLayout footer = new HorizontalLayout();
        footer.addStyleName(ValoTheme.WINDOW_BOTTOM_TOOLBAR);
        footer.setWidth(100.0f, Unit.PERCENTAGE);

        Button cancelButton = new Button(Language.get(Word.CANCEL));
        cancelButton.setIcon(VaadinIcons.CLOSE);
        cancelButton.addClickListener(event -> {
            close();
        });

        saveButton = new Button(Language.get(Word.SAVE));
        saveButton.setIcon(VaadinIcons.CHECK);
        saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
        saveButton.addClickListener(event -> {
            boolean error = false;
            if (!user.getFirstName().equals(firstNameField.getValue())) {
                boolean success = UserUtils.changeFirstName(user, firstNameField.getValue());
                if (!success) {
                    error = true;
                }
            }
            if (!user.getLastName().equals(lastNameField.getValue())) {
                boolean success = UserUtils.changeLastName(user, lastNameField.getValue());
                if (!success) {
                    error = true;
                }
            }
            if (!user.getUsername().equals(usernameField.getValue())) {
                boolean success = UserUtils.changeUsername(user, usernameField.getValue());
                if (!success) {
                    error = true;
                }
            }
            if (!user.getEmail().equals(emailField.getValue())) {
                UI.getCurrent().addWindow(ActivateWindow.get());
                boolean success = UserUtils.changeEmail(user, user.getEmail(), emailField.getValue(),
                        emailField.getValue());
                if (!success) {
                    error = true;
                }
            }
            boolean wrongPW = false;
            if (!password1Field.isEmpty() && password1Field.getValue().equals(password2Field.getValue())) {
                wrongPW = !UserUtils.changePassword(user, oldPasswordField.getValue(), password1Field.getValue(),
                        password2Field.getValue());
            }
            if (error) {
                VaadinUtils.errorNotification(Language.get(Word.UNEXPECTED_ERROR));
            } else if (wrongPW) {
                VaadinUtils.errorNotification(Language.get(Word.WRONG_PASSWORD));
            } else {
                VaadinUtils.infoNotification(Language.get(Word.SUCCESSFULLY_SAVED));
                close();
            }
        });
        saveButton.focus();

        Label placeholder = new Label();

        footer.addComponents(placeholder, cancelButton, saveButton);
        footer.setExpandRatio(placeholder, 5);
        footer.setComponentAlignment(cancelButton, Alignment.TOP_CENTER);
        footer.setComponentAlignment(saveButton, Alignment.TOP_CENTER);
        return footer;
    }

    private final HashMap<Component, Boolean> errors = new HashMap<>();

    public boolean setError(Component toBeChecked, boolean error) {
        errors.put(toBeChecked, error);
        return errors.size() == 7 && errors.values().stream().allMatch(v -> v == false);
    }

    static HashMap<User, Map<LocalDate, Integer>> emailsSend = new HashMap<>();

    private Component buildSupportTab(User user) {
        VerticalLayout root = new VerticalLayout();
        root.setCaption(Language.get(Word.SUPPORT));
        root.setIcon(VaadinIcons.HEADSET);
        root.setWidth("100%");
        root.setHeight("100%");
        root.setSpacing(true);
        root.setMargin(true);

        TextArea textAreaMessage = new TextArea(Language.get(Word.MESSAGE));
        textAreaMessage.setWidth("100%");
        textAreaMessage.setHeight("100%");

        Button buttonSend = new Button(Language.get(Word.SEND), VaadinIcons.ENVELOPE);
        buttonSend.addStyleName(ValoTheme.BUTTON_PRIMARY);
        buttonSend.addClickListener(ce -> {
            try {
                if (emailsSend.containsKey(user)) {
                    Map<LocalDate, Integer> times = emailsSend.get(user);
                    if (times.containsKey(LocalDate.now())) {
                        if (times.get(LocalDate.now()) > 3) {
                            if (times.get(LocalDate.now()) > 15) {
                                UserUtils.banUser(user);
                                VaadinUtils.errorNotification("BANNED DUE TO TOO MUCH EMAILS");
                            } else {
                                VaadinUtils.errorNotification("TOO MUCH EMAILS");
                            }
                            return;
                        } else {
                            times.put(LocalDate.now(), times.get(LocalDate.now()) + 1);
                        }
                    } else {
                        times.put(LocalDate.now(), 1);
                    }
                } else {
                    HashMap<LocalDate, Integer> times = new HashMap<>();
                    times.put(LocalDate.now(), 1);
                    emailsSend.put(user, times);
                }
                Mail.send(Props.get("supportmail"), "SUPPORT", user.toString() + "\n" + textAreaMessage.getValue());
                VaadinUtils.middleInfoNotification(Language.get(Word.SUCCESSFULLY_SEND));
                textAreaMessage.clear();
            } catch (EmailException ex) {
                VaadinUtils.errorNotification(Language.get(Word.SEND_FAILED));
                Log.error("Could not send Supportmail: ", ex);
            }
        });

        root.addComponents(textAreaMessage, buttonSend);
        root.setExpandRatio(textAreaMessage, 5);
        root.setComponentAlignment(buttonSend, Alignment.MIDDLE_LEFT);

        return root;
    }

}