/** * Copyright © 2002 Instituto Superior Técnico * * This file is part of FenixEdu Academic. * * FenixEdu Academic is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Academic is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.academic.domain.util.email; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Set; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.util.Email; import org.fenixedu.academic.domain.util.EmailAddressList; import org.fenixedu.academic.predicate.AccessControl; import org.fenixedu.bennu.core.domain.Bennu; import org.joda.time.DateTime; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.Atomic.TxMode; import com.google.common.base.Strings; public class Message extends Message_Base { static final public Comparator<Message> COMPARATOR_BY_CREATED_DATE_OLDER_FIRST = new Comparator<Message>() { @Override public int compare(Message o1, Message o2) { return o1.getCreated().compareTo(o2.getCreated()); } }; static final public Comparator<Message> COMPARATOR_BY_CREATED_DATE_OLDER_LAST = new Comparator<Message>() { @Override public int compare(Message o1, Message o2) { return o2.getCreated().compareTo(o1.getCreated()); } }; public static final int NUMBER_OF_SENT_EMAILS_TO_STAY = 500; public Message() { super(); setRootDomainObject(Bennu.getInstance()); } public Message(final Sender sender, String to, String subject, String body) { this(sender, sender.getReplyTosSet(), null, subject, body, to); } public Message(final Sender sender, final Collection<? extends ReplyTo> replyTos, final Collection<Recipient> tos, final Collection<Recipient> ccs, final Collection<Recipient> recipientsBccs, final String subject, final String body, final Set<String> bccs) { this(sender, replyTos, recipientsBccs, subject, body, bccs); if (tos != null) { for (final Recipient recipient : tos) { addTos(recipient); } } if (ccs != null) { for (final Recipient recipient : ccs) { addCcs(recipient); } } } public Message(final Sender sender, final Collection<? extends ReplyTo> replyTos, final Collection<Recipient> tos, final Collection<Recipient> ccs, final Collection<Recipient> recipientsBccs, final String subject, final String body, final Set<String> bccs, final String htmlBody) { this(sender, replyTos, recipientsBccs, subject, body, bccs); if (tos != null) { for (final Recipient recipient : tos) { addTos(recipient); } } if (ccs != null) { for (final Recipient recipient : ccs) { addCcs(recipient); } } } public Message(final Sender sender, final Recipient recipient, final String subject, final String body) { this(sender, sender.getConcreteReplyTos(), Collections.singleton(recipient), subject, body, new EmailAddressList( Collections.EMPTY_LIST).toString()); } public Message(final Sender sender, final Collection<? extends ReplyTo> replyTos, final Collection<Recipient> recipients, final String subject, final String body, final Set<String> bccs) { this(sender, replyTos, recipients, subject, body, new EmailAddressList(bccs).toString()); } public Message(final Sender sender, final Collection<? extends ReplyTo> replyTos, final Collection<Recipient> recipients, final String subject, final String body, final String bccs) { super(); final Bennu rootDomainObject = Bennu.getInstance(); setRootDomainObject(rootDomainObject); setRootDomainObjectFromPendingRelation(rootDomainObject); setSender(sender); if (replyTos != null) { for (final ReplyTo replyTo : replyTos) { addReplyTos(replyTo); } } if (recipients != null) { for (final Recipient recipient : recipients) { addRecipients(recipient); } } setSubject(subject); setBody(body); setBccs(bccs); final Person person = AccessControl.getPerson(); setPerson(person); setCreated(new DateTime()); } public Message(final Sender sender, final Collection<? extends ReplyTo> replyTos, final Collection<Recipient> recipients, final String subject, final String body, final String bccs, final String htmlBody) { super(); final Bennu rootDomainObject = Bennu.getInstance(); setRootDomainObject(rootDomainObject); setRootDomainObjectFromPendingRelation(rootDomainObject); setSender(sender); if (replyTos != null) { for (final ReplyTo replyTo : replyTos) { addReplyTos(replyTo); } } if (recipients != null) { for (final Recipient recipient : recipients) { addRecipients(recipient); } } setSubject(subject); setBody(body); setHtmlBody(htmlBody); setBccs(bccs); final Person person = AccessControl.getPerson(); setPerson(person); setCreated(new DateTime()); } public void safeDelete() { if (getSent() == null) { delete(); } } public void delete() { for (final Recipient recipient : getRecipientsSet()) { removeRecipients(recipient); } for (final Recipient recipient : getTosSet()) { removeTos(recipient); } for (final Recipient recipient : getCcsSet()) { removeCcs(recipient); } for (final ReplyTo replyTo : getReplyTosSet()) { replyTo.safeDelete(); } for (final Email email : getEmailsSet()) { email.delete(); } setSender(null); setPerson(null); setRootDomainObjectFromPendingRelation(null); setRootDomainObject(null); deleteDomainObject(); } public String getRecipientsAsText() { final StringBuilder stringBuilder = new StringBuilder(); recipients2Text(stringBuilder, getRecipientsSet()); if (getBccs() != null && !getBccs().isEmpty()) { if (stringBuilder.length() > 0) { stringBuilder.append("\n"); } stringBuilder.append(getBccs()); } return stringBuilder.toString(); } public String getRecipientsAsToText() { return recipients2Text(getTosSet()); } public String getRecipientsAsCcText() { return recipients2Text(getCcsSet()); } protected static String recipients2Text(final Set<Recipient> recipients) { final StringBuilder stringBuilder = new StringBuilder(); recipients2Text(stringBuilder, recipients); return stringBuilder.toString(); } protected static void recipients2Text(final StringBuilder stringBuilder, final Set<Recipient> recipients) { for (final Recipient recipient : recipients) { if (stringBuilder.length() > 0) { stringBuilder.append("\n"); } stringBuilder.append(recipient.getToName()); } } public String getRecipientsGroupMembersInText() { StringBuilder builder = new StringBuilder(); Collection<Recipient> recipients = getRecipientsSet(); for (Recipient recipient : recipients) { builder.append(recipient.getMembersEmailInText()); } return builder.toString(); } protected static Set<String> getRecipientAddresses(Set<Recipient> recipients) { final Set<String> emailAddresses = new HashSet<String>(); for (final Recipient recipient : recipients) { recipient.addDestinationEmailAddresses(emailAddresses); } return emailAddresses; } protected Set<String> getDestinationBccs() { final Set<String> emailAddresses = new HashSet<String>(); if (getBccs() != null && !getBccs().isEmpty()) { for (final String emailAddress : getBccs().replace(',', ' ').replace(';', ' ').split(" ")) { final String trimmed = emailAddress.trim(); if (!trimmed.isEmpty()) { emailAddresses.add(emailAddress); } } } for (final Recipient recipient : getRecipientsSet()) { recipient.addDestinationEmailAddresses(emailAddresses); } return emailAddresses; } protected String[] getReplyToAddresses(final Person person) { final String[] replyToAddresses = new String[getReplyTosSet().size()]; int i = 0; for (final ReplyTo replyTo : getReplyTosSet()) { replyToAddresses[i++] = replyTo.getReplyToAddress(person); } return replyToAddresses; } public int dispatch() { if (Strings.isNullOrEmpty(getSubject())) { return 0; } if (Strings.isNullOrEmpty(getBody()) && Strings.isNullOrEmpty(getHtmlBody())) { return 0; } final Person person = getPerson(); final Set<String> destinationBccs = getDestinationBccs(); final Set<String> tos = getRecipientAddresses(getTosSet()); final Set<String> ccs = getRecipientAddresses(getCcsSet()); createEmailBatch(person, tos, ccs, split(destinationBccs)); return destinationBccs.size() + tos.size() + ccs.size(); } @Atomic(mode = TxMode.WRITE) private void createEmailBatch(final Person person, final Set<String> tos, final Set<String> ccs, Set<Set<String>> destinationBccs) { if (getRootDomainObjectFromPendingRelation() != null) { for (final Set<String> bccs : destinationBccs) { if (!bccs.isEmpty()) { new Email(getReplyToAddresses(person), Collections.emptySet(), Collections.emptySet(), bccs, this); } } if (!tos.isEmpty() || !ccs.isEmpty()) { new Email(getReplyToAddresses(person), tos, ccs, Collections.emptySet(), this); } setRootDomainObjectFromPendingRelation(null); setSent(new DateTime()); } } private Set<Set<String>> split(final Set<String> destinations) { final Set<Set<String>> result = new HashSet<Set<String>>(); int i = 0; Set<String> subSet = new HashSet<String>(); for (final String destination : destinations) { if (i++ == 50) { result.add(subSet); subSet = new HashSet<String>(); i = 1; } subSet.add(destination); } result.add(subSet); return result; } public int getPossibleRecipientsCount() { return (int) getRecipientsSet().stream().flatMap(r -> r.getMembers().getMembers()).distinct().count(); } public int getRecipientsWithEmailCount() { return (int) getRecipientsSet().stream().flatMap(r -> r.getMembers().getMembers()).distinct() .filter(u -> u.getPerson().getEmailAddressForSendingEmails() != null).count(); } public int getSentMailsCount() { return (int) getEmailsSet().stream().filter(e -> e.getConfirmedAddresses() != null) .flatMap(e -> e.getConfirmedAddresses().toCollection().stream()).distinct().count(); } public int getFailedMailsCount() { return (int) getEmailsSet().stream().filter(e -> e.getFailedAddresses() != null) .flatMap(e -> e.getFailedAddresses().toCollection().stream()).distinct().count(); } public String getFromName() { return getSender().getFromName().replace(",", ""); } public String getFromAddress() { return getSender().getFromAddress(); } }