package org.jscsi.target.settings; import java.util.regex.Matcher; /** * This is a {@link NumericalValue} sub-class for representing integer * intervals. Each {@link NumericalValueRange} is defined by two integers - {@link #min} and {@link #max} - * the lower and the upper bound of the * represented interval. * * @author Andreas Ergenzinger */ public final class NumericalValueRange extends NumericalValue { /** * The lower boundary of the represented interval. */ private final int min; /** * The upper boundary of the represented interval. */ private final int max; /** * The build method for creating {@link NumericalValueRange} objects. The * specified <i>min</i> and <i>max</i> parameters are going to be used for * initializing the {@link #min} and {@link #max} variables of the new {@link NumericalValueRange}. Since * this only makes sense if <i>min</i> * ≤ <i>max</i>, <code>null</code> will be returned if this requirement * is violated. * * @param min * the lower bound * @param max * the upper bound * @return a {@link NumericalValueRange} representing the specified interval * or <code>null</code> */ public static final NumericalValueRange create(final int min, final int max) { if (min > max) return null; return new NumericalValueRange(min, max); } /** * Parses a {@link NumericalValueRange} from a {@link String}. The lower and * boundaries must be separated by a '~' character and the the leading * integer must not be larger than the trailing one. If these format * requirements are violated the method will return <code>null</code>. * * @param value * the {@link String} to parse * @return a {@link NumericalValueRange} representing the interval in the * parsed {@link String} or <code>null</code> */ public static final NumericalValueRange parseNumericalValueRange(final String value) { // check formatting final Matcher rangeMatcher = NUMERICAL_RANGE_PATTERN.matcher(value); if (!rangeMatcher.matches()) { return null; } int min, max; // split parameter at '~' sign and parse boundaries individually String[] numbers = value.split("~"); final SingleNumericalValue minVal = SingleNumericalValue.parseSingleNumericValue(numbers[0]); final SingleNumericalValue maxVal = SingleNumericalValue.parseSingleNumericValue(numbers[1]); if (minVal == null || maxVal == null) return null;// not possible, format checked by rangeMatcher min = minVal.getValue(); max = maxVal.getValue(); // return with sanity check, enforce min <= max return create(min, max); } /** * The private constructor for {@link NumericalValueRange} objects. * <p> * This method has a limited visibility to make sure that {@link #min} ≤ {@link #max} is always true, * by forcing users to rely on {@link #create(int, int)}. * * @param min * the lower boundary of the specified interval * @param max * the upper boundary of the specified interval */ private NumericalValueRange(final int min, final int max) { if (min <= max) { this.min = min; this.max = max; } else { this.min = max; this.max = min; } } /** * Returns the lower boundary. * * @return the lower boundary */ public final int getMin() { return min; } /** * Returns the upper boundary. * * @return the upper boundary */ public final int getMax() { return max; } @Override public final String toString() { return "[" + min + "," + max + "]"; } @Override public boolean contains(final Object value) { if (value instanceof NumericalValue) return contains((NumericalValue)value); if (value instanceof Integer) return contains((int)((Integer)value)); return false; } /** * Returns true if the passed {@link NumericalValue} lies completely inside * the interval represented by this {@link NumericalValueRange}. * * @param value * the {@link NumericalValue} to check * @return <code>true</code> if the value is complete contained, <code>false</code> if it is not */ public boolean contains(final NumericalValue value) { if (value instanceof SingleNumericalValue) return contains((SingleNumericalValue)value); if (value instanceof NumericalValueRange) return contains((NumericalValueRange)value); return false; } /** * Returns true if the passed {@link NumericalValueRange} lies completely * inside the interval represented by this {@link NumericalValueRange}. * * @param range * the {@link NumericalValueRange} to check * @return <code>true</code> if the value is complete contained, <code>false</code> if it is not */ public boolean contains(final NumericalValueRange range) { if (range == null) return false; if (min <= range.getMin() && range.getMax() <= max) return true; return false; } /** * Returns true if the passed {@link SingleNumericalValue} lies completely * inside the interval represented by this {@link NumericalValueRange}. * * @param value * the {@link SingleNumericalValue} to check * @return <code>true</code> if the value is complete contained, <code>false</code> if it is not */ public boolean contains(final SingleNumericalValue value) { if (value == null) return false; return contains(value.getValue()); } @Override public boolean contains(final int value) { if (min <= value && value <= max) return true; return false; } }