JAVA mails API using IMAP- Reading mails based on UID that too without changing seen/unseen status at mail server send

JAVA mails API using IMAP- Reading mails based on UID that too without changing seen/unseen status at mail server send

Here I would like to share a scenario where I have to process mails using JAVA mails API based on UID and that too without changing seen/unseen status at mail server end. Now to start reading mails based on UID you first need to trigger some action point from where you can start mails reading so that you can access the mail UIDs of the mails and then next time you can use the last processed mail UID to process futher mails. Here as an action point i have used current received date. So, for the current received date I will process the mail and then I will store the mail UID of the last mail processed at that particular instance. Here I am actually storing the mail UID of the current processed mail and then overriding the stored mail UID as am further processing the mails. That wise I will get the last mail UID using current received date as SearchTerm.

	public void connectToMailBox() {
				numberOfAttachments=0;
				Properties props = new Properties();
				props.setProperty("mail.store.protocol", protocol);
				
				props.setProperty("mail.imaps.socketFactory.class", SSL_FACTORY);
				props.setProperty("mail.imaps.socketFactory.fallback", "false");
			    props.setProperty("mail.imaps.port", IMAPS_PORT);
			    props.setProperty("mail.imap.ssl.enable", "true");
			    props.setProperty("mail.imaps.socketFactory.port", IMAPS_PORT);
			    props.setProperty("mail.imap.starttls.enable", "true");
				
				Session session = Session.getInstance(props, null);
				Store store;
				try {
					store = session.getStore(protocol);
					
					store.connect(<ImapServer>, <EmailAddress>, <Password>));
					
					Folder inbox = store.getFolder("INBOX");
					UIDFolder uf = (UIDFolder)inbox;
					inbox.open(Folder.READ_WRITE);
			       
					Message messages[]=null;

				    long mailMaxUID = 0L;
				    if(mailDao.checkIfMailMaxUIDIsPresent(<EmailAddress>)){
				    	mailMaxUID=mailDao.getMailMaxUID(<EmailAddress>);
				    	if(mailMaxUID!=0){
				    		messages=uf.getMessagesByUID(mailMaxUID+1, UIDFolder.LASTUID);
				    		logger.info("Total no. of messages--"+messages.length);
				    	}
				    }else{
				    	Date currentDate = new Date();
				    	//search todays messages
				    	ReceivedDateTerm dateEQtodaySearchTerm = new ReceivedDateTerm(ComparisonTerm.EQ, currentDate);
				    	messages = inbox.search(dateEQtodaySearchTerm);
				    	logger.info("Total no. of messages--"+messages.length);
				    }

				    for(int i = 0; i<messages.length; i++){
                                     boolean seenStatus=false;
					    long uid = uf.getUID(messages[i]); //save this UID
						logger.info("LONG messageUId--"+uid);
                                    					    if (messages[i].isSet(Flags.Flag.SEEN)) {
					    	logger.info("---------Mail is Read---------");
					    	seenStatus=true;
					    }else{
					    	logger.info("*********Mail is UnRead*********");
					    	seenStatus=false;
					    }//save the seen/unseen status before processing the mail
                                     //further process your mails
                                     if(!seenStatus){
							logger.info("#########Marking as UnRead#########");
							messages[i].setFlag(Flags.Flag.SEEN, false);
						}//if the mail was unseen before processing mails so change the status to unseen
                                    }
}

As we are saving the mail UID of the last processed mail, so next time when the processing starts we will just do uf.getMessagesByUID(mailMaxUID+1, UIDFolder.LASTUID); to get a set of messages ranging from last processed mail(excluding) till the last UID in the folder at that particular instance. Also since we are processing the mails so it’s natural that the mails will be marked as SEEN status, so here before processing the mail we will store its status and after processing if the the mail’s status was UNSEEN so we will forcefully change the status to UNSEEN using messages[i].setFlag(Flags.Flag.SEEN, false);