193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair/* 278795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair * Copyright 20078 the original author or authors. 393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * 493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Licensed under the Apache License, Version 2.0 (the "License"); 593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * you may not use this file except in compliance with the License. 693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * You may obtain a copy of the License at 793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * 893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * http://www.apache.org/licenses/LICENSE-2.0 993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * 1093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Unless required by applicable law or agreed to in writing, software 1193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * distributed under the License is distributed on an "AS IS" BASIS, 1293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * See the License for the specific language governing permissions and 1493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * limitations under the License. 1593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 1693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismairpackage org.mockftpserver.core.command; 1793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 1847fb67a4e600f339064de4c08f10279accc95e92chrismairimport org.mockftpserver.core.CommandSyntaxException; 1947fb67a4e600f339064de4c08f10279accc95e92chrismairimport org.mockftpserver.core.util.Assert; 2047fb67a4e600f339064de4c08f10279accc95e92chrismair 2193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismairimport java.util.Arrays; 2278795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismairimport java.util.List; 2393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 2493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair/** 2593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Represents a command received from an FTP client, containing a command name and parameters. 2693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Objects of this class are immutable. 2747fb67a4e600f339064de4c08f10279accc95e92chrismair * 2893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @author Chris Mair 2947fb67a4e600f339064de4c08f10279accc95e92chrismair * @version $Revision$ - $Date$ 3093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 3193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismairpublic final class Command { 3293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 3393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair private String name; 3493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair private String[] parameters; 3547fb67a4e600f339064de4c08f10279accc95e92chrismair 3693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 3793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Construct a new immutable instance with the specified command name and parameters 3847fb67a4e600f339064de4c08f10279accc95e92chrismair * 3947fb67a4e600f339064de4c08f10279accc95e92chrismair * @param name - the command name; may not be null 4078795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair * @param parameters - the command parameters; may be empty; may not be null 4193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 4293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public Command(String name, String[] parameters) { 4393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair Assert.notNull(name, "name"); 4493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair Assert.notNull(parameters, "parameters"); 4593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair this.name = name; 4693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair this.parameters = copy(parameters); 4793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 4893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 4993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 5078795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair * Construct a new immutable instance with the specified command name and parameters 5147fb67a4e600f339064de4c08f10279accc95e92chrismair * 5247fb67a4e600f339064de4c08f10279accc95e92chrismair * @param name - the command name; may not be null 5378795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair * @param parameters - the command parameters; may be empty; may not be null 5478795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair */ 5578795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair public Command(String name, List parameters) { 5678795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair this(name, (String[]) parameters.toArray(new String[parameters.size()])); 5778795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair } 5847fb67a4e600f339064de4c08f10279accc95e92chrismair 5978795c9e5e3c55fc294f011bcc129b7aab0f49b7chrismair /** 6093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @return the name 6193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 6293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public String getName() { 6393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return name; 6493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 6547fb67a4e600f339064de4c08f10279accc95e92chrismair 6693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 6793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @return the parameters 6893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 6993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public String[] getParameters() { 7093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return copy(parameters); 7193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 7293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 7393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 7493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Get the String value of the parameter at the specified index 7547fb67a4e600f339064de4c08f10279accc95e92chrismair * 7693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @param index - the index 7793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @return the parameter value as a String 7847fb67a4e600f339064de4c08f10279accc95e92chrismair * @throws org.mockftpserver.core.util.AssertFailedException 7947fb67a4e600f339064de4c08f10279accc95e92chrismair * if the parameter index is invalid or the value is not a valid String 8093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 8131d38a11c73497bc273bfc0081b0d3b723482239chrismair public String getRequiredParameter(int index) { 8293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair assertValidIndex(index); 8393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return parameters[index]; 8493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 8593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 8693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 8793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Get the String value of the parameter at the specified index; return null if no parameter exists for the index 8847fb67a4e600f339064de4c08f10279accc95e92chrismair * 8993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @param index - the index 9093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @return the parameter value as a String, or null if this Command does not have a parameter for that index 9193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 9233e5281191636818c9efc791bdcd670c3a845f7echrismair public String getParameter(int index) { 9393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return (parameters.length > index) ? parameters[index] : null; 9493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 9593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 9693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 9733e5281191636818c9efc791bdcd670c3a845f7echrismair * Get the String value of the parameter at the specified index; return null if no 9833e5281191636818c9efc791bdcd670c3a845f7echrismair * parameter exists for the index. This is an alias for {@link #getParameter(int)}. 9947fb67a4e600f339064de4c08f10279accc95e92chrismair * 10033e5281191636818c9efc791bdcd670c3a845f7echrismair * @param index - the index 10133e5281191636818c9efc791bdcd670c3a845f7echrismair * @return the parameter value as a String, or null if this Command does not have a parameter for that index 10233e5281191636818c9efc791bdcd670c3a845f7echrismair */ 10333e5281191636818c9efc791bdcd670c3a845f7echrismair public String getOptionalString(int index) { 10433e5281191636818c9efc791bdcd670c3a845f7echrismair return getParameter(index); 10533e5281191636818c9efc791bdcd670c3a845f7echrismair } 10633e5281191636818c9efc791bdcd670c3a845f7echrismair 10733e5281191636818c9efc791bdcd670c3a845f7echrismair /** 10893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @see java.lang.Object#equals(java.lang.Object) 10993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 11093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public boolean equals(Object obj) { 11193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair if (this == obj) { 11293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return true; 11393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 11493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair if (obj == null || !(obj instanceof Command)) { 11593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return false; 11693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 11793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return this.hashCode() == obj.hashCode(); 11893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 11993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 12093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 12193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @see java.lang.Object#hashCode() 12293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 12393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public int hashCode() { 12493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair String str = name + Arrays.asList(parameters); 12593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return str.hashCode(); 12693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 12747fb67a4e600f339064de4c08f10279accc95e92chrismair 12893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 12993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Return the String representation of this object 13047fb67a4e600f339064de4c08f10279accc95e92chrismair * 13193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @see java.lang.Object#toString() 13293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 13393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public String toString() { 13433e5281191636818c9efc791bdcd670c3a845f7echrismair return "Command[" + name + ":" + Arrays.asList(parameters) + "]"; 13593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 13693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair 13793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 13893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Return the name, normalized to a common format - convert to upper case. 13947fb67a4e600f339064de4c08f10279accc95e92chrismair * 14093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @return the name converted to upper case 14193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 14293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair public static String normalizeName(String name) { 14393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return name.toUpperCase(); 14493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 14547fb67a4e600f339064de4c08f10279accc95e92chrismair 14693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 14793102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Construct a shallow copy of the specified array 14847fb67a4e600f339064de4c08f10279accc95e92chrismair * 14993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @param array - the array to copy 15093102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @return a new array with the same contents 15193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 15293102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair private static String[] copy(String[] array) { 15393102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair String[] newArray = new String[array.length]; 15493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair System.arraycopy(array, 0, newArray, 0, array.length); 15593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair return newArray; 15693102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 15747fb67a4e600f339064de4c08f10279accc95e92chrismair 15893102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair /** 15993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * Assert that the index is valid 16047fb67a4e600f339064de4c08f10279accc95e92chrismair * 16193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair * @param index - the index 16247fb67a4e600f339064de4c08f10279accc95e92chrismair * @throws org.mockftpserver.core.CommandSyntaxException 16347fb67a4e600f339064de4c08f10279accc95e92chrismair * - if the parameter index is invalid 16493102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair */ 16593102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair private void assertValidIndex(int index) { 16647fb67a4e600f339064de4c08f10279accc95e92chrismair if (index < 0 || index >= parameters.length) { 16747fb67a4e600f339064de4c08f10279accc95e92chrismair throw new CommandSyntaxException("The parameter index " + index + " is not valid for " + this); 16847fb67a4e600f339064de4c08f10279accc95e92chrismair } 16993102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair } 17047fb67a4e600f339064de4c08f10279accc95e92chrismair 17193102446a7b7c3d17888064b4e2e4e5cb534e6d0chrismair} 172