All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nyla.solutions.email.ReadMail Maven / Gradle / Ivy

The newest version!
package nyla.solutions.email;
import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Store;

import nyla.solutions.core.exception.ConnectionException;
import nyla.solutions.core.io.IO;
import nyla.solutions.core.util.Text;
import nyla.solutions.email.data.EmailMessage;

public class ReadMail implements Closeable
{
	public ReadMail(Store store)
	{
		this(store,"Inbox");
	}//------------------------------------------------
	/**
	 * Constructor
	 * @param store the read mail
	 * @param folderName the folder name
	 */
	public ReadMail(Store store, String folderName)
	{
		if(store == null)
					throw new IllegalArgumentException("store is required");
		
		if(folderName == null || folderName.trim().length() == 0)
					throw new IllegalArgumentException("folderName is required");
		try
		{
			inbox = store.getFolder(folderName);
			
			if(inbox == null)
				throw new NullPointerException(folderName+" does not exists");
		}
		catch (MessagingException e)
		{
			throw new ConnectionException(e.getMessage(),e);
		}
		catch(RuntimeException e)
		{
			if(e.getMessage().contains("Not connected"))
			{
				throw new ConnectionException("Not connected, try the properties mail.auth.required,"+
					" mail.from "+
					" mail.from.password "+
					" mail.imap.host "+
					" mail.stmp.host "
					);
			}
			throw e;
			
		}
		
	}//------------------------------------------------
	/**
	 * 
	 * @param count the number of records to read
	 * @param startIndex the starting message index
	 * @param pattern the Complex regular expression to match
	 * @param subjectOnly flag to determine if only the subject will be checked
	 * @return matching email message
	 * @throws MessagingException when a mail server communication error occurs
	 * @throws IOException when IO error occurs
	 */
	public Collection readMatches(int count, int startIndex, String pattern, boolean subjectOnly) 
	throws MessagingException, IOException
	{
		if(!inbox.isOpen())
		{
			inbox.open(Folder.READ_ONLY);
		}

		if(startIndex< 1)
			throw new IllegalArgumentException("startIndex must be greater than 0");
		
		if(count < 1)
			throw new IllegalArgumentException("Count must be greater than 0");
			
		/* Get the messages which is unread in the Inbox */
		int totalCount = inbox.getMessageCount();
		if(startIndex >  totalCount)
			return null;
		
		if(startIndex+ count-1 > totalCount)
		{
			count = totalCount - startIndex;
		}
		
		Message[] msgs = inbox.getMessages(startIndex,startIndex+ count-1);
		
		if(msgs == null || msgs.length == 0)
			return null;
		
			ArrayList results = Arrays.asList(msgs).stream().filter(msg -> {
							try
							{
								if(msg == null)
									return false;
								
								if(Text.matches(msg.getSubject(),pattern))
									return false;
								
								if(subjectOnly)
								{	
									return true;
								}

								//do not filter/remove the matching patterns
								return !Text.matches(getContent(msg),pattern);
								
							}
							catch (IOException e)
							{
								throw new nyla.solutions.core.exception.CommunicationException(e.getMessage());
							}
							catch (MessagingException e)
							{
								throw new nyla.solutions.core.exception.CommunicationException(e.getMessage());
							}
						}
					).map(message -> {
						try
						{
							return toEmailMessage(message);
						}
						catch (MessagingException | IOException e)
						{
							throw new RuntimeException(e);
						}
					}  ).collect(Collectors.toCollection(ArrayList::new));
			
			if(results.isEmpty())
				return null;
			
			return results;
		
	}//------------------------------------------------

	/* Print the envelope(FromAddress,ReceivedDate,Subject) */
	private EmailMessage toEmailMessage(Message message) 
	throws MessagingException, IOException 
	{
		EmailMessage emailMessage = new EmailMessage();
		// FROM
		Address[] froms = message.getFrom();
		
		if (froms != null)
		{
			for (int j = 0; j < froms.length; j++)
			{
				emailMessage.addFrom(froms[j].toString());
			}
		}
		// TO
		
		Address[] tos = message.getRecipients(Message.RecipientType.TO);

		if (tos != null)
		{
			for (int j = 0; j < tos.length; j++)
			{
				emailMessage.addTo(tos[j].toString());
			}
		}
		
		emailMessage.setSubject(message.getSubject());
		emailMessage.setRecievedDate(message.getReceivedDate());
		emailMessage.setContent(getContent(message));
		
		System.out.println("emailMessage : " + emailMessage);
		
		return emailMessage;
		//getContent(message);
	}//------------------------------------------------

	private String getContent(Message msg) 
	throws MessagingException, IOException
	{
		Object obj = msg.getContent();
		
		if(obj == null)
			return null;
		
		if(!Multipart.class.isAssignableFrom(obj.getClass()))
			return obj.toString();
		
		Multipart mp = (Multipart) msg.getContent();
		int count = mp.getCount(); 
			
			StringBuilder results = new StringBuilder();
			
			for (int i = 0; i < count; i++)
			{
				results.append(readTextPart(mp.getBodyPart(i)));
			}

			return results.toString();
	}//------------------------------------------------

	private String readTextPart(Part p) 
	throws IOException, MessagingException
	{
		// Dump input stream ..
		InputStream is = p.getInputStream();
		// If "is" is not already buffered, wrap a BufferedInputStream
		// around it.
		if (!(is instanceof BufferedInputStream))
		{
			is = new BufferedInputStream(is);
		}
		return IO.readText(is, true);
	}//------------------------------------------------

	@Override
	public synchronized void close() throws IOException
	{
		if(isClosed)
			return;
		try
		{
			inbox.close(false);
		}
		catch (MessagingException e)
		{
			throw new nyla.solutions.core.exception.CommunicationException(e.getMessage(),e);
		}
		
		this.isClosed =  true;
		
	}//------------------------------------------------
	private final Folder inbox;
	private boolean isClosed = false;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy