diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/EmailSender.java b/service/src/main/java/lcsb/mapviewer/services/utils/EmailSender.java index 132f72207c0b9610d3323fe1f85a3ee3002fcc95..4aa84c18f5f4a7e6bebac8e1581e3b304de06d01 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/EmailSender.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/EmailSender.java @@ -1,26 +1,37 @@ package lcsb.mapviewer.services.utils; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.FileDataSource; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; +import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Store; import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; - -import lcsb.mapviewer.model.user.ConfigurationElementType; -import lcsb.mapviewer.model.user.User; -import lcsb.mapviewer.services.interfaces.IConfigurationService; +import javax.mail.internet.MimeMultipart; import org.apache.log4j.Logger; import com.sun.mail.smtp.SMTPTransport; +import lcsb.mapviewer.model.user.ConfigurationElementType; +import lcsb.mapviewer.model.user.User; +import lcsb.mapviewer.services.interfaces.IConfigurationService; + /** * Class that allows to send emails. It requires access to email account from * which emails will be sent. @@ -29,218 +40,274 @@ import com.sun.mail.smtp.SMTPTransport; * */ public class EmailSender { - /** - * Default class logger. - */ - private Logger logger = Logger.getLogger(EmailSender.class); - - /** - * String (usualy email address) that should appear in sender field of the - * email. - */ - private String sender; - /** - * Login used for accessing mail account. - */ - private String login; - /** - * Password used for accessing mail account. - */ - private String password; - /** - * Server used for smtp. - */ - private String smtpHost; - /** - * Port on the server used by imap. - */ - private String imapHost; - /** - * Port on the server used by smtp. - */ - private String smtpPort; - - /** - * Default constructor that initializes data. - * - * @param address - * {@link #sender} - * @param login - * {@link #login} - * @param password - * {@link #password} - * @param smtpServerAddress - * {@link #smtpHost} - * @param imapServerAddress - * {@link #imapHost} - * @param smtpServerPort - * {@link #smtpPort} - */ - public EmailSender(String address, String login, String password, String smtpServerAddress, String imapServerAddress, String smtpServerPort) { - this.sender = address; - this.login = login; - this.password = password; - this.smtpHost = smtpServerAddress; - this.imapHost = imapServerAddress; - this.smtpPort = smtpServerPort; - - } - - /** - * Creates email sender class from data taken from - * {@link IConfigurationService}. - * - * @param configurationService - * configuration service that contains information required to access - * email account - */ - public EmailSender(IConfigurationService configurationService) { - this(configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_ADDRESS), // - configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_LOGIN), // - configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_PASSWORD), // - configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_SERVER), // - configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_IMAP_SERVER), // - configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_PORT)); - } - - /** - * Sends email. - * - * @param subject - * subject of the email - * @param message - * content of the message - * @param receiver - * user that should receive email - * @throws MessagingException - * thrown whene there is a problem with sending email - */ - public void sendEmail(String subject, String message, User receiver) throws MessagingException { - if (receiver.getEmail() == null || receiver.getEmail().equals("")) { - logger.warn("Cannot send email to user: " + receiver.getName() + " " + receiver.getSurname() + ". Email set to null"); - return; - } - List<String> recipients = new ArrayList<String>(); - recipients.add(receiver.getEmail()); - sendEmail(recipients, new ArrayList<String>(), subject, message); - - } - - /** - * Sends email. - * - * @param recipients - * list of email recipients - * @param ccRecipients - * list of cc email recipients - * @param subject - * subject of the email - * @param message - * message content - * @throws MessagingException - * thrown when there is a problem with sending email - */ - public void sendEmail(List<String> recipients, List<String> ccRecipients, String subject, String message) throws MessagingException { - if (smtpHost.equals(ConfigurationElementType.EMAIL_SMTP_SERVER.getDefaultValue())) { - logger.warn("Cannot send email. No smpt server defined"); - return; - } - // set data of the mail account - - Properties props = System.getProperties(); - props.setProperty("mail.smtp.host", smtpHost); - props.setProperty("mail.smtp.port", smtpPort); - props.put("mail.smtps.quitwait", "false"); - - Session session = Session.getInstance(props, null); - - final MimeMessage msg = new MimeMessage(session); - - // set from address - - msg.setFrom(new InternetAddress(sender)); - - // add recipients - InternetAddress[] rec = new InternetAddress[recipients.size()]; - for (int i = 0; i < recipients.size(); i++) { - rec[i] = new InternetAddress(recipients.get(i)); - } - - msg.setRecipients(Message.RecipientType.TO, rec); - - // add cc recipients - InternetAddress[] cc = new InternetAddress[ccRecipients.size()]; - for (int i = 0; i < ccRecipients.size(); i++) { - rec[i] = new InternetAddress(ccRecipients.get(i)); - } - - msg.setRecipients(Message.RecipientType.CC, cc); - - // set subject - msg.setSubject(subject); - - // set timestamp - msg.setSentDate(new Date()); - - // and content - msg.setContent(message, "text/html; charset=utf-8"); - - // connect and send - SMTPTransport t = (SMTPTransport) session.getTransport("smtp"); - - t.connect(smtpHost, login, password); - t.sendMessage(msg, msg.getAllRecipients()); - t.close(); - } - - /** - * Returns number of emails in email account. - * - * @return number of emails in email account. - * @throws MessagingException - * thrown when there is a problem with accessing email account - */ - public int getInboxCount() throws MessagingException { - /* Set the mail properties */ - Properties props = System.getProperties(); - props.setProperty(imapHost, "imaps"); - - /* Create the session and get the store for read the mail. */ - Session session = Session.getDefaultInstance(props, null); - Store store = session.getStore("imaps"); - store.connect(imapHost, login, password); - - /* Mention the folder name which you want to read. */ - Folder inbox = store.getFolder("Inbox"); - int result = inbox.getUnreadMessageCount(); - - store.close(); - - return result; - - } - - /** - * Sends email. - * - * @param subject - * subject of the email - * @param message - * content of the message - * @param emailAddress - * email address that should receive email - * @throws MessagingException - * thrown whene there is a problem with sending email - */ - public void sendEmail(String subject, String message, String emailAddress) throws MessagingException { - if (emailAddress == null || emailAddress.equals("")) { - logger.warn("Cannot send email to user: " + emailAddress + ". Email set to null"); - return; - } - List<String> recipients = new ArrayList<String>(); - recipients.add(emailAddress); - sendEmail(recipients, new ArrayList<String>(), subject, message); - - } + + /** + * Max size of the content that is allowed as plain text. For emails with longer + * content the content will be compressed and added as an attachment file. + */ + private static final int MAX_EMAIL_CONTENT_SIZE = 32 * 1024; + + /** + * Default class logger. + */ + private Logger logger = Logger.getLogger(EmailSender.class); + + /** + * String (usually email address) that should appear in sender field of the + * email. + */ + private String sender; + /** + * Login used for accessing mail account. + */ + private String login; + /** + * Password used for accessing mail account. + */ + private String password; + /** + * Server used for SMTP. + */ + private String smtpHost; + /** + * Port on the server used by IMAP. + */ + private String imapHost; + /** + * Port on the server used by SMTP. + */ + private String smtpPort; + + /** + * Default constructor that initializes data. + * + * @param address + * {@link #sender} + * @param login + * {@link #login} + * @param password + * {@link #password} + * @param smtpServerAddress + * {@link #smtpHost} + * @param imapServerAddress + * {@link #imapHost} + * @param smtpServerPort + * {@link #smtpPort} + */ + public EmailSender(String address, String login, String password, String smtpServerAddress, String imapServerAddress, + String smtpServerPort) { + this.sender = address; + this.login = login; + this.password = password; + this.smtpHost = smtpServerAddress; + this.imapHost = imapServerAddress; + this.smtpPort = smtpServerPort; + + } + + /** + * Creates email sender class from data taken from + * {@link IConfigurationService}. + * + * @param configurationService + * configuration service that contains information required to access + * email account + */ + public EmailSender(IConfigurationService configurationService) { + this(configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_ADDRESS), // + configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_LOGIN), // + configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_PASSWORD), // + configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_SERVER), // + configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_IMAP_SERVER), // + configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_PORT)); + } + + /** + * Sends email. + * + * @param subject + * subject of the email + * @param message + * content of the message + * @param receiver + * user that should receive email + * @throws MessagingException + * thrown when there is a problem with sending email + */ + public void sendEmail(String subject, String message, User receiver) throws MessagingException { + if (receiver.getEmail() == null || receiver.getEmail().equals("")) { + logger.warn( + "Cannot send email to user: " + receiver.getName() + " " + receiver.getSurname() + ". Email set to null"); + return; + } + List<String> recipients = new ArrayList<String>(); + recipients.add(receiver.getEmail()); + sendEmail(recipients, new ArrayList<String>(), subject, message); + + } + + /** + * Sends email. + * + * @param recipients + * list of email recipients + * @param ccRecipients + * list of cc email recipients + * @param subject + * subject of the email + * @param message + * message content + * @throws MessagingException + * thrown when there is a problem with sending email + */ + public void sendEmail(List<String> recipients, List<String> ccRecipients, String subject, String message) + throws MessagingException { + if (smtpHost.equals(ConfigurationElementType.EMAIL_SMTP_SERVER.getDefaultValue())) { + logger.warn("Cannot send email. No smpt server defined"); + return; + } + // set data of the mail account + + Properties props = System.getProperties(); + props.setProperty("mail.smtp.host", smtpHost); + props.setProperty("mail.smtp.port", smtpPort); +// props.setProperty("mail.smtp.user", login); +// props.setProperty("mail.smtp.password", password); +// props.setProperty("mail.smtp.auth", "true"); + + props.put("mail.smtps.quitwait", "false"); + + Session session = Session.getInstance(props, null); + + final MimeMessage msg = new MimeMessage(session); + + // set from address + + msg.setFrom(new InternetAddress(sender)); + + // add recipients + InternetAddress[] rec = new InternetAddress[recipients.size()]; + for (int i = 0; i < recipients.size(); i++) { + rec[i] = new InternetAddress(recipients.get(i)); + } + + msg.setRecipients(Message.RecipientType.TO, rec); + + // add cc recipients + InternetAddress[] cc = new InternetAddress[ccRecipients.size()]; + for (int i = 0; i < ccRecipients.size(); i++) { + rec[i] = new InternetAddress(ccRecipients.get(i)); + } + + msg.setRecipients(Message.RecipientType.CC, cc); + + // set subject + msg.setSubject(subject); + + // set time stamp + msg.setSentDate(new Date()); + + File attachment = createAttachmentZipForBigMessage(message); + + if (attachment != null) { + MimeBodyPart textBodyPart = new MimeBodyPart(); + textBodyPart.setText("Content zipped, because it's size exceeded max size: " + MAX_EMAIL_CONTENT_SIZE, "UTF-8"); + + MimeBodyPart attachmentBodyPart = new MimeBodyPart(); + attachmentBodyPart = new MimeBodyPart(); + DataSource source = new FileDataSource(attachment); + attachmentBodyPart.setDataHandler(new DataHandler(source)); + attachmentBodyPart.setFileName("content.zip"); + + Multipart multipart = new MimeMultipart(); + multipart.addBodyPart(textBodyPart); + multipart.addBodyPart(attachmentBodyPart); + + msg.setContent(multipart); + } else { + // and content + msg.setContent(message, "text/html; charset=utf-8"); + } + + // connect and send + SMTPTransport t = (SMTPTransport) session.getTransport("smtp"); + + t.connect(smtpHost, login, password); + t.sendMessage(msg, msg.getAllRecipients()); + t.close(); + } + + private File createAttachmentZipForBigMessage(String message) { + File attachment = null; + if (message.length() > MAX_EMAIL_CONTENT_SIZE) { + try { + attachment = File.createTempFile("attachment", ".zip"); + + ZipOutputStream out = new ZipOutputStream(new FileOutputStream(attachment)); + ZipEntry e = new ZipEntry("content.txt"); + out.putNextEntry(e); + + byte[] data = message.getBytes(); + out.write(data, 0, data.length); + out.closeEntry(); + + out.close(); + } catch (IOException e1) { + logger.error("Problem with creating attachment. Fall back into putting everything into content"); + attachment = null; + } + } + return attachment; + } + + /** + * Returns number of emails in email account. + * + * @return number of emails in email account. + * @throws MessagingException + * thrown when there is a problem with accessing email account + */ + public int getInboxCount() throws MessagingException { + /* Set the mail properties */ + Properties props = System.getProperties(); + props.setProperty(imapHost, "imaps"); + + /* Create the session and get the store for read the mail. */ + Session session = Session.getDefaultInstance(props, null); + Store store = session.getStore("imaps"); + store.connect(imapHost, login, password); + + /* Mention the folder name which you want to read. */ + Folder inbox = store.getFolder("Inbox"); + int result = inbox.getUnreadMessageCount(); + + store.close(); + + return result; + + } + + /** + * Sends email. + * + * @param subject + * subject of the email + * @param message + * content of the message + * @param emailAddress + * email address that should receive email + * @throws MessagingException + * thrown whene there is a problem with sending email + */ + public void sendEmail(String subject, String message, String emailAddress) throws MessagingException { + if (emailAddress == null || emailAddress.equals("")) { + logger.warn("Cannot send email to user: " + emailAddress + ". Email set to null"); + return; + } + List<String> recipients = new ArrayList<String>(); + recipients.add(emailAddress); + sendEmail(recipients, new ArrayList<String>(), subject, message); + + } } diff --git a/service/src/test/java/lcsb/mapviewer/services/utils/EmailSenderTest.java b/service/src/test/java/lcsb/mapviewer/services/utils/EmailSenderTest.java index 053d44c477811863f9214d4291f5401bb7ed090c..1226c4dd307680ae6fe2625cc2e603376e7c90d5 100644 --- a/service/src/test/java/lcsb/mapviewer/services/utils/EmailSenderTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/utils/EmailSenderTest.java @@ -3,37 +3,37 @@ package lcsb.mapviewer.services.utils; import java.util.ArrayList; import java.util.List; -import lcsb.mapviewer.services.ServiceTestFunctions; - import org.apache.log4j.Logger; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import lcsb.mapviewer.services.ServiceTestFunctions; + public class EmailSenderTest extends ServiceTestFunctions { - Logger logger = Logger.getLogger(EmailSenderTest.class); - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - @Ignore("This is just a showcase") - public void test() throws Exception { - try { - EmailSender emailSender = new EmailSender(configurationService); - List<String> recipients = new ArrayList<String>(); - recipients.add("piotr.gawron@uni.lu"); - emailSender.sendEmail(recipients, new ArrayList<String>(), "Test subject", "Test content"); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } + Logger logger = Logger.getLogger(EmailSenderTest.class); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + @Ignore("This is just a showcase") + public void test() throws Exception { + try { + EmailSender emailSender = new EmailSender(configurationService); + List<String> recipients = new ArrayList<>(); + recipients.add("piotr.gawron@uni.lu"); + emailSender.sendEmail(recipients, new ArrayList<>(), "Test subject", "Test content"); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } }