package fr.openwide.core.wicket.more.model; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import com.google.common.collect.Range; import fr.openwide.core.wicket.more.util.model.Detachables; /** * A range model representing an interval between two values. */ public class RangeModel<C extends Comparable<?>> extends AbstractReadOnlyModel<Range<C>> { private static final long serialVersionUID = 2798667461907515108L; /** * <p>Returns a point, represented by a closed range model in which the lower and the upper bounds are equal. */ public static <C extends Comparable<?>> RangeModel<C> singleton(IModel<? extends C> pointModel) { return new RangeModel<C>(pointModel, pointModel); } /** * <p>Returns a closed range model bounded by the values contained in the given * {@code lowerBoundModel} and {@code upperBoundModel}. * * @throws IllegalArgumentException * if the value of {@code lowerBoundModel} is greater than the value of {@code upperBoundModel} */ public static <C extends Comparable<?>> RangeModel<C> closed(IModel<? extends C> lowerBoundModel, IModel<? extends C> upperBoundModel) { return new RangeModel<C>(lowerBoundModel, upperBoundModel); } /** * <p>Returns a right-closed left-unbounded range model bounded by the value contained in the given * {@code upperBoundModel}. */ public static <C extends Comparable<?>> RangeModel<C> atMost(IModel<? extends C> upperBoundModel) { return new RangeModel<C>(null, upperBoundModel); } /** * <p>Returns a left-closed right-unbounded range model bounded by the value contained in the given * {@code lowerBoundModel}. */ public static <C extends Comparable<?>> RangeModel<C> atLeast(IModel<? extends C> lowerBoundModel) { return new RangeModel<C>(lowerBoundModel, null); } private final IModel<? extends C> lowerBoundModel; private final IModel<? extends C> upperBoundModel; /** * Constructs a closed range model from a lower and an upper bound. * * @param lowerBoundModel * the lower bound of this range, or null for negative infinity * @param upperBoundModel * the upper bound of this range, or null for positive infinity */ private RangeModel(IModel<? extends C> lowerBoundModel, IModel<? extends C> upperBoundModel) { super(); this.lowerBoundModel = lowerBoundModel; this.upperBoundModel = upperBoundModel; } @Override public Range<C> getObject() { if ((lowerBoundModel == null || lowerBoundModel.getObject() == null) && (upperBoundModel == null || upperBoundModel.getObject() == null)) { return null; } else if (lowerBoundModel == null || lowerBoundModel.getObject() == null) { return Range.<C>atMost(upperBoundModel.getObject()); } else if (upperBoundModel == null || upperBoundModel.getObject() == null) { return Range.<C>atLeast(lowerBoundModel.getObject()); } else { return Range.<C>closed(lowerBoundModel.getObject(), upperBoundModel.getObject()); } } @Override public void detach() { super.detach(); Detachables.detach(lowerBoundModel, upperBoundModel); } }