選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

RangeValidator.java 7.2KB

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