// Turn the command into an enum for matching on
Command cmdType;
try {
cmdType = Command.valueOf(parts[0].toUpperCase());
} catch (IllegalArgumentException e) {
throw new UnknownCommandException("unknown command: " + parts[0].toLowerCase());
}
// Produce the initial command message, for filling in later
CommandMessage cmd = CommandMessage.command(cmdType);
// TODO there is a certain amount of fudgery here related to common things like 'noreply', etc. that could be refactored nicely
// Dispatch on the type of command
if (cmdType == Command.ADD ||
cmdType == Command.SET ||
cmdType == Command.REPLACE ||
cmdType == Command.CAS ||
cmdType == Command.APPEND ||
cmdType == Command.PREPEND) {
// if we don't have all the parts, it's malformed
if (numParts < 5) {
throw new MalformedCommandException("invalid command length");
}
// Fill in all the elements of the command
int size = Integer.parseInt(parts[4]);
int expire = Integer.parseInt(parts[3]);
int flags = Integer.parseInt(parts[2]);
cmd.element = new MCElement(parts[1], flags, expire != 0 && expire < MCElement.THIRTY_DAYS ? MCElement.Now() + expire : expire, size);
// look for cas and "noreply" elements
if (numParts > 5) {
int noreply = cmdType == Command.CAS ? 6 : 5;
if (cmdType == Command.CAS) {
cmd.cas_key = Long.valueOf(parts[5]);
}
if (numParts == noreply + 1 && parts[noreply].equalsIgnoreCase(NOREPLY))
cmd.noreply = true;
}
// Now indicate that we need more for this command by changing the session status's state.
// This instructs the frame decoder to start collecting data for us.
status.needMore(size, cmd);
} else if (cmdType == Command.GET ||
cmdType == Command.GETS ||
cmdType == Command.STATS ||
cmdType == Command.QUIT ||
cmdType == Command.VERSION) {
// Get all the keys
cmd.keys.addAll(Arrays.asList(parts).subList(1, numParts));
// Pass it on.
Channels.fireMessageReceived(channelHandlerContext, cmd, channel.getRemoteAddress());
} else if (cmdType == Command.INCR ||
cmdType == Command.DECR) {
// Malformed
if (numParts < 2 || numParts > 3)
throw new MalformedCommandException("invalid increment command");
cmd.keys.add(parts[1]);
cmd.incrAmount = Integer.valueOf(parts[2]);
if (numParts == 3 && parts[2].equalsIgnoreCase(NOREPLY)) {
cmd.noreply = true;
}
Channels.fireMessageReceived(channelHandlerContext, cmd, channel.getRemoteAddress());
} else if (cmdType == Command.DELETE) {
cmd.keys.add(parts[1]);
if (numParts >= 2) {
if (parts[numParts - 1].equalsIgnoreCase(NOREPLY)) {
cmd.noreply = true;
if (numParts == 4)
cmd.time = Integer.valueOf(parts[2]);
} else if (numParts == 3)
cmd.time = Integer.valueOf(parts[2]);
}
Channels.fireMessageReceived(channelHandlerContext, cmd, channel.getRemoteAddress());
} else if (cmdType == Command.FLUSH_ALL) {
if (numParts >= 1) {
if (parts[numParts - 1].equalsIgnoreCase(NOREPLY)) {
cmd.noreply = true;
if (numParts == 3)
cmd.time = Integer.valueOf(parts[1]);
} else if (numParts == 2)
cmd.time = Integer.valueOf(parts[1]);
}
Channels.fireMessageReceived(channelHandlerContext, cmd, channel.getRemoteAddress());
} else {
throw new UnknownCommandException("unknown command: " + cmdType);
}
}