/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.wicket.validation.validator; import java.io.Serializable; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.IValidationError; import org.apache.wicket.validation.IValidator; import org.apache.wicket.validation.ValidationError; /** * Base class for validators that check if a given value falls within [min,max] range. * * If either min or max are {@code null} they are not checked. * * <p> * Resource keys: * <ul> * <li>{@code <class.simpleName>.exact} if min==max</li> * <li>{@code <class.simpleName>.range} if both min and max are not {@code null}</li> * <li>{@code <class.simpleName>.minimum} if max is {@code null}</li> * <li>{@code <class.simpleName>.maximum} if min is {@code null}</li> * </ul> * </p> * * <p> * Error Message Variables: * <ul> * <li>{@code name}: the id of {@code Component} that failed</li> * <li>{@code label}: the label of the {@code Component} (either comes from * {@code FormComponent.labelModel} or resource key {@code <form-id>.<form-component-id>}</li> * <li>{@code input}: the input value</li> * <li>{@code minimum}: the minimum allowed value</li> * <li>{@code maximum}: the maximum allowed value</li> * </ul> * </p> * * @param <R> * type of range value * @param <V> * type of validatable * * @author igor */ public abstract class AbstractRangeValidator<R extends Comparable<? super R> & Serializable, V extends Serializable> extends Behavior implements IValidator<V> { private static final long serialVersionUID = 1L; private R minimum; private R maximum; /** * Constructor that sets the minimum and maximum values. * * @param minimum * the minimum value * @param maximum * the maximum value */ public AbstractRangeValidator(R minimum, R maximum) { setRange(minimum, maximum); } /** * Constructor used for subclasses who want to set the range using * {@link #setRange(Comparable, Comparable)} */ protected AbstractRangeValidator() { } /** * Sets validator range * * @param minimum * @param maximum */ protected final void setRange(R minimum, R maximum) { if (minimum == null && maximum == null) { throw new IllegalArgumentException("Both minimum and maximum values cannot be null"); } this.minimum = minimum; this.maximum = maximum; } @Override public void validate(IValidatable<V> validatable) { R value = getValue(validatable); final R min = getMinimum(); final R max = getMaximum(); if ((min != null && value.compareTo(min) < 0) || (max != null && value.compareTo(max) > 0)) { Mode mode = getMode(); ValidationError error = new ValidationError(this, mode.getVariation()); if (min != null) { error.setVariable("minimum", min); } if (max != null) { error.setVariable("maximum", max); } if (mode == Mode.EXACT) { error.setVariable("exact", max); } validatable.error(decorate(error, validatable)); } } /** * Gets the value that should be validated against the range * * @param validatable * @return value to validate */ protected abstract R getValue(IValidatable<V> validatable); /** * Gets the minimum value. * * @return minimum value */ public R getMinimum() { return minimum; } /** * Gets the maximum value. * * @return maximum value */ public R getMaximum() { return maximum; } /** * Allows subclasses to decorate reported errors * * @param error * @param validatable * @return decorated error */ protected IValidationError decorate(IValidationError error, IValidatable<V> validatable) { return error; } /** * Gets validation mode which is determined by whether min, max, or both values are provided * * @return validation mode */ public final Mode getMode() { final R min = getMinimum(); final R max = getMaximum(); if (min == null && max != null) { return Mode.MAXIMUM; } else if (max == null && min != null) { return Mode.MINIMUM; } else if ((min == null && max == null) || max.equals(min)) { return Mode.EXACT; } else { return Mode.RANGE; } } /** * Validator mode * * @author igor */ public static enum Mode { MINIMUM, MAXIMUM, RANGE, EXACT; public String getVariation() { return name().toLowerCase(); } } }