1 package org.jscsi.target.settings; 2 3 4 import java.util.regex.Matcher; 5 6 7 /** 8 * This is a {@link NumericalValue} sub-class for representing integer intervals. Each {@link NumericalValueRange} is 9 * defined by two integers - {@link #min} and {@link #max} - the lower and the upper bound of the represented interval. 10 * 11 * @author Andreas Ergenzinger 12 */ 13 public final class NumericalValueRange extends NumericalValue { 14 15 /** 16 * The lower boundary of the represented interval. 17 */ 18 private final int min; 19 20 /** 21 * The upper boundary of the represented interval. 22 */ 23 private final int max; 24 25 /** 26 * The build method for creating {@link NumericalValueRange} objects. The specified <i>min</i> and <i>max</i> 27 * parameters are going to be used for initializing the {@link #min} and {@link #max} variables of the new 28 * {@link NumericalValueRange}. Since this only makes sense if <i>min</i> ≤ <i>max</i>, <code>null</code> will be 29 * returned if this requirement is violated. 30 * 31 * @param min the lower bound 32 * @param max the upper bound 33 * @return a {@link NumericalValueRange} representing the specified interval or <code>null</code> 34 */ 35 public static final NumericalValueRange create (final int min, final int max) { 36 if (min > max) return null; 37 return new NumericalValueRange(min, max); 38 } 39 40 /** 41 * Parses a {@link NumericalValueRange} from a {@link String}. The lower and boundaries must be separated by a '~' 42 * character and the the leading integer must not be larger than the trailing one. If these format requirements are 43 * violated the method will return <code>null</code>. 44 * 45 * @param value the {@link String} to parse 46 * @return a {@link NumericalValueRange} representing the interval in the parsed {@link String} or <code>null</code> 47 */ 48 public static final NumericalValueRange parseNumericalValueRange (final String value) { 49 // check formatting 50 final Matcher rangeMatcher = NUMERICAL_RANGE_PATTERN.matcher(value); 51 if (!rangeMatcher.matches()) { return null; } 52 int min, max; 53 54 // split parameter at '~' sign and parse boundaries individually 55 String[] numbers = value.split("~"); 56 final SingleNumericalValue minVal = SingleNumericalValue.parseSingleNumericValue(numbers[0]); 57 final SingleNumericalValue maxVal = SingleNumericalValue.parseSingleNumericValue(numbers[1]); 58 if (minVal == null || maxVal == null) return null;// not possible, format checked by rangeMatcher 59 min = minVal.getValue(); 60 max = maxVal.getValue(); 61 62 // return with sanity check, enforce min <= max 63 return create(min, max); 64 } 65 66 /** 67 * The private constructor for {@link NumericalValueRange} objects. 68 * <p> 69 * This method has a limited visibility to make sure that {@link #min} ≤ {@link #max} is always true, by forcing 70 * users to rely on {@link #create(int, int)}. 71 * 72 * @param min the lower boundary of the specified interval 73 * @param max the upper boundary of the specified interval 74 */ 75 private NumericalValueRange (final int min, final int max) { 76 if (min <= max) { 77 this.min = min; 78 this.max = max; 79 } else { 80 this.min = max; 81 this.max = min; 82 } 83 } 84 85 /** 86 * Returns the lower boundary. 87 * 88 * @return the lower boundary 89 */ 90 public final int getMin () { 91 return min; 92 } 93 94 /** 95 * Returns the upper boundary. 96 * 97 * @return the upper boundary 98 */ 99 public final int getMax () { 100 return max; 101 } 102 103 @Override 104 public final String toString () { 105 return "[" + min + "," + max + "]"; 106 } 107 108 @Override 109 public boolean contains (final Object value) { 110 if (value instanceof NumericalValue) return contains((NumericalValue) value); 111 if (value instanceof Integer) return contains((int) ((Integer) value)); 112 return false; 113 } 114 115 /** 116 * Returns true if the passed {@link NumericalValue} lies completely inside the interval represented by this 117 * {@link NumericalValueRange}. 118 * 119 * @param value the {@link NumericalValue} to check 120 * @return <code>true</code> if the value is complete contained, <code>false</code> if it is not 121 */ 122 public boolean contains (final NumericalValue value) { 123 if (value instanceof SingleNumericalValue) return contains((SingleNumericalValue) value); 124 if (value instanceof NumericalValueRange) return contains((NumericalValueRange) value); 125 return false; 126 } 127 128 /** 129 * Returns true if the passed {@link NumericalValueRange} lies completely inside the interval represented by this 130 * {@link NumericalValueRange}. 131 * 132 * @param range the {@link NumericalValueRange} to check 133 * @return <code>true</code> if the value is complete contained, <code>false</code> if it is not 134 */ 135 public boolean contains (final NumericalValueRange range) { 136 if (range == null) return false; 137 if (min <= range.getMin() && range.getMax() <= max) return true; 138 return false; 139 } 140 141 /** 142 * Returns true if the passed {@link SingleNumericalValue} lies completely inside the interval represented by this 143 * {@link NumericalValueRange}. 144 * 145 * @param value the {@link SingleNumericalValue} to check 146 * @return <code>true</code> if the value is complete contained, <code>false</code> if it is not 147 */ 148 public boolean contains (final SingleNumericalValue value) { 149 if (value == null) return false; 150 return contains(value.getValue()); 151 } 152 153 @Override 154 public boolean contains (final int value) { 155 if (min <= value && value <= max) return true; 156 return false; 157 } 158 }