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.

Converter.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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.function.Function;
  19. import com.vaadin.data.Binder.BindingBuilder;
  20. import com.vaadin.server.SerializableFunction;
  21. /**
  22. * Interface that implements conversion between a model and a presentation type.
  23. * <p>
  24. * Converters must not have any side effects (never update UI from inside a
  25. * converter).
  26. *
  27. * @param <PRESENTATION>
  28. * The presentation type.
  29. * @param <MODEL>
  30. * The model type.
  31. * @author Vaadin Ltd.
  32. * @since 8.0
  33. */
  34. public interface Converter<PRESENTATION, MODEL> extends Serializable {
  35. /**
  36. * Converts the given value from model type to presentation type.
  37. * <p>
  38. * A converter can optionally use locale to do the conversion.
  39. *
  40. * @param value
  41. * The value to convert. Can be null
  42. * @param context
  43. * The value context for the conversion.
  44. * @return The converted value compatible with the source type
  45. */
  46. public Result<MODEL> convertToModel(PRESENTATION value,
  47. ValueContext context);
  48. /**
  49. * Converts the given value from presentation type to model type.
  50. * <p>
  51. * A converter can optionally use locale to do the conversion.
  52. *
  53. * @param value
  54. * The value to convert. Can be null
  55. * @param context
  56. * The value context for the conversion.
  57. * @return The converted value compatible with the source type
  58. */
  59. public PRESENTATION convertToPresentation(MODEL value,
  60. ValueContext context);
  61. /**
  62. * Returns a converter that returns its input as-is in both directions.
  63. *
  64. * @param <T>
  65. * the input and output type
  66. * @return an identity converter
  67. */
  68. public static <T> Converter<T, T> identity() {
  69. return from(t -> Result.ok(t), t -> t);
  70. }
  71. /**
  72. * Constructs a converter from two functions. Any {@code Exception}
  73. * instances thrown from the {@code toModel} function are converted into
  74. * error-bearing {@code Result} objects using the given {@code onError}
  75. * function.
  76. *
  77. * @param <P>
  78. * the presentation type
  79. * @param <M>
  80. * the model type
  81. * @param toModel
  82. * the function to convert to model
  83. * @param toPresentation
  84. * the function to convert to presentation
  85. * @param onError
  86. * the function to provide error messages
  87. * @return the new converter
  88. *
  89. * @see Result
  90. * @see Function
  91. */
  92. public static <P, M> Converter<P, M> from(
  93. SerializableFunction<P, M> toModel,
  94. SerializableFunction<M, P> toPresentation,
  95. SerializableFunction<Exception, String> onError) {
  96. return from(val -> Result.of(() -> toModel.apply(val), onError),
  97. toPresentation);
  98. }
  99. /**
  100. * Constructs a converter from a filter and a function.
  101. *
  102. * @param <P>
  103. * the presentation type
  104. * @param <M>
  105. * the model type
  106. * @param toModel
  107. * the function to convert to model
  108. * @param toPresentation
  109. * the function to convert to presentation
  110. * @return the new converter
  111. *
  112. * @see Function
  113. */
  114. public static <P, M> Converter<P, M> from(
  115. SerializableFunction<P, Result<M>> toModel,
  116. SerializableFunction<M, P> toPresentation) {
  117. return new Converter<P, M>() {
  118. @Override
  119. public Result<M> convertToModel(P value, ValueContext context) {
  120. return toModel.apply(value);
  121. }
  122. @Override
  123. public P convertToPresentation(M value, ValueContext context) {
  124. return toPresentation.apply(value);
  125. }
  126. };
  127. }
  128. /**
  129. * Returns a converter that chains together this converter with the given
  130. * type-compatible converter.
  131. * <p>
  132. * The chained converters will form a new converter capable of converting
  133. * from the presentation type of this converter to the model type of the
  134. * other converter.
  135. * <p>
  136. * In most typical cases you should not need this method but instead only
  137. * need to define one converter for a binding using
  138. * {@link BindingBuilder#withConverter(Converter)}.
  139. *
  140. * @param <T>
  141. * the model type of the resulting converter
  142. * @param other
  143. * the converter to chain, not null
  144. * @return a chained converter
  145. */
  146. public default <T> Converter<PRESENTATION, T> chain(
  147. Converter<MODEL, T> other) {
  148. return new Converter<PRESENTATION, T>() {
  149. @Override
  150. public Result<T> convertToModel(PRESENTATION value,
  151. ValueContext context) {
  152. Result<MODEL> model = Converter.this.convertToModel(value,
  153. context);
  154. return model.flatMap(v -> other.convertToModel(v, context));
  155. }
  156. @Override
  157. public PRESENTATION convertToPresentation(T value,
  158. ValueContext context) {
  159. MODEL model = other.convertToPresentation(value, context);
  160. return Converter.this.convertToPresentation(model, context);
  161. }
  162. };
  163. }
  164. }