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.

BindingValidationStatus.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * Copyright 2000-2016 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;
  17. import java.io.Serializable;
  18. import java.util.Collections;
  19. import java.util.List;
  20. import java.util.Objects;
  21. import java.util.Optional;
  22. import com.vaadin.data.Binder.Binding;
  23. import com.vaadin.data.Binder.BindingBuilder;
  24. /**
  25. * Represents the status of field validation. Status can be {@code Status.OK},
  26. * {@code Status.ERROR} or {@code Status.UNRESOLVED}. Status OK and ERROR are
  27. * always associated with a ValidationResult {@link #getResult}.
  28. * <p>
  29. * Use
  30. * {@link BindingBuilder#withValidationStatusHandler(BindingValidationStatusHandler)}
  31. * to register a handler for field level validation status changes.
  32. *
  33. * @author Vaadin Ltd
  34. *
  35. * @param <TARGET>
  36. * the target data type of the binding for which the validation
  37. * status changed, matches the field type unless a converter has been
  38. * set
  39. *
  40. * @see BindingBuilder#withValidationStatusHandler(BindingValidationStatusHandler)
  41. * @see Binding#validate()
  42. * @see BindingValidationStatusHandler
  43. * @see BinderValidationStatus
  44. *
  45. * @since 8.0
  46. */
  47. public class BindingValidationStatus<TARGET> implements Serializable {
  48. /**
  49. * Status of the validation.
  50. * <p>
  51. * The status is the part of {@link BindingValidationStatus} which indicates
  52. * whether the validation failed or not, or whether it is in unresolved
  53. * state (e.g. after clear or reset).
  54. */
  55. public enum Status {
  56. /** Validation passed. */
  57. OK,
  58. /** Validation failed. */
  59. ERROR,
  60. /**
  61. * Unresolved status, e.g field has not yet been validated because value
  62. * was cleared.
  63. * <p>
  64. * In practice this status means that the value might be invalid, but
  65. * validation errors should be hidden.
  66. */
  67. UNRESOLVED;
  68. }
  69. private final Status status;
  70. private final List<ValidationResult> results;
  71. private final Binding<?, TARGET> binding;
  72. private Result<TARGET> result;
  73. /**
  74. * Convenience method for creating a {@link Status#UNRESOLVED} validation
  75. * status for the given binding.
  76. *
  77. * @param source
  78. * the source binding
  79. * @return unresolved validation status
  80. * @param <TARGET>
  81. * the target data type of the binding for which the validation
  82. * status was reset
  83. */
  84. public static <TARGET> BindingValidationStatus<TARGET> createUnresolvedStatus(
  85. Binding<?, TARGET> source) {
  86. return new BindingValidationStatus<TARGET>(null, source);
  87. }
  88. /**
  89. * Creates a new validation status for the given binding and validation
  90. * result.
  91. *
  92. * @param source
  93. * the source binding
  94. * @param result
  95. * the result of the validation
  96. */
  97. @Deprecated
  98. public BindingValidationStatus(Binding<?, TARGET> source,
  99. ValidationResult result) {
  100. this(source, result.isError() ? Status.ERROR : Status.OK, result);
  101. }
  102. /**
  103. * Creates a new status change event.
  104. * <p>
  105. * The {@code message} must be {@code null} if the {@code status} is
  106. * {@link Status#OK}.
  107. *
  108. * @param source
  109. * field whose status has changed, not {@code null}
  110. * @param status
  111. * updated status value, not {@code null}
  112. * @param result
  113. * the related result, may be {@code null}
  114. */
  115. @Deprecated
  116. public BindingValidationStatus(Binding<?, TARGET> source, Status status,
  117. ValidationResult result) {
  118. this(result.isError() ? Result.error(result.getErrorMessage())
  119. : Result.ok(null), source);
  120. }
  121. /**
  122. * Creates a new status change event.
  123. * <p>
  124. * If {@code result} is {@code null}, the {@code status} is
  125. * {@link Status#UNRESOLVED}.
  126. *
  127. * @param result
  128. * the related result object, may be {@code null}
  129. * @param source
  130. * field whose status has changed, not {@code null}
  131. *
  132. * @since 8.2
  133. */
  134. public BindingValidationStatus(Result<TARGET> result,
  135. Binding<?, TARGET> source) {
  136. Objects.requireNonNull(source, "Event source may not be null");
  137. binding = source;
  138. if (result != null) {
  139. this.status = result.isError() ? Status.ERROR : Status.OK;
  140. if (result instanceof ValidationResultWrap) {
  141. results = ((ValidationResultWrap<TARGET>) result)
  142. .getValidationResults();
  143. } else {
  144. results = Collections.emptyList();
  145. }
  146. } else {
  147. this.status = Status.UNRESOLVED;
  148. results = Collections.emptyList();
  149. }
  150. this.result = result;
  151. }
  152. /**
  153. * Gets status of the validation.
  154. *
  155. * @return status
  156. */
  157. public Status getStatus() {
  158. return status;
  159. }
  160. /**
  161. * Gets whether the validation failed or not.
  162. *
  163. * @return {@code true} if validation failed, {@code false} if validation
  164. * passed
  165. */
  166. public boolean isError() {
  167. return status == Status.ERROR;
  168. }
  169. /**
  170. * Gets error validation message if status is {@link Status#ERROR}.
  171. *
  172. * @return an optional validation error status or an empty optional if
  173. * status is not an error
  174. */
  175. public Optional<String> getMessage() {
  176. if (getStatus() == Status.OK || result == null) {
  177. return Optional.empty();
  178. }
  179. return result.getMessage();
  180. }
  181. /**
  182. * Gets the validation result if status is either {@link Status#OK} or
  183. * {@link Status#ERROR} or an empty optional if status is
  184. * {@link Status#UNRESOLVED}.
  185. *
  186. * @return the validation result
  187. */
  188. public Optional<ValidationResult> getResult() {
  189. if (result == null) {
  190. return Optional.empty();
  191. }
  192. return Optional.of(result.isError()
  193. ? ValidationResult.error(result.getMessage().orElse(""))
  194. : ValidationResult.ok());
  195. }
  196. /**
  197. * Gets all the validation results related to this binding validation
  198. * status.
  199. *
  200. * @return list of validation results
  201. *
  202. * @since 8.2
  203. */
  204. public List<ValidationResult> getValidationResults() {
  205. return Collections.unmodifiableList(results);
  206. }
  207. /**
  208. * Gets the source binding of the validation status.
  209. *
  210. * @return the source binding
  211. */
  212. public Binding<?, TARGET> getBinding() {
  213. return binding;
  214. }
  215. /**
  216. * Gets the bound field for this status.
  217. *
  218. * @return the field
  219. */
  220. public HasValue<?> getField() {
  221. return getBinding().getField();
  222. }
  223. }