/* * 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.geode.redis.internal; import io.netty.buffer.ByteBuf; import java.nio.channels.SocketChannel; import java.util.List; /** * The command class is used in holding a received Redis command. Each sent command resides in an * instance of this class. This class is designed to be used strictly by getter and setter methods. * * */ public class Command { private final List<byte[]> commandElems; private final RedisCommandType commandType; private ByteBuf response; private String key; private ByteArrayWrapper bytes; /** * Constructor for {@link Command}. Must initialize Command with a {@link SocketChannel} and a * {@link List} of command elements * * @param commandElems List of elements in command */ public Command(List<byte[]> commandElems) { if (commandElems == null || commandElems.isEmpty()) throw new IllegalArgumentException( "List of command elements cannot be empty -> List:" + commandElems); this.commandElems = commandElems; this.response = null; RedisCommandType type; try { byte[] charCommand = commandElems.get(0); String commandName = Coder.bytesToString(charCommand).toUpperCase(); type = RedisCommandType.valueOf(commandName); } catch (Exception e) { type = RedisCommandType.UNKNOWN; } this.commandType = type; } /** * Used to get the command element list * * @return List of command elements in form of {@link List} */ public List<byte[]> getProcessedCommand() { return this.commandElems; } /** * Getter method for the command type * * @return The command type */ public RedisCommandType getCommandType() { return this.commandType; } /** * Getter method to get the response to be sent * * @return The response */ public ByteBuf getResponse() { return response; } /** * Setter method to set the response to be sent * * @param response The response to be sent */ public void setResponse(ByteBuf response) { this.response = response; } public boolean hasError() { if (response == null) return false; if (response.getByte(0) == Coder.ERROR_ID) return true; return false; } /** * Convenience method to get a String representation of the key in a Redis command, always at the * second position in the sent command array * * @return Returns the second element in the parsed command list, which is always the key for * commands indicating a key */ public String getStringKey() { if (this.commandElems.size() > 1) { if (this.bytes == null) { this.bytes = new ByteArrayWrapper(this.commandElems.get(1)); this.key = this.bytes.toString(); } else if (this.key == null) this.key = this.bytes.toString(); return this.key; } else return null; } public ByteArrayWrapper getKey() { if (this.commandElems.size() > 1) { if (this.bytes == null) this.bytes = new ByteArrayWrapper(this.commandElems.get(1)); return this.bytes; } else return null; } @Override public String toString() { StringBuilder b = new StringBuilder(); for (byte[] bs : this.commandElems) { b.append(Coder.bytesToString(bs)); b.append(' '); } return b.toString(); } }