AbstractNumericProperty.java
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 }