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