Java tutorial
/* * 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; } } }