edu.harvard.med.iccbl.screensaver.io.AdminEmailApplication.java Source code

Java tutorial

Introduction

Here is the source code for edu.harvard.med.iccbl.screensaver.io.AdminEmailApplication.java

Source

// $HeadURL:
// http://seanderickson1@forge.abcd.harvard.edu/svn/screensaver/trunk/core/src/main/java/edu/harvard/med/iccbl/screensaver/io/AdminEmailApplication.java
// $
// $Id$
//
// Copyright  2006, 2010, 2011, 2012 by the President and Fellows of Harvard College.
//
// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.

package edu.harvard.med.iccbl.screensaver.io;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import edu.harvard.med.screensaver.io.CommandLineApplication;
import edu.harvard.med.screensaver.model.users.AdministratorUser;
import edu.harvard.med.screensaver.model.users.ScreensaverUser;
import edu.harvard.med.screensaver.service.EmailService;
import edu.harvard.med.screensaver.service.ServiceMessages;
import edu.harvard.med.screensaver.service.SmtpEmailService;

public class AdminEmailApplication extends CommandLineApplication {
    private static Logger log = Logger.getLogger(AdminEmailApplication.class);

    public static final int SHORT_OPTION_INDEX = 0;
    public static final int ARG_INDEX = 1;
    public static final int LONG_OPTION_INDEX = 2;
    public static final int DESCRIPTION_INDEX = 3;

    public static final DateTimeFormatter EXPIRE_DATE_FORMATTER = DateTimeFormat.fullDate();
    public static String USER_PRINT_FORMAT = "|%1$-10s|%2$-30s|%3$-60s";

    private ServiceMessages _messages = null;

    public static final String[] EMAIL_RECIPIENT_LIST_OPTION = { "mr", "comma-separated-list",
            "mail-recipient-list",
            "Additional recipients to notify, delimited by \"" + EmailService.DELIMITER + "\"" };

    public static final String[] NO_NOTIFY_OPTION = { "noemail", "", "no-email",
            "Do not send email notifications" };

    public static final String[] TEST_EMAIL_ONLY = { "testemail", "", "test-email-only",
            "send all email notifications to the admin only (not to any users, for testing)" };

    public static final String[] EMAIL_DSL_ADMINS_ONLY = { "emaildsladminsonly", "", "email-dsl-admins-only",
            "send email only to the data sharing level admins (and to the admin running the process), not to any users" };

    @SuppressWarnings("static-access")
    public AdminEmailApplication(String[] cmdLineArgs) {
        super(cmdLineArgs);

        addCommandLineOption(OptionBuilder.hasArg().withArgName(EMAIL_RECIPIENT_LIST_OPTION[ARG_INDEX])
                .withDescription(EMAIL_RECIPIENT_LIST_OPTION[DESCRIPTION_INDEX])
                .withLongOpt(EMAIL_RECIPIENT_LIST_OPTION[LONG_OPTION_INDEX])
                .create(EMAIL_RECIPIENT_LIST_OPTION[SHORT_OPTION_INDEX]));
        addCommandLineOption(OptionBuilder.withDescription(NO_NOTIFY_OPTION[DESCRIPTION_INDEX])
                .withLongOpt(NO_NOTIFY_OPTION[LONG_OPTION_INDEX]).create(NO_NOTIFY_OPTION[SHORT_OPTION_INDEX]));
        addCommandLineOption(OptionBuilder.withDescription(TEST_EMAIL_ONLY[DESCRIPTION_INDEX])
                .withLongOpt(TEST_EMAIL_ONLY[LONG_OPTION_INDEX]).create(TEST_EMAIL_ONLY[SHORT_OPTION_INDEX]));
        addCommandLineOption(OptionBuilder.withDescription(EMAIL_DSL_ADMINS_ONLY[DESCRIPTION_INDEX])
                .withLongOpt(EMAIL_DSL_ADMINS_ONLY[LONG_OPTION_INDEX])
                .create(EMAIL_DSL_ADMINS_ONLY[SHORT_OPTION_INDEX]));
    }

    public boolean isAdminEmailOnly() {
        return isCommandLineFlagSet(EMAIL_DSL_ADMINS_ONLY[SHORT_OPTION_INDEX]);
    }

    public static String printUserHeader() {
        return String.format(USER_PRINT_FORMAT, "ID", "Name", "Email");
    }

    public static String printUser(ScreensaverUser user) {
        return String.format(USER_PRINT_FORMAT, user.getEntityId(), user.getFullNameFirstLast(), user.getEmail());
    }

    public static List<String> printUserInformation(ScreensaverUser user) {
        List<String> buf = Lists.newLinkedList();
        buf.add("User ID: " + user.getEntityId());
        buf.add("Login ID: " + user.getLoginId());
        buf.add("eCommons ID: " + user.getECommonsId());
        buf.add("Name: " + user.getFullNameFirstLast());
        buf.add("Email: \"" + user.getEmail() + "\"");
        return buf;
    }

    @Override
    /**
     * Throws IllegalArgumentException if the AdministratorUser account does not have an email address.
     * 
     * @throws IllegalArgumentException
     */
    public AdministratorUser findAdministratorUser() throws IllegalArgumentException {
        AdministratorUser admin = super.findAdministratorUser();
        if (admin != null) {
            if (admin.getEmail() == null) {
                throw new IllegalArgumentException(
                        "The administrative account given does not have an email address");
            }
        }
        return admin;
    }

    /**
     * Generate an email, with the subject, message, and stacktrace to the admin user running the application.
     * 
     * @param subject
     * @param msg
     * @param e the exception (may be null)
     * @throws MessagingException
     */
    public final void sendErrorMail(String subject, String msg, Exception e) throws MessagingException {
        if (e != null) {
            log.error(subject + "; " + msg, e);
            StringWriter out = new StringWriter();
            e.printStackTrace(new PrintWriter(out));
            msg += "\nException:\n" + out.toString();
        } else {
            log.error(subject + "; " + msg);
        }
        sendAdminEmails(subject, msg);
    }

    public boolean sendEmail(String subject, String msg, ScreensaverUser user) throws MessagingException {
        List<String> failMessages = Lists.newArrayList();
        if (StringUtils.isEmpty(user.getEmail())) {
            failMessages.add("Empty address for the user: " + printUser(user));
        } else {
            EmailService emailService = getEmailServiceBasedOnCommandLineOption();
            if (isAdminEmailOnly()) {
                sendAdminEmails("Admin email only: " + subject,
                        "originally for: " + printUser(user) + "\nOriginal Message:\n" + msg);
            } else {
                try {
                    InternetAddress userAddress = new InternetAddress(user.getEmail());
                    emailService.send(subject, msg, getAdminEmail(), new InternetAddress[] { userAddress }, null);
                } catch (AddressException e) {
                    failMessages.add("Address exception for user: " + printUser(user) + ", " + e.getMessage());
                }
            }
        }
        if (!failMessages.isEmpty()) {
            sendFailMessages("User message: " + subject, msg, failMessages);
        }
        return failMessages.isEmpty();
    }

    /**
     * Send email to the administratorUser (running this program), to the &quot;extra recipients&quot; (specified on the
     * command line), and to the admin accounts, passed in.
     * 
     * @param subject
     * @param msg
     * @throws MessagingException
     */
    public boolean sendEmails(String subject, String msg, Collection<? extends ScreensaverUser> users)
            throws MessagingException {
        List<String> failMessages = Lists.newArrayList();
        Set<InternetAddress> recipients = Sets.newHashSet();

        if (users != null) {
            for (ScreensaverUser user : users) {
                String address = user.getEmail();
                if (StringUtils.isEmpty(address))
                    failMessages.add("Empty address for the user: " + printUser(user));
                else {
                    try {
                        recipients.add(new InternetAddress(address));
                    } catch (AddressException e) {
                        failMessages.add("Address excption for user: " + printUser(user) + ", " + e.getMessage());
                    }
                }
            }
        }

        if (!recipients.isEmpty()) {
            EmailService emailService = getEmailServiceBasedOnCommandLineOption();

            emailService.send(subject, msg.toString(), getAdminEmail(),
                    recipients.toArray(new InternetAddress[] {}), (InternetAddress[]) null);
        }
        if (!failMessages.isEmpty()) {
            sendFailMessages(subject, msg, failMessages);
        }
        return failMessages.isEmpty();
    }

    public void sendAdminEmails(String subject, String msg) throws MessagingException {
        sendAdminEmails(subject, msg, null, null);
    }

    public void sendAdminEmails(String subject, String msg, File attachedFile) throws MessagingException {
        sendAdminEmails(subject, msg, null, attachedFile);
    }

    /**
     * Send email to the administratorUser (running this program), to the &quot;extra recipients&quot; (specified on the
     * command line), and to the admin accounts, passed in.
     * 
     * @param subject
     * @param msg
     * @throws MessagingException
     */
    public void sendAdminEmails(String subject, String msg, Collection<ScreensaverUser> adminUsers)
            throws MessagingException {
        sendAdminEmails(subject, msg, adminUsers, null);
    }

    public void sendAdminEmails(String subject, String msg, Collection<ScreensaverUser> adminUsers,
            File attachedFile) throws MessagingException {
        List<String> failMessages = Lists.newArrayList();
        Set<InternetAddress> adminRecipients = Sets.newHashSet();
        adminRecipients.add(getAdminEmail());

        for (String r : getExtraRecipients()) {
            try {
                adminRecipients.add(new InternetAddress(r));
            } catch (AddressException e) {
                failMessages.add("Address excption for: " + r + ", " + e.getMessage());
            }
        }

        if (adminUsers != null) {
            for (ScreensaverUser user : adminUsers) {
                String address = user.getEmail();
                if (StringUtils.isEmpty(address))
                    failMessages.add("Empty address for the user: " + printUser(user));
                else {
                    try {
                        adminRecipients.add(new InternetAddress(address));
                    } catch (AddressException e) {
                        failMessages.add("Address excption for user: " + printUser(user) + ", " + e.getMessage());
                    }
                }
            }
        }

        EmailService emailService = getEmailServiceBasedOnCommandLineOption();

        try {
            emailService.send(subject, msg.toString(), getAdminEmail(),
                    adminRecipients.toArray(new InternetAddress[] {}), (InternetAddress[]) null, attachedFile);
        } catch (IOException e) {
            String errmsg = "Exception when trying to attach the file: " + attachedFile;
            log.warn(errmsg, e);
            failMessages.add(errmsg + ", " + e.getMessage());
        }

        if (!failMessages.isEmpty()) {
            sendFailMessages(subject, msg, failMessages);
        }

    }

    private void sendFailMessages(String subject, String msg, List<String> failMessages) throws MessagingException {
        StringBuilder errmsg = new StringBuilder("Failures: \n");
        for (String m : failMessages) {
            errmsg.append("\n").append(m);
        }
        errmsg.append("\nOriginal Message:\n").append(msg);
        sendAdminEmails("Failed Message delivery for: " + subject, errmsg.toString());
    }

    public final Set<String> getExtraRecipients() {
        Set<String> stringSet = Sets.newHashSet();
        if (isCommandLineFlagSet(EMAIL_RECIPIENT_LIST_OPTION[SHORT_OPTION_INDEX])) {
            String recipientList = getCommandLineOptionValue(EMAIL_RECIPIENT_LIST_OPTION[SHORT_OPTION_INDEX]);
            stringSet.addAll(Arrays.asList(recipientList.split(EmailService.DELIMITER)));
        }
        return stringSet;
    }

    public ServiceMessages getMessages() {
        if (_messages == null) {
            _messages = (ServiceMessages) getSpringBean("serviceMessages");
        }
        return _messages;
    }

    public final EmailService getEmailServiceBasedOnCommandLineOption() {
        EmailService emailService = null;
        if (isCommandLineFlagSet(NO_NOTIFY_OPTION[SHORT_OPTION_INDEX])) {
            emailService = new EmailService() {
                public void send(String subject, String message, InternetAddress from, InternetAddress[] recipients,
                        InternetAddress[] cclist) throws MessagingException {
                    try {
                        send(subject, message, from, recipients, cclist, null);
                    } catch (IOException e) { // this shall never happen
                        e.printStackTrace();
                    }
                }

                public void send(String subject, String message, InternetAddress from, InternetAddress[] recipients,
                        InternetAddress[] cclist, File attachedFile) throws MessagingException, IOException {
                    log.info("Mock Email (Not Sent):\n"
                            + SmtpEmailService.printEmail(subject, message, from, null, recipients, cclist,
                                    (attachedFile == null ? "" : "" + attachedFile.getCanonicalFile())));
                }
            };
        } else if (isCommandLineFlagSet(TEST_EMAIL_ONLY[SHORT_OPTION_INDEX])) {
            InternetAddress adminEmail = null;
            try {
                adminEmail = new InternetAddress(findAdministratorUser().getEmail());
            } catch (AddressException e) {
                String msg = "Admin account used has an email problem: "
                        + printUserInformation(findAdministratorUser());
                throw new IllegalArgumentException(msg, e);
            }
            final InternetAddress finalAdminEmail = adminEmail;
            final EmailService wrappedEmailService = (EmailService) getSpringBean("emailService");
            emailService = new EmailService() {
                public void send(String subject, String message, InternetAddress from, InternetAddress[] recipients,
                        InternetAddress[] cclist) throws MessagingException {
                    try {
                        send(subject, message, from, recipients, cclist, null);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                public void send(String subject, String message, InternetAddress from, InternetAddress[] recipients,
                        InternetAddress[] ccrecipients, File attachedFile) throws MessagingException, IOException {
                    message = "Testing Email Wrapper:  redirect email to admin, original email to be sent to:\n"
                            + Arrays.asList(recipients) + "\n=======message=========\n" + message;
                    wrappedEmailService.send("Redirected to: " + finalAdminEmail + ", Subject: " + subject, message,
                            finalAdminEmail, new InternetAddress[] { finalAdminEmail }, null, attachedFile);
                }
            };
        } else {
            emailService = (EmailService) getSpringBean("emailService");
        }
        return emailService;
    }

    private InternetAddress getAdminEmail() {
        try {
            return new InternetAddress(findAdministratorUser().getEmail());
        } catch (AddressException e) {
            throw new IllegalArgumentException(
                    "Problem with the admin email: " + printUserInformation(findAdministratorUser()), e);
        }
    }
}