1/*
2 * Copyright 20078 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.mockftpserver.core.command;
17
18import org.mockftpserver.core.CommandSyntaxException;
19import org.mockftpserver.core.util.Assert;
20
21import java.util.Arrays;
22import java.util.List;
23
24/**
25 * Represents a command received from an FTP client, containing a command name and parameters.
26 * Objects of this class are immutable.
27 *
28 * @author Chris Mair
29 * @version $Revision$ - $Date$
30 */
31public final class Command {
32
33    private String name;
34    private String[] parameters;
35
36    /**
37     * Construct a new immutable instance with the specified command name and parameters
38     *
39     * @param name       - the command name; may not be null
40     * @param parameters - the command parameters; may be empty; may not be null
41     */
42    public Command(String name, String[] parameters) {
43        Assert.notNull(name, "name");
44        Assert.notNull(parameters, "parameters");
45        this.name = name;
46        this.parameters = copy(parameters);
47    }
48
49    /**
50     * Construct a new immutable instance with the specified command name and parameters
51     *
52     * @param name       - the command name; may not be null
53     * @param parameters - the command parameters; may be empty; may not be null
54     */
55    public Command(String name, List parameters) {
56        this(name, (String[]) parameters.toArray(new String[parameters.size()]));
57    }
58
59    /**
60     * @return the name
61     */
62    public String getName() {
63        return name;
64    }
65
66    /**
67     * @return the parameters
68     */
69    public String[] getParameters() {
70        return copy(parameters);
71    }
72
73    /**
74     * Get the String value of the parameter at the specified index
75     *
76     * @param index - the index
77     * @return the parameter value as a String
78     * @throws org.mockftpserver.core.util.AssertFailedException
79     *          if the parameter index is invalid or the value is not a valid String
80     */
81    public String getRequiredParameter(int index) {
82        assertValidIndex(index);
83        return parameters[index];
84    }
85
86    /**
87     * Get the String value of the parameter at the specified index; return null if no parameter exists for the index
88     *
89     * @param index - the index
90     * @return the parameter value as a String, or null if this Command does not have a parameter for that index
91     */
92    public String getParameter(int index) {
93        return (parameters.length > index) ? parameters[index] : null;
94    }
95
96    /**
97     * Get the String value of the parameter at the specified index; return null if no
98     * parameter exists for the index. This is an alias for {@link #getParameter(int)}.
99     *
100     * @param index - the index
101     * @return the parameter value as a String, or null if this Command does not have a parameter for that index
102     */
103    public String getOptionalString(int index) {
104        return getParameter(index);
105    }
106
107    /**
108     * @see java.lang.Object#equals(java.lang.Object)
109     */
110    public boolean equals(Object obj) {
111        if (this == obj) {
112            return true;
113        }
114        if (obj == null || !(obj instanceof Command)) {
115            return false;
116        }
117        return this.hashCode() == obj.hashCode();
118    }
119
120    /**
121     * @see java.lang.Object#hashCode()
122     */
123    public int hashCode() {
124        String str = name + Arrays.asList(parameters);
125        return str.hashCode();
126    }
127
128    /**
129     * Return the String representation of this object
130     *
131     * @see java.lang.Object#toString()
132     */
133    public String toString() {
134        return "Command[" + name + ":" + Arrays.asList(parameters) + "]";
135    }
136
137    /**
138     * Return the name, normalized to a common format - convert to upper case.
139     *
140     * @return the name converted to upper case
141     */
142    public static String normalizeName(String name) {
143        return name.toUpperCase();
144    }
145
146    /**
147     * Construct a shallow copy of the specified array
148     *
149     * @param array - the array to copy
150     * @return a new array with the same contents
151     */
152    private static String[] copy(String[] array) {
153        String[] newArray = new String[array.length];
154        System.arraycopy(array, 0, newArray, 0, array.length);
155        return newArray;
156    }
157
158    /**
159     * Assert that the index is valid
160     *
161     * @param index - the index
162     * @throws org.mockftpserver.core.CommandSyntaxException
163     *          - if the parameter index is invalid
164     */
165    private void assertValidIndex(int index) {
166        if (index < 0 || index >= parameters.length) {
167            throw new CommandSyntaxException("The parameter index " + index + " is not valid for " + this);
168        }
169    }
170
171}
172