All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
es.iti.wakamiti.email.EmailHelper Maven / Gradle / Ivy
package es.iti.wakamiti.email;
import es.iti.wakamiti.api.WakamitiException;
import es.iti.wakamiti.api.util.ThrowableFunction;
import es.iti.wakamiti.api.util.WakamitiLogger;
import org.awaitility.Awaitility;
import org.awaitility.Duration;
import org.slf4j.Logger;
import javax.mail.*;
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;
import javax.mail.event.MessageCountListener;
import javax.mail.internet.MimeBodyPart;
import javax.mail.search.FlagTerm;
import javax.mail.search.SearchTerm;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class EmailHelper {
private static Logger logger = WakamitiLogger.forClass(EmailStepContributor.class);
private Session session;
private Store store;
private Map folders = new HashMap<>();
public EmailHelper(String protocol, String host, Integer port, String address, String password) {
try {
Objects.requireNonNull(protocol, "Email store protocol is not defined");
Objects.requireNonNull(host, "Email host is not defined");
Objects.requireNonNull(address, "Email address is not defined");
Objects.requireNonNull(password, "Email password is not defined");
this.session = Session.getDefaultInstance(new Properties(), null);
this.store = session.getStore(protocol);
if (port == null) {
this.store.connect(host, address, password);
} else {
this.store.connect(host, port, address, password);
}
} catch (MessagingException | NullPointerException e) {
throw new WakamitiException(e);
}
}
public void close() {
try {
closeFolders();
if (this.store != null) {
this.store.close();
this.store = null;
}
if (this.session != null) {
this.session = null;
}
} catch (MessagingException e) {
throw new WakamitiException("Error closing email session", e);
}
}
private void closeFolders() {
for (Map.Entry entry : folders.entrySet()) {
try {
entry.getValue().close(true);
} catch (MessagingException e) {
logger.error("Cannot close email folder {} : {}", entry.getKey(), e.getMessage());
logger.debug("", e);
}
}
folders.clear();
}
private Folder folder(String folderName) {
if (folderName == null) {
throw new WakamitiException("Email folder not defined");
}
if (this.folders.containsKey(folderName)) {
return folders.get(folderName);
}
try {
Folder folder = store.getFolder(folderName);
folder.open(Folder.READ_WRITE);
this.folders.put(folderName, folder);
return folder;
} catch (MessagingException e) {
throw new WakamitiException("Cannot open email folder {}", folderName, e);
}
}
public Integer getUnreadMessages(String folderName) {
try {
Flags seen = new Flags(Flags.Flag.SEEN);
SearchTerm unseenFlagTerm = new FlagTerm(seen, false);
return folder(folderName).search(unseenFlagTerm).length;
} catch (MessagingException e) {
throw new WakamitiException(e);
}
}
public Message getLatestMessage(String folderName) {
try {
Folder folder = folder(folderName);
for (int i=folder.getMessageCount(); i>0; i--) {
Message message = folder.getMessage(i);
if (!message.isSet(Flags.Flag.DELETED)) {
return message;
}
}
return null;
} catch (IndexOutOfBoundsException e) {
return null;
} catch (MessagingException e) {
throw new WakamitiException(e);
}
}
public Message waitForIncomingMessage(String folderName, long seconds) {
Folder folder = folder(folderName);
AtomicBoolean received = new AtomicBoolean();
MessageCountListener listener = new MessageCountAdapter() {
@Override
public void messagesAdded(MessageCountEvent e) {
received.set(true);
}
};
folder.addMessageCountListener(listener);
try {
Awaitility.await().atMost(seconds, TimeUnit.SECONDS).pollDelay(Duration.ONE_SECOND).untilTrue(received);
if (!received.get()) {
throw new AssertionError("No new email messages received within " + seconds + " seconds");
}
return folder.getMessage(folder.getMessageCount());
} catch (MessagingException e) {
throw new WakamitiException(e);
} finally {
folder.removeMessageCountListener(listener);
}
}
public Map getAllAttachments(Message message) {
try {
if (message.getContent() instanceof Multipart) {
Multipart multipart = (Multipart) message.getContent();
return findAttachments(multipart, Integer.MAX_VALUE);
} else {
return Map.of();
}
} catch (IOException | MessagingException e) {
throw new WakamitiException(e);
}
}
public Map.Entry getFirstAttachment(Message message) {
try {
if (message.getContent() instanceof Multipart) {
Multipart multipart = (Multipart) message.getContent();
Iterator> iterator = findAttachments(multipart, 1).entrySet().iterator();
if (iterator.hasNext()) {
return iterator.next();
}
}
throw new NoSuchElementException();
} catch (IOException | MessagingException e) {
throw new WakamitiException(e);
}
}
public String getBody(Message message) {
try {
Object content = message.getContent();
if (content instanceof String) {
return (String) content;
}
if (message.getContent() instanceof Multipart) {
StringBuilder body = new StringBuilder();
Multipart multipart = (Multipart) message.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
if (bodyPart.getDisposition() == null) {
body.append(bodyPart.getContent());
}
}
return body.toString();
}
throw new WakamitiException("Cannot extract email body of type {}", content.getClass());
} catch (IOException | MessagingException e) {
throw new WakamitiException(e);
}
}
private static Map findAttachments(Multipart multipart, int maxAttachments) {
try {
Map attachments = new HashMap<>();
for (int i = 0; i < multipart.getCount() && attachments.size() < maxAttachments; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) && bodyPart instanceof MimeBodyPart) {
attachments.put(bodyPart.getFileName(), readBytes(((MimeBodyPart) bodyPart)));
}
}
return attachments;
} catch (IOException | MessagingException e) {
throw new WakamitiException(e);
}
}
public void deleteMessages(String folderName, ThrowableFunction condition) {
try {
Folder folder = folder(folderName);
for (int i = 1; i <= folder.getMessageCount(); i++) {
Message message = folder.getMessage(i);
if (Boolean.TRUE.equals(condition.apply(message))) {
message.setFlag(Flags.Flag.DELETED, true);
}
}
} catch (MessagingException e) {
throw new WakamitiException(e);
}
}
private static byte[] readBytes(MimeBodyPart bodyPart) throws MessagingException, IOException {
return bodyPart.getInputStream().readAllBytes();
}
public Message[] getAllMessages(String folderName) throws MessagingException {
return folder(folderName).getMessages();
}
}