
org.apache.james.imap.decode.parser.StatusCommandParser Maven / Gradle / Ivy
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.imap.decode.parser;
import java.util.EnumSet;
import javax.inject.Inject;
import org.apache.james.imap.api.ImapConstants;
import org.apache.james.imap.api.ImapMessage;
import org.apache.james.imap.api.Tag;
import org.apache.james.imap.api.display.HumanReadableText;
import org.apache.james.imap.api.message.StatusDataItems;
import org.apache.james.imap.api.message.response.StatusResponseFactory;
import org.apache.james.imap.api.process.ImapSession;
import org.apache.james.imap.decode.DecodingException;
import org.apache.james.imap.decode.ImapRequestLineReader;
import org.apache.james.imap.decode.base.AbstractImapCommandParser;
import org.apache.james.imap.message.request.StatusRequest;
/**
* Parse STATUS commands
*/
public class StatusCommandParser extends AbstractImapCommandParser {
@Inject
public StatusCommandParser(StatusResponseFactory statusResponseFactory) {
super(ImapConstants.STATUS_COMMAND, statusResponseFactory);
}
@Override
protected ImapMessage decode(ImapRequestLineReader request, Tag tag, ImapSession session) throws DecodingException {
String mailboxName = request.mailbox();
StatusDataItems statusDataItems = statusDataItems(request);
request.eol();
return new StatusRequest(mailboxName, statusDataItems, tag);
}
static StatusDataItems statusDataItems(ImapRequestLineReader request) throws DecodingException {
return new StatusDataItems(splitWords(request));
}
private static EnumSet splitWords(ImapRequestLineReader request) throws DecodingException {
EnumSet words = EnumSet.noneOf(StatusDataItems.StatusItem.class);
request.nextWordChar();
request.consumeChar('(');
request.nextWordChar();
while (request.nextChar() != ')') {
words.add(parseStatus(request));
request.nextWordChar();
}
request.consumeChar(')');
return words;
}
private static StatusDataItems.StatusItem parseStatus(ImapRequestLineReader request) throws DecodingException {
// All the matching must be done in a case-insensitive fashion.
// See rfc3501 9. Formal Syntax and IMAP-282
char c = request.nextWordChar();
if (c == 'a' || c == 'A') {
return readAppendLimit(request);
}
if (c == 'm' || c == 'M') {
return readM(request);
}
if (c == 'd' || c == 'D') {
return readDeleted(request);
}
if (c == 'r' || c == 'R') {
return readRecent(request);
}
if (c == 'h' || c == 'H') {
return readHighestModseq(request);
}
if (c == 'u' || c == 'U') {
return readU(request);
}
if (c == 's' || c == 'S') {
return readSize(request);
}
throw new DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unknown status item: '" + request.consumeWord(ImapRequestLineReader.NoopCharValidator.INSTANCE) + "'");
}
private static StatusDataItems.StatusItem readM(ImapRequestLineReader request) throws DecodingException {
request.consume();
char c2 = request.nextChar();
if (c2 == 'e' || c2 == 'E') {
return readMessages(request);
} else {
return readMailboxId(request);
}
}
private static StatusDataItems.StatusItem readU(ImapRequestLineReader request) throws DecodingException {
char c;
assertChar(request, 'u', 'U');
c = request.nextWordChar();
if (c == 'n' || c == 'N') {
return readUnseen(request);
}
assertChar(request, 'i', 'I');
assertChar(request, 'd', 'D');
c = request.nextWordChar();
if (c == 'n' || c == 'N') {
return readUidNext(request);
}
readValidity(request);
return StatusDataItems.StatusItem.UID_VALIDITY;
}
private static void readValidity(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'v', 'V');
assertChar(request, 'a', 'A');
assertChar(request, 'l', 'L');
assertChar(request, 'i', 'I');
assertChar(request, 'd', 'D');
assertChar(request, 'i', 'I');
assertChar(request, 't', 'T');
assertChar(request, 'y', 'Y');
}
private static StatusDataItems.StatusItem readAppendLimit(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'a', 'A');
assertChar(request, 'p', 'P');
assertChar(request, 'p', 'P');
assertChar(request, 'e', 'E');
assertChar(request, 'n', 'N');
assertChar(request, 'd', 'D');
assertChar(request, 'l', 'L');
assertChar(request, 'i', 'I');
assertChar(request, 'm', 'M');
assertChar(request, 'i', 'I');
assertChar(request, 't', 'T');
return StatusDataItems.StatusItem.APPENDLIMIT;
}
private static StatusDataItems.StatusItem readSize(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 's', 'S');
assertChar(request, 'i', 'I');
assertChar(request, 'z', 'Z');
assertChar(request, 'e', 'E');
return StatusDataItems.StatusItem.SIZE;
}
private static StatusDataItems.StatusItem readUidNext(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'n', 'N');
assertChar(request, 'e', 'E');
assertChar(request, 'x', 'X');
assertChar(request, 't', 'T');
return StatusDataItems.StatusItem.UID_NEXT;
}
private static StatusDataItems.StatusItem readUnseen(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'n', 'N');
assertChar(request, 's', 'S');
assertChar(request, 'e', 'E');
assertChar(request, 'e', 'E');
assertChar(request, 'n', 'N');
return StatusDataItems.StatusItem.UNSEEN;
}
private static StatusDataItems.StatusItem readHighestModseq(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'h', 'H');
assertChar(request, 'i', 'I');
assertChar(request, 'g', 'G');
assertChar(request, 'h', 'H');
assertChar(request, 'e', 'E');
assertChar(request, 's', 'S');
assertChar(request, 't', 'T');
assertChar(request, 'm', 'M');
assertChar(request, 'o', 'O');
assertChar(request, 'd', 'D');
assertChar(request, 's', 'S');
assertChar(request, 'e', 'E');
assertChar(request, 'q', 'Q');
return StatusDataItems.StatusItem.HIGHEST_MODSEQ;
}
private static StatusDataItems.StatusItem readRecent(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'r', 'R');
assertChar(request, 'e', 'E');
assertChar(request, 'c', 'C');
assertChar(request, 'e', 'E');
assertChar(request, 'n', 'N');
assertChar(request, 't', 'T');
return StatusDataItems.StatusItem.RECENT;
}
private static StatusDataItems.StatusItem readMessages(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'e', 'E');
assertChar(request, 's', 'S');
assertChar(request, 's', 'S');
assertChar(request, 'a', 'A');
assertChar(request, 'g', 'G');
assertChar(request, 'e', 'E');
assertChar(request, 's', 'S');
return StatusDataItems.StatusItem.MESSAGES;
}
private static StatusDataItems.StatusItem readDeleted(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'd', 'D');
assertChar(request, 'e', 'E');
assertChar(request, 'l', 'L');
assertChar(request, 'e', 'E');
assertChar(request, 't', 'T');
assertChar(request, 'e', 'E');
assertChar(request, 'd', 'D');
char c = request.nextWordChar();
if (c == '-') {
assertChar(request, '-', '-');
assertChar(request, 's', 'S');
assertChar(request, 't', 'T');
assertChar(request, 'o', 'O');
assertChar(request, 'r', 'R');
assertChar(request, 'a', 'A');
assertChar(request, 'g', 'G');
assertChar(request, 'e', 'E');
return StatusDataItems.StatusItem.DELETED_STORAGE;
}
return StatusDataItems.StatusItem.DELETED;
}
private static StatusDataItems.StatusItem readMailboxId(ImapRequestLineReader request) throws DecodingException {
assertChar(request, 'a', 'A');
assertChar(request, 'i', 'I');
assertChar(request, 'l', 'L');
assertChar(request, 'b', 'B');
assertChar(request, 'o', 'O');
assertChar(request, 'x', 'X');
assertChar(request, 'i', 'I');
assertChar(request, 'd', 'D');
return StatusDataItems.StatusItem.MAILBOXID;
}
private static void assertChar(ImapRequestLineReader reader, char low, char up) throws DecodingException {
char c = reader.consume();
if (c != low && c != up) {
throw new DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unexpected token in Status item. Expecting " + up + " got " + c);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy