You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RangeValidator.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright 2000-2014 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.data.validator;
  17. import java.util.Comparator;
  18. import java.util.Objects;
  19. import com.vaadin.data.Result;
  20. /**
  21. * Verifies that a value is within the given range.
  22. *
  23. * @param <T>
  24. * the type to validate
  25. * @author Vaadin Ltd.
  26. * @since 8.0
  27. */
  28. public class RangeValidator<T> extends AbstractValidator<T> {
  29. private T minValue = null;
  30. private T maxValue = null;
  31. private boolean minValueIncluded = true;
  32. private boolean maxValueIncluded = true;
  33. private Comparator<? super T> comparator;
  34. /**
  35. * Creates a new range validator of the given type. Passing null to either
  36. * {@code minValue} or {@code maxValue} means there is no limit in that
  37. * direction. Both limits may be null; this can be useful if the limits are
  38. * resolved programmatically. The result of passing null to {@code apply}
  39. * depends on the given comparator.
  40. *
  41. * @param errorMessage
  42. * the error message to return if validation fails, not null
  43. * @param comparator
  44. * the comparator to compare with, not null
  45. * @param minValue
  46. * the least value of the accepted range or null for no limit
  47. * @param maxValue
  48. * the greatest value of the accepted range or null for no limit
  49. */
  50. public RangeValidator(String errorMessage, Comparator<? super T> comparator,
  51. T minValue, T maxValue) {
  52. super(errorMessage);
  53. Objects.requireNonNull(comparator, "comparator cannot be null");
  54. this.minValue = minValue;
  55. this.maxValue = maxValue;
  56. this.minValueIncluded = minValue != null;
  57. this.maxValueIncluded = maxValue != null;
  58. this.comparator = comparator;
  59. }
  60. /**
  61. * Returns a {@code RangeValidator} comparing values of a {@code Comparable}
  62. * type using their <i>natural order</i>. Passing null to either
  63. * {@code minValue} or {@code maxValue} means there is no limit in that
  64. * direction. Both limits may be null; this can be useful if the limits are
  65. * resolved programmatically.
  66. * <p>
  67. * Null is considered to be less than any non-null value. This means null
  68. * never passes validation if a minimum value is specified.
  69. *
  70. * @param <C>
  71. * the {@code Comparable} value type
  72. * @param errorMessage
  73. * the error message to return if validation fails, not null
  74. * @param minValue
  75. * the least value of the accepted range or null for no limit
  76. * @param maxValue
  77. * the greatest value of the accepted range or null for no limit
  78. * @return the new validator
  79. */
  80. public static <C extends Comparable<? super C>> RangeValidator<C> of(
  81. String errorMessage, C minValue, C maxValue) {
  82. return new RangeValidator<>(errorMessage,
  83. Comparator.nullsFirst(Comparator.naturalOrder()), minValue,
  84. maxValue);
  85. }
  86. /**
  87. * Returns {@code Result.ok} if the value is within the specified bounds,
  88. * {@code Result.error} otherwise. If null is passed to {@code apply}, the
  89. * behavior depends on the used comparator.
  90. */
  91. @Override
  92. public Result<T> apply(T value) {
  93. return toResult(value, isValid(value));
  94. }
  95. /**
  96. * Returns whether the minimum value is part of the accepted range.
  97. *
  98. * @return true if the minimum value is part of the range, false otherwise
  99. */
  100. public boolean isMinValueIncluded() {
  101. return minValueIncluded;
  102. }
  103. /**
  104. * Sets whether the minimum value is part of the accepted range.
  105. *
  106. * @param minValueIncluded
  107. * true if the minimum value should be part of the range, false
  108. * otherwise
  109. */
  110. public void setMinValueIncluded(boolean minValueIncluded) {
  111. this.minValueIncluded = minValueIncluded;
  112. }
  113. /**
  114. * Returns whether the maximum value is part of the accepted range.
  115. *
  116. * @return true if the maximum value is part of the range, false otherwise
  117. */
  118. public boolean isMaxValueIncluded() {
  119. return maxValueIncluded;
  120. }
  121. /**
  122. * Sets whether the maximum value is part of the accepted range.
  123. *
  124. * @param maxValueIncluded
  125. * true if the maximum value should be part of the range, false
  126. * otherwise
  127. */
  128. public void setMaxValueIncluded(boolean maxValueIncluded) {
  129. this.maxValueIncluded = maxValueIncluded;
  130. }
  131. /**
  132. * Returns the minimum value of the range.
  133. *
  134. * @return the minimum value
  135. */
  136. public T getMinValue() {
  137. return minValue;
  138. }
  139. /**
  140. * Sets the minimum value of the range. Use
  141. * {@link #setMinValueIncluded(boolean)} to control whether this value is
  142. * part of the range or not.
  143. *
  144. * @param minValue
  145. * the minimum value
  146. */
  147. public void setMinValue(T minValue) {
  148. this.minValue = minValue;
  149. }
  150. /**
  151. * Gets the maximum value of the range.
  152. *
  153. * @return the maximum value
  154. */
  155. public T getMaxValue() {
  156. return maxValue;
  157. }
  158. /**
  159. * Sets the maximum value of the range. Use
  160. * {@link #setMaxValueIncluded(boolean)} to control whether this value is
  161. * part of the range or not.
  162. *
  163. * @param maxValue
  164. * the maximum value
  165. */
  166. public void setMaxValue(T maxValue) {
  167. this.maxValue = maxValue;
  168. }
  169. @Override
  170. public String toString() {
  171. T min = getMinValue();
  172. T max = getMaxValue();
  173. return String.format("%s %c%s, %s%c", getClass().getSimpleName(),
  174. isMinValueIncluded() ? '[' : '(', min != null ? min : "-∞",
  175. max != null ? max : "∞", isMaxValueIncluded() ? ']' : ')');
  176. }
  177. /**
  178. * Returns whether the given value lies in the valid range.
  179. *
  180. * @param value
  181. * the value to validate
  182. * @return true if the value is valid, false otherwise
  183. */
  184. protected boolean isValid(T value) {
  185. if (value == null) {
  186. return true;
  187. }
  188. if (getMinValue() != null) {
  189. int result = comparator.compare(value, getMinValue());
  190. if (result < 0) {
  191. return false;
  192. } else if (result == 0 && !isMinValueIncluded()) {
  193. return false;
  194. }
  195. }
  196. if (getMaxValue() != null) {
  197. int result = comparator.compare(value, getMaxValue());
  198. if (result > 0) {
  199. return false;
  200. } else if (result == 0 && !isMaxValueIncluded()) {
  201. return false;
  202. }
  203. }
  204. return true;
  205. }
  206. }