// See RFC4551 3.2. STORE and UID STORE Command;
//
// Use of UNCHANGEDSINCE with a modification sequence of 0 always
// fails if the metadata item exists. A system flag MUST always be
// considered existent, whether it was set or not.
final StatusResponse response = getStatusResponseFactory().taggedOk(tag, command, HumanReadableText.FAILED, ResponseCode.condStore(idSet));
responder.respond(response);
return;
}
}
}
final List<Long> failed = new ArrayList<Long>();
final List<String> userFlags = Arrays.asList(flags.getUserFlags());
for (int i = 0; i < idSet.length; i++) {
final SelectedMailbox selected = session.getSelected();
MessageRange messageSet = messageRange(selected, idSet[i], useUids);
if (messageSet != null) {
if (unchangedSince != -1) {
// Ok we have a CONDSTORE option so use the CONDSTORE_COMMAND
imapCommand = CONDSTORE_COMMAND;
List<Long> uids = new ArrayList<Long>();
MessageResultIterator results = mailbox.getMessages(messageSet, FetchGroupImpl.MINIMAL, mailboxSession);
while(results.hasNext()) {
MessageResult r = results.next();
long uid = r.getUid();
boolean fail = false;
// Check if UNCHANGEDSINCE 0 was used and the Message contains the request flag.
// In such cases we need to fail for this message.
//
// From RFC4551:
// Use of UNCHANGEDSINCE with a modification sequence of 0 always
// fails if the metadata item exists. A system flag MUST always be
// considered existent, whether it was set or not.
if (unchangedSince == 0) {
String[] uFlags = r.getFlags().getUserFlags();
for (int a = 0; a < uFlags.length; a++) {
if (userFlags.contains(uFlags[a])) {
fail = true;
break;
}
}
}
// Check if the mod-sequence of the message is <= the unchangedsince.
//
// See RFC4551 3.2. STORE and UID STORE Commands
if (!fail && r.getModSeq() <= unchangedSince) {
uids.add(uid);
} else {
if (useUids) {
failed.add(uid);
} else {
failed.add((long) selected.msn(uid));
}
}
}
List<MessageRange> mRanges = MessageRange.toRanges(uids);
for (int a = 0 ; a < mRanges.size(); a++) {
setFlags(request, mailboxSession, mailbox, mRanges.get(a), session, tag, imapCommand, responder);
}
} else {
setFlags(request, mailboxSession, mailbox, messageSet, session, tag, imapCommand, responder);
}
}
}
final boolean omitExpunged = (!useUids);
unsolicitedResponses(session, responder, omitExpunged, useUids);
// check if we had some failed uids which didn't pass the UNCHANGEDSINCE filter
if (failed.isEmpty()) {
okComplete(imapCommand, tag, responder);
} else {
// Convert the MessageRanges to an array of IdRange.
// TODO: Maybe this should get moved in an util class
List<MessageRange> ranges = MessageRange.toRanges(failed);
IdRange[] idRanges = new IdRange[ranges.size()];
for (int i = 0 ; i < ranges.size(); i++) {
MessageRange r = ranges.get(i);
if (r.getType() == Type.ONE) {
idRanges[i] = new IdRange(r.getUidFrom());
} else {
idRanges[i] = new IdRange(r.getUidFrom(), r.getUidTo());
}
}
// we need to return the failed sequences
//
// See RFC4551 3.2. STORE and UID STORE Commands
final StatusResponse response = getStatusResponseFactory().taggedOk(tag, command, HumanReadableText.FAILED, ResponseCode.condStore(idRanges));
responder.respond(response);
}
} catch (MessageRangeException e) {
if (session.getLog().isDebugEnabled()) {