diff options
Diffstat (limited to 'server/src/main/java/com/vaadin/data/Result.java')
-rw-r--r-- | server/src/main/java/com/vaadin/data/Result.java | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/data/Result.java b/server/src/main/java/com/vaadin/data/Result.java new file mode 100644 index 0000000000..0d6ffad94e --- /dev/null +++ b/server/src/main/java/com/vaadin/data/Result.java @@ -0,0 +1,170 @@ +/* + * Copyright 2000-2014 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.Objects; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Represents the result of an operation that might fail, such as input + * validation or type conversion. A result may contain either a value, + * signifying a successful operation, or an error message in case of a failure. + * <p> + * Result instances are created using the factory methods {@link #ok(R)} and + * {@link #error(String)}, denoting success and failure respectively. + * <p> + * Unless otherwise specified, {@code Result} method arguments cannot be null. + * + * @param <R> + * the result value type + */ +public interface Result<R> extends Serializable { + + /** + * Returns a successful result wrapping the given value. + * + * @param <R> + * the result value type + * @param value + * the result value, can be null + * @return a successful result + */ + public static <R> Result<R> ok(R value) { + return new SimpleResult<>(value, null); + } + + /** + * Returns a failure result wrapping the given error message. + * + * @param <R> + * the result value type + * @param message + * the error message + * @return a failure result + */ + public static <R> Result<R> error(String message) { + Objects.requireNonNull(message, "message cannot be null"); + return new SimpleResult<R>(null, message); + } + + /** + * Returns a Result representing the result of invoking the given supplier. + * If the supplier returns a value, returns a {@code Result.ok} of the + * value; if an exception is thrown, returns the message in a + * {@code Result.error}. + * + * @param <R> + * the result value type + * @param supplier + * the supplier to run + * @param onError + * the function to provide the error message + * @return the result of invoking the supplier + */ + public static <R> Result<R> of(Supplier<R> supplier, + Function<Exception, String> onError) { + Objects.requireNonNull(supplier, "supplier cannot be null"); + Objects.requireNonNull(onError, "onError cannot be null"); + + try { + return ok(supplier.get()); + } catch (Exception e) { + return error(onError.apply(e)); + } + } + + /** + * If this Result has a value, returns a Result of applying the given + * function to the value. Otherwise, returns a Result bearing the same error + * as this one. Note that any exceptions thrown by the mapping function are + * not wrapped but allowed to propagate. + * + * @param <S> + * the type of the mapped value + * @param mapper + * the mapping function + * @return the mapped result + */ + public default <S> Result<S> map(Function<R, S> mapper) { + return flatMap(value -> ok(mapper.apply(value))); + } + + /** + * If this Result has a value, applies the given Result-returning function + * to the value. Otherwise, returns a Result bearing the same error as this + * one. Note that any exceptions thrown by the mapping function are not + * wrapped but allowed to propagate. + * + * @param <S> + * the type of the mapped value + * @param mapper + * the mapping function + * @return the mapped result + */ + public <S> Result<S> flatMap(Function<R, Result<S>> mapper); + + /** + * Invokes either the first callback or the second one, depending on whether + * this Result denotes a success or a failure, respectively. + * + * @param ifOk + * the function to call if success + * @param ifError + * the function to call if failure + */ + public void handle(Consumer<R> ifOk, Consumer<String> ifError); + + /** + * Applies the {@code consumer} if result is not an error. + * + * @param consumer + * consumer to apply in case it's not an error + */ + public default void ifOk(Consumer<R> consumer) { + handle(consumer, error -> { + }); + } + + /** + * Applies the {@code consumer} if result is an error. + * + * @param consumer + * consumer to apply in case it's an error + */ + public default void ifError(Consumer<String> consumer) { + handle(value -> { + }, consumer); + } + + /** + * Returns {@code true} if result is an error. + * + * @return whether the result is an error + */ + public boolean isError(); + + /** + * Returns an Optional of the result message, or an empty Optional if none. + * + * @return the optional message + */ + public Optional<String> getMessage(); +} |