diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java index dba6cf25a3..491dca8cde 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java @@ -27,12 +27,10 @@ import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Store; import javax.mail.URLName; -import javax.mail.Flags.Flag; import javax.mail.internet.MimeMessage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.beans.factory.DisposableBean; import org.springframework.integration.context.IntegrationObjectSupport; import org.springframework.util.Assert; @@ -64,7 +62,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl private volatile boolean shouldDeleteMessages = false; - private volatile Boolean shouldMarkMessagesAsRead; + private volatile int folderOpenMode = Folder.READ_ONLY; private volatile Properties javaMailProperties = new Properties(); @@ -150,21 +148,6 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl public void setShouldDeleteMessages(boolean shouldDeleteMessages) { this.shouldDeleteMessages = shouldDeleteMessages; } - /** - * Check if messages should be marked as read - * @return - */ - public Boolean isShouldMarkMessagesAsRead() { - return shouldMarkMessagesAsRead; - } - /** - * Specify is messages should be marked as read - * @return - */ - public void setShouldMarkMessagesAsRead(Boolean shouldMarkMessagesAsRead) { - this.shouldMarkMessagesAsRead = shouldMarkMessagesAsRead; - } - /** * Indicates whether the mail messages should be deleted after being received. */ @@ -223,14 +206,9 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl if (logger.isDebugEnabled()) { logger.debug("opening folder [" + MailTransportUtils.toPasswordProtectedString(this.url) + "]"); } - if (this.shouldDeleteMessages() || this.shouldMarkMessagesAsRead) { - this.folder.open(Folder.READ_WRITE); - } - else { - this.folder.open(Folder.READ_ONLY); - } + this.folder.open(folderOpenMode); } - + public synchronized Message[] receive() { try { this.openFolder(); @@ -252,9 +230,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl Message[] copiedMessages = new Message[messages.length]; for (int i = 0; i < messages.length; i++) { - if (this.shouldMarkMessagesAsRead != null && this.shouldMarkMessagesAsRead) { - messages[i].setFlag(Flag.SEEN, true); - } + this.setAdditionalFlags(messages[i]); copiedMessages[i] = new MimeMessage((MimeMessage) messages[i]); } if (this.shouldDeleteMessages()) { @@ -313,4 +289,12 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl public String toString() { return this.url.toString(); } + + protected void setAdditionalFlags(Message message) throws MessagingException { + // nothing at the base class + } + + void setFolderOpenMode(int folderOpenMode) { + this.folderOpenMode = folderOpenMode; + } } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java index 8c5a26a959..21c8c42a1e 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java @@ -17,6 +17,7 @@ package org.springframework.integration.mail; import javax.mail.Flags; +import javax.mail.Flags.Flag; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; @@ -45,7 +46,7 @@ import com.sun.mail.imap.IMAPFolder; * @author Oleg Zhurakousky */ public class ImapMailReceiver extends AbstractMailReceiver { - + private volatile boolean shouldMarkMessagesAsRead = true;; private final MessageCountListener messageCountListener = new SimpleMessageCountListener(); @@ -65,7 +66,20 @@ public class ImapMailReceiver extends AbstractMailReceiver { } } - + /** + * Check if messages should be marked as read + * @return + */ + public Boolean isShouldMarkMessagesAsRead() { + return shouldMarkMessagesAsRead; + } + /** + * Specify is messages should be marked as read + * @return + */ + public void setShouldMarkMessagesAsRead(Boolean shouldMarkMessagesAsRead) { + this.shouldMarkMessagesAsRead = shouldMarkMessagesAsRead; + } /** * This method is unique to the IMAP receiver and only works if IMAP IDLE * is supported (see RFC 2177 for more detail). @@ -161,7 +175,20 @@ public class ImapMailReceiver extends AbstractMailReceiver { } } } + /** + * + */ protected void onInit() throws Exception { - this.setShouldMarkMessagesAsRead(this.isShouldMarkMessagesAsRead() == null ? true : this.isShouldMarkMessagesAsRead()); + if (this.shouldMarkMessagesAsRead){ + this.setFolderOpenMode(Folder.READ_WRITE); + } + } + /** + * + */ + protected void setAdditionalFlags(Message message) throws MessagingException{ + if (this.shouldMarkMessagesAsRead) { + message.setFlag(Flag.SEEN, true); + } } } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java index fd7c948d17..002425eff6 100644 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailReceiverFactoryBean.java @@ -152,7 +152,7 @@ public class MailReceiverFactoryBean implements FactoryBean, Dispo if (isPop3){ logger.warn("Setting 'should-mark-messages-as-read' to 'true' while using POP3 has no effect"); } else if (isImap){ - receiver.setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead); + ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead); } } return receiver; diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/AbstractMailReceiverTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/AbstractMailReceiverTests.java index f97cea81d6..999b1d0255 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/AbstractMailReceiverTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/AbstractMailReceiverTests.java @@ -15,6 +15,7 @@ */ package org.springframework.integration.mail; +import javax.mail.Folder; import javax.mail.Message; import javax.mail.Flags.Flag; import javax.mail.internet.MimeMessage; @@ -23,6 +24,7 @@ import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.springframework.beans.DirectFieldAccessor; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -39,14 +41,20 @@ public class AbstractMailReceiverTests { @Test public void receieveAndMarkAsReadDontDelete() throws Exception{ AbstractMailReceiver receiver = new ImapMailReceiver(); - receiver.setShouldMarkMessagesAsRead(true); + ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(true); receiver = spy(receiver); + receiver.afterPropertiesSet(); Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) throws Throwable { - // just to avoid the exception + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode != Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_WRITE mode"); + } return null; } }).when(receiver).openFolder(); @@ -70,15 +78,20 @@ public class AbstractMailReceiverTests { @Test public void receieveMarkAsReadAndDelete() throws Exception{ AbstractMailReceiver receiver = new ImapMailReceiver(); - receiver.setShouldMarkMessagesAsRead(true); + ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(true); receiver.setShouldDeleteMessages(true); receiver = spy(receiver); + receiver.afterPropertiesSet(); Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) throws Throwable { - // just to avoid the exception + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode != Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_WRITE mode"); + } return null; } }).when(receiver).openFolder(); @@ -102,14 +115,19 @@ public class AbstractMailReceiverTests { @Test public void receieveAndDontMarkAsRead() throws Exception{ AbstractMailReceiver receiver = new ImapMailReceiver(); - receiver.setShouldMarkMessagesAsRead(false); + ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(false); receiver = spy(receiver); + receiver.afterPropertiesSet(); Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) throws Throwable { - // just to avoid the exception + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode == Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_ONLY mode"); + } return null; } }).when(receiver).openFolder(); @@ -130,4 +148,39 @@ public class AbstractMailReceiverTests { verify(msg1, times(0)).setFlag(Flag.SEEN, true); verify(msg2, times(0)).setFlag(Flag.SEEN, true); } + @Test + public void receieveAndIgnoreMarkAsReadDontDelete() throws Exception{ + AbstractMailReceiver receiver = new ImapMailReceiver(); + receiver = spy(receiver); + receiver.afterPropertiesSet(); + Message msg1 = mock(MimeMessage.class); + Message msg2 = mock(MimeMessage.class); + final Message[] messages = new Message[]{msg1, msg2}; + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock()); + int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode"); + if (folderOpenMode != Folder.READ_WRITE){ + throw new IllegalArgumentException("Folder had to be open in READ_WRITE mode"); + } + return null; + } + }).when(receiver).openFolder(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return messages; + } + }).when(receiver).searchForNewMessages(); + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).fetchMessages(messages); + receiver.receive(); + verify(msg1, times(1)).setFlag(Flag.SEEN, true); + verify(msg2, times(1)).setFlag(Flag.SEEN, true); + verify(receiver, times(0)).deleteMessages((Message[]) Mockito.any()); + } } diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/InboundChannelAdapterParserTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/InboundChannelAdapterParserTests.java index f23005bf0a..b3ca495135 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/InboundChannelAdapterParserTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/InboundChannelAdapterParserTests.java @@ -64,22 +64,6 @@ public class InboundChannelAdapterParserTests { assertTrue(value); } - @Test - public void pop3IgnoreMarkAsReadWithTrue() { - AbstractMailReceiver receiver = this.getReceiver("pop3ShouldMarkAsReadTrue"); - assertEquals(Pop3MailReceiver.class, receiver.getClass()); - Boolean value = (Boolean) new DirectFieldAccessor(receiver).getPropertyValue("shouldMarkMessagesAsRead"); - assertNull(value); - } - - @Test - public void pop3IgnoreMarkAsReadWithFalse() { - AbstractMailReceiver receiver = this.getReceiver("pop3ShouldMarkAsReadFalse"); - assertEquals(Pop3MailReceiver.class, receiver.getClass()); - Boolean value = (Boolean) new DirectFieldAccessor(receiver).getPropertyValue("shouldMarkMessagesAsRead"); - assertNull(value); - } - @Test public void imapShouldMarkMessagesAsRead() { AbstractMailReceiver receiver = this.getReceiver("imapShouldMarkAsReadTrue");