From 1de86c5cdd3d05f5089d7af0e5c0296ddfa58add Mon Sep 17 00:00:00 2001 From: Markus Kreth Date: Thu, 21 Nov 2019 22:52:41 +0100 Subject: [PATCH] Emails versenden. --- .../vaadinclubhelper/email/Email.java | 93 ++++++ .../vaadinclubhelper/email/EmailCommand.java | 8 + .../email/EmailException.java | 23 ++ .../email/MuttEmailCommand.java | 77 +++++ .../menu/LoggedinMenuitemState.java | 11 +- .../ui/navigation/ClubhelperNavigation.java | 1 + .../ui/navigation/ClubhelperViews.java | 3 +- .../ui/navigation/ExportEmails.java | 223 +------------- .../ui/navigation/SendEmails.java | 290 ++++++++++++++++++ 9 files changed, 506 insertions(+), 223 deletions(-) create mode 100644 src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/Email.java create mode 100644 src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailCommand.java create mode 100644 src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailException.java create mode 100644 src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/MuttEmailCommand.java create mode 100644 src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/SendEmails.java diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/Email.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/Email.java new file mode 100644 index 0000000..e6e006f --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/Email.java @@ -0,0 +1,93 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.email; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class Email { + + private final String subject; + + private final String message; + + private final List emails; + + private final List attachements; + + private Email(Builder builder) { + this.subject = builder.subject; + this.message = builder.message; + this.emails = Collections.unmodifiableList(builder.emails); + this.attachements = Collections.unmodifiableList(builder.attachements); + } + + public String getSubject() { + return subject; + } + + public String getMessage() { + return message; + } + + public List getEmails() { + return emails; + } + + public List getAttachements() { + return attachements; + } + + @Override + public String toString() { + return "Email [subject=" + subject + ", emails=" + emails + "]"; + } + + public static class Builder { + + private String subject; + + private String message; + + private List emails; + + private List attachements; + + private Builder() { + emails = new ArrayList<>(); + attachements = new ArrayList<>(); + } + + public Builder setSubject(String subject) { + this.subject = subject; + return this; + } + + public Builder setMessage(String message) { + this.message = message; + return this; + } + + public Builder addEmails(List emails) { + this.emails.addAll(emails); + return this; + } + + public boolean addAttachment(Path e) { + return attachements.add(e); + } + + public boolean addAttachments(Collection c) { + return attachements.addAll(c); + } + + public Email build() { + return new Email(this); + } + } + + public static Builder builder() { + return new Builder(); + } +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailCommand.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailCommand.java new file mode 100644 index 0000000..1c6cbc4 --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailCommand.java @@ -0,0 +1,8 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.email; + +import java.io.IOException; + +public interface EmailCommand { + + void send(Email email) throws IOException; +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailException.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailException.java new file mode 100644 index 0000000..08ca710 --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/EmailException.java @@ -0,0 +1,23 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.email; + +import java.util.List; + +public class EmailException extends RuntimeException { + + private final List failedEmails; + + public EmailException(String message, List failedEmails) { + super(message); + this.failedEmails = failedEmails; + } + + public EmailException(String message, List failedEmails, Throwable cause) { + super(message, cause); + this.failedEmails = failedEmails; + } + + public List getFailedEmails() { + return failedEmails; + } + +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/MuttEmailCommand.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/MuttEmailCommand.java new file mode 100644 index 0000000..9d75abe --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/email/MuttEmailCommand.java @@ -0,0 +1,77 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.email; + +import java.io.File; +import java.io.IOException; +import java.lang.ProcessBuilder.Redirect; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.springframework.stereotype.Component; + +@Component +public class MuttEmailCommand implements EmailCommand { + + @Override + public void send(Email email) throws IOException { + + final List arguments = createArguments(email); + final List errors = new ArrayList<>(); + + File log = new File("email.log"); + List adresses = email.getEmails(); + for (String adress : adresses) { + List builders = new ArrayList<>(); + + ProcessBuilder echoProcess = new ProcessBuilder("echo", quote(email.getMessage())); + echoProcess.redirectOutput(Redirect.PIPE); + builders.add(echoProcess); + + List command = new ArrayList<>(arguments); + command.add(adress); + ProcessBuilder procBuilder = new ProcessBuilder(command); + procBuilder.redirectOutput(log); + builders.add(procBuilder); + + List pipeline = ProcessBuilder.startPipeline(builders); + Process last = pipeline.get(pipeline.size() - 1); + try { + +// new BufferedReader(new InputStreamReader(last.getInputStream())).lines().collect(Collectors.counting()); + + int result = last.waitFor(); + if (result != 0) { + errors.add(adress); + } + } + catch (InterruptedException e) { + } + + } + + if (errors.isEmpty() == false) { + throw new RuntimeException("Errors: " + errors); + } + } + + private String quote(String text) { + return "\"" + text + "\""; + } + + private List createArguments(Email email) { + List arguments = new ArrayList<>(); + arguments.add("mutt"); + arguments.add("-s"); + arguments.add(quote(email.getSubject())); +// +// List attachements = email.getAttachements(); +// for (Path path : attachements) { +// arguments.add("-a"); +// arguments.add(quote(path.toAbsolutePath().toString())); +// } + + arguments = Collections.unmodifiableList(arguments); + return arguments; + } + +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/menu/LoggedinMenuitemState.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/menu/LoggedinMenuitemState.java index a819343..102e740 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/menu/LoggedinMenuitemState.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/menu/LoggedinMenuitemState.java @@ -61,6 +61,8 @@ class LoggedinMenuitemState extends LoggedOffState { private MenuItem exportEmailsMenuItem; + private MenuItem sendEmailsMenuItem; + public LoggedinMenuitemState(ApplicationContext context, UI ui, Supplier startProvider, Supplier endProvider, BiConsumer printConsumer) { super(context, startProvider, endProvider, printConsumer); @@ -124,9 +126,14 @@ class LoggedinMenuitemState extends LoggedOffState { createMeldungMenuItem = createMeldungCommand.addTo(editMenu); CommandWrapper exportEmails = new CommandWrapper(new SwitchViewCommand(context, "Emails exportieren", - VaadinIcons.CALENDAR, ClubhelperViews.ExportEmails)); + VaadinIcons.ENVELOPE_O, ClubhelperViews.ExportEmails)); exportEmailsMenuItem = exportEmails.addTo(editMenu); + CommandWrapper sendMail = new CommandWrapper(new SwitchViewCommand(context, "Emails senden", + VaadinIcons.ENVELOPE_O, ClubhelperViews.SendEmails)); + + sendEmailsMenuItem = sendMail.addTo(editMenu); + CommandWrapper deleeteEvent = new CommandWrapper(new DeleteEventCommand(this::deleteEvent)); deleteMenuItem = deleeteEvent.addTo(editMenu); @@ -151,6 +158,7 @@ class LoggedinMenuitemState extends LoggedOffState { } exportEmailsMenuItem.setEnabled(false); + sendEmailsMenuItem.setEnabled(false); if (ClubhelperViews.PersonEditView == view) { openPersonMenuItem.setChecked(true); @@ -160,6 +168,7 @@ class LoggedinMenuitemState extends LoggedOffState { calendarMenuItem.setChecked(true); calendarMenuItem.setEnabled(false); exportEmailsMenuItem.setEnabled(true); + sendEmailsMenuItem.setEnabled(true); } else if (ClubhelperViews.EventDetails.equals(view)) { eventDetailItem.setChecked(true); diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperNavigation.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperNavigation.java index a59eec6..6b01b59 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperNavigation.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperNavigation.java @@ -86,6 +86,7 @@ public class ClubhelperNavigation implements ApplicationContextAware { navi.addView(ClubhelperViews.LoginUI.name(), new LoginUI(personBusiness, securityGroupVerifier)); navi.addView(ClubhelperViews.PersonEditView.name(), personEdit); navi.addView(ClubhelperViews.EventDetails.name(), new EventDetails(context)); + navi.addView(ClubhelperViews.SendEmails.name(), new SendEmails(context, true)); navi.addView(ClubhelperViews.ExportEmails.name(), new ExportEmails(context)); page.addBrowserWindowResizeListener(ev -> { diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperViews.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperViews.java index 84b8ab6..3a9948f 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperViews.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ClubhelperViews.java @@ -10,7 +10,8 @@ public enum ClubhelperViews { EventDetails, PersonEditView, ExportEmails, - LoginUI; + LoginUI, + SendEmails; public static ClubhelperViews byState(String state) { if (state.isBlank()) { diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ExportEmails.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ExportEmails.java index 69abdc6..208e528 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ExportEmails.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/ExportEmails.java @@ -1,230 +1,11 @@ package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.navigation; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import org.springframework.context.ApplicationContext; -import com.vaadin.data.HasValue.ValueChangeEvent; -import com.vaadin.data.provider.DataProvider; -import com.vaadin.data.provider.ListDataProvider; -import com.vaadin.navigator.View; -import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; -import com.vaadin.shared.ui.ContentMode; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.Grid; -import com.vaadin.ui.Grid.SelectionMode; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.VerticalLayout; - -import de.kreth.vaadin.clubhelper.vaadinclubhelper.business.PersonBusiness; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.GroupDao; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Contact; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.GroupDef; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.menu.ClubhelperMenuBar; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.menu.MenuItemStateFactory; - -public class ExportEmails extends VerticalLayout implements View { - - private PersonBusiness personBusiness; - - private List allGroups; - - private Set selected; - - private ListDataProvider dataProvider; - - private final List items; - - private MenuItemStateFactory stateFactory; - - private TextArea asText; +public class ExportEmails extends SendEmails { public ExportEmails(ApplicationContext context) { - - this.stateFactory = context.getBean(MenuItemStateFactory.class); - this.personBusiness = context.getBean(PersonBusiness.class); - allGroups = context.getBean(GroupDao.class).listAll(); - selected = new HashSet<>(); - - items = new ArrayList<>(); - - dataProvider = DataProvider.ofCollection(items); - - } - - @Override - public void enter(ViewChangeEvent event) { - View.super.enter(event); - - ClubhelperMenuBar menubar = new ClubhelperMenuBar(stateFactory.currentState()); - - HorizontalLayout groupCheck = new HorizontalLayout(); - for (GroupDef groupDef : allGroups) { - CheckBox box = new CheckBox(groupDef.getName()); - box.setData(groupDef); - if (groupDef.hasValidId() && groupDef.getId() == 1) { - box.setValue(true); - selected.add(groupDef); - } - box.addValueChangeListener(this::groupBoxEvent); - groupCheck.addComponent(box); - } - - Grid grid = new Grid<>(); - grid.addColumn(EmailHolder::getPrename).setCaption("Vorname"); - grid.addColumn(EmailHolder::getSurname).setCaption("Nachname"); - grid.addColumn(EmailHolder::getEmail).setCaption("Emailadresse"); - - grid.setSelectionMode(SelectionMode.MULTI); - grid.setDataProvider(dataProvider); - - asText = new TextArea("Emails als Text"); - asText.setWidth(10, Unit.CM); - asText.setWordWrap(false); - asText.setRows(25); - asText.setEnabled(false); - - addComponent(menubar); - addComponent(new Label("

Export von Emailadressen

", ContentMode.HTML)); - addComponent(groupCheck); - - addComponent(new HorizontalLayout(grid, asText)); - refreshData(); + super(context, false); } - private void groupBoxEvent(ValueChangeEvent event) { - CheckBox box = (CheckBox) event.getComponent(); - GroupDef groupDef = (GroupDef) box.getData(); - Boolean checked = box.getValue(); - if (Boolean.TRUE.equals(checked)) { - selected.add(groupDef); - } - else { - selected.remove(groupDef); - } - refreshData(); - } - - private void refreshData() { - items.clear(); - personBusiness.listAll().stream() - .filter(this::matchGroupSelection) - .map(this::getEmails) - .forEach(items::addAll); - dataProvider.refreshAll(); - - StringBuilder text = new StringBuilder(); - for (EmailHolder emailHolder : items) { - if (text.length() > 0) { - text.append(",\n"); - } - text.append(emailHolder.getEmail()); - } - asText.setValue(text.toString()); - } - - private boolean matchGroupSelection(Person p) { - Set personGroups = p.getGroups(); - boolean contains = false; - for (GroupDef g : selected) { - if (personGroups.contains(g)) { - contains = true; - break; - } - } - return contains; - } - - private Collection getEmails(Person person) { - - List emails = new ArrayList<>(); - List contacts = person.getContacts(); - for (Contact contact : contacts) { - if (Contact.Type.EMAIL.getName().equals(contact.getType())) { - emails.add(contact); - } - } - Set holders = new HashSet<>(); - for (Contact c : emails) { - holders.add(new EmailHolder(person, c)); - } - return holders; - } - - private class EmailHolder { - - private final Person person; - - private final Contact contact; - - public EmailHolder(Person person, Contact contact) { - super(); - this.person = person; - this.contact = contact; - } - - public String getEmail() { - return contact.getValue(); - } - - public String getPrename() { - return person.getPrename(); - } - - public String getSurname() { - return person.getSurname(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getEnclosingInstance().hashCode(); - result = prime * result + ((contact.getValue() == null) ? 0 : contact.getValue().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - EmailHolder other = (EmailHolder) obj; - if (!getEnclosingInstance().equals(other.getEnclosingInstance())) { - return false; - } - if (contact.getValue() == null) { - if (other.contact.getValue() != null) { - return false; - } - } - else if (!contact.getValue().equals(other.contact.getValue())) { - return false; - } - return true; - } - - @Override - public String toString() { - return contact.getValue(); - } - - private ExportEmails getEnclosingInstance() { - return ExportEmails.this; - } - - } } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/SendEmails.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/SendEmails.java new file mode 100644 index 0000000..3e63a5e --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/navigation/SendEmails.java @@ -0,0 +1,290 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.navigation; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.context.ApplicationContext; + +import com.vaadin.data.HasValue.ValueChangeEvent; +import com.vaadin.data.provider.DataProvider; +import com.vaadin.data.provider.ListDataProvider; +import com.vaadin.icons.VaadinIcons; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.shared.ui.ContentMode; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +import de.kreth.vaadin.clubhelper.vaadinclubhelper.business.PersonBusiness; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.GroupDao; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Contact; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.GroupDef; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.email.Email; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.email.EmailCommand; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.menu.ClubhelperMenuBar; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.menu.MenuItemStateFactory; + +public class SendEmails extends VerticalLayout implements View { + + private PersonBusiness personBusiness; + + private List allGroups; + + private Set selected; + + private ListDataProvider dataProvider; + + private final List items; + + private MenuItemStateFactory stateFactory; + + private TextArea asText; + + private boolean withSend; + + private final EmailCommand emailCommand; + + public SendEmails(ApplicationContext context, boolean withSend) { + + this.stateFactory = context.getBean(MenuItemStateFactory.class); + this.personBusiness = context.getBean(PersonBusiness.class); + allGroups = context.getBean(GroupDao.class).listAll(); + selected = new HashSet<>(); + + items = new ArrayList<>(); + + dataProvider = DataProvider.ofCollection(items); + this.withSend = withSend; + if (withSend) { + this.emailCommand = context.getBean(EmailCommand.class); + } + else { + this.emailCommand = null; + } + } + + @Override + public void enter(ViewChangeEvent event) { + View.super.enter(event); + + ClubhelperMenuBar menubar = new ClubhelperMenuBar(stateFactory.currentState()); + + HorizontalLayout groupCheck = new HorizontalLayout(); + for (GroupDef groupDef : allGroups) { + CheckBox box = new CheckBox(groupDef.getName()); + box.setData(groupDef); + if (groupDef.hasValidId() && groupDef.getId() == 1) { + box.setValue(true); + selected.add(groupDef); + } + box.addValueChangeListener(this::groupBoxEvent); + groupCheck.addComponent(box); + } + + Grid grid = new Grid<>(); + grid.addColumn(EmailHolder::getPrename).setCaption("Vorname"); + grid.addColumn(EmailHolder::getSurname).setCaption("Nachname"); + grid.addColumn(EmailHolder::getEmail).setCaption("Emailadresse"); + + grid.setSelectionMode(SelectionMode.MULTI); + grid.setDataProvider(dataProvider); + + asText = new TextArea("Emails als Text"); + asText.setWidth(10, Unit.CM); + asText.setWordWrap(false); + asText.setRows(25); + asText.setEnabled(false); + + addComponent(menubar); + addComponent(new Label("

Export von Emailadressen

", ContentMode.HTML)); + addComponent(groupCheck); + + if (withSend) { + addSending(); + } + addComponent(new HorizontalLayout(grid, asText)); + refreshData(); + } + + private void addSending() { + Label subjectLbl = new Label("Betreff"); + TextField subject = new TextField(); + TextArea body = new TextArea(); + body.setWidth(25, Unit.CM); + body.setWordWrap(false); + body.setRows(10); + TextArea errorMessage = new TextArea(); + errorMessage.setWidth(25, Unit.CM); + + Button send = new Button("Senden", VaadinIcons.ENVELOPE_O); + send.addClickListener(ev -> { + List adresses = items.stream() + .map(EmailHolder::getEmail) + .collect(Collectors.toList()); + Email email = Email.builder() + .setSubject(subject.getValue()) + .setMessage(body.getValue()) + .addEmails(adresses) + .build(); + try { + emailCommand.send(email); + } + catch (IOException e) { + StringWriter out = new StringWriter(); + PrintWriter writer = new PrintWriter(out); + e.printStackTrace(writer); + errorMessage.setValue(errorMessage.getValue() + "\n" + e.getMessage() + "\n" + out.toString()); + } + }); + + addComponent(subjectLbl); + addComponent(subject); + addComponent(body); + addComponent(send); + addComponent(errorMessage); + } + + private void groupBoxEvent(ValueChangeEvent event) { + CheckBox box = (CheckBox) event.getComponent(); + GroupDef groupDef = (GroupDef) box.getData(); + Boolean checked = box.getValue(); + if (Boolean.TRUE.equals(checked)) { + selected.add(groupDef); + } + else { + selected.remove(groupDef); + } + refreshData(); + } + + private void refreshData() { + items.clear(); + personBusiness.listAll().stream() + .filter(this::matchGroupSelection) + .map(this::getEmails) + .forEach(items::addAll); + dataProvider.refreshAll(); + + StringBuilder text = new StringBuilder(); + for (EmailHolder emailHolder : items) { + if (text.length() > 0) { + text.append(",\n"); + } + text.append(emailHolder.getEmail()); + } + asText.setValue(text.toString()); + } + + private boolean matchGroupSelection(Person p) { + Set personGroups = p.getGroups(); + boolean contains = false; + for (GroupDef g : selected) { + if (personGroups.contains(g)) { + contains = true; + break; + } + } + return contains; + } + + private Collection getEmails(Person person) { + + List emails = new ArrayList<>(); + List contacts = person.getContacts(); + for (Contact contact : contacts) { + if (Contact.Type.EMAIL.getName().equals(contact.getType())) { + emails.add(contact); + } + } + Set holders = new HashSet<>(); + for (Contact c : emails) { + holders.add(new EmailHolder(person, c)); + } + return holders; + } + + private class EmailHolder { + + private final Person person; + + private final Contact contact; + + public EmailHolder(Person person, Contact contact) { + super(); + this.person = person; + this.contact = contact; + } + + public String getEmail() { + return contact.getValue(); + } + + public String getPrename() { + return person.getPrename(); + } + + public String getSurname() { + return person.getSurname(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getEnclosingInstance().hashCode(); + result = prime * result + ((contact.getValue() == null) ? 0 : contact.getValue().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EmailHolder other = (EmailHolder) obj; + if (!getEnclosingInstance().equals(other.getEnclosingInstance())) { + return false; + } + if (contact.getValue() == null) { + if (other.contact.getValue() != null) { + return false; + } + } + else if (!contact.getValue().equals(other.contact.getValue())) { + return false; + } + return true; + } + + @Override + public String toString() { + return contact.getValue(); + } + + private SendEmails getEnclosingInstance() { + return SendEmails.this; + } + + } +}