| EnumType.java |
/*
* $Id: EnumType.java,v 1.26 2008/07/04 10:22:40 agoubard Exp $
*
* Copyright 2003-2008 Online Breedband B.V.
* See the COPYRIGHT file for redistribution and use restrictions.
*/
package org.xins.common.types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.xins.common.MandatoryArgumentChecker;
/**
* Abstract base class for enumeration types. An enumeration type only accepts
* a defined set of values.
*
* @version $Revision: 1.26 $ $Date: 2008/07/04 10:22:40 $
* @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
*
* @since XINS 1.0.0
*
* @see EnumItem
*/
public abstract class EnumType extends Type {
/**
* Map that links symbolic names to enumeration values.
*/
private final Map _namesToValues;
/**
* Map that links enumeration values to their symbolic names.
*/
private final Map _valuesToNames;
/**
* Map that links symbolic names to enumeration item objects.
*/
protected final Map _namesToItems;
/**
* Map that links enumeration values to enumeration item objects.
*/
protected final Map _valuesToItems;
/**
* List of the <code>EnumItem</code>.
*/
private final List _items;
/**
* The list of accepted values.
*/
private final String[] _values;
/**
* Creates a new <code>EnumType</code> instance. The name of the type needs
* to be specified. The value class (see {@link Type#getValueClass()}) is
* set to {@link String String.class}.
*
* <p />The items this type accepts should be passed. If
* <code>items == null</code>, then this type will contain no items. This
* is the same as passing a zero-size {@link EnumItem} array.
*
* <p />Note that the <code>items</code> array may contain
* <code>null</code> values. These will be ignored.
*
* @param name
* the name of the type, not <code>null</code>.
*
* @param items
* the items for the type, or <code>null</code>.
*
* @throws IllegalArgumentException
* if <code>name == null</code>.
*/
public EnumType(String name, EnumItem[] items)
throws IllegalArgumentException {
super(name, EnumItem.class);
_namesToValues = new HashMap();
_valuesToNames = new HashMap();
_namesToItems = new HashMap();
_valuesToItems = new HashMap();
_items = new ArrayList();
int count = items == null ? 0 : items.length;
String[] values = new String[count];
int actualItems = 0;
for (int i = 0; i < count; i++) {
EnumItem item = items[i];
if (item != null) {
String itemName = item.getName();
String itemValue = item.getValue();
_namesToValues.put(itemName, itemValue);
_valuesToNames.put(itemValue, itemName);
values[actualItems++] = itemValue;
_namesToItems.put(itemName, item);
_valuesToItems.put(itemValue, item);
_items.add(item);
}
}
_values = new String[actualItems];
System.arraycopy(values, 0, _values, 0, actualItems);
}
/**
* Actually checks if the specified value is valid for this type. This
* method is called from {@link #isValidValue(String)}. It is guaranteed that
* the argument is not <code>null</code>.
*
* @param value
* the value that should be checked for validity, never
* <code>null</code>.
*
* @return
* <code>true</code> if and only if the specified value is valid,
* <code>false</code> otherwise.
*/
protected final boolean isValidValueImpl(String value) {
for (int i = 0; i < _values.length; i++) {
if (_values[i].equals(value)) {
return true;
}
}
return false;
}
/**
* Converts the specified <code>EnumItem</code> to a string.
*
* @param value
* the value to convert, can be <code>null</code>.
*
* @return
* the textual representation of the value, or <code>null</code> if and
* only if <code>value == null</code>.
*/
public String toString(EnumItem value) {
// Short-circuit if the argument is null
if (value == null) {
return null;
} else {
return value.getValue();
}
}
/**
* Generates a string representation of the specified value for this type.
* The specified value must be an instance of the value class for this type
* (see {@link #getValueClass()}). Also, it has to fall within the range of
* valid values.
*
* @param value
* the value, cannot be <code>null</code>.
*
* @return
* the string representation of the specified value for this type,
* cannot be <code>null</code>.
*
* @throws IllegalArgumentException
* if <code>value == null</code>.
*
* @throws ClassCastException
* if <code>getValueClass().isInstance(value) == false</code>.
*
* @throws TypeValueException
* if the specified value is not in the allowed range.
*/
public final String toString(Object value)
throws IllegalArgumentException, ClassCastException, TypeValueException {
MandatoryArgumentChecker.check("value", value);
EnumItem item = (EnumItem) value;
return item.getValue();
}
/**
* Gets the value matching the specified name.
*
* @param name
* the name to match a corresponding value by, cannot be
* <code>null</code>.
*
* @return
* the corresponding value, or <code>null</code> if there is none.
*
* @throws IllegalArgumentException
* if <code>name == null</code>.
*/
public final String getValueByName(String name)
throws IllegalArgumentException {
// Check preconditions
MandatoryArgumentChecker.check("name", name);
return (String) _namesToValues.get(name);
}
/**
* Gets the name matching the specified value.
*
* @param value
* the value to match a corresponding name by, cannot be
* <code>null</code>.
*
* @return
* the corresponding name, or <code>null</code> if there is none.
*
* @throws IllegalArgumentException
* if <code>value == null</code>.
*/
public final String getNameByValue(String value)
throws IllegalArgumentException {
// Check preconditions
MandatoryArgumentChecker.check("value", value);
return (String) _valuesToNames.get(value);
}
/**
* Get the list of the EnumItem included in this <code>EnumType</code>.
*
* @return
* the list of {@link EnumItem} included in this <code>EnumType</code>.
*/
public final List getEnumItems() {
return _items;
}
}