Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: edu/ucsb/ccs/jaqual/standard/InRange.java


1   package edu.ucsb.ccs.jaqual.standard;
2   
3   import edu.ucsb.ccs.jaqual.Assertion;
4   
5   /**
6    * An assertion to determine if a number falls in a given range.  The
7    * assertion supports both integer and floating point comparison.  You
8    * can specify whether or not the bounding values are included or
9    * excluded from the range.
10   *
11   * @author Parker Abercrombie
12   * @version $Id: InRange.java,v 1.3 2002/07/13 09:08:10 parkera Exp $
13   */
14  
15  public class InRange implements Assertion {
16  
17    /**
18     * Constant to indicate the bound is inclusive.  The bounding value
19     * is included in the range.
20     */
21    public static final int INCLUSIVE = 0;
22  
23    /**
24     * Constant to indicate the bound is exclusive.  The bounding value
25     * is not included in the range.
26     */
27    public static final int EXCLUSIVE = 1;
28  
29    /**
30     * Constant to indicate the comparison is performed using only
31     * integer values.  Floating point values will be rounded.
32     */
33    protected static final int INTEGER_COMPARISON = 0;
34  
35    /**
36     * Constant to indicate the comparison is performed using floating
37     * point values and a tolerance.
38     */
39    protected static final int FLOAT_COMPARISON = 1;
40  
41    /**
42     * The comparison mode to use for the lower bound, either INCLUSIVE
43     * or EXCLUSIVE.
44     */
45    protected int lowerMode;
46  
47    /**
48     * The comparison mode to use for the upper bound, either INCLUSIVE
49     * or EXCLUSIVE.
50     */
51    protected int upperMode;
52  
53    /**
54     * Maximum bound for integer comparison.
55     */
56    protected long intMin;
57  
58    /**
59     * Minimum bound for integer comparison.
60     */
61    protected long intMax;
62  
63    /**
64     * Minimum bound for floating point comparison.
65     */
66    protected double realMin;
67  
68    /**
69     * Maximum bound for floating point comparison.
70     */
71    protected double realMax;
72  
73    /**
74     * The tolerance to use when comparing floating point numbers.
75     */
76    protected double tolerance;
77  
78    /**
79     * The comparison type, either INTEGER_COMPARISON or
80     * FLOAT_COMPARISON.
81     */
82    protected int comparisonType;
83  
84    /**
85     * Create an assertion to test that a value falls in the interval
86     * [minVal, maxVal].  The bounds are inclusive, and the values are
87     * integers.
88     *
89     * @param minVal the lower bound.
90     * @param maxVal the upper bound.
91     */
92    public InRange (long minVal, long maxVal) {
93      this(minVal, maxVal, INCLUSIVE, INCLUSIVE);
94    }
95  
96    /**
97     * Create an assertion to test that a value falls between `minVal'
98     * and `maxVal'.  The values are integers.
99     *
100    * @param minVal the lower bound.
101    * @param maxVal the upper bound.
102    * @param mode the comparison mode to use for both bounds, either
103    *             INCLUSIVE or EXCLUSIVE.
104    */
105   public InRange (long minVal, long maxVal, int mode) {
106     this(minVal, maxVal, mode, mode);
107   }
108 
109   /**
110    * Create an assertion to test that a value falls between `minVal'
111    * and `maxVal'.  The values are integers.
112    *
113    * @param minVal the lower bound.
114    * @param maxVal the upper bound.
115    * @param lowerMode the comparison mode to use for the lower bound, either
116    *                  INCLUSIVE or EXCLUSIVE.
117    * @param upperMode the comparison mode to use for the upper bound, either
118    *                  INCLUSIVE or EXCLUSIVE.
119    */
120   public InRange (long minVal, long maxVal, int lowerMode, int upperMode) {
121     comparisonType = INTEGER_COMPARISON;
122     intMin = minVal;
123     intMax = maxVal;
124     this.lowerMode = lowerMode;
125     this.upperMode = upperMode;
126   }
127 
128   /**
129    * Create an assertion to test that a value falls in the interval
130    * [minVal, maxVal].  The bounds are inclusive, and the values are
131    * floating point.
132    *
133    * @param minVal the lower bound.
134    * @param maxVal the upper bound.
135    * @param tolerance the tolerance to use in the floating point
136    *                  comparison.
137    */
138   public InRange (double minVal, double maxVal, double tolerance) {
139     this(minVal, maxVal, tolerance, INCLUSIVE, INCLUSIVE);
140   }
141 
142   /**
143    * Create an assertion to test that a value falls in the interval
144    * [minVal, maxVal].  The values are floating point.
145    *
146    * @param minVal the lower bound.
147    * @param maxVal the upper bound.
148    * @param tolerance the tolerance to use in the floating point
149    *                  comparison.
150    * @param mode the comparison mode to use for both bounds, either
151    *             INCLUSIVE or EXCLUSIVE.
152    */
153   public InRange (double minVal, double maxVal, double tolerance, int mode) {
154     this(minVal, maxVal, tolerance, mode, mode);
155   }
156 
157   /**
158    * Create an assertion to test that a value falls in the interval
159    * [minVal, maxVal].  The values are floating point.
160    *
161    * @param minVal the lower bound.
162    * @param maxVal the upper bound.
163    * @param tolerance the tolerance to use in the floating point
164    *                  comparison.
165    * @param lowerMode the comparison mode to use for the lower bound, either
166    *                  INCLUSIVE or EXCLUSIVE.
167    * @param upperMode the comparison mode to use for the upper bound, either
168    *                  INCLUSIVE or EXCLUSIVE.
169    */
170   public InRange (double minVal, double maxVal, double tolerance,
171                   int lowerMode, int upperMode) { 
172     comparisonType = FLOAT_COMPARISON;
173     realMin = minVal;
174     realMax = maxVal;
175     this.lowerMode = lowerMode;
176     this.upperMode = upperMode;
177     this.tolerance = tolerance;
178   }
179 
180   /**
181    * Determine if a value is in the allowed range.  If the comparison
182    * type is FLOAT_COMPARISON, the comparison is performed using a
183    * tolerance.
184    *
185    * @param o the value to examine.  This must be an instance of
186    *          java.lang.Number.
187    *
188    * @exception IllegalArgumentException if `o' is not an instance of
189    *            java.lang.Number.
190    */
191   public boolean eval (Object o) throws IllegalArgumentException {
192     if (o instanceof Number) {
193       if (comparisonType == INTEGER_COMPARISON) {
194         long val = ((Number) o).longValue();
195         if ((lowerMode == INCLUSIVE) && (upperMode == INCLUSIVE)) {
196           return (val >= intMin) && (val <= intMax);
197         } else if ((lowerMode == INCLUSIVE) && (upperMode == EXCLUSIVE)) {
198           return (val >= intMin) && (val < intMax);
199         } else if ((lowerMode == EXCLUSIVE) && (upperMode == INCLUSIVE)) {
200           return (val > intMin) && (val <= intMax);
201         } else {
202 //            assert((lowerMode == EXCLUSIVE) && (upperMode == EXCLUSIVE));
203           return (val > intMin) && (val < intMax);
204         }
205       } else {
206 //          assert(comparisonType == FLOAT_COMPARISON);
207         double val = ((Number) o).doubleValue();
208 
209         if ((lowerMode == INCLUSIVE) && (upperMode == INCLUSIVE)) {
210           return (compare(val, realMin) >= 0) && (compare(val, realMax) <= 0);
211         } else if ((lowerMode == INCLUSIVE) && (upperMode == EXCLUSIVE)) {
212           return (compare(val, realMin) >= 0) && (compare(val, realMax) < 0);
213         } else if ((lowerMode == EXCLUSIVE) && (upperMode == INCLUSIVE)) {
214           return (compare(val, realMin) > 0) && (compare(val, realMax) <= 0);
215         } else {
216 //            assert((lowerMode == EXCLUSIVE) && (upperMode == EXCLUSIVE));
217           return (compare(val, realMin) > 0) && (compare(val, realMax) < 0);
218         }
219       }
220     } else {
221       throw new IllegalArgumentException("Object is not an instance of java.lang.Number");
222     }
223   }
224 
225   /**
226    * Compare two floating point numbers.
227    *
228    * @return  0 if the numbers are equal (within a tolerance defined
229    *            by `tolerance').<br>
230    *          1 if `val1' > `val2'.<br>
231    *         -1 if `val1' < `val'.
232    */
233   protected int compare (double val1, double val2) {
234     double diff = Math.abs(val1 - val2);
235     if (diff <= tolerance) {
236       return 0;
237     } else if (val1 > val2) {
238       return 1;
239     } else {
240       return -1;
241     }
242   }
243 
244   protected boolean _Invariant () {
245     return ((comparisonType == INTEGER_COMPARISON)
246             || (comparisonType == FLOAT_COMPARISON))
247       && ((lowerMode == INCLUSIVE) || (lowerMode == EXCLUSIVE))
248       && ((upperMode == INCLUSIVE) || (upperMode == EXCLUSIVE));
249   }
250 }