Skip to content

Commit e554b67

Browse files
committed
GH-9613: Expose AbstractMailReceiver.setFlaggedAsFallback()
Fixes: #9613 Issue link: #9613 Sometimes even if `\Recent` or user flag is not supported by mail server, the `\Flagged` is also undesirable * Expose `AbstractMailReceiver.setFlaggedAsFallback()` to disable setting `\Flagged` on the message as fallback * As well as expose `MailInboundChannelAdapterSpec.flaggedAsFallback()` * Document the new option
1 parent ba57ee8 commit e554b67

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
114114

115115
private boolean autoCloseFolder = true;
116116

117+
private boolean flaggedAsFallback = true;
118+
117119
private volatile Store store;
118120

119121
private volatile Folder folder;
@@ -293,6 +295,16 @@ public void setAutoCloseFolder(boolean autoCloseFolder) {
293295
this.autoCloseFolder = autoCloseFolder;
294296
}
295297

298+
/**
299+
* Whether the {@link Flags.Flag#FLAGGED} flag should be added to the message
300+
* when {@code \Recent} or user flags are not supported on mail server.
301+
* @param flaggedAsFallback {@code false} to not add {@link Flags.Flag#FLAGGED} flag as a fallback.
302+
* @since 6.4
303+
*/
304+
public void setFlaggedAsFallback(boolean flaggedAsFallback) {
305+
this.flaggedAsFallback = flaggedAsFallback;
306+
}
307+
296308
protected Folder getFolder() {
297309
return this.folder;
298310
}
@@ -544,7 +556,7 @@ private void setMessageFlags(Message[] filteredMessages) throws MessagingExcepti
544556
siFlags.add(this.userFlag);
545557
message.setFlags(siFlags, true);
546558
}
547-
else {
559+
else if (this.flaggedAsFallback) {
548560
this.logger.debug("USER flags are not supported by this mail server. " +
549561
"Flagging message with system flag");
550562
message.setFlag(Flags.Flag.FLAGGED, true);
@@ -554,10 +566,6 @@ private void setMessageFlags(Message[] filteredMessages) throws MessagingExcepti
554566
}
555567
}
556568

557-
/**
558-
* Will filter Messages thru selector. Messages that did not pass selector filtering criteria
559-
* will be filtered out and remain on the server as never touched.
560-
*/
561569
private MimeMessage[] filterMessagesThruSelector(Message[] messages) throws MessagingException {
562570
List<MimeMessage> filteredMessages = new LinkedList<>();
563571
for (Message message1 : messages) {
@@ -567,13 +575,13 @@ private MimeMessage[] filterMessagesThruSelector(Message[] messages) throws Mess
567575
this.selectorExpression.getValue(this.evaluationContext, message, Boolean.class))) {
568576
filteredMessages.add(message);
569577
}
570-
else if (this.logger.isDebugEnabled()) {
578+
else {
571579
if (message.isExpunged()) {
572580
this.logger.debug("Expunged message discarded and will not be further processed.");
573581
}
574582
else {
575583
String subject = message.getSubject();
576-
this.logger.debug("Fetched email with subject '" + subject +
584+
this.logger.debug(() -> "Fetched email with subject '" + subject +
577585
"' will be discarded by the matching filter and will not be flagged as SEEN.");
578586
}
579587
}
@@ -586,7 +594,7 @@ else if (this.logger.isDebugEnabled()) {
586594
}
587595

588596
/**
589-
* Fetches the specified messages from this receiver's folder. Default
597+
* Fetch the specified messages from this receiver's folder. Default
590598
* implementation {@link Folder#fetch(Message[], FetchProfile) fetches}
591599
* every {@link jakarta.mail.FetchProfile.Item}.
592600
* @param messages the messages to fetch
@@ -601,7 +609,7 @@ protected void fetchMessages(Message[] messages) throws MessagingException {
601609
}
602610

603611
/**
604-
* Deletes the given messages from this receiver's folder.
612+
* Delete the given messages from this receiver's folder.
605613
* @param messages the messages to delete
606614
* @throws MessagingException in case of JavaMail errors
607615
*/

spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/MailInboundChannelAdapterSpec.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,19 @@ public S autoCloseFolder(boolean autoCloseFolder) {
269269
return _this();
270270
}
271271

272+
/**
273+
* Whether the {@link jakarta.mail.Flags.Flag#FLAGGED} flag should be added to the message
274+
* when {@code \Recent} or user flags are not supported on mail server.
275+
* @param flaggedAsFallback {@code false} to not add {@link jakarta.mail.Flags.Flag#FLAGGED} flag as a fallback.
276+
* @return the spec.
277+
* @since 6.4
278+
*/
279+
public S flaggedAsFallback(boolean flaggedAsFallback) {
280+
assertReceiver();
281+
this.receiver.setFlaggedAsFallback(flaggedAsFallback);
282+
return _this();
283+
}
284+
272285
@Override
273286
public Map<Object, String> getComponentsToRegister() {
274287
return Collections.singletonMap(this.receiver, this.receiver.getComponentName());

src/reference/antora/modules/ROOT/pages/mail.adoc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ The following example configures an IMAP `idle` mail channel:
328328

329329
You can provide `javaMailProperties` by creating and populating a regular `java.utils.Properties` object -- for example, by using the `util` namespace provided by Spring.
330330

331-
IMPORTANT: If your username contains the '@' character, use '%40' instead of '@' to avoid parsing errors from the underlying JavaMail API.
331+
IMPORTANT: If your username contains the `@` character, use `%40` instead of `@` to avoid parsing errors from the underlying JavaMail API.
332332

333333
The following example shows how to configure a `java.util.Properties` object:
334334

@@ -459,8 +459,11 @@ If `shouldMarkMessagesAsRead` is true, the IMAP adapters set the `\Seen` flag.
459459
In addition, when an email server does not support the `\Recent` flag, the IMAP adapters mark messages with a user flag (by default, `spring-integration-mail-adapter`), as long as the server supports user flags.
460460
If not, `Flag.FLAGGED` is set to `true`.
461461
These flags are applied regardless of the `shouldMarkMessagesRead` setting.
462+
However, starting with version 6.4, the `\Flagged` can be disabled, too.
463+
The `AbstractMailReceiver` exposes a `setFlaggedAsFallback(boolean flaggedAsFallback)` option to skip setting `\Flagged`.
464+
In some scenarios such a flag on the message in mailbox is not desirable, regardless `\Recent` or user flag is not suppoerted as well.
462465

463-
As discussed in xref:mail.adoc#search-term[null], the default `SearchTermStrategy` ignore messages that are so flagged.
466+
As discussed in xref:mail.adoc#search-term[`SearchTerm`], the default `SearchTermStrategy` ignore messages that are so flagged.
464467

465468
Starting with version 4.2.2, you can set the name of the user flag by using `setUserFlag` on the `MailReceiver`.
466469
Doing so lets multiple receivers use a different flag (as long as the mail server supports user flags).
@@ -473,12 +476,12 @@ Very often, you may encounter a requirement to filter incoming messages (for exa
473476
You can accomplish this by connecting an inbound mail adapter with an expression-based `Filter`.
474477
Although it would work, there is a downside to this approach.
475478
Since messages would be filtered after going through the inbound mail adapter, all such messages would be marked as read (`SEEN`) or unread (depending on the value of `should-mark-messages-as-read` attribute).
476-
However, in reality, it be more useful to mark messages as `SEEN` only if they pass the filtering criteria.
479+
However, in reality, it is more useful to mark messages as `SEEN` only if they pass the filtering criteria.
477480
This is similar to looking at your email client while scrolling through all the messages in the preview pane, but only flagging messages that were actually opened and read as `SEEN`.
478481

479482
Spring Integration 2.0.4 introduced the `mail-filter-expression` attribute on `inbound-channel-adapter` and `imap-idle-channel-adapter`.
480483
This attribute lets you provide an expression that is a combination of SpEL and a regular expression.
481-
For example if you would like to read only emails that contain 'Spring Integration' in the subject line, you would configure the `mail-filter-expression` attribute like as follows: `mail-filter-expression="subject matches '(?i).*Spring Integration.*"`.
484+
For example if you would like to read only emails that contain 'Spring Integration' in the subject line, you would configure the `mail-filter-expression` attribute like as follows: `mail-filter-expression="subject matches '(?i).\*Spring Integration.*"`.
482485

483486
Since `jakarta.mail.internet.MimeMessage` is the root context of the SpEL evaluation context, you can filter on any value available through `MimeMessage`, including the actual body of the message.
484487
This one is particularly important, since reading the body of the message typically results in such messages being marked as `SEEN` by default.

src/reference/antora/modules/ROOT/pages/whats-new.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,9 @@ See xref:zip.adoc[Zip Support] for more information.
9797

9898
The Python scripts evaluation is now migrated to the GraalVM Polyglot.
9999
See xref:scripting.adoc[Scripting Support] for more information.
100+
101+
[[x6.4-mail-changes]]
102+
=== Mail Changes
103+
104+
The `AbstractMailReceiver` exposes an option to disable setting `Flags.Flag.FLAGGED` into a received message as fallback flag.
105+
See xref:mail.adoc[Mail Support] for more information.

0 commit comments

Comments
 (0)