Class FormField.Builder<I,O>

java.lang.Object
google.registry.ui.forms.FormField.Builder<I,O>
Type Parameters:
I - input value type
O - output value type
Enclosing class:
FormField<I,O>

public static final class FormField.Builder<I,O> extends Object
Mutable builder for FormField.
  • Method Details

    • withDefault

      public FormField.Builder<I,O> withDefault(O defaultValue)
      Causes defaultValue to be substituted if value is null.
    • required

      public FormField.Builder<I,O> required()
      Ensure value is not null.
    • emptyToNull

      public FormField.Builder<I,O> emptyToNull()
      Transform empty values into null.
      Throws:
      IllegalStateException - if current output type is not a CharSequence or Collection.
    • trimmed

      public FormField.Builder<I,String> trimmed()
      Modify String input to remove whitespace around the sides.

      null values are passed through.

      Throws:
      IllegalStateException - if current output type is not a String.
    • uppercased

      public FormField.Builder<I,String> uppercased()
      Modify String input to be uppercase.

      null values are passed through.

      Throws:
      IllegalStateException - if current output type is not a String.
    • lowercased

      public FormField.Builder<I,String> lowercased()
      Modify String input to be lowercase.

      null values are passed through.

      Throws:
      IllegalStateException - if current output type is not a String.
    • matches

      public FormField.Builder<I,O> matches(com.google.re2j.Pattern pattern, @Nullable String errorMessage)
      Ensure input matches pattern.

      null values are passed through.

      Parameters:
      pattern - is used to validate the user input. It matches against the whole string, so you don't need to use the ^$ characters.
      errorMessage - is a helpful error message, which should include an example. If this is not provided, a default error message will be shown that includes the regexp pattern.
      Throws:
      IllegalStateException - if current output type is not a CharSequence.
      See Also:
    • matches

      public FormField.Builder<I,O> matches(com.google.re2j.Pattern pattern)
    • retains

      public FormField.Builder<I,String> retains(com.google.common.base.CharMatcher matcher)
      Removes all characters not in matcher.

      null values are passed through.

      Parameters:
      matcher - indicates which characters are to be retained
      Throws:
      IllegalStateException - if current output type is not a CharSequence
    • range

      public FormField.Builder<I,O> range(com.google.common.collect.Range<Integer> range)
      Enforce value length/size/value is within range.

      The following input value types are supported:

      null values are passed through. Please note that setting a lower bound on your range does not imply required(), as range checking only applies to non-null values.

      Throws:
      IllegalStateException - if current output type is not one of the above types.
    • in

      public FormField.Builder<I,O> in(Set<O> values)
      Enforce value be a member of values.

      null values are passed through.

      Throws:
      IllegalArgumentException - if values is empty.
    • transform

      public <T> FormField.Builder<I,T> transform(Class<T> newType, Function<O,T> transform)
      Performs arbitrary type transformation from O to T.

      Your transform function is expected to pass-through null values as a no-op, since it's up to required() to block them. You might also want to consider using a try block that rethrows exceptions as FormFieldException.

      Here's an example of how you'd convert from String to Integer:

         FormField.named("foo", String.class)
             .transform(Integer.class, new Function<String, Integer>() {
               @Nullable
               @Override
               public Integer apply(@Nullable String input) {
                 try {
                   return input != null ? Integer.parseInt(input) : null;
                 } catch (IllegalArgumentException e) {
                   throw new FormFieldException("Invalid number.", e);
                 }
               }})
             .build();
      See Also:
    • transform

      public FormField.Builder<I,O> transform(Function<O,O> transform)
      Manipulates values without changing type.

      Please see transform(Class, Function) for information about the contract to which transform is expected to conform.

    • asEnum

      public <C extends Enum<C>> FormField.Builder<I,C> asEnum(Class<C> enumClass)
      Uppercases value and converts to an enum field of enumClass.

      null values are passed through.

      Throws:
      IllegalArgumentException - if enumClass is not an enum class.
      IllegalStateException - if current output type is not a String.
    • asList

      public FormField.Builder<List<I>,List<O>> asList()
      Turns this form field into something that processes lists.

      The current object definition will be applied to each item in the list. If a FormFieldException is thrown when processing an item, then its fieldName will be rewritten to include the index, e.g. name becomes name[0].

      The outputted list will be an ImmutableList. This is not reflected in the generic typing for the sake of brevity.

      A null value for list will be passed through. List items that convert to null will be discarded (since ImmutableList does not permit null values).

    • asList

      public FormField.Builder<String,List<O>> asList(com.google.common.base.Splitter splitter)
      Turns this form field into a split string list that applies itself to each item.

      The behavior of this method is counter-intuitive. It behaves similar to asList() in the sense that all transforms specified before this method will be applied to the individual resulting list items.

      For example, to turn a comma-delimited string into an enum list:

         
      
         private static final FormField<String, List<State>> STATES_FIELD =
             FormField.named("states")
                  .uppercased()
                  .asEnum(State.class)
                  .asList(Splitter.on(',').omitEmptyStrings().trimResults())
                  .build();

      You'll notice that the transforms specified before this method are applied to each list item. However unlike asList(), if an error is thrown on an individual item, then FormFieldException.getFieldName() will not contain the index.

      Throws:
      IllegalStateException - If either the current input type isn't String.
    • asSet

      public FormField.Builder<List<I>,Set<O>> asSet()
      Same as asList() but outputs an ImmutableSet instead.
      Throws:
      IllegalStateException - if you called asList() before calling this method.
    • asSet

      public FormField.Builder<String,Set<O>> asSet(com.google.common.base.Splitter splitter)
      Same as asList(Splitter) but outputs an ImmutableSet instead.
      Throws:
      IllegalStateException - If the current input type isn't String.
    • build

      public FormField<I,O> build()
      Creates a new FormField instance.