/* * (c) Copyright Hewlett-Packard Company 2001 * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE and no warranty * that the program does not infringe the Intellectual Property rights of * a third party. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */ package jade.wrapper; import jade.util.leap.Serializable; import jade.util.leap.Comparable; /** * Provides an abstract base class for implementations of state. <br> <b>NOT available in MIDP</b> <br> * @author David Bell, Dick Cowan: Hewlett-Packard */ public abstract class StateBase implements State, Comparable, Serializable { /** * Code corresponding to first legal state name. Typically 0 or 1. */ private int baseCode; /** * The integer code that identifies which state this object represents. */ private int m_code; /** * An array of string names, one for each of the valid state this object * can represent. */ private String stateNames[]; private StateBase() { // empty } /** * Creates a state object for a given code. To avoid coding errors, * the integer codes used to create instances of this class should * come from the concrete extensions of this class. * <p> * If the code is "out of range" (i.e. not a valid code), an * {@link java.lang.IllegalArgumentException IllegalArgumentException} * will be thrown. * * @param code The integer code identifier for a particular state. * @param aBaseCode Value corresponding to first entry in names. Typically 0 or 1. * @param names Names of the states. */ StateBase(int code, int aBaseCode, String[] names) { baseCode = aBaseCode; if (names == null) { throw new IllegalArgumentException( "State names must not be null"); } stateNames = names; if ((code >= baseCode) && (code <= (baseCode + stateNames.length - 1))) { m_code = code; } else { throw new IllegalArgumentException( "State code out of range(" + baseCode + "-" + (baseCode + stateNames.length - 1) + "): " + code); } } /** * Returns the descriptive name of the state. * @return The descriptive name of the state. Will never return null. */ public String getName() { String rtVal = getName(m_code); // Should never happen, but just in case... if (rtVal == null) { rtVal = "Unknown"; } return rtVal; } /** * Return the integer code that identifies this state. * @return The integer code that identifies this state. */ public int getCode() { return (m_code); } /** * Converts a descriptive state name into a state code. * The name comparison is not case sensitive. * If the name cannot be located for any reason a * {@link java.lang.IllegalArgumentException IllegalArgumentException} * will be thrown * @param name The descriptive name of a state to convert to a state code. * @return The integer state code corresponding to the provided state * name. */ int getCode(String name) { if (name == null) { throw new IllegalArgumentException("null argument not allowed"); } boolean found = false; int idx; for (idx = 0; (!found && (idx < stateNames.length)); idx++) { if (stateNames[idx].equalsIgnoreCase(name)) { found = true; } } if (found) { return baseCode + idx; } else { throw new IllegalArgumentException("No such state name: " + name); } } /** * Converts a state code to a descriptive state name. * @param code A state code to convert to a state name. * @return The descriptive name of the state or null if the state * code is "out of range" (i.e. invalid). */ String getName(int code) { if ((code >= baseCode) && (code <= (baseCode + stateNames.length - 1))) { return stateNames[code - baseCode]; } else { return null; } } /** * Determines if an object is equal to this object. In order for the * the passed object to be equal to this one the passed object must * be an instance if State and contain the same state code. * @param object An object to test for equality. * @return True if the object represent the same state and False otherwise. */ public boolean equals(Object object) { boolean equal = false; if (object != null) { equal = (m_code == ((State) object).getCode()); } return (equal); } /** * Compares a given object to this state object for the purpose of * collating. This method is used for the sorting of states. * A positive value means the receiver (this object) is "greater than" * the passed object. * A negative value means the receiver is "less than" the passed object. * A value of zero means the receiver and the passed object are equal * to each other. * * @param object An object to compare this object to. * * @return The result of the comparison. * <p> * The value 1 is returned if: * <ul> * <li> the passed object is null (the receiver is considered "greater than" * null objects)</li> * <li> the state code held by the receiver (this object) is * greater than * the code of the passed object</li> * </ul> * <p> * The value 0 (zero) is returned if: * <ul> * <li>the two state objects hold the same state code</li> * </ul> * <p> * The value -1 is returned if: * <ul> * <li> the passed object is not a AgentStateImpl object * (the receiver is considered "less than" objects of other types)</li> * <li> the state code held by the receiver (this object) is * less than * the code of the passed object</li> * <ul> */ public int compareTo(Object object) { int result = 0; if (object == null) { return 1; } if (object.getClass().isAssignableFrom(State.class)) { if (m_code > ((State) object).getCode()) { result = 1; } else if (m_code < ((State) object).getCode()) { result = -1; } else { result = 0; } } else { result = -1; } return (result); } /** * Returns the hash code for this state. The hash code equals the * state code. * * @return The state code for this state. */ public int hashCode() { return (m_code); } /** * A string representation of this state. * The returned string is of the form StateName(StateCode). * @return A string containing the name and code for this state. */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append(getName()).append("(").append(m_code).append(")"); return (buf.toString()); } /** * Return a string containing all descriptions and their codes. * Usefull for debugging. * @return String Is of the form StateName(StateCode), StateName(StateCode), .... */ String legalRange() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < stateNames.length; i++) { int code = i + baseCode; buf.append(getName(code)).append("(").append(code).append(")"); if (i < stateNames.length - 1) { buf.append(", "); } } return (buf.toString()); } }