INT-1804, INT-1825 finished up with support for filtering email messages and flagging messages with arbitrary flags if RECENT flag is not supported (e.g., GMAIL)

This commit is contained in:
Oleg Zhurakousky
2011-03-08 15:43:10 -05:00
parent 653c61e8d1
commit ff46bec6ad
7 changed files with 79 additions and 74 deletions

View File

@@ -53,6 +53,8 @@ import org.springframework.util.PatternMatchUtils;
*/
public abstract class AbstractMailReceiver extends IntegrationObjectSupport implements MailReceiver, DisposableBean{
public final static String SI_USER_FLAG = "spring-integration-mail-adapter";
protected final Log logger = LogFactory.getLog(this.getClass());
private final URLName url;
@@ -243,25 +245,33 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
List<Message> copiedMessages = new LinkedList<Message>();
logger.debug("Recieved " + messages.length + " messages");
boolean recentFlagSupported = this.getFolder().getPermanentFlags().contains(Flags.Flag.RECENT);
for (int i = 0; i < messages.length; 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);
if (!recentFlagSupported){
if (this.getFolder().getPermanentFlags().contains(Flags.Flag.USER)){
logger.debug("USER flags are supported by this mail server. Flagging message with '" + SI_USER_FLAG + "' user flag");
Flags siFlags = new Flags();
siFlags.add(SI_USER_FLAG);
messages[i].setFlags(siFlags, true);
}
else {
logger.debug("USER flags are not supported by this mail server. Flagging message with system flag");
messages[i].setFlag(Flags.Flag.FLAGGED, 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 {
logger.debug("Fetched email with subject '" + message.getSubject() + "' will be discarded by the matching filter" +
" and will not be flagged as SEEN.");
}
}
else {
this.setAdditionalFlags(messages[i]);

View File

@@ -132,45 +132,63 @@ public class ImapMailReceiver extends AbstractMailReceiver {
private SearchTerm compileSearchTerms(Flags supportedFlags){
SearchTerm searchTerm = null;
boolean recentFlagSupported = false;
if (supportedFlags != null) {
if (supportedFlags.contains(Flags.Flag.RECENT)) {
recentFlagSupported = supportedFlags.contains(Flags.Flag.RECENT);
if (recentFlagSupported) {
searchTerm = new FlagTerm(new Flags(Flags.Flag.RECENT), true);
}
if (supportedFlags.contains(Flags.Flag.ANSWERED)) {
FlagTerm answeredTerm = new FlagTerm(new Flags(Flags.Flag.ANSWERED), false);
NotTerm notAnswered = new NotTerm(new FlagTerm(new Flags(Flags.Flag.ANSWERED), true));
if (searchTerm == null) {
searchTerm = answeredTerm;
searchTerm = notAnswered;
}
else {
searchTerm = new AndTerm(searchTerm, answeredTerm);
searchTerm = new AndTerm(searchTerm, notAnswered);
}
}
if (supportedFlags.contains(Flags.Flag.DELETED)) {
FlagTerm deletedTerm = new FlagTerm(new Flags(Flags.Flag.DELETED), false);
NotTerm notDeleted = new NotTerm(new FlagTerm(new Flags(Flags.Flag.DELETED), true));
if (searchTerm == null) {
searchTerm = deletedTerm;
searchTerm = notDeleted;
}
else {
searchTerm = new AndTerm(searchTerm, deletedTerm);
searchTerm = new AndTerm(searchTerm, notDeleted);
}
}
if (supportedFlags.contains(Flags.Flag.SEEN)) {
NotTerm notSeen = new NotTerm(new FlagTerm(new Flags(Flags.Flag.SEEN), true));
if (searchTerm == null) {
searchTerm = notSeen;
}
else {
searchTerm = new AndTerm(searchTerm, notSeen);
}
}
}
NotTerm notDeleted = new NotTerm( new FlagTerm(new Flags(Flags.Flag.DELETED), true) );
NotTerm notSeen = new NotTerm( new FlagTerm(new Flags(Flags.Flag.SEEN), true) );
if (searchTerm == null){
searchTerm = notDeleted;
}
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)});
if (!recentFlagSupported){
NotTerm notFlagged = null;
if (this.getFolder().getPermanentFlags().contains(Flags.Flag.USER)){
logger.debug("This email server does not support RECENT flag but it does support " +
"USER flags which will be used to prevent duplicates during email fetch");
Flags siFlags = new Flags();
siFlags.add(SI_USER_FLAG);
notFlagged = new NotTerm(new FlagTerm(siFlags, true));
}
else {
logger.debug("This email server does not support RECENT or USER flags. " +
"System flag 'Flag.FLAGGED' will be used to prevent duplicates during email fetch");
notFlagged = new NotTerm(new FlagTerm(new Flags(Flags.Flag.FLAGGED), true));
}
if (searchTerm == null){
searchTerm = notFlagged;
}
else {
searchTerm = new AndTerm(searchTerm, notFlagged);
}
}
else {
searchTerm = new AndTerm(new SearchTerm[]{searchTerm, notSeen, new FlagTerm(new Flags(Flags.Flag.FLAGGED), false)});
}
return searchTerm;
}

View File

@@ -88,7 +88,7 @@ public class ImapIdleChannelAdapterParser extends AbstractSingleBeanDefinitionPa
receiverBuilder.addPropertyValue("shouldMarkMessagesAsRead", markAsRead);
}
String selectorExpression = element.getAttribute("message-matcher-expression");
String selectorExpression = element.getAttribute("mail-filter-expression");
RootBeanDefinition expressionDef = null;
if (StringUtils.hasText(selectorExpression)){

View File

@@ -85,7 +85,7 @@ public class MailInboundChannelAdapterParser extends AbstractPollingInboundChann
receiverBuilder.addPropertyValue("shouldMarkMessagesAsRead", markAsRead);
}
String selectorExpression = element.getAttribute("message-matcher-expression");
String selectorExpression = element.getAttribute("mail-filter-expression");
RootBeanDefinition expressionDef = null;
if (StringUtils.hasText(selectorExpression)){

View File

@@ -157,10 +157,10 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="message-matcher-expression" type="xsd:string">
<xsd:attribute name="mail-filter-expression" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Allows you to provide a SpEL expression which defines a fine grained filtering criteria for the emails to be processed by this adapter.
Allows you to provide a SpEL expression which defines a fine grained filtering criteria for the mail messages to be processed by this adapter.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>

View File

@@ -173,8 +173,6 @@ public class ImapMailReceiverTests {
final Message[] messages = new Message[]{msg1, msg2};
doAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation) throws Throwable {
DirectFieldAccessor accessor = new DirectFieldAccessor(invocation.getMock());
int folderOpenMode = (Integer) accessor.getPropertyValue("folderOpenMode");
return null;
}
}).when(receiver).openFolder();

View File

@@ -56,12 +56,11 @@ public class ImapMailSearchTermsTests {
compileSearchTerms.setAccessible(true);
Flags flags = new Flags();
SearchTerm searchTerms = (SearchTerm) compileSearchTerms.invoke(receiver, flags);
assertTrue(searchTerms instanceof AndTerm);
AndTerm andTerm = (AndTerm) searchTerms;
SearchTerm[] terms = andTerm.getTerms();
assertEquals(3, terms.length);
NotTerm notTerm = (NotTerm) terms[1];
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(Flag.SEEN));
assertTrue(searchTerms instanceof NotTerm);
NotTerm notTerm = (NotTerm) searchTerms;
Flags siFlags = new Flags();
siFlags.add(AbstractMailReceiver.SI_USER_FLAG);
notTerm.getTerm().equals(siFlags);
}
@Test
public void validateSearchTermsWhenShouldMarkAsReadWithExistingFlags() throws Exception {
@@ -83,9 +82,13 @@ public class ImapMailSearchTermsTests {
assertTrue(searchTerms instanceof AndTerm);
AndTerm andTerm = (AndTerm) searchTerms;
SearchTerm[] terms = andTerm.getTerms();
assertEquals(3, terms.length);
NotTerm notTerm = (NotTerm) terms[1];
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(Flag.SEEN));
assertEquals(2, terms.length);
NotTerm notTerm = (NotTerm) terms[0];
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(Flag.ANSWERED));
notTerm = (NotTerm) terms[1];
Flags siFlags = new Flags();
siFlags.add(AbstractMailReceiver.SI_USER_FLAG);
assertTrue(((FlagTerm)notTerm.getTerm()).getFlags().contains(siFlags));
}
@Test
@@ -104,30 +107,6 @@ public class ImapMailSearchTermsTests {
compileSearchTerms.setAccessible(true);
Flags flags = new Flags();
SearchTerm searchTerms = (SearchTerm) compileSearchTerms.invoke(receiver, flags);
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 AndTerm);
AndTerm andTerm = (AndTerm) searchTerms;
SearchTerm[] andTerms = andTerm.getTerms();
assertTrue(andTerms.length == 3);
assertTrue(((FlagTerm)andTerms[0]).getFlags().contains(Flag.ANSWERED));
assertTrue(searchTerms instanceof NotTerm);
}
}