Class Question

java.lang.Object
nz.org.riskscape.wizard.Question

public class Question extends Object

A Question to ask the user within a Survey.

Questions can have a predicate test (i.e. askWhen(Predicate) associated with them to control whether or not they should be asked. Questions may be optional or required, and may accept multiple Answers. Questions can have dependencies (i.e. dependsOn(String), so they don't get asked until after an earlier Question has been answered.

  • Field Details

    • HIDDEN_VALUE

      public static final Question.Hidden HIDDEN_VALUE

      The only instance of the hidden value you'll ever need. Should be stored as the bound value in a Response object, with an empty string or empty list as the user's original value (or some other non null and empty value)

    • DEFAULT_I18N_LOOKUP

      public static final Question.I18nLookupFunction DEFAULT_I18N_LOOKUP
    • ONE_REQUIRED

      public static final com.google.common.collect.Range<Integer> ONE_REQUIRED
    • ONE_AT_LEAST

      public static final com.google.common.collect.Range<Integer> ONE_AT_LEAST
    • OPTIONAL_ONE

      public static final com.google.common.collect.Range<Integer> OPTIONAL_ONE
    • OPTIONAL_MANY

      public static final com.google.common.collect.Range<Integer> OPTIONAL_MANY
    • NO_VALUE

      public static final String NO_VALUE

      Assigned to annotations without values, so that we don't have to deal with null

      See Also:
    • DEPENDS_NOTHING

      public static final String DEPENDS_NOTHING

      No dependencies

      See Also:
  • Constructor Details

    • Question

      public Question(String name, Class<?> parameterType)
  • Method Details

    • readyToBeAsked

      public boolean readyToBeAsked(IncrementalBuildState buildState)

      Checks the dependent questions have already been asked and the question is applicable.

    • isFollowing

      public boolean isFollowing(Question question)
      Returns:
      true if this question is dependent on (i.e. follows) the given question.
    • atLeastOne

      public Question atLeastOne()
    • requiredOne

      public Question requiredOne()
    • optionalOne

      public Question optionalOne()
    • optionalMany

      public Question optionalMany()
    • hidden

      public Question hidden()

      Constructs a clone of this question, but makes it a hidden question. A hidden question is one that doesn't require any input from the user, but is needed for some automatic changes to take place. For example, a hidden question might be at the end of a set of questions to plop a name on the last pipeline step to give it a well-known name for later questions to locate it simply. A hidden question should be processed automatically as soon as the previous question is answered. Note that hidden questions won't be supported by the original Survey APIs and is destined for use with the newer Survey2 APIs

      Returns:
      a new question with the arity set to one and the type as Question.Hidden
    • parseAnnotations

      public Question parseAnnotations(String... newAnnotationStrings)
      Parameters:
      newAnnotationStrings - a list of annotations to parse, each string can be either a tag (which will be assigned NO_VALUE) or a tag=value string.
      Returns:
      a copy of this Question but with the given tags replacing whatever was there before.
    • withAnnotations

      public Question withAnnotations(String k1, String v1)
      Returns:
      a copy of this Question but with the given tags replacing whatever was there before
    • withAnnotations

      public Question withAnnotations(String k1, String v1, String k2, String v2)
      Returns:
      a copy of this Question but with the given tags replacing whatever was there before
    • withAnnotations

      public Question withAnnotations(String k1, String v1, String k2, String v2, String k3, String v3)
      Returns:
      a copy of this Question but with the given tags replacing whatever was there before
    • hasAnnotation

      public boolean hasAnnotation(String tag)
      Returns:
      true if there is a tag attached to this Question that matches the given string
    • hasAnnotationWithValue

      public boolean hasAnnotationWithValue(String tag, String value)
      Returns:
      true if there is a tag attached to this Question that matches the tag and it has contains value
    • getAnnotation

      public Optional<String> getAnnotation(String tag)
    • dependsOn

      public Question dependsOn(String newDependsOn)

      Make a new Question that's dependent on the given questionName being asked first. Note that these dependencies are only for Questions within the same QuestionSet.

    • withType

      public Question withType(Class<?> newParameterType)

      Clone this question, but with a new parameter type field.

    • askWhen

      public Question askWhen(Predicate<IncrementalBuildState> conditionMet)

      Adds a predicate condition that should be met before this question is asked.

    • isSingleValueQuestion

      public boolean isSingleValueQuestion()
      Returns:
      true if this question wants at most one answer
    • isRequired

      public boolean isRequired()
      Returns:
      true if at least one response is required for this question
    • isHidden

      public boolean isHidden()
      Returns:
      true if this question should be hidden from the user. See hidden()
    • isRequired

      public boolean isRequired(IncrementalBuildState buildState)

      Check if the question is really required. A question if required if it should be asked, and also requires an answer.

      Returns:
      true if question requires a response
    • checkValidity

      public void checkValidity(List<Object> values)

      sanity checking code to prevent an invalid answer being recorded - the errors are not meant for human consumption but we might want to adapt them later

    • requireSingleValueQuestion

      public void requireSingleValueQuestion()

      Explosive method for API users to fail fast if when they do a single value thing on a multi value question

    • getId

      public String getId()

      Returns a unique ID for the Question (which is dependent on the QuestionSet it belongs to.

    • toParameter

      public nz.org.riskscape.engine.bind.Parameter toParameter()

      Returns a Parameter representing this question (so that saved wizard answers can be overridden from the CLI).

    • hasDependency

      public boolean hasDependency()
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • getQuestionSet

      public QuestionSet getQuestionSet()
      Returns:
      the QuestionSet this question belongs to
      Throws:
      IllegalStateException - if this question is unassigned
    • isUnassigned

      public boolean isUnassigned()
      Returns:
      true if the question does not yet belong to a QuestionSet. A question can assigned to a set by calling the inSet clone method.
    • inSet

      public Question inSet(QuestionSet newQuestionSet)
      Returns:
      a clone of this Question but with it assigned to the given question set
    • withName

      public Question withName(String newName)
    • withI18nLookup

      public Question withI18nLookup(Question.I18nLookupFunction newLookup)
    • withI18nLookup

      public Question withI18nLookup(BiFunction<String,Locale,String> newLookup)
    • atLocation

      public Question atLocation(ChangeLocation newChangeLocation)
    • getTitle

      public Optional<String> getTitle(Locale locale)
    • getDescription

      public Optional<String> getDescription(Locale locale)
    • getMessage

      public Optional<String> getMessage(String suffix, Locale locale)
    • getMessageSource

      public nz.org.riskscape.engine.i18n.MessageSource getMessageSource()
    • getSurvey

      public Survey getSurvey()
    • withBackingDataFunction

      public Question withBackingDataFunction(Function<IncrementalBuildState,BackingData> newFunction)
      Returns:
      a clone of this question with backingDataFunction replaced by newFunction. See getBackingData(IncrementalBuildState) for more info
    • getBackingData

      public BackingData getBackingData(IncrementalBuildState buildState)
      Returns:
      BackingData for a UI to help the user answer this question, based on the given build state. By default, this returns empty, but a Question can be customized to return specific backing data by creating a question with withBackingDataFunction(Function).
    • getName

      @NonNull public @NonNull String getName()
    • getParameterType

      @NonNull public @NonNull Class<?> getParameterType()
    • getDependsOn

      public String getDependsOn()
    • getShouldBeAsked

      @NonNull public @NonNull Predicate<IncrementalBuildState> getShouldBeAsked()
    • getArity

      @NonNull public @NonNull com.google.common.collect.Range<Integer> getArity()
    • getAnnotations

      @NonNull public @NonNull com.google.common.collect.ImmutableMap<String,String> getAnnotations()
    • getI18nLookup

      public Question.I18nLookupFunction getI18nLookup()
    • getBackingDataFunction

      public Function<IncrementalBuildState,BackingData> getBackingDataFunction()
    • getChangeLocation

      @NonNull public @NonNull ChangeLocation getChangeLocation()
      Returns:
      a ChangeLocation that is associated with this question. The ChangeLocation provides an indication to UIs and to Survey code of where the change triggered by a response to this question should be applied. It defaults to 'at the last change', which is what 90% of questions will want to do when incrementally building.
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • canEqual

      protected boolean canEqual(Object other)
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object