Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/modules/servers/partials/configure/jvm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,17 @@ Ex in `jvm.properties`
----
james.rights.crossdomain.allow=false
----

== Drop IMAP Recent handling

This allows for dropping the legacy IMAP flag support, considering all emails as recent. This has no impact on modern
IMAP application as this flag is concidered innacurate.

Note that this flag is removed in IMAP4Rev2.

Ex in `jvm.properties`
----
james.mailbox.handleRecent=false
----

Defaults to true (no breaking changes)
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.cassandra.ids.CassandraId;
import org.apache.james.mailbox.cassandra.table.CassandraMailboxRecentsTable;
import org.apache.james.mailbox.store.StoreMessageManager;

import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.ProtocolVersion;
Expand Down Expand Up @@ -101,6 +102,9 @@ private PreparedStatement createAddStatement(CqlSession session) {
}

public Flux<MessageUid> getRecentMessageUidsInMailbox(CassandraId mailboxId) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Flux.empty();
}
return cassandraAsyncExecutor.executeRows(bindWithMailbox(mailboxId, readStatement))
.map(row -> TypeCodecs.BIGINT.decodePrimitive(row.getBytesUnsafe(0), protocolVersion))
.map(MessageUid::of);
Expand All @@ -112,12 +116,18 @@ private BoundStatement bindWithMailbox(CassandraId mailboxId, PreparedStatement
}

public Mono<Void> removeFromRecent(CassandraId mailboxId, MessageUid messageUid) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Mono.empty();
}
return cassandraAsyncExecutor.executeVoid(deleteStatement.bind()
.setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())
.setLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, messageUid.asLong()));
}

public Mono<Void> removeFromRecent(CassandraId mailboxId, List<MessageUid> uids) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Mono.empty();
}
if (uids.size() == 1) {
return cassandraAsyncExecutor.executeVoid(deleteStatement.bind()
.setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())
Expand All @@ -139,17 +149,26 @@ public Mono<Void> removeFromRecent(CassandraId mailboxId, List<MessageUid> uids)
}

public Mono<Void> delete(CassandraId mailboxId) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Mono.empty();
}
return cassandraAsyncExecutor.executeVoid(deleteAllStatement.bind()
.setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid()));
}

public Mono<Void> addToRecent(CassandraId mailboxId, MessageUid messageUid) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Mono.empty();
}
return cassandraAsyncExecutor.executeVoid(addStatement.bind()
.setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())
.setLong(CassandraMailboxRecentsTable.RECENT_MESSAGE_UID, messageUid.asLong()));
}

public Mono<Void> addToRecent(CassandraId mailboxId, List<MessageUid> uids) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Mono.empty();
}
if (uids.size() == 1) {
return cassandraAsyncExecutor.executeVoid(addStatement.bind()
.setUuid(CassandraMailboxRecentsTable.MAILBOX_ID, mailboxId.asUuid())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import jakarta.mail.Flags;

import org.apache.james.mailbox.cassandra.table.Flag;
import org.apache.james.mailbox.store.StoreMessageManager;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.ProtocolVersion;
Expand All @@ -44,6 +45,9 @@ public static Flags getFlags(Row row) {
private static Flags getFlags(Row row, ProtocolVersion protocolVersion) {
Flags flags = new Flags();
for (CqlIdentifier cqlId : Flag.ALL_LOWERCASE) {
if (!StoreMessageManager.HANDLE_RECENT && cqlId.equals(Flag.RECENT)) {
continue;
}
if (TypeCodecs.BOOLEAN.decodePrimitive(row.getBytesUnsafe(cqlId), protocolVersion)) {
flags.add(Flag.JAVAX_MAIL_FLAG.get(cqlId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.apache.james.mailbox.postgres.PostgresMailboxId;
import org.apache.james.mailbox.postgres.PostgresMessageId;
import org.apache.james.mailbox.postgres.mail.PostgresMessageDataDefinition.MessageTable;
import org.apache.james.mailbox.store.StoreMessageManager;
import org.apache.james.mailbox.store.mail.MessageMapper;
import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
import org.apache.james.mailbox.store.mail.model.MailboxMessage;
Expand Down Expand Up @@ -170,6 +171,9 @@ public Flux<MessageUid> listUnseen(PostgresMailboxId mailboxId, MessageRange ran
}

public Flux<MessageUid> findAllRecentMessageUid(PostgresMailboxId mailboxId) {
if (!StoreMessageManager.HANDLE_RECENT) {
return Flux.empty();
}
return postgresExecutor.executeRows(dslContext -> Flux.from(dslContext.select(MESSAGE_UID)
.from(TABLE_NAME)
.where(MAILBOX_ID.eq((mailboxId.asUuid())))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.apache.james.mailbox.postgres.PostgresMailboxId;
import org.apache.james.mailbox.postgres.PostgresMessageId;
import org.apache.james.mailbox.postgres.mail.PostgresMessageDataDefinition;
import org.apache.james.mailbox.store.StoreMessageManager;
import org.apache.james.mailbox.store.mail.MessageMapper;
import org.apache.james.mailbox.store.mail.model.impl.Properties;
import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
Expand All @@ -83,6 +84,9 @@ interface PostgresMailboxMessageDAOUtils {
Function<Record, Flags> RECORD_TO_FLAGS_FUNCTION = record -> {
Flags flags = new Flags();
BOOLEAN_FLAGS_MAPPING.forEach((flagColumn, flagMapped) -> {
if (!StoreMessageManager.HANDLE_RECENT && flagColumn.equals(IS_RECENT)) {
return;
}
if (record.get(flagColumn)) {
flags.add(flagMapped);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@
* {@link MailboxSession}'s.
*/
public class StoreMessageManager implements MessageManager {
public static final boolean HANDLE_RECENT = Optional.ofNullable(System.getProperty("james.mailbox.handleRecent"))
.map(Boolean::parseBoolean)
.orElse(true);
/**
* The minimal Permanent flags the {@link MessageManager} must support. <br>
*
Expand Down Expand Up @@ -494,7 +497,7 @@ private Flags getFlags(MailboxSession mailboxSession, boolean isRecent, Flags fl
trimFlags(flags, mailboxSession);

}
if (isRecent) {
if (isRecent && HANDLE_RECENT) {
flags.add(Flag.RECENT);
}
return flags;
Expand Down