package de.uni_passau.fim.infosun.prophet.plugin.plugins.mailPlugin; import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.swing.SpinnerNumberModel; import de.uni_passau.fim.infosun.prophet.experimentViewer.EViewer; import de.uni_passau.fim.infosun.prophet.plugin.Plugin; import de.uni_passau.fim.infosun.prophet.util.Pair; import de.uni_passau.fim.infosun.prophet.util.qTree.Attribute; import de.uni_passau.fim.infosun.prophet.util.qTree.QTreeNode; import de.uni_passau.fim.infosun.prophet.util.settings.Setting; import de.uni_passau.fim.infosun.prophet.util.settings.SettingsList; import de.uni_passau.fim.infosun.prophet.util.settings.components.ComboBoxSetting; import de.uni_passau.fim.infosun.prophet.util.settings.components.PasswordFieldSetting; import de.uni_passau.fim.infosun.prophet.util.settings.components.SpinnerSetting; import de.uni_passau.fim.infosun.prophet.util.settings.components.TextFieldSetting; import static de.uni_passau.fim.infosun.prophet.util.language.UIElementNames.getLocalized; import static de.uni_passau.fim.infosun.prophet.util.qTree.QTreeNode.Type.EXPERIMENT; /** * A <code>Plugin</code> that can send the folder that results from an experiment run (containing answers.xml and other * files) as an attachment to a predefined Email address. */ public class MailPlugin implements Plugin { private static final String KEY = "sendmail"; private static final String SMTP_SERVER = "smtp_server"; private static final String SMTP_USER = "smtp_user"; private static final String SMTP_PASS = "smtp_pass"; private static final String SMTP_SENDER = "smtp_sender"; private static final String SMTP_RECEIVER = "smtp_receiver"; private static final String SMTP_SERVER_PORT = "smtp_server_port"; private static final String SMTP_SERVER_SEC = "smtp_server_sec"; private static final String SEC_NONE = "-"; private static final String SEC_STARTTLS = "STARTTLS"; private static final String SEC_SSL_TLS = "SSL/TLS"; private boolean enabled; private String smtpServer; private String smtpUser; private String smtpPass; private String smtpSender; private String smtpReceiver; private String smtpSec; private int smtpPort; private EViewer experimentViewer; @Override public Setting getSetting(QTreeNode node) { if (node.getType() != EXPERIMENT) { return null; } Attribute mainAttribute = node.getAttribute(KEY); SettingsList settingsList = new SettingsList(mainAttribute, getClass().getSimpleName(), true); settingsList.setCaption(getLocalized("MAIL_SEND_MAIL")); Attribute subAttribute = mainAttribute.getSubAttribute(SMTP_SENDER); Setting subSetting = new TextFieldSetting(subAttribute, null); subSetting.setCaption(getLocalized("MAIL_SMTP_SENDER") + ':'); settingsList.addSetting(subSetting); subAttribute = mainAttribute.getSubAttribute(SMTP_RECEIVER); subSetting = new TextFieldSetting(subAttribute, null); subSetting.setCaption(getLocalized("MAIL_SMTP_RECIPIENT") + ':'); settingsList.addSetting(subSetting); subAttribute = mainAttribute.getSubAttribute(SMTP_SERVER); subSetting = new TextFieldSetting(subAttribute, null); subSetting.setCaption(getLocalized("MAIL_SMTP_SERVER") + ':'); settingsList.addSetting(subSetting); subAttribute = mainAttribute.getSubAttribute(SMTP_SERVER_PORT); subSetting = new SpinnerSetting(subAttribute, null, new SpinnerNumberModel(587, 0, 65535, 1)); subSetting.setCaption(getLocalized("MAIL_SMTP_SERVER_PORT") + ':'); settingsList.addSetting(subSetting); List<Pair<String, String>> items = new ArrayList<>(); items.add(Pair.of(SEC_NONE, SEC_NONE)); items.add(Pair.of(SEC_STARTTLS, SEC_STARTTLS)); items.add(Pair.of(SEC_SSL_TLS, SEC_SSL_TLS)); subAttribute = mainAttribute.getSubAttribute(SMTP_SERVER_SEC); subSetting = new ComboBoxSetting(subAttribute, null, items); subSetting.setCaption(getLocalized("MAIL_SMTP_SECURITY") + ':'); settingsList.addSetting(subSetting); subAttribute = mainAttribute.getSubAttribute(SMTP_USER); subSetting = new TextFieldSetting(subAttribute, null); subSetting.setCaption(getLocalized("MAIL_SMTP_USER") + ':'); settingsList.addSetting(subSetting); subAttribute = mainAttribute.getSubAttribute(SMTP_PASS); subSetting = new PasswordFieldSetting(subAttribute, null); subSetting.setCaption(getLocalized("MAIL_SMTP_PASSWORD") + ':'); settingsList.addSetting(subSetting); return settingsList; } @Override public void experimentViewerRun(EViewer experimentViewer) { this.experimentViewer = experimentViewer; } @Override public boolean denyEnterNode(QTreeNode node) { return false; } @Override public void enterNode(QTreeNode node) { if (node.getType() != EXPERIMENT) { return; } enabled = node.containsAttribute(KEY) && Boolean.parseBoolean(node.getAttribute(KEY).getValue()); if (enabled) { Attribute attributes = node.getAttribute(KEY); smtpServer = attributes.getSubAttribute(SMTP_SERVER).getValue(); smtpUser = attributes.getSubAttribute(SMTP_USER).getValue(); smtpPass = PasswordFieldSetting.decode(attributes.getSubAttribute(SMTP_PASS).getValue()); smtpSender = attributes.getSubAttribute(SMTP_SENDER).getValue(); smtpReceiver = attributes.getSubAttribute(SMTP_RECEIVER).getValue(); smtpSec = attributes.getSubAttribute(SMTP_SERVER_SEC).getValue(); smtpPort = Integer.parseInt(attributes.getSubAttribute(SMTP_SERVER_PORT).getValue()); } } @Override public String denyNextNode(QTreeNode currentNode) { return null; } @Override public void exitNode(QTreeNode node) { } @Override public String finishExperiment() { if (enabled) { ZFile attachment = new ZFile(experimentViewer.getSaveDir().toURI()); try { sendEMail(experimentViewer.getSaveDir().getName(), "", attachment.zip().orElse(null)); } catch (MessagingException e) { System.err.println("Could not send the EMail containing the zipped experiment results."); System.err.println(e.getMessage()); return getLocalized("MAIL_MESSAGE_COULD_NOT_SEND_MAIL"); } } return null; } /** * Sends an EMail with the given <code>subject</code>, <code>text</code> and optionally an attachment file to * the address configured via the <code>Plugin</code> settings. * * @param subject * the subject line for the EMail * @param text * the text for the EMail * @param attachmentFile * the attachment file or <code>null</code> for no attachment file * * @throws MessagingException * if there is an error creating or sending the EMail */ private void sendEMail(String subject, String text, File attachmentFile) throws MessagingException { Properties properties = new Properties(); properties.setProperty("mail.smtp.host", smtpServer); properties.setProperty("mail.smtp.port", String.valueOf(smtpPort)); properties.setProperty("mail.smtp.auth", "true"); if (SEC_STARTTLS.equals(smtpSec)) { properties.setProperty("mail.smtp.starttls.enable", "true"); } else if (SEC_SSL_TLS.equals(smtpSec)) { properties.setProperty("mail.smtp.ssl.enable", "true"); } Session session = Session.getInstance(properties); Transport transport = session.getTransport("smtp"); Message message = new MimeMessage(session); MimeMultipart content = new MimeMultipart(); MimeBodyPart textPart = new MimeBodyPart(); textPart.setText(text); content.addBodyPart(textPart); if (attachmentFile != null) { DataSource fileDataSource = new FileDataSource(attachmentFile); BodyPart attachmentPart = new MimeBodyPart(); attachmentPart.setDataHandler(new DataHandler(fileDataSource)); attachmentPart.setFileName(attachmentFile.getName()); content.addBodyPart(attachmentPart); } message.setContent(content); message.setSentDate(new Date()); message.setFrom(new InternetAddress(smtpSender)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(smtpReceiver, false)); message.setSubject(subject); try { transport.connect(smtpUser, smtpPass); transport.sendMessage(message, message.getAllRecipients()); } finally { transport.close(); } } }