diff --git a/spring-integration-mail/.project b/spring-integration-mail/.project
index d8c432b36e..0f6d43ac2a 100644
--- a/spring-integration-mail/.project
+++ b/spring-integration-mail/.project
@@ -15,8 +15,14 @@
+
+ org.springframework.ide.eclipse.core.springbuilder
+
+
+
+ org.springframework.ide.eclipse.core.springnature
org.maven.ide.eclipse.maven2Nature
org.eclipse.jdt.core.javanature
diff --git a/spring-integration-mail/pom.xml b/spring-integration-mail/pom.xml
index 2aafa0b8f8..577ba2557d 100644
--- a/spring-integration-mail/pom.xml
+++ b/spring-integration-mail/pom.xml
@@ -50,6 +50,10 @@
org.easymock
easymockclassextension
+
+ org.mockito
+ mockito-all
+
org.springframework
spring-test
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 c9d1bac5fc..3b89672fce 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,6 +27,7 @@ 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;
@@ -42,6 +43,7 @@ import org.springframework.util.Assert;
* @author Jonas Partner
* @author Mark Fisher
* @author Iwein Fuld
+ * @author Oleg Zhurakousky
*/
public abstract class AbstractMailReceiver implements MailReceiver, DisposableBean {
@@ -60,6 +62,8 @@ public abstract class AbstractMailReceiver implements MailReceiver, DisposableBe
private volatile Folder folder;
private volatile boolean shouldDeleteMessages = false;
+
+ private volatile boolean shouldMarkMessagesAsRead = false;
private volatile Properties javaMailProperties = new Properties();
@@ -143,8 +147,21 @@ public abstract class AbstractMailReceiver implements MailReceiver, DisposableBe
* Specify whether mail messages should be deleted after retrieval.
*/
public void setShouldDeleteMessages(boolean shouldDeleteMessages) {
+ if (this.shouldMarkMessagesAsRead && shouldDeleteMessages){
+ throw new IllegalArgumentException("setting both 'shouldDeleteMessages' and 'shouldMarkMessagesAsRead' to true is not allowed");
+ }
this.shouldDeleteMessages = shouldDeleteMessages;
}
+ public boolean isShouldMarkMessagesAsRead() {
+ return shouldMarkMessagesAsRead;
+ }
+
+ public void setShouldMarkMessagesAsRead(boolean shouldMarkMessagesAsRead) {
+ if (this.shouldDeleteMessages && shouldMarkMessagesAsRead){
+ throw new IllegalArgumentException("setting both 'shouldDeleteMessages' and 'shouldMarkMessagesAsRead' to true is not allowed");
+ }
+ this.shouldMarkMessagesAsRead = shouldMarkMessagesAsRead;
+ }
/**
* Indicates whether the mail messages should be deleted after being received.
@@ -204,10 +221,10 @@ public abstract class AbstractMailReceiver implements MailReceiver, DisposableBe
if (logger.isDebugEnabled()) {
logger.debug("opening folder [" + MailTransportUtils.toPasswordProtectedString(this.url) + "]");
}
- if (this.shouldDeleteMessages()) {
+ if (this.shouldDeleteMessages() || this.shouldMarkMessagesAsRead) {
this.folder.open(Folder.READ_WRITE);
}
- else {
+ else {
this.folder.open(Folder.READ_ONLY);
}
}
@@ -230,13 +247,17 @@ public abstract class AbstractMailReceiver implements MailReceiver, DisposableBe
if (messages.length > 0) {
this.fetchMessages(messages);
}
- if (this.shouldDeleteMessages()) {
- this.deleteMessages(messages);
- }
+
Message[] copiedMessages = new Message[messages.length];
for (int i = 0; i < messages.length; i++) {
+ if (this.isShouldMarkMessagesAsRead()){
+ messages[i].setFlag(Flag.SEEN, true);
+ }
copiedMessages[i] = new MimeMessage((MimeMessage) messages[i]);
}
+ if (this.shouldDeleteMessages()) {
+ this.deleteMessages(messages);
+ }
return copiedMessages;
}
catch (Exception e) {
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 db65c081d7..78ba075fce 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
@@ -25,6 +25,7 @@ import javax.mail.event.MessageCountEvent;
import javax.mail.event.MessageCountListener;
import javax.mail.search.AndTerm;
import javax.mail.search.FlagTerm;
+import javax.mail.search.NotTerm;
import javax.mail.search.SearchTerm;
import org.springframework.util.Assert;
@@ -41,6 +42,7 @@ import com.sun.mail.imap.IMAPFolder;
*
* @author Arjen Poutsma
* @author Mark Fisher
+ * @author Oleg Zhurakousky
*/
public class ImapMailReceiver extends AbstractMailReceiver {
@@ -99,6 +101,11 @@ public class ImapMailReceiver extends AbstractMailReceiver {
@Override
protected Message[] searchForNewMessages() throws MessagingException {
Flags supportedFlags = this.getFolder().getPermanentFlags();
+ SearchTerm searchTerm = this.compileSearchTerms(supportedFlags);
+ return searchTerm != null ? this.getFolder().search(searchTerm) : this.getFolder().getMessages();
+ }
+
+ private SearchTerm compileSearchTerms(Flags supportedFlags){
SearchTerm searchTerm = null;
if (supportedFlags != null) {
if (supportedFlags.contains(Flags.Flag.RECENT)) {
@@ -123,7 +130,16 @@ public class ImapMailReceiver extends AbstractMailReceiver {
}
}
}
- return searchTerm != null ? this.getFolder().search(searchTerm) : this.getFolder().getMessages();
+ if (searchTerm == null){
+ if (this.isShouldMarkMessagesAsRead()){
+ searchTerm = new NotTerm( new FlagTerm(new Flags(Flags.Flag.SEEN), true) );
+ }
+ } else {
+ if (this.isShouldMarkMessagesAsRead()){
+ searchTerm = new AndTerm(searchTerm, new NotTerm( new FlagTerm(new Flags(Flags.Flag.SEEN), true) ));
+ }
+ }
+ return searchTerm;
}
diff --git a/spring-integration-mail/src/test/java/log4j.properties b/spring-integration-mail/src/test/java/log4j.properties
new file mode 100644
index 0000000000..cf091a2e8e
--- /dev/null
+++ b/spring-integration-mail/src/test/java/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootCategory=DEBUG, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%c{1}: %m%n
+
+log4j.category.org.springframework.integration=WARN
+log4j.category.org.springframework.integration.file=WARN
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
new file mode 100644
index 0000000000..b0b5a032d4
--- /dev/null
+++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/AbstractMailReceiverTests.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2002-2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.integration.mail;
+
+import javax.mail.Message;
+import javax.mail.Flags.Flag;
+import javax.mail.internet.MimeMessage;
+
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * @author Oleg Zhurakousky
+ *
+ */
+public class AbstractMailReceiverTests {
+
+ @Test(expected=IllegalArgumentException.class)
+ public void validateDeleteAndReadIsNotAllowed(){
+ AbstractMailReceiver receiver = new ImapMailReceiver();
+ receiver.setShouldDeleteMessages(true);
+ receiver.setShouldMarkMessagesAsRead(true);
+ }
+ @Test
+ public void validateDeleteOrReadIsAllowed_Read(){
+ AbstractMailReceiver receiver = new ImapMailReceiver();
+ receiver.setShouldDeleteMessages(false);
+ receiver.setShouldMarkMessagesAsRead(true);
+ }
+ @Test
+ public void validateDeleteOrReadIsAllowed_Delete(){
+ AbstractMailReceiver receiver = new ImapMailReceiver();
+ receiver.setShouldDeleteMessages(true);
+ receiver.setShouldMarkMessagesAsRead(false);
+ }
+
+ @Test
+ public void receieveAndMarkAsRead() throws Exception{
+ AbstractMailReceiver receiver = new ImapMailReceiver();
+ receiver.setShouldMarkMessagesAsRead(true);
+ receiver = spy(receiver);
+ Message msg1 = mock(MimeMessage.class);
+ Message msg2 = mock(MimeMessage.class);
+ final Message[] messages = new Message[]{msg1, msg2};
+ doAnswer(new Answer