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:
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user