Class ValueBuilder<T>

  • All Implemented Interfaces:
    ProblemContainer


    public class ValueBuilder<T>
    extends java.lang.Object
    implements ProblemContainer
    Contains a non-null value and accumulates problems as aspects of the value are updated.

    This class is commonly used to track problems associated with the gradual construction of a value, and keep track of all problems discovered. Care must be taken to ensure proper "then" logic if one value depends on another (say, to get the stored email, the user ID must be known, but the user ID must be valid).

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.util.Collection<Problem> anyProblems​()
      Return all the problems in this object, even if the container is "ok".
      WarningVal<T> asWarning​()
      Create a warning version of this builder.
      java.lang.String debugProblems​(java.lang.String joinedWith)
      Return the problems as a single string, which combines the Object.toString() output of each problem with the given joining string parameter.
      RetVal<T> evaluate​()
      Convert this builder into a RetVal; if any problems exist, then the returned object will have those problems, otherwise it will contain the value.
      static <T> ValueBuilder<T> from​(T value)
      Construct a new value builder for the given initial state of the value.
      ProblemCollector getCollector​()
      Get the underlying problem collector.
      T getValue​()
      Get the value stored in this builder.
      boolean hasProblems​()
      Returns whether this object contains 1 or more problems.
      boolean isOk​()
      Returns whether this object contains zero problems.
      boolean isProblem​()
      Returns whether this object contains 1 or more problems.
      void joinProblemsWith​(java.util.Collection<Problem> problemList)
      Add all problems in this container into the argument.
      RetVal<T> then​()
      Convert this builder into a RetVal; if any problems exist, then the returned object will have those problems, otherwise it will contain the value.
      java.util.Collection<Problem> validProblems​()
      Returns all contained problems in this object, but only if this object contains 1 or more problems.
      <V> ValueBuilder<T> with​(RetNullable<V> arg, NonnullFirstBiConsumer<T,V> consumer)
      Calls the consumer with arguments (getValue(), arg.result()) if arg has no problems.
      <V> ValueBuilder<T> with​(RetVal<V> arg, NonnullBiConsumer<T,V> consumer)
      Calls the consumer with arguments (getValue(), arg.result()) if arg has no problems.
      ValueBuilder<T> with​(RetVoid problems)
      Join any problems in the argument with this builder.
      ValueBuilder<T> withValue​(NonnullConsumer<T> consumer)
      Call the consumer with the current value; commonly used to set a single, no-problem attribute on the value.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • from

        @Nonnull
        public static <T> ValueBuilder<T> from​(@Nonnull
                                               T value)
        Construct a new value builder for the given initial state of the value.
        Type Parameters:
        T - type of the value
        Parameters:
        value - source value
        Returns:
        the new builder.
      • getValue

        @Nonnull
        public T getValue​()
        Get the value stored in this builder.
        Returns:
        the stored value.
      • evaluate

        @Nonnull
        public RetVal<T> evaluate​()
        Convert this builder into a RetVal; if any problems exist, then the returned object will have those problems, otherwise it will contain the value.
        Returns:
        the value or problems.
      • then

        @Nonnull
        public RetVal<T> then​()
        Convert this builder into a RetVal; if any problems exist, then the returned object will have those problems, otherwise it will contain the value.

        Identical to evaluate(); used for symmetry with the other Ret classes. However, this can lead to usage confusion and cluttered reading of the code.

        Returns:
        the value or problems.
      • asWarning

        @Nonnull
        public WarningVal<T> asWarning​()
        Create a warning version of this builder.
        Returns:
        the value + all problems
      • with

        @Nonnull
        public <V> ValueBuilder<T> with​(@Nonnull
                                        RetVal<V> arg,
                                        @Nonnull
                                        NonnullBiConsumer<T,V> consumer)
        Calls the consumer with arguments (getValue(), arg.result()) if arg has no problems. This ignores the current problem state of the builder.

        Used to set or update the value stored by this builder based on a problematic value.

        Type Parameters:
        V - type of the argument
        Parameters:
        arg - a new parameter to include in the built value.
        consumer - updates the built value with the value of the parameter.
        Returns:
        this builder
      • with

        @Nonnull
        public <V> ValueBuilder<T> with​(@Nonnull
                                        RetNullable<V> arg,
                                        @Nonnull
                                        NonnullFirstBiConsumer<T,V> consumer)
        Calls the consumer with arguments (getValue(), arg.result()) if arg has no problems. This ignores the current problem state of the builder.

        Used to set or update the value stored by this builder based on a problematic value.

        Type Parameters:
        V - type of the argument
        Parameters:
        arg - a new parameter to include in the built value.
        consumer - updates the built value with the value of the parameter.
        Returns:
        this builder
      • with

        @Nonnull
        public ValueBuilder<T> with​(@Nonnull
                                    RetVoid problems)
        Join any problems in the argument with this builder.

        This commonly has use when another process builds values that are not directly set in the caller. For example, if the built value has a final value that is populated elsewhere, its problems will need to be included here.

        Parameters:
        problems - possible problem-contained non-value.
        Returns:
        this instance.
      • withValue

        @Nonnull
        public ValueBuilder<T> withValue​(@Nonnull
                                         NonnullConsumer<T> consumer)
        Call the consumer with the current value; commonly used to set a single, no-problem attribute on the value. Provided for symmetry with the other "with" calls.

        A common use case is to have the builder method return the value builder without intermediate steps. This method allows for chained calls to flow fluently:

             RetVal<StringBuilder> create() {
                 return ValueBuilder.from(new StringBuilder("Name: "))
                      .with(discoverName(), StringBuilder::append)
                      .withValue((sb) -> sb.append("; Age: "))
                      .with(discoverAge(), StringBuilder::append)
                      .then();
             }
         
        Parameters:
        consumer - accepts the value
        Returns:
        this instance.
      • getCollector

        @Nonnull
        public ProblemCollector getCollector​()
        Get the underlying problem collector. This contains all the problems discovered so far.
        Returns:
        the problem collector.
      • isProblem

        public boolean isProblem​()
        Description copied from interface: ProblemContainer
        Returns whether this object contains 1 or more problems.
        Specified by:
        isProblem in interface ProblemContainer
        Returns:
        true if there is a problem, false if there is no problem.
      • isOk

        public boolean isOk​()
        Description copied from interface: ProblemContainer
        Returns whether this object contains zero problems.
        Specified by:
        isOk in interface ProblemContainer
        Returns:
        true if there are no problems, false if there is a problem.
      • anyProblems

        @Nonnull
        public java.util.Collection<Problem> anyProblems​()
        Description copied from interface: ProblemContainer
        Return all the problems in this object, even if the container is "ok".

        Generally, this combines the problems in this instance with a larger collection, which can itself be used to check if any of the values had problems.

        The returned collection is read-only, and contains no null values.

        Specified by:
        anyProblems in interface ProblemContainer
        Returns:
        the problems contained in this container, even if there are none.
      • validProblems

        @Nonnull
        public java.util.Collection<Problem> validProblems​()
        Description copied from interface: ProblemContainer
        Returns all contained problems in this object, but only if this object contains 1 or more problems. If it contains 0, then this throws an IllegalStateException.

        The returned collection is read-only, and contains no null values.

        Specified by:
        validProblems in interface ProblemContainer
        Returns:
        the problems in this container, and the collection will contain at least 1 item.
      • debugProblems

        @Nonnull
        public java.lang.String debugProblems​(@Nonnull
                                              java.lang.String joinedWith)
        Description copied from interface: ProblemContainer
        Return the problems as a single string, which combines the Object.toString() output of each problem with the given joining string parameter. If this object contains no problems, then an empty string is returned instead.
        Specified by:
        debugProblems in interface ProblemContainer
        Parameters:
        joinedWith - the text to join multiple problem strings together.
        Returns:
        the combined text of the problems, or an empty string if there are no problems.
      • joinProblemsWith

        public void joinProblemsWith​(@Nonnull
                                     java.util.Collection<Problem> problemList)
        Description copied from interface: ProblemContainer
        Add all problems in this container into the argument. This has a very specific usage to indicate that this container, even if it has no problems, is part of a bigger issue. Therefore, this is fine to call even if there are no problems in this container.
        Specified by:
        joinProblemsWith in interface ProblemContainer
        Parameters:
        problemList - a modifiable collection of zero or more problems.