/* * @(#)TextVariable.java 0.0.3 99/07/31 * * Copyright (c) 1999 by Willie Wheeler. All rights reserved. */ package stats; import lang.*; /** * Class to represent a qualitative variable, whether nominal or ordinal. * The variable must have finitely many values, which are represented * internally as Integers in the range 0 through n-1, for * n values. These integer representations can be mapped to * corresponding String representations. *

* If the variable is intended to be nominal, then the ordering of the values * can be ignored. On the other hand, if the variable is ordinal, then the * values are ordered from 0 to n-1. * * @version 0.0.3 07/31/99 * @author Willie Wheeler */ public class TextVariable extends Variable { /** Version ID for serialization. */ static final long serialVersionUID = -7690630931465982331L; /** * The clear value for TextVariable, which is simply an * Integer representation of zero. */ public static final Integer CLEAR_VALUE = new Integer(0); /** * Name of the numValues property. */ public static final String NUM_VALUES_PROPERTY = "numValues"; /** * Name of the values property. */ public static final String VALUES_PROPERTY = "values"; /** * Array of possible values, represented as Strings. * * @serial */ protected String[] values; /** * Builds a qualitative variable with null name and an empty * list of possible values. */ public TextVariable() { this(null, new String[0]); } /** * Builds a qualitative variable with the given name and an empty list * of possible values. * * @param name name for this variable */ public TextVariable(String name) { this(name, new String[0]); } /** * Builds a qualitative variable with the given name and number of * possible values. The values have the form 'Value i'. * * @param name name for this variable * @param numValues number of possible values */ public TextVariable(String name, int numValues) { super(name); setNumValues(numValues); } /** * Builds a qualitative variable with the given name and array of * possible values. * * @param name name for this variable * @param values array of possible values */ public TextVariable(String name, String[] values) { super(name); this.values = values; } /** * Sets the number of possible values for this variable. If the new * number of values is greater than the old number, then extra values of * the form 'Value i' are added. If the new number of values is less * than the old number, then values are truncated from the end of the * list. * * @param numValues new number of values * @exception IllegalArgumentException if the * number of values is negative */ public void setNumValues(int numValues) { int oldNumValues = values.length; int newNumValues = numValues; // Check for bad input. if (numValues < 0) { String msg = "Number of values cannot be negative."; throw new IllegalArgumentException(msg); } if (numValues > oldNumValues) { // Pad with extra values. String[] newValues = new String[newNumValues]; System.arraycopy(values, 0, newValues, 0, oldNumValues); for (int i = oldNumValues; i < newNumValues; i++) { newValues[i] = "Value " + i; } this.values = newValues; } else if (numValues < oldNumValues) { // Truncate. String[] newValues = new String[newNumValues]; System.arraycopy(values, 0, newValues, 0, newNumValues); this.values = newValues; } firePropertyChange(NUM_VALUES_PROPERTY, new Integer(oldNumValues), new Integer(newNumValues)); } /** * Returns the number of possible values for this variable. * * @return number of possible values */ public int getNumValues() { return values.length; } /** * Sets the list of possible values for this variable. * * @param values array of all possible values */ public void setValues(String[] values) { String[] oldValues = this.values; if (values == null) { this.values = new String[0]; } else { this.values = values; } firePropertyChange(VALUES_PROPERTY, oldValues, this.values); } /** * Returns an array containing all possible values for this variable. * * @return array of all possible values */ public String[] getValues() { return values; } /** * Sets the variable value specified by the given index. * * @param index variable index * @param value new variable value */ public void setValue(int index, String value) { String[] oldValues = this.values; values[index] = value; firePropertyChange(VALUES_PROPERTY, oldValues, this.values); } /** * Returns the variable value specified by the given index. * * @param index index mapping to a variable value * @return variable value */ public String getValue(int index) { return values[index]; } /** * Returns true if the passed value represents an integer inside * the range of acceptable values for this variable. If the * variable has n possible values, then the passed value should * represent an integer from 0 to n-1. * * @param value a value to be checked */ public boolean checkValue(Object value) { // Disqualify if the value does not represent an integer. int primInt = 0; try { primInt = NumberUtils.asPrimInt(value); } catch (Exception e) { return false; } // Disqualify if the value lies outside the range of acceptable values. if (! (0 <= primInt && primInt < getNumValues())) { return false; } // Value A-OK! return true; } /** * Attempts to convert the passed value into an Integer. * * @param value a value to be converted * @return the Integer equivalent of the passed * value * @exception ClassCastException if the passed * value is neither a Number nor a * String * @exception NumberFormatException if the passed * value is an unparseable String */ public Object filterValue(Object value) { return NumberUtils.asClassInt(value); } /** * Returns Integer.class, since TextVariable values * must be of type Integer. Note that while the values are * mapped to Strings, they are not themselves Strings, * and so this method does not return String.class. * * @return Integer.class, which represents the * class type for TextVariable values */ public Class getValueClass() { return Integer.class; } /** * Returns the clear value for the TextVariable class, which is * an Integer representation of zero. * * @return the TextVariable clear value, zero */ public Object getClearValue() { return CLEAR_VALUE; } }