Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

Validator.java 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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.tokka.data;
  17. import java.io.Serializable;
  18. import java.util.Objects;
  19. import java.util.function.Function;
  20. import java.util.function.Predicate;
  21. import com.vaadin.tokka.data.util.Result;
  22. /**
  23. * A functional interface for validating user input or other potentially invalid
  24. * data. When a validator instance is applied to a value of the corresponding
  25. * type, it returns a <i>result</i> signifying that the value either passed or
  26. * failed the validation.
  27. * <p>
  28. * For instance, the following validator checks if a number is positive:
  29. * </p>
  30. *
  31. * <pre>
  32. * Validator&lt;Integer&gt; v = num -> {
  33. * if (num >= 0)
  34. * return Result.ok(num);
  35. * else
  36. * return Result.error("number must be positive");
  37. * };
  38. * </pre>
  39. *
  40. * @author Vaadin Ltd.
  41. *
  42. * @param <T>
  43. * the type of the value to validate
  44. *
  45. * @see Result
  46. *
  47. * @since
  48. */
  49. @FunctionalInterface
  50. public interface Validator<T> extends Function<T, Result<T>>, Serializable {
  51. /**
  52. * Returns a validator that passes any value.
  53. *
  54. * @param <T>
  55. * the value type
  56. * @return an always-passing validator
  57. */
  58. public static <T> Validator<T> alwaysPass() {
  59. return v -> Result.ok(v);
  60. }
  61. /**
  62. * Returns a validator that chains this validator with the given function.
  63. * Specifically, the function may be another validator. The resulting
  64. * validator first applies this validator, and if the value passes, then the
  65. * given validator.
  66. * <p>
  67. * For instance, the following chained validator checks if a number is
  68. * between 0 and 10, inclusive:
  69. * </p>
  70. * <pre>
  71. * Validator&lt;Integer&gt; v = Validator
  72. * .from(num -> num >= 0, "number must be >= 0")
  73. * .chain(Validator.from(num -> num <= 10, "number must be <= 10"));
  74. * </pre>
  75. *
  76. * @param next
  77. * the validator to apply next, not null
  78. * @return a chained validator
  79. *
  80. * @see #from(Predicate, String)
  81. */
  82. public default Validator<T> chain(Function<T, Result<T>> next) {
  83. Objects.requireNonNull(next, "next cannot be null");
  84. return val -> apply(val).flatMap(next);
  85. }
  86. /**
  87. * Validates the given value. Returns a {@code Result} instance representing
  88. * the outcome of the validation: either {@link Result#ok(Object) Result.ok}
  89. * if the value passed validation or {@link Result#error(String)
  90. * Result.error} otherwise.
  91. *
  92. * @param value
  93. * the input value to validate
  94. * @return the validation result
  95. */
  96. @Override
  97. public Result<T> apply(T value);
  98. /**
  99. * Builds a validator out of a conditional function and an error message. If
  100. * the function returns true, the validator returns {@code Result.ok()}; if
  101. * it returns false or throws an exception, {@code Result.error()} is
  102. * returned with the given message.
  103. * <p>
  104. * For instance, the following validator checks if a number is between 0 and
  105. * 10, inclusive:
  106. * </p>
  107. * <pre>
  108. * Validator&lt;Integer&gt; v = Validator.from(
  109. * num -> num >= 0 && num <= 10,
  110. * "number must be between 0 and 10");
  111. * </pre>
  112. *
  113. * @param <T>
  114. * the value type
  115. * @param guard
  116. * the function used to validate, not null
  117. * @param errorMessage
  118. * the message returned if validation fails, not null
  119. * @return the new validator using the function
  120. */
  121. public static <T> Validator<T> from(Predicate<T> guard,
  122. String errorMessage) {
  123. Objects.requireNonNull(guard, "guard cannot be null");
  124. Objects.requireNonNull(errorMessage, "errorMessage cannot be null");
  125. return value -> {
  126. if (guard.test(value)) {
  127. return Result.ok(value);
  128. } else {
  129. return Result.error(errorMessage);
  130. }
  131. };
  132. }
  133. }