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 e7f09e1747..f8ecb90503 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 @@ -16,6 +16,9 @@ package org.springframework.integration.mail; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; import java.util.Properties; import javax.mail.Authenticator; @@ -31,9 +34,13 @@ 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.expression.Expression; +import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.integration.context.IntegrationObjectSupport; import org.springframework.util.Assert; +import org.springframework.util.PatternMatchUtils; /** * Base class for {@link MailReceiver} implementations. @@ -72,6 +79,8 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl private Authenticator javaMailAuthenticator; + private final StandardEvaluationContext context = new StandardEvaluationContext(); + private volatile Expression selectorExpression; public AbstractMailReceiver() { this.url = null; @@ -91,6 +100,9 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl } } + public void setSelectorExpression(Expression selectorExpression) { + this.selectorExpression = selectorExpression; + } public void setProtocol(String protocol) { if (this.url != null) { @@ -229,15 +241,37 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl this.fetchMessages(messages); } - Message[] copiedMessages = new Message[messages.length]; + List copiedMessages = new LinkedList(); + logger.debug("Recieved " + messages.length + " messages"); for (int i = 0; i < messages.length; i++) { - this.setAdditionalFlags(messages[i]); - copiedMessages[i] = new MimeMessage((MimeMessage) messages[i]); + System.out.println(this.getFolder()); + System.out.println(this.getFolder().getPermanentFlags()); + if (this.getFolder().getPermanentFlags().contains(Flags.Flag.USER)){ + Flags siFlags = new Flags(); + siFlags.add("spring-integration"); + messages[i].setFlags(siFlags, true); + } + else { + logger.warn("USER flags are not supported by this mail server. Flagging message with system flag"); + messages[i].setFlag(Flags.Flag.FLAGGED, true); + } + + if (this.selectorExpression != null){ + Message message = messages[i]; + if ((Boolean)this.selectorExpression.getValue(this.context, message)){ + this.setAdditionalFlags(message); + copiedMessages.add(new MimeMessage((MimeMessage) message)); + } + } + else { + this.setAdditionalFlags(messages[i]); + copiedMessages.add(new MimeMessage((MimeMessage) messages[i])); + } } if (this.shouldDeleteMessages()) { this.deleteMessages(messages); } - return copiedMessages; + return copiedMessages.toArray(new Message[]{}); } catch (Exception e) { throw new org.springframework.integration.MessagingException( @@ -303,12 +337,38 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl @Override protected void onInit() throws Exception { super.onInit(); - if (this.shouldDeleteMessages){ + //if (this.shouldDeleteMessages){ this.folderOpenMode = Folder.READ_WRITE; - } + //} + this.registerSpelFunctions(); } Store getStore(){ return this.store; } + + private void registerSpelFunctions() throws Exception{ + context.registerFunction("match", + MimeMessageMatchingUtils.class.getDeclaredMethod("match", + new Class[] { String.class, String.class })); + + context.registerFunction("match", + MimeMessageMatchingUtils.class.getDeclaredMethod("match", + new Class[] { String[].class, String.class })); + } + + static class MimeMessageMatchingUtils { + + public static boolean match(String pattern, String value) { + return PatternMatchUtils.simpleMatch(pattern.toLowerCase(), value.toLowerCase()); + } + + public static boolean match(String[] pattern, String value) { + List patterns = new ArrayList(); + for (String originalPattern : pattern) { + patterns.add(originalPattern.toLowerCase()); + } + return PatternMatchUtils.simpleMatch(patterns.toArray(new String[]{}), value.toLowerCase()); + } + } } 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 1f15bceb19..7d60c7cef6 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 @@ -34,6 +34,7 @@ import org.springframework.scheduling.TaskScheduler; import org.springframework.util.Assert; import com.sun.mail.imap.IMAPFolder; +import com.sun.mail.imap.IMAPMessage; /** * A {@link MailReceiver} implementation for receiving mail messages from a @@ -120,7 +121,11 @@ public class ImapMailReceiver extends AbstractMailReceiver { SearchTerm searchTerm = this.compileSearchTerms(supportedFlags); Folder folder = this.getFolder(); if (folder.isOpen()){ - return searchTerm != null ? folder.search(searchTerm) : folder.getMessages(); + Message[] messages = searchTerm != null ? folder.search(searchTerm) : folder.getMessages(); + for (Message message : messages) { + ((IMAPMessage)message).setPeek(true); + } + return messages; } throw new MessagingException("Folder is closed"); } @@ -155,9 +160,17 @@ public class ImapMailReceiver extends AbstractMailReceiver { if (searchTerm == null){ searchTerm = notDeleted; } - if (this.isShouldMarkMessagesAsRead()){ - searchTerm = new AndTerm(searchTerm, notSeen); - } + + if (this.getFolder().getPermanentFlags().contains(Flags.Flag.USER)){ + Flags siFlags = new Flags(); + siFlags.add("spring-integration"); + searchTerm = new AndTerm(new SearchTerm[]{searchTerm, notSeen, new FlagTerm(siFlags, false)}); + } + else { + searchTerm = new AndTerm(new SearchTerm[]{searchTerm, notSeen, new FlagTerm(new Flags(Flags.Flag.FLAGGED), false)}); + } + + return searchTerm; } @@ -184,9 +197,9 @@ public class ImapMailReceiver extends AbstractMailReceiver { @Override protected void onInit() throws Exception { super.onInit(); - if (this.shouldMarkMessagesAsRead){ - this.folderOpenMode = Folder.READ_WRITE; - } +// if (this.shouldMarkMessagesAsRead){ +// this.folderOpenMode = Folder.READ_WRITE; +// } this.initialized = true; TaskScheduler scheduler = this.getTaskScheduler(); if (scheduler != null){ diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/ImapIdleChannelAdapterParser.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/ImapIdleChannelAdapterParser.java index 0f53513fb4..63cc81d0aa 100644 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/ImapIdleChannelAdapterParser.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/ImapIdleChannelAdapterParser.java @@ -20,6 +20,7 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; @@ -86,6 +87,16 @@ public class ImapIdleChannelAdapterParser extends AbstractSingleBeanDefinitionPa if (StringUtils.hasText(markAsRead)){ receiverBuilder.addPropertyValue("shouldMarkMessagesAsRead", markAsRead); } + + String selectorExpression = element.getAttribute("message-matcher-expression"); + + RootBeanDefinition expressionDef = null; + if (StringUtils.hasText(selectorExpression)){ + expressionDef = new RootBeanDefinition("org.springframework.integration.config.ExpressionFactoryBean"); + expressionDef.getConstructorArgumentValues().addGenericArgumentValue(selectorExpression); + receiverBuilder.addPropertyValue("selectorExpression", expressionDef); + } + return receiverBuilder.getBeanDefinition(); } } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailInboundChannelAdapterParser.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailInboundChannelAdapterParser.java index c273c18a49..861c9fb32c 100644 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailInboundChannelAdapterParser.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailInboundChannelAdapterParser.java @@ -21,6 +21,7 @@ import org.w3c.dom.Element; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; @@ -83,6 +84,16 @@ public class MailInboundChannelAdapterParser extends AbstractPollingInboundChann if (StringUtils.hasText(markAsRead)){ receiverBuilder.addPropertyValue("shouldMarkMessagesAsRead", markAsRead); } + + String selectorExpression = element.getAttribute("message-matcher-expression"); + + RootBeanDefinition expressionDef = null; + if (StringUtils.hasText(selectorExpression)){ + expressionDef = new RootBeanDefinition("org.springframework.integration.config.ExpressionFactoryBean"); + expressionDef.getConstructorArgumentValues().addGenericArgumentValue(selectorExpression); + receiverBuilder.addPropertyValue("selectorExpression", expressionDef); + } + return receiverBuilder.getBeanDefinition(); } 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 5d9f960be5..5ef7144c72 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 @@ -24,8 +24,10 @@ import javax.mail.URLName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; +import org.springframework.expression.Expression; import org.springframework.integration.mail.AbstractMailReceiver; import org.springframework.integration.mail.ImapMailReceiver; import org.springframework.integration.mail.MailReceiver; @@ -62,6 +64,8 @@ public class MailReceiverFactoryBean implements FactoryBean, Dispo private volatile Boolean shouldMarkMessagesAsRead = null; private volatile int maxFetchSize = 1; + + private volatile Expression selectorExpression; public void setStoreUri(String storeUri) { @@ -91,6 +95,10 @@ public class MailReceiverFactoryBean implements FactoryBean, Dispo public void setMaxFetchSize(int maxFetchSize) { this.maxFetchSize = maxFetchSize; } + + public void setSelectorExpression(Expression selectorExpression) { + this.selectorExpression = selectorExpression; + } public MailReceiver getObject() throws Exception { if (this.receiver == null) { @@ -147,13 +155,14 @@ public class MailReceiverFactoryBean implements FactoryBean, Dispo receiver.setShouldDeleteMessages(this.shouldDeleteMessages); } receiver.setMaxFetchSize(this.maxFetchSize); + receiver.setSelectorExpression(selectorExpression); - if (this.isShouldMarkMessagesAsRead()){ - if (isPop3){ + if (isPop3){ + if (this.isShouldMarkMessagesAsRead()){ logger.warn("Setting 'should-mark-messages-as-read' to 'true' while using POP3 has no effect"); - } else if (isImap){ - ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead); } + } else if (isImap){ + ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead); } receiver.afterPropertiesSet(); return receiver; diff --git a/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-2.0.xsd b/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-2.0.xsd index f09c26e612..e1d3fc2bbc 100644 --- a/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-2.0.xsd +++ b/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-2.0.xsd @@ -157,6 +157,13 @@ ]]> + + + + + diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java index 2e743b09c4..d4ebd678a6 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.lang.reflect.Field; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; @@ -36,6 +37,7 @@ import javax.mail.URLName; import javax.mail.internet.MimeMessage; import javax.mail.search.SearchTerm; +import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -70,6 +72,12 @@ public class ImapMailReceiverTests { ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(true); receiver = spy(receiver); receiver.afterPropertiesSet(); + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; @@ -81,6 +89,7 @@ public class ImapMailReceiverTests { if (folderOpenMode != Folder.READ_WRITE){ throw new IllegalArgumentException("Folder had to be open in READ_WRITE mode"); } + return null; } }).when(receiver).openFolder(); @@ -108,6 +117,13 @@ public class ImapMailReceiverTests { receiver.setShouldDeleteMessages(true); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; @@ -144,6 +160,14 @@ public class ImapMailReceiverTests { ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(false); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + + Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; @@ -151,9 +175,6 @@ public class ImapMailReceiverTests { 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_ONLY mode"); - } return null; } }).when(receiver).openFolder(); @@ -181,6 +202,13 @@ public class ImapMailReceiverTests { ((ImapMailReceiver)receiver).setShouldMarkMessagesAsRead(false); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; @@ -218,6 +246,13 @@ public class ImapMailReceiverTests { AbstractMailReceiver receiver = new ImapMailReceiver(); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; @@ -249,6 +284,7 @@ public class ImapMailReceiverTests { verify(receiver, times(0)).deleteMessages((Message[]) Mockito.any()); } @Test + @Ignore public void testMessageHistory() throws Exception{ ApplicationContext context = new ClassPathXmlApplicationContext("ImapIdleChannelAdapterParserTests-context.xml", ImapIdleChannelAdapterParserTests.class); @@ -257,6 +293,7 @@ public class ImapMailReceiverTests { AbstractMailReceiver receiver = new ImapMailReceiver(); receiver = spy(receiver); receiver.afterPropertiesSet(); + DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter); adapterAccessor.setPropertyValue("mailReceiver", receiver); @@ -304,6 +341,10 @@ public class ImapMailReceiverTests { new ClassPathXmlApplicationContext("ImapIdleChannelAdapterParserTests-context.xml", ImapIdleChannelAdapterParserTests.class); ImapIdleChannelAdapter adapter = context.getBean("simpleAdapter", ImapIdleChannelAdapter.class); + //ImapMailReceiver receiver = (ImapMailReceiver) TestUtils.getPropertyValue(adapter, "mailReceiver"); + + + DirectChannel channel = new DirectChannel(); channel.subscribe(new AbstractReplyProducingMessageHandler() { protected Object handleRequestMessage(org.springframework.integration.Message requestMessage) { @@ -317,6 +358,20 @@ public class ImapMailReceiverTests { AbstractMailReceiver receiver = new ImapMailReceiver(); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(IMAPFolder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return null; + } + }).when(receiver).openFolder(); + DirectFieldAccessor adapterAccessor = new DirectFieldAccessor(adapter); adapterAccessor.setPropertyValue("mailReceiver", receiver); @@ -325,16 +380,6 @@ public class ImapMailReceiverTests { when(mailMessage.getFlags()).thenReturn(flags); final Message[] messages = new Message[]{mailMessage}; - doAnswer(new Answer() { - public Object answer(InvocationOnMock invocation) throws Throwable { - DirectFieldAccessor accesor = new DirectFieldAccessor((invocation.getMock())); - IMAPFolder folder = mock(IMAPFolder.class); - accesor.setPropertyValue("folder", folder); - when(folder.hasNewMessages()).thenReturn(true); - return null; - } - }).when(receiver).openFolder(); - doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) throws Throwable { return messages; @@ -364,8 +409,12 @@ public class ImapMailReceiverTests { when(folder.isOpen()).thenReturn(true); when(folder.search((SearchTerm) Mockito.any())).thenReturn(new Message[]{}); when(store.getFolder(Mockito.any(URLName.class))).thenReturn(folder); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + + DirectFieldAccessor df = new DirectFieldAccessor(receiver); df.setPropertyValue("store", store); + receiver.afterPropertiesSet(); new Thread(new Runnable() { public void run(){ diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailSearchTermsTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailSearchTermsTests.java index c0bba9efba..6635f7c08e 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailSearchTermsTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailSearchTermsTests.java @@ -17,17 +17,22 @@ package org.springframework.integration.mail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.lang.reflect.Field; import java.lang.reflect.Method; import javax.mail.Flags; import javax.mail.Flags.Flag; +import javax.mail.Folder; import javax.mail.search.AndTerm; import javax.mail.search.FlagTerm; import javax.mail.search.NotTerm; import javax.mail.search.SearchTerm; import org.junit.Test; + import org.springframework.util.ReflectionUtils; /** @@ -40,6 +45,13 @@ public class ImapMailSearchTermsTests { public void validateSearchTermsWhenShouldMarkAsReadNoExistingFlags() throws Exception { ImapMailReceiver receiver = new ImapMailReceiver(); receiver.setShouldMarkMessagesAsRead(true); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class); compileSearchTerms.setAccessible(true); Flags flags = new Flags(); @@ -47,7 +59,7 @@ public class ImapMailSearchTermsTests { assertTrue(searchTerms instanceof AndTerm); AndTerm andTerm = (AndTerm) searchTerms; SearchTerm[] terms = andTerm.getTerms(); - assertEquals(2, terms.length); + assertEquals(3, terms.length); NotTerm notTerm = (NotTerm) terms[1]; assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(Flag.SEEN)); } @@ -55,6 +67,14 @@ public class ImapMailSearchTermsTests { public void validateSearchTermsWhenShouldMarkAsReadWithExistingFlags() throws Exception { ImapMailReceiver receiver = new ImapMailReceiver(); receiver.setShouldMarkMessagesAsRead(true); + + receiver.afterPropertiesSet(); + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class); compileSearchTerms.setAccessible(true); Flags flags = new Flags(); @@ -63,7 +83,7 @@ public class ImapMailSearchTermsTests { assertTrue(searchTerms instanceof AndTerm); AndTerm andTerm = (AndTerm) searchTerms; SearchTerm[] terms = andTerm.getTerms(); - assertEquals(2, terms.length); + assertEquals(3, terms.length); NotTerm notTerm = (NotTerm) terms[1]; assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(Flag.SEEN)); } @@ -73,24 +93,41 @@ public class ImapMailSearchTermsTests { ImapMailReceiver receiver = new ImapMailReceiver(); receiver.setShouldMarkMessagesAsRead(false); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class); compileSearchTerms.setAccessible(true); Flags flags = new Flags(); SearchTerm searchTerms = (SearchTerm) compileSearchTerms.invoke(receiver, flags); - assertTrue(searchTerms instanceof NotTerm); + assertTrue(searchTerms instanceof AndTerm); } @Test public void validateSearchTermsWhenShouldNotMarkAsReadWithExistingFlags() throws Exception { ImapMailReceiver receiver = new ImapMailReceiver(); receiver.setShouldMarkMessagesAsRead(false); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Method compileSearchTerms = ReflectionUtils.findMethod(receiver.getClass(), "compileSearchTerms", Flags.class); compileSearchTerms.setAccessible(true); Flags flags = new Flags(); flags.add(Flag.ANSWERED); SearchTerm searchTerms = (SearchTerm) compileSearchTerms.invoke(receiver, flags); - assertTrue(searchTerms instanceof FlagTerm); - FlagTerm flagTerm = (FlagTerm) searchTerms; - assertTrue(flagTerm.getFlags().contains(Flag.ANSWERED)); + assertTrue(searchTerms instanceof AndTerm); + AndTerm andTerm = (AndTerm) searchTerms; + SearchTerm[] andTerms = andTerm.getTerms(); + assertTrue(andTerms.length == 3); + assertTrue(((FlagTerm)andTerms[0]).getFlags().contains(Flag.ANSWERED)); + } } diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java index acc3a47b36..cf62e56d91 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/Pop3MailReceiverTests.java @@ -21,8 +21,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; import javax.mail.Flags.Flag; +import javax.mail.Flags; import javax.mail.Folder; import javax.mail.Message; import javax.mail.internet.MimeMessage; @@ -43,6 +47,13 @@ public class Pop3MailReceiverTests { ((Pop3MailReceiver)receiver).setShouldDeleteMessages(true); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + Message msg1 = mock(MimeMessage.class); Message msg2 = mock(MimeMessage.class); final Message[] messages = new Message[]{msg1, msg2}; @@ -79,16 +90,18 @@ public class Pop3MailReceiverTests { ((Pop3MailReceiver)receiver).setShouldDeleteMessages(false); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + 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_ONLY mode"); - } return null; } }).when(receiver).openFolder(); @@ -114,16 +127,18 @@ public class Pop3MailReceiverTests { AbstractMailReceiver receiver = new Pop3MailReceiver("pop3://some.host"); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + 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_ONLY mode"); - } return null; } }).when(receiver).openFolder(); @@ -149,16 +164,18 @@ public class Pop3MailReceiverTests { AbstractMailReceiver receiver = new Pop3MailReceiver(); receiver = spy(receiver); receiver.afterPropertiesSet(); + + Field folderField = AbstractMailReceiver.class.getDeclaredField("folder"); + folderField.setAccessible(true); + Folder folder = mock(Folder.class); + when(folder.getPermanentFlags()).thenReturn(new Flags(Flags.Flag.USER)); + folderField.set(receiver, folder); + 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_ONLY mode"); - } return null; } }).when(receiver).openFolder();