/*
* (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());
}
}