package org.limewire.setting; import java.util.Properties; /** * Provides a {@link Number} setting value and * ensures any value you set in the future falls within a range. As a subclass * of <code>Setting</code>, the setting has a key. If the value is set outside * the number range, the value is set to the closer value of either the minimum * or maximum range value. For example, if the range is [0,2] and you set the * value to 8, the value is actually set to 2. * <p> * Additionally, <code>AbstractNumber</code> defines a method * for subclasses to convert a string to a {@link Comparable}. */ public abstract class AbstractNumberSetting<T extends Number & Comparable<T>> extends AbstractSetting<T> { /** * Adds a safeguard against remote making a setting take a value beyond the * reasonable max */ protected final T MAX_VALUE; /** * Adds a safeguard against remote making a setting take a value below the * reasonable min */ protected final T MIN_VALUE; /** Whether or not this is a remote setting. */ private final boolean remote; protected AbstractNumberSetting(Properties defaultProps, Properties props, String key, String defaultValue, boolean remote, T min, T max) { super(defaultProps, props, key, defaultValue); this.remote = remote; if(max != null && min != null) {//do we need to check max, min? if(max.compareTo(min) < 0) //max less than min? throw new IllegalArgumentException("max less than min"); } MAX_VALUE = max; MIN_VALUE = min; setValueInternal(getValueAsString()); // performs normalization } /** * Set new property value * @param value new property value */ @Override protected void setValueInternal(String value) { if(remote) { assert MAX_VALUE != null : "remote setting created with no max"; assert MIN_VALUE != null : "remote setting created with no min"; } value = normalizeValue(value); super.setValueInternal(value); } /** * Returns the minimum value for this setting, may return null if no minimum is set. */ public T getMinValue() { return MIN_VALUE; } /** * Returns the minimum value for this setting, may return null if no maximum is set. */ public T getMaxValue() { return MAX_VALUE; } /** * Normalizes a value to an acceptable value for this setting. */ protected String normalizeValue(String value) { Comparable<T> comparableValue; try { comparableValue = convertToComparable(value); } catch (NumberFormatException e) { return DEFAULT_VALUE; } if (MAX_VALUE != null && comparableValue.compareTo(MAX_VALUE) > 0) { return MAX_VALUE.toString(); } else if (MIN_VALUE != null && comparableValue.compareTo(MIN_VALUE) < 0) { return MIN_VALUE.toString(); } return value; } /** Converts a String to a Comparable of the same type as MAX_VALUE and MIN_VALUE. */ abstract protected Comparable<T> convertToComparable(String value); }