All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ru.progrm_jarvis.javacommons.object.ValueContainer Maven / Gradle / Ivy

package ru.progrm_jarvis.javacommons.object;

import lombok.*;
import lombok.experimental.Delegate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.function.Supplier;

/**
 * A value which may be present (which includes {@code null}) or not-present.
 * 

* This differs from {@link java.util.Optional} as presence of a {@code null} value * does not make this value container empty. * * @param type of stored value */ @SuppressWarnings("PublicInnerClass") public interface ValueContainer extends Supplier { /** * Gets a value container being empty. * * @param type of stored value * @return empty value container */ @SuppressWarnings("unchecked") static @NotNull ValueContainer empty() { return (ValueContainer) Empty.INSTANCE; } /** * Gets a non-empty value container containing {@code null}. * * @param type of stored value * @return value container containing {@code null} */ @SuppressWarnings("unchecked") static @NotNull ValueContainer ofNull() { return (ValueContainer) OfNull.INSTANCE; } /** * Gets a non-empty value container containing the specified value. * * @param value nullable value stored in the container * @param type of stored value * @return non-empty value container containing the specified value */ @SuppressWarnings("unchecked") static @NotNull ValueContainer of(final @Nullable T value) { return value == null ? (ValueContainer) OfNull.INSTANCE : new Containing<>(value); } /** * Gets a value container containing the specified value or an empty one if the values is {@code null}. * * @param value value stored in the container * @param type of stored value * @return non-empty value container containing the specified value * if it is not {@code null} and an empty one otherwise */ @SuppressWarnings("unchecked") static @NotNull ValueContainer nonnullOrEmpty(final @Nullable T value) { return value == null ? (ValueContainer) Empty.INSTANCE : new Containing<>(value); } /** * Gets the value stored in this value container. * * @return stored value if it is {@link #isPresent() present} * * @throws EmptyValueException if this value container is empty */ @Override T get(); /** * Checks whether the object is present ot not. * * @return {@code true} if the value is present (might be {@code null}) and {@code false} otherwise */ boolean isPresent(); /** * Gets the value if it is present otherwise using the specified one. * * @param value value to use if this value container is empty * @return this value container's value if it is not empty or the specified value otherwise */ @Nullable T orElse(@Nullable T value); /** * Gets the value if it is present otherwise using the one got from the specified supplier. * * @param defaultValueSupplier supplier to be used for getting the value if this value container is empty * @return this value container's value if it is not empty or the one got from the supplier otherwise */ @Nullable T orElseGet(@NonNull Supplier defaultValueSupplier); /** * Gets the value if it is present otherwise throwing an exception. * * @param exceptionSupplier supplier to be used for getting the exception if this value container is empty * @param type of an exception thrown if this value container is empty * @return this value container's value if it is not empty * * @throws X if this value container is empty */ @Nullable T orElseThrow(final @NonNull Supplier exceptionSupplier) throws X; /** * Gets the value if it is present otherwise throwing an exception. * Throws {@code X} if this value container is empty. * * @param exceptionSupplier supplier to be used for getting the exception if this value container is empty * @param type of an exception thrown if this value container is empty * @return this value container's value if it is not empty */ @SneakyThrows default @Nullable T orElseSneakyThrow(final @NonNull Supplier exceptionSupplier) { return orElseThrow(exceptionSupplier); } /** * Converts this value container into a {@link Result#nullError() null-error result}. * * @param type of the result error * @return {@link Result#success(Object) successful result} containing the value contained by this value container * if is is {@link #isPresent() present} or a {@link Result#nullError() null-error result} otherwise * * @see #asResult(Supplier) alternative with customizable error value */ @NotNull Result asResult(); /** * Converts this value container into a {@link Result}. * * @param errorSupplier supplier of the error in case of this value container being empty * @param type of the result error * @return {@link Result#success(Object) successful result} containing the value contained by this value container * if is is {@link #isPresent() present} or an {@link Result#error(Object) error result} * with the error got by using the specified supplier * * @see #asResult() alternative with default (i.e. null) error */ @NotNull Result asResult(Supplier errorSupplier); /** * Empty value-container. * * @param type of stored value */ // use identity equals and hashCode @NoArgsConstructor(access = AccessLevel.PRIVATE) final class Empty implements ValueContainer { /** * Singleton instance of this empty {@link ValueContainer value-container} */ private static final ValueContainer INSTANCE = new Empty<>(); @Override public boolean isPresent() { return false; } @Override public T get() { throw new EmptyValueException("There is no value associated with this value container"); } @Override public @Nullable T orElse(final @Nullable T value) { return value; } @Override public @Nullable T orElseGet(final @NonNull Supplier defaultValueSupplier) { return defaultValueSupplier.get(); } @Override public @Nullable T orElseThrow(final @NonNull Supplier exceptionSupplier) throws X { throw exceptionSupplier.get(); } @Override public @NotNull Result asResult() { return Result.nullError(); } @Override public @NotNull Result asResult(final Supplier errorSupplier) { return Result.error(errorSupplier.get()); } @Override public String toString() { return "Empty ValueContainer"; } } /** * Non-empty value-container containing {@code null}. * * @param type of stored value */ // use identity equals and hashCode @NoArgsConstructor(access = AccessLevel.PRIVATE) final class OfNull implements ValueContainer { /** * Singleton instance of this {@link ValueContainer value-container} containing {@code null} */ private static final ValueContainer INSTANCE = new OfNull<>(); @Override public boolean isPresent() { return true; } @Override public T get() { return null; } @Override public @Nullable T orElse(final @Nullable T value) { return null; } @Override public @Nullable T orElseGet(final @NonNull Supplier defaultValueSupplier) { return null; } @Override public @Nullable T orElseThrow(final @NonNull Supplier exceptionSupplier) { return null; } @Override public @NotNull Result asResult() { return Result.nullSuccess(); } @Override public @NotNull Result asResult(final Supplier errorSupplier) { return Result.nullSuccess(); } @Override public String toString() { return "ValueContainer{null}"; } } /** * A simple value-container which is meant to keep one unchanged value. * * @param type of stored value */ @Value @RequiredArgsConstructor(access = AccessLevel.PRIVATE) class Containing implements ValueContainer { /** * Value stored by this value container */ @NonNull T value; @Override public boolean isPresent() { return true; } @Override public T get() { return value; } @Override public @Nullable T orElse(final @Nullable T value) { return value; } @Override public @Nullable T orElseGet(final @NonNull Supplier defaultValueSupplier) { return value; } @Override public @Nullable T orElseThrow(final @NonNull Supplier exceptionSupplier) { return value; } @Override public @NotNull Result asResult() { return Result.success(value); } @Override public @NotNull Result asResult(final Supplier errorSupplier) { return Result.success(value); } } /** * Value-container which provides new values for each request. * * @param type of stored value */ @Value @RequiredArgsConstructor(access = AccessLevel.PRIVATE) class Supplying implements ValueContainer { /** * Supplier responsible for supplying new values on each value request */ @Getter(AccessLevel.NONE) @Delegate @NotNull Supplier valueSupplier; @Override public boolean isPresent() { return true; } @Override public @Nullable T orElse(final @Nullable T value) { return valueSupplier.get(); } @Override public @Nullable T orElseGet(final @NonNull Supplier defaultValueSupplier) { return valueSupplier.get(); } @Override public @Nullable T orElseThrow(final @NonNull Supplier exceptionSupplier) { return valueSupplier.get(); } @Override public @NotNull Result asResult() { return Result.success(valueSupplier.get()); } @Override public @NotNull Result asResult(final Supplier errorSupplier) { return Result.success(valueSupplier.get()); } } /** * An exception thrown whenever {@link #get()} is called on an empty value container. */ @NoArgsConstructor @SuppressWarnings("PublicConstructor") class EmptyValueException extends RuntimeException { // /** * Constructs a new exception with the specified message. * * @param message message describing the exception cause */ public EmptyValueException(final String message) { super(message); } /** * Constructs a new exception with the specified message and cause. * * @param message message describing the exception cause * @param cause cause of this exception */ public EmptyValueException(final String message, final Throwable cause) { super(message, cause); } /** * Constructs a new exception with the specified cause. * * @param cause cause of this exception */ public EmptyValueException(final Throwable cause) { super(cause); } /** * Constructs a new exception with the specified message and cause. * * @param message message describing the exception cause * @param cause cause of this exception * @param enableSuppression flag indicating whether or not suppression * is enabled or disabled for this exception * @param writableStackTrace flag indicating whether or not not the stack trace * should be writable for this exception */ public EmptyValueException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } // } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy