/* * Copyright 2000-2016 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.vaadin.data; import java.io.Serializable; import java.util.function.Function; import com.vaadin.data.Binder.BindingBuilder; import com.vaadin.server.SerializableFunction; /** * Interface that implements conversion between a model and a presentation type. *

* Converters must not have any side effects (never update UI from inside a * converter). * * @param * The presentation type. * @param * The model type. * @author Vaadin Ltd. * @since 8.0 */ public interface Converter extends Serializable { /** * Converts the given value from model type to presentation type. *

* A converter can optionally use locale to do the conversion. * * @param value * The value to convert. Can be null * @param context * The value context for the conversion. * @return The converted value compatible with the source type */ public Result convertToModel(PRESENTATION value, ValueContext context); /** * Converts the given value from presentation type to model type. *

* A converter can optionally use locale to do the conversion. * * @param value * The value to convert. Can be null * @param context * The value context for the conversion. * @return The converted value compatible with the source type */ public PRESENTATION convertToPresentation(MODEL value, ValueContext context); /** * Returns a converter that returns its input as-is in both directions. * * @param * the input and output type * @return an identity converter */ public static Converter identity() { return from(t -> Result.ok(t), t -> t); } /** * Constructs a converter from two functions. Any {@code Exception} * instances thrown from the {@code toModel} function are converted into * error-bearing {@code Result} objects using the given {@code onError} * function. * * @param

* the presentation type * @param * the model type * @param toModel * the function to convert to model * @param toPresentation * the function to convert to presentation * @param onError * the function to provide error messages * @return the new converter * * @see Result * @see Function */ public static Converter from( SerializableFunction toModel, SerializableFunction toPresentation, SerializableFunction onError) { return from(val -> Result.of(() -> toModel.apply(val), onError), toPresentation); } /** * Constructs a converter from a filter and a function. * * @param

* the presentation type * @param * the model type * @param toModel * the function to convert to model * @param toPresentation * the function to convert to presentation * @return the new converter * * @see Function */ public static Converter from( SerializableFunction> toModel, SerializableFunction toPresentation) { return new Converter() { @Override public Result convertToModel(P value, ValueContext context) { return toModel.apply(value); } @Override public P convertToPresentation(M value, ValueContext context) { return toPresentation.apply(value); } }; } /** * Returns a converter that chains together this converter with the given * type-compatible converter. *

* The chained converters will form a new converter capable of converting * from the presentation type of this converter to the model type of the * other converter. *

* In most typical cases you should not need this method but instead only * need to define one converter for a binding using * {@link BindingBuilder#withConverter(Converter)}. * * @param * the model type of the resulting converter * @param other * the converter to chain, not null * @return a chained converter */ public default Converter chain( Converter other) { return new Converter() { @Override public Result convertToModel(PRESENTATION value, ValueContext context) { Result model = Converter.this.convertToModel(value, context); return model.flatMap(v -> other.convertToModel(v, context)); } @Override public PRESENTATION convertToPresentation(T value, ValueContext context) { MODEL model = other.convertToPresentation(value, context); return Converter.this.convertToPresentation(model, context); } }; } }