153295844df24dff0a1f59e1104795e640b54c2efchrismair/*
253295844df24dff0a1f59e1104795e640b54c2efchrismair * Copyright 2007 the original author or authors.
353295844df24dff0a1f59e1104795e640b54c2efchrismair *
453295844df24dff0a1f59e1104795e640b54c2efchrismair * Licensed under the Apache License, Version 2.0 (the "License");
553295844df24dff0a1f59e1104795e640b54c2efchrismair * you may not use this file except in compliance with the License.
653295844df24dff0a1f59e1104795e640b54c2efchrismair * You may obtain a copy of the License at
753295844df24dff0a1f59e1104795e640b54c2efchrismair *
853295844df24dff0a1f59e1104795e640b54c2efchrismair *      http://www.apache.org/licenses/LICENSE-2.0
953295844df24dff0a1f59e1104795e640b54c2efchrismair *
1053295844df24dff0a1f59e1104795e640b54c2efchrismair * Unless required by applicable law or agreed to in writing, software
1153295844df24dff0a1f59e1104795e640b54c2efchrismair * distributed under the License is distributed on an "AS IS" BASIS,
1253295844df24dff0a1f59e1104795e640b54c2efchrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1353295844df24dff0a1f59e1104795e640b54c2efchrismair * See the License for the specific language governing permissions and
1453295844df24dff0a1f59e1104795e640b54c2efchrismair * limitations under the License.
1553295844df24dff0a1f59e1104795e640b54c2efchrismair */
1653295844df24dff0a1f59e1104795e640b54c2efchrismairpackage org.mockftpserver.core.command;
1753295844df24dff0a1f59e1104795e640b54c2efchrismair
1853295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.Arrays;
1953295844df24dff0a1f59e1104795e640b54c2efchrismair
2053295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.util.Assert;
2153295844df24dff0a1f59e1104795e640b54c2efchrismair
2253295844df24dff0a1f59e1104795e640b54c2efchrismair/**
2353295844df24dff0a1f59e1104795e640b54c2efchrismair * Represents a command received from an FTP client, containing a command name and parameters.
2453295844df24dff0a1f59e1104795e640b54c2efchrismair * Objects of this class are immutable.
2553295844df24dff0a1f59e1104795e640b54c2efchrismair *
2653295844df24dff0a1f59e1104795e640b54c2efchrismair * @version $Revision$ - $Date$
2753295844df24dff0a1f59e1104795e640b54c2efchrismair *
2853295844df24dff0a1f59e1104795e640b54c2efchrismair * @author Chris Mair
2953295844df24dff0a1f59e1104795e640b54c2efchrismair */
3053295844df24dff0a1f59e1104795e640b54c2efchrismairpublic final class Command {
3153295844df24dff0a1f59e1104795e640b54c2efchrismair
3253295844df24dff0a1f59e1104795e640b54c2efchrismair    private String name;
3353295844df24dff0a1f59e1104795e640b54c2efchrismair    private String[] parameters;
3453295844df24dff0a1f59e1104795e640b54c2efchrismair
3553295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
3653295844df24dff0a1f59e1104795e640b54c2efchrismair     * Construct a new immutable instance with the specified command name and parameters
3753295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param name - the command name; may not be null
3853295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param parameters - the command parameters; may be empty; may not benull
3953295844df24dff0a1f59e1104795e640b54c2efchrismair     */
4053295844df24dff0a1f59e1104795e640b54c2efchrismair    public Command(String name, String[] parameters) {
4153295844df24dff0a1f59e1104795e640b54c2efchrismair        Assert.notNull(name, "name");
4253295844df24dff0a1f59e1104795e640b54c2efchrismair        Assert.notNull(parameters, "parameters");
4353295844df24dff0a1f59e1104795e640b54c2efchrismair        this.name = name;
4453295844df24dff0a1f59e1104795e640b54c2efchrismair        this.parameters = copy(parameters);
4553295844df24dff0a1f59e1104795e640b54c2efchrismair    }
4653295844df24dff0a1f59e1104795e640b54c2efchrismair
4753295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
4853295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the name
4953295844df24dff0a1f59e1104795e640b54c2efchrismair     */
5053295844df24dff0a1f59e1104795e640b54c2efchrismair    public String getName() {
5153295844df24dff0a1f59e1104795e640b54c2efchrismair        return name;
5253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
5353295844df24dff0a1f59e1104795e640b54c2efchrismair
5453295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
5553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the parameters
5653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
5753295844df24dff0a1f59e1104795e640b54c2efchrismair    public String[] getParameters() {
5853295844df24dff0a1f59e1104795e640b54c2efchrismair        return copy(parameters);
5953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
6053295844df24dff0a1f59e1104795e640b54c2efchrismair
6153295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
6253295844df24dff0a1f59e1104795e640b54c2efchrismair     * Get the String value of the parameter at the specified index
6353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param index - the index
6453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the parameter value as a String
6553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @throws AssertFailedException if the parameter index is invalid or the value is not a valid String
6653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
6753295844df24dff0a1f59e1104795e640b54c2efchrismair    public String getRequiredString(int index) {
6853295844df24dff0a1f59e1104795e640b54c2efchrismair        assertValidIndex(index);
6953295844df24dff0a1f59e1104795e640b54c2efchrismair        return parameters[index];
7053295844df24dff0a1f59e1104795e640b54c2efchrismair    }
7153295844df24dff0a1f59e1104795e640b54c2efchrismair
7253295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
7353295844df24dff0a1f59e1104795e640b54c2efchrismair     * Get the String value of the parameter at the specified index; return null if no parameter exists for the index
7453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param index - the index
7553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the parameter value as a String, or null if this Command does not have a parameter for that index
7653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
7753295844df24dff0a1f59e1104795e640b54c2efchrismair    public String getOptionalString(int index) {
7853295844df24dff0a1f59e1104795e640b54c2efchrismair        return (parameters.length > index) ? parameters[index] : null;
7953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
8053295844df24dff0a1f59e1104795e640b54c2efchrismair
8153295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
8253295844df24dff0a1f59e1104795e640b54c2efchrismair     * @see java.lang.Object#equals(java.lang.Object)
8353295844df24dff0a1f59e1104795e640b54c2efchrismair     */
8453295844df24dff0a1f59e1104795e640b54c2efchrismair    public boolean equals(Object obj) {
8553295844df24dff0a1f59e1104795e640b54c2efchrismair        if (this == obj) {
8653295844df24dff0a1f59e1104795e640b54c2efchrismair            return true;
8753295844df24dff0a1f59e1104795e640b54c2efchrismair        }
8853295844df24dff0a1f59e1104795e640b54c2efchrismair        if (obj == null || !(obj instanceof Command)) {
8953295844df24dff0a1f59e1104795e640b54c2efchrismair            return false;
9053295844df24dff0a1f59e1104795e640b54c2efchrismair        }
9153295844df24dff0a1f59e1104795e640b54c2efchrismair        return this.hashCode() == obj.hashCode();
9253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
9353295844df24dff0a1f59e1104795e640b54c2efchrismair
9453295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
9553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @see java.lang.Object#hashCode()
9653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
9753295844df24dff0a1f59e1104795e640b54c2efchrismair    public int hashCode() {
9853295844df24dff0a1f59e1104795e640b54c2efchrismair        String str = name + Arrays.asList(parameters);
9953295844df24dff0a1f59e1104795e640b54c2efchrismair        return str.hashCode();
10053295844df24dff0a1f59e1104795e640b54c2efchrismair    }
10153295844df24dff0a1f59e1104795e640b54c2efchrismair
10253295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
10353295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the String representation of this object
10453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @see java.lang.Object#toString()
10553295844df24dff0a1f59e1104795e640b54c2efchrismair     */
10653295844df24dff0a1f59e1104795e640b54c2efchrismair    public String toString() {
10753295844df24dff0a1f59e1104795e640b54c2efchrismair        return "Command[" + name + ": " + Arrays.asList(parameters) + "]";
10853295844df24dff0a1f59e1104795e640b54c2efchrismair    }
10953295844df24dff0a1f59e1104795e640b54c2efchrismair
11053295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
11153295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the name, normalized to a common format - convert to upper case.
11253295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the name converted to upper case
11353295844df24dff0a1f59e1104795e640b54c2efchrismair     */
11453295844df24dff0a1f59e1104795e640b54c2efchrismair    public static String normalizeName(String name) {
11553295844df24dff0a1f59e1104795e640b54c2efchrismair        return name.toUpperCase();
11653295844df24dff0a1f59e1104795e640b54c2efchrismair    }
11753295844df24dff0a1f59e1104795e640b54c2efchrismair
11853295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
11953295844df24dff0a1f59e1104795e640b54c2efchrismair     * Construct a shallow copy of the specified array
12053295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param array - the array to copy
12153295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return a new array with the same contents
12253295844df24dff0a1f59e1104795e640b54c2efchrismair     */
12353295844df24dff0a1f59e1104795e640b54c2efchrismair    private static String[] copy(String[] array) {
12453295844df24dff0a1f59e1104795e640b54c2efchrismair        String[] newArray = new String[array.length];
12553295844df24dff0a1f59e1104795e640b54c2efchrismair        System.arraycopy(array, 0, newArray, 0, array.length);
12653295844df24dff0a1f59e1104795e640b54c2efchrismair        return newArray;
12753295844df24dff0a1f59e1104795e640b54c2efchrismair    }
12853295844df24dff0a1f59e1104795e640b54c2efchrismair
12953295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
13053295844df24dff0a1f59e1104795e640b54c2efchrismair     * Assert that the index is valid
13153295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param index - the index
13253295844df24dff0a1f59e1104795e640b54c2efchrismair     * @throws AssertFailedException if the parameter index is invalid
13353295844df24dff0a1f59e1104795e640b54c2efchrismair     */
13453295844df24dff0a1f59e1104795e640b54c2efchrismair    private void assertValidIndex(int index) {
13553295844df24dff0a1f59e1104795e640b54c2efchrismair        Assert.isTrue(index >= 0 && index < parameters.length, "The parameter index " + index + " is not valid for " + this);
13653295844df24dff0a1f59e1104795e640b54c2efchrismair    }
13753295844df24dff0a1f59e1104795e640b54c2efchrismair
13853295844df24dff0a1f59e1104795e640b54c2efchrismair}
139