* @param responder
* @throws MailboxException
*/
private void setFlags(StoreRequest request, MailboxSession mailboxSession, MessageManager mailbox, MessageRange messageSet, ImapSession session, String tag, ImapCommand command, Responder responder) throws MailboxException {
final Flags flags = request.getFlags();
final boolean useUids = request.isUseUids();
final boolean silent = request.isSilent();
final boolean isSignedPlus = request.isSignedPlus();
final boolean isSignedMinus = request.isSignedMinus();
final long unchangedSince = request.getUnchangedSince();
final boolean replace;
final boolean value;
if (isSignedMinus) {
value = false;
replace = false;
} else if (isSignedPlus) {
value = true;
replace = false;
} else {
replace = true;
value = true;
}
SelectedMailbox selected = session.getSelected();
final Map<Long, Flags> flagsByUid = mailbox.setFlags(flags, value, replace, messageSet, mailboxSession);
// As the STORE command is allowed to create a new "flag/keyword", we need to send a FLAGS and PERMANENTFLAGS response before the FETCH response
// if some new flag/keyword was used
// See IMAP-303
if (selected.hasNewApplicableFlags()) {
flags(responder, selected);
permanentFlags(responder, mailbox.getMetaData(false, mailboxSession, FetchGroup.NO_COUNT), selected);
selected.resetNewApplicableFlags();
}
Set<String> enabled = EnableProcessor.getEnabledCapabilities(session);
boolean qresyncEnabled = enabled.contains(ImapConstants.SUPPORTS_QRESYNC);
boolean condstoreEnabled = enabled.contains(ImapConstants.SUPPORTS_CONDSTORE);
if (!silent || unchangedSince != -1 || qresyncEnabled || condstoreEnabled) {
final Map<Long, Long> modSeqs = new HashMap<Long, Long>();
// Check if we need to also send the the mod-sequences back to the client
//
// This is the case if one of these is true:
// - UNCHANGEDSINCE was used
// - CONDSTORE was enabled via ENABLE CONDSTORE
// - QRESYNC was enabled via ENABLE QRESYNC
//
if (unchangedSince != -1 || qresyncEnabled || condstoreEnabled) {
MessageResultIterator results = mailbox.getMessages(messageSet, FetchGroupImpl.MINIMAL, mailboxSession);
while(results.hasNext()) {
MessageResult r = results.next();
// Store the modseq for the uid for later usage in the response
modSeqs.put(r.getUid(),r.getModSeq());
}
}
for (Map.Entry<Long, Flags> entry : flagsByUid.entrySet()) {
final long uid = entry.getKey();
final int msn = selected.msn(uid);
if (msn == SelectedMailbox.NO_SUCH_MESSAGE) {
if(session.getLog().isDebugEnabled()) {
session.getLog().debug("No message found with uid " + uid + " in the uid<->msn mapping for mailbox " + selected.getPath().getFullName(mailboxSession.getPathDelimiter()) +" , this may be because it was deleted by a concurrent session. So skip it..");
}
// skip this as it was not found in the mapping
//
// See IMAP-346
continue;
}
final Flags resultFlags = entry.getValue();
final Long resultUid;
// Check if we need to include the uid. T
//
// This is the case if one of these is true:
// - FETCH (UID...) was used
// - QRESYNC was enabled via ENABLE QRESYNC
if (useUids || qresyncEnabled) {
resultUid = uid;
} else {
resultUid = null;
}
if (selected.isRecent(uid)) {
resultFlags.add(Flags.Flag.RECENT);
}
final FetchResponse response;
// For more informations related to the FETCH response see
//