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

Java tutorial

Introduction

Here is the source code for dhbw.clippinggorilla.userinterface.windows.NewSourceWindow.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.KeyCode;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.Sizeable;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.Registration;
import com.vaadin.shared.ui.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Image;
import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.RadioButtonGroup;
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.objects.category.Category;
import dhbw.clippinggorilla.objects.crawler.Crawler;
import dhbw.clippinggorilla.objects.crawler.CrawlerUtils;
import dhbw.clippinggorilla.objects.article.Article;
import dhbw.clippinggorilla.objects.article.ArticleUtils;
import dhbw.clippinggorilla.objects.source.Source;
import dhbw.clippinggorilla.objects.source.SourceUtils;
import dhbw.clippinggorilla.utilities.language.Language;
import dhbw.clippinggorilla.utilities.language.Word;
import dhbw.clippinggorilla.utilities.log.Log;
import dhbw.clippinggorilla.utilities.ui.VaadinUtils;
import eu.maxschuster.vaadin.famfamflags.FamFamFlags;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.LocaleUtils;

/**
 * This is the window to create a new source
 * @author frank
 */
public class NewSourceWindow extends Window {

    public static Window create() {
        return new NewSourceWindow();
    }

    public static Window createEditMode(Source s) {
        return new NewSourceWindow(s);
    }

    public NewSourceWindow() {
        setModal(true);
        setSizeUndefined();
        setDraggable(true);
        addCloseShortcut(KeyCode.ENTER, null);
        setContent(getFirstStage());
    }

    public NewSourceWindow(Source s) {
        setModal(true);
        setSizeUndefined();
        setDraggable(true);
        addCloseShortcut(KeyCode.ENTER, null);
        setContent(getSecondStage(s));
    }

    public Component getFirstStage() {
        Label header = new Label(Language.get(Word.RSS));
        header.addStyleName(ValoTheme.LABEL_H1);

        FormLayout forms = new FormLayout();
        forms.setSizeFull();

        TextField rssField = new TextField(Language.get(Word.RSS));
        rssField.setWidth("750px");
        forms.addComponents(rssField);

        Runnable cancel = () -> close();
        Runnable next = () -> validateFirstStage(rssField.getValue());

        VerticalLayout windowLayout = new VerticalLayout();
        windowLayout.addComponents(header, forms, getFooter(cancel, next));
        windowLayout.setComponentAlignment(header, Alignment.MIDDLE_CENTER);
        return windowLayout;
    }

    public void validateFirstStage(String url) {
        try {
            Source s = SourceUtils.createSourceFromRSS(url).join();
            setContent(getSecondStage(s));
            ArticleUtils.parseAndCrawlArticlesFromRSS(s);
            //center();
        } catch (Exception e) {
            VaadinUtils.errorNotification("Could not read RSS Feed");
            Log.debug("Could not read RSS Feed" + e);
        }
    }

    /**
     * If no value present, choose a empty string
     *
     * @param title
     * @param link
     * @param description
     * @param language
     * @param imageUrl
     * @return
     */
    private Component getSecondStage(Source s) {
        Label header = new Label(Language.get(Word.SOURCE));
        header.addStyleName(ValoTheme.LABEL_H1);

        FormLayout forms = new FormLayout();
        forms.setSizeFull();

        TextField textFieldId = new TextField(Language.get(Word.ID));
        textFieldId.setEnabled(false);
        textFieldId.setValue(s.getId());
        textFieldId.setWidth("750px");

        TextField textFieldName = new TextField(Language.get(Word.NAME));
        textFieldName.setValue(s.getName());
        textFieldName.setWidth("750px");

        TextField textFieldDescription = new TextField(Language.get(Word.DESCRIPTION));
        textFieldDescription.setValue(s.getDescription());
        textFieldDescription.setWidth("750px");

        TextField textFieldURL = new TextField(Language.get(Word.URL));
        if (s.getUrl() != null) {
            textFieldURL.setValue(s.getUrl().toExternalForm());
        }
        textFieldURL.setWidth("750px");

        ComboBox<Category> comboBoxCategories = new ComboBox<>(Language.get(Word.CATEGORY),
                EnumSet.allOf(Category.class));
        comboBoxCategories.setItemCaptionGenerator(c -> c.getName());
        comboBoxCategories.setItemIconGenerator(c -> c.getIcon());
        comboBoxCategories.setEmptySelectionAllowed(false);
        comboBoxCategories.setTextInputAllowed(false);
        comboBoxCategories.setWidth("375px");
        if (s.getCategory() != null) {
            comboBoxCategories.setSelectedItem(s.getCategory());
        }

        ComboBox<Locale> comboBoxLanguage = new ComboBox<>(Language.get(Word.LANGUAGE), getLanguages());
        comboBoxLanguage.setItemCaptionGenerator(l -> l.getDisplayLanguage(VaadinSession.getCurrent().getLocale()));
        comboBoxLanguage.setEmptySelectionAllowed(false);
        comboBoxLanguage.setWidth("375px");
        if (!s.getLanguage().isEmpty()) {
            Locale selected = new Locale(s.getLanguage());
            comboBoxLanguage.setSelectedItem(selected);
        }

        Locale loc = VaadinSession.getCurrent().getLocale();

        Map<String, Locale> countries = getCountries();
        List<Locale> locales = countries.values().parallelStream()
                .sorted((l1, l2) -> l1.getDisplayCountry(loc).compareTo(l2.getDisplayCountry(loc)))
                .collect(Collectors.toList());
        ComboBox<Locale> comboBoxCountry = new ComboBox<>(Language.get(Word.COUNTRY), locales);
        comboBoxCountry.setItemCaptionGenerator(l -> l.getDisplayCountry(VaadinSession.getCurrent().getLocale()));
        comboBoxCountry.setItemIconGenerator(l -> FamFamFlags.fromLocale(l));
        comboBoxCountry.setEmptySelectionAllowed(false);
        comboBoxCountry.setWidth("375px");
        if (!s.getCountry().isEmpty()) {
            comboBoxCountry.setSelectedItem(countries.getOrDefault(s.getCountry(), Locale.ROOT));
        }

        Image imageLogo = new Image(Language.get(Word.LOGO));

        TextField textFieldLogo = new TextField(Language.get(Word.LOGO_URL));
        if (s.getLogo() != null) {
            textFieldLogo.setValue(s.getLogo().toExternalForm());
            imageLogo.setSource(new ExternalResource(s.getLogo()));
        }
        textFieldLogo.addValueChangeListener(ce -> imageLogo.setSource(new ExternalResource(ce.getValue())));
        textFieldLogo.setWidth("750px");

        if (imageLogo.getHeight() > 125) {
            imageLogo.setHeight("125px");
        }

        forms.addComponents(textFieldId, textFieldName, textFieldDescription, textFieldURL, comboBoxCategories,
                comboBoxLanguage, comboBoxCountry, textFieldLogo, imageLogo);

        Runnable cancel = () -> close();
        Runnable next = () -> validateSecondStage(s, textFieldId.getValue(), textFieldName.getValue(),
                textFieldURL.getValue(), textFieldDescription.getValue(),
                comboBoxCategories.getSelectedItem().orElse(null),
                comboBoxLanguage.getSelectedItem().orElse(Locale.ROOT),
                comboBoxCountry.getSelectedItem().orElse(Locale.ROOT), textFieldLogo.getValue());

        VerticalLayout windowLayout = new VerticalLayout();
        windowLayout.addComponents(header, forms, getFooter(cancel, next));
        windowLayout.setComponentAlignment(header, Alignment.MIDDLE_CENTER);
        return windowLayout;
    }

    public void validateSecondStage(Source s, String id, String title, String url, String description,
            Category category, Locale language, Locale country, String imageUrl) {
        String errors = "";
        if (id == null || id.isEmpty()) {
            errors += "Empty Id<br>";
        }
        if (title == null || title.isEmpty()) {
            errors += "Empty Name<br>";
        }
        if (!isURL(url)) {
            errors += "Empty or invalid URL<br>";
        }
        if (description == null || description.isEmpty()) {
            errors += "Empty Description<br>";
        }
        if (category == null) {
            errors += "Empty Category<br>";
        }
        if (language == null || language.equals(Locale.ROOT)) {
            errors += "Empty Language<br>";
        }
        if (country == null || country.equals(Locale.ROOT)) {
            errors += "Empty Country<br>";
        }
        if (!isURL(imageUrl)) {
            errors += "Empty or invalid ImageURL";
        }
        if (!errors.isEmpty()) {
            VaadinUtils.errorNotification("Errors during Source setup<br>" + errors);
        } else {
            s.setName(title);
            s.setUrl(url);
            s.setDescription(description);
            s.setCategory(category.name());//Ignore possible null pointer, cant happen
            s.setLanguageAndCountry(language.getLanguage(), country.getCountry());//Ignore possible null pointer, cant happen
            s.setLogo(imageUrl);
            setContent(getThirdStage(s));
            center();
        }

    }

    Boolean include = true;
    Registration reg = null;

    public Component getThirdStage(Source s) {
        Label header = new Label(Language.get(Word.CRAWLER));
        header.addStyleName(ValoTheme.LABEL_H1);

        Crawler crawler;
        if (s.getCrawler() != null) {
            crawler = s.getCrawler();
        } else {
            crawler = new Crawler(s);
            s.setCrawler(crawler);
        }

        GridLayout mainGrid = new GridLayout(2, 2);
        mainGrid.setSizeFull();
        mainGrid.setSpacing(true);

        FormLayout layoutForms = new FormLayout();

        //Exclude or Include
        RadioButtonGroup<Boolean> radios = new RadioButtonGroup<>();
        radios.setItems(true, false);
        radios.setItemCaptionGenerator(b -> b ? Language.get(Word.INCLUDE_TAGS) : Language.get(Word.EXCLUDE_TAGS));
        radios.setItemIconGenerator(b -> b ? VaadinIcons.CHECK : VaadinIcons.CLOSE);
        radios.setSelectedItem(true);
        radios.addValueChangeListener(event -> include = event.getValue());

        //By Class
        CssLayout addByClassGroup = new CssLayout();
        addByClassGroup.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        TextField textFieldAddByClass = new TextField();
        textFieldAddByClass.setWidth("465px");
        Button buttonAddByClass = new Button(VaadinIcons.PLUS);
        buttonAddByClass.addClickListener(e -> {
            crawler.addByClass(textFieldAddByClass.getValue(), include);
            refreshList(mainGrid, crawler);
            textFieldAddByClass.clear();
        });
        addByClassGroup.addComponents(textFieldAddByClass, buttonAddByClass);
        addByClassGroup.setCaption(Language.get(Word.BYCLASS));

        //ByTag
        CssLayout addByTagGroup = new CssLayout();
        addByTagGroup.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        TextField textFieldAddByTag = new TextField();
        Button buttonAddByTag = new Button(VaadinIcons.PLUS);
        textFieldAddByTag.setWidth("465px");
        buttonAddByTag.addClickListener(e -> {
            crawler.addByTag(textFieldAddByTag.getValue(), include);
            refreshList(mainGrid, crawler);
            textFieldAddByTag.clear();
        });
        addByTagGroup.addComponents(textFieldAddByTag, buttonAddByTag);
        addByTagGroup.setCaption(Language.get(Word.BYTAG));

        //ByID
        CssLayout addByIDGroup = new CssLayout();
        addByIDGroup.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        TextField textFieldAddByID = new TextField();
        textFieldAddByID.setWidth("465px");
        Button buttonAddByID = new Button(VaadinIcons.PLUS);
        buttonAddByID.addClickListener(e -> {
            crawler.addByID(textFieldAddByID.getValue(), include);
            refreshList(mainGrid, crawler);
            textFieldAddByID.clear();
        });
        addByIDGroup.addComponents(textFieldAddByID, buttonAddByID);
        addByIDGroup.setCaption(Language.get(Word.BYID));

        //ByAttribute
        CssLayout addByAttributeGroup = new CssLayout();
        addByAttributeGroup.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        TextField textFieldAddByAttributeKey = new TextField();
        textFieldAddByAttributeKey.setWidth("233px");
        TextField textFieldAddByAttributeValue = new TextField();
        textFieldAddByAttributeValue.setWidth("232px");
        Button buttonAddByAttribute = new Button(VaadinIcons.PLUS);
        buttonAddByAttribute.addClickListener(e -> {
            crawler.addByAttribute(textFieldAddByAttributeKey.getValue(), textFieldAddByAttributeValue.getValue(),
                    include);
            refreshList(mainGrid, crawler);
            textFieldAddByAttributeKey.clear();
            textFieldAddByAttributeValue.clear();
        });
        addByAttributeGroup.addComponents(textFieldAddByAttributeKey, textFieldAddByAttributeValue,
                buttonAddByAttribute);
        addByAttributeGroup.setCaption(Language.get(Word.BYATTRIBUTEVALUE));

        layoutForms.addComponents(radios, addByClassGroup, addByTagGroup, addByIDGroup, addByAttributeGroup);
        mainGrid.addComponent(layoutForms);

        Label labelResult = new Label();
        Panel panelResult = new Panel(labelResult);
        labelResult.setWidth("100%");
        panelResult.setWidth("100%");
        panelResult.setHeight("175px");
        mainGrid.addComponent(panelResult, 0, 1, 1, 1);

        Button buttonTestURL = new Button();
        buttonTestURL.setIcon(VaadinIcons.EXTERNAL_LINK);
        buttonTestURL.setCaption(Language.get(Word.OPEN_LINK));

        Button buttonTest = new Button(Language.get(Word.TEST), VaadinIcons.CLIPBOARD_CHECK);
        buttonTest.addClickListener(ce -> {
            Article a = CrawlerUtils.executeRandom(crawler);
            labelResult.setValue(a.getBody());
            if (reg != null) {
                reg.remove();
            }
            reg = buttonTestURL
                    .addClickListener(cev -> UI.getCurrent().getPage().open(a.getUrl(), "_blank", false));
        });

        refreshList(mainGrid, crawler);

        Runnable cancel = () -> close();
        Runnable next = () -> validateThirdStage(s);

        VerticalLayout windowLayout = new VerticalLayout();
        windowLayout.addComponents(header, mainGrid, getFooter(cancel, next, buttonTest, buttonTestURL));
        windowLayout.setComponentAlignment(header, Alignment.MIDDLE_CENTER);
        windowLayout.setExpandRatio(mainGrid, 5);
        windowLayout.setWidth("1250px");
        return windowLayout;
    }

    private void refreshList(GridLayout grid, Crawler c) {
        VerticalLayout layoutList = new VerticalLayout();
        layoutList.setWidth("100%");
        layoutList.setSpacing(false);
        layoutList.setMargin(false);
        Panel panelList = new Panel(layoutList);
        panelList.setHeight("325px");
        c.getIncludesByClass()
                .forEach(s -> layoutList.addComponent(getRow(layoutList, () -> c.removeByClass(s, true),
                        Language.get(Word.INCLUDE_TAGS) + " " + Language.get(Word.BYCLASS), s, null)));
        c.getIncludesByTag().forEach(s -> layoutList.addComponent(getRow(layoutList, () -> c.removeByTag(s, true),
                Language.get(Word.INCLUDE_TAGS) + " " + Language.get(Word.BYTAG), s, null)));
        c.getIncludesByID().forEach(s -> layoutList.addComponent(getRow(layoutList, () -> c.removeByID(s, true),
                Language.get(Word.INCLUDE_TAGS) + " " + Language.get(Word.BYID), s, null)));
        c.getIncludesByAttribute()
                .forEach((k, v) -> layoutList.addComponent(getRow(layoutList, () -> c.removeByAttribute(k, v, true),
                        Language.get(Word.INCLUDE_TAGS) + " " + Language.get(Word.BYATTRIBUTEVALUE), k, v)));
        c.getExcludeByClass()
                .forEach(s -> layoutList.addComponent(getRow(layoutList, () -> c.removeByClass(s, false),
                        Language.get(Word.EXCLUDE_TAGS) + " " + Language.get(Word.BYCLASS), s, null)));
        c.getExcludeByTag().forEach(s -> layoutList.addComponent(getRow(layoutList, () -> c.removeByTag(s, false),
                Language.get(Word.EXCLUDE_TAGS) + " " + Language.get(Word.BYTAG), s, null)));
        c.getExcludeByID().forEach(s -> layoutList.addComponent(getRow(layoutList, () -> c.removeByID(s, false),
                Language.get(Word.EXCLUDE_TAGS) + " " + Language.get(Word.BYID), s, null)));
        c.getExcludeByAttribute().forEach(
                (k, v) -> layoutList.addComponent(getRow(layoutList, () -> c.removeByAttribute(k, v, false),
                        Language.get(Word.EXCLUDE_TAGS) + " " + Language.get(Word.BYATTRIBUTEVALUE), k, v)));
        grid.removeComponent(1, 0);
        grid.addComponent(panelList, 1, 0);
    }

    /**
     * Value is optional
     *
     * @param action
     * @param content
     * @param value
     * @return
     */
    private Component getRow(Layout parent, Runnable onDelete, String action, String content, String value) {
        Panel panelRow = new Panel();
        GridLayout layoutRow = new GridLayout(2, 1);

        Label labelInfo = new Label("", ContentMode.HTML);
        String stringInfo = action.toUpperCase() + "<br>";
        if (value != null) {
            stringInfo += content + " = " + value;
        } else {
            stringInfo += content + " ";
        }
        labelInfo.setValue(stringInfo);

        Button buttonDelete = new Button(VaadinIcons.TRASH);
        buttonDelete.addStyleName(ValoTheme.BUTTON_DANGER);
        buttonDelete.addClickListener(ce -> {
            onDelete.run();
            parent.removeComponent(panelRow);
        });

        layoutRow.addComponents(labelInfo, buttonDelete);
        layoutRow.setComponentAlignment(buttonDelete, Alignment.MIDDLE_RIGHT);
        layoutRow.setComponentAlignment(labelInfo, Alignment.MIDDLE_LEFT);
        layoutRow.setWidth("100%");
        layoutRow.setMargin(true);
        layoutRow.addStyleName("crawler");
        panelRow.setContent(layoutRow);
        panelRow.setWidth("100%");
        return panelRow;
    }

    public void validateThirdStage(Source s) {
        ManageSourcesWindow.getCurrent().refreshSources();
        close();
        //Stores this source to the database
        SourceUtils.addSource(s);
        VaadinUtils.middleInfoNotification("Successfully added Source " + s.getName());
    }

    public Component getFooter(Runnable cancelRunnable, Runnable nextRunnable, Component... extraComponents) {
        Label placeholder = new Label();
        Button cancel = new Button(Language.get(Word.CANCEL), VaadinIcons.CLOSE);
        cancel.addClickListener(ce -> cancelRunnable.run());
        Button next = new Button(Language.get(Word.NEXT), VaadinIcons.ARROW_RIGHT);
        next.addClickListener(ce -> nextRunnable.run());
        GridLayout footer = new GridLayout(3 + extraComponents.length, 1);
        footer.setSpacing(true);
        footer.addStyleName(ValoTheme.WINDOW_BOTTOM_TOOLBAR);
        footer.setWidth(100.0f, Sizeable.Unit.PERCENTAGE);
        footer.setSizeUndefined();
        footer.setWidth("100%");
        for (Component extraComponent : extraComponents) {
            footer.addComponent(extraComponent);
            footer.setComponentAlignment(extraComponent, Alignment.MIDDLE_CENTER);
        }
        footer.addComponents(placeholder, cancel, next);
        footer.setColumnExpandRatio(footer.getColumns() - 1 - 2, 1);//ExpandRatio(placeholder, 1);
        footer.setComponentAlignment(cancel, Alignment.MIDDLE_CENTER);
        footer.setComponentAlignment(next, Alignment.MIDDLE_CENTER);
        return footer;
    }

    public static List<Locale> getLanguages() {
        return Arrays.asList(Locale.getISOLanguages()).parallelStream().map(s -> new Locale(s))
                .sorted((l1, l2) -> l1.getDisplayLanguage(VaadinSession.getCurrent().getLocale())
                        .compareTo(l2.getDisplayLanguage(VaadinSession.getCurrent().getLocale())))
                .collect(Collectors.toList());
    }

    public static Map<String, Locale> getCountries() {
        List<String> countries = Arrays.asList(Locale.getISOCountries());
        HashMap<String, Locale> mapCountries = new HashMap<>();
        countries.parallelStream().forEach((country) -> {
            List<Locale> locales = LocaleUtils.languagesByCountry(country);
            if (!locales.isEmpty()) {
                mapCountries.put(country, new Locale(locales.get(0).getLanguage(), country));
            }
        });
        return mapCountries;
    }

    public static boolean isURL(String url) {
        try {
            URL url1 = new URL(url);
            return true;
        } catch (MalformedURLException e) {
            return false;
        }
    }

}