001 package net.sourceforge.pmd.lang.rule.properties;
002
003 import java.util.Map;
004
005 import net.sourceforge.pmd.NumericPropertyDescriptor;
006
007 /**
008 * Maintains a pair of boundary limit values between which all values managed
009 * by the subclasses must fit.
010 *
011 * @author Brian Remedios
012 */
013 public abstract class AbstractNumericProperty<T> extends AbstractScalarProperty<T> implements NumericPropertyDescriptor<T> {
014
015 private Number lowerLimit;
016 private Number upperLimit;
017
018 /**
019 *
020 * @param theName
021 * @param theDescription
022 * @param lower
023 * @param upper
024 * @param theDefault
025 * @param theUIOrder
026 * @throws IllegalArgumentException
027 */
028 protected AbstractNumericProperty(String theName, String theDescription, Number lower, Number upper, T theDefault, float theUIOrder) {
029 super(theName, theDescription, theDefault, theUIOrder);
030
031 if (lower.doubleValue() > upper.doubleValue()) {
032 throw new IllegalArgumentException("Lower limit cannot be greater than the upper limit");
033 }
034
035 lowerLimit = lower;
036 upperLimit = upper;
037 }
038
039 /**
040 * Returns the minimum value that instances of the property can have
041 * @return The minimum value.
042 * @see net.sourceforge.pmd.NumericPropertyDescriptor#lowerLimit()
043 */
044 public Number lowerLimit() {
045 return lowerLimit;
046 }
047
048 /**
049 * @return String
050 */
051 protected String defaultAsString() {
052 return defaultValue().toString();
053 }
054
055 /**
056 * Returns the maximum value that instances of the property can have
057 * @return The maximum value.
058 * @see net.sourceforge.pmd.NumericPropertyDescriptor#upperLimit()
059 */
060 public Number upperLimit() {
061 return upperLimit;
062 }
063
064 /**
065 * @return String
066 */
067 public String rangeString() {
068 StringBuilder sb = new StringBuilder();
069 sb.append('(').append(lowerLimit);
070 sb.append(" -> ").append(upperLimit);
071 sb.append(')');
072 return sb.toString();
073 }
074
075 /**
076 * Returns a string describing any error the value may have when
077 * characterized by the receiver.
078 *
079 * @param value Object
080 * @return String
081 */
082 protected String valueErrorFor(Object value) {
083
084 double number = ((Number)value).doubleValue();
085
086 if (number > upperLimit.doubleValue() || number < lowerLimit.doubleValue() ) {
087 return value + " is out of range " + rangeString();
088 }
089
090 return null;
091 }
092
093 /**
094 * Method addAttributesTo.
095 * @param attributes Map<String,String>
096 */
097 protected void addAttributesTo(Map<String, String> attributes) {
098 super.addAttributesTo(attributes);
099
100 attributes.put("min", lowerLimit.toString());
101 attributes.put("max", upperLimit.toString());
102 }
103 }
|