package tudelft.healthpsychology.traumaontologies.answerstate; import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import java.util.List; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import tudelft.healthpsychology.traumaontologies.questiontypes.Bool; import tudelft.healthpsychology.traumaontologies.questiontypes.TypedQuestion; import tudelft.utilities.tree.Tree; /** * {@link #node} points to a type of object of which there may be multiple * relevant instances , eg "Persoon". This keeps track of asking the user all * details about all instances. * * Contains the state of a set of answers for a given OntologyNode, handling * depth first: first handle the Properties of a selected node, then deal with * the next object of given node class. * */ public class AnswersDepthFirstState implements AnswerState { private final String nodelabel; // root node that this answer is about private final List answerstates; private final boolean isFinal; private final Bool more; // eg "you have more items?" /** * Construct new state with one open OntologyAnswerState * * @param node the node that this answer is about. * @param havemore the message to show to ask user if he has more items. */ public AnswersDepthFirstState(String node, String havemore, Tree, OntologyNode> tree) { this(node, Arrays.asList(new OntoPropAnswerState( new OntologyAnswerState(tree.get(node), null), null)), false, new Bool(havemore, "internal")); } /** * Construct new state with a list of OntologyAnswerState, the last being * possibly nonfinal If the last is final and askedForMore=true * * @param node the node label that this answer is about. * @param answerstates the list of answer states. Must contain at least 1 * answerstate. * @param askedMore true iff the state is final, no more new objects to * be added and all answerstates are complete. * @param fin true iff the state is final * @param havemore the Bool question to show to ask user if he has more * items. */ @JsonCreator public AnswersDepthFirstState(@JsonProperty("nodelabel") String node, @JsonProperty("answerstates") List answerstates, @JsonProperty("isFinal") boolean fin, @JsonProperty("more") Bool havemore) { this.nodelabel = node; this.answerstates = answerstates; this.isFinal = fin; this.more = havemore; } @Override public TypedQuestion getOptions( Tree, OntologyNode> tree) { OntoPropAnswerState lastState = answerstates .get(answerstates.size() - 1); TypedQuestion options = lastState.getOptions(tree); if (options != null) { return options; } if (!isFinal) { return more; } return null; } @Override public AnswersDepthFirstState with(String answer, Tree, OntologyNode> tree) { if (isFinal) return this; TypedQuestion opts = getOptions(tree); if (!opts.fits(answer)) { throw new IllegalArgumentException( "Answer " + answer + " does not fit " + opts); } // check what the question was OntoPropAnswerState lastState = answerstates .get(answerstates.size() - 1); TypedQuestion options = lastState.getOptions(tree); if (options != null) { // last question was about OntoProp List newStates = new LinkedList<>( answerstates); newStates.set(newStates.size() - 1, lastState.with(answer, tree)); return new AnswersDepthFirstState(nodelabel, newStates, false, more); } // current onto question is complete. So we asked boolean "more" // question. We set explanation to "" as we already gave explanation the // first time. if (Bool.matchesYes(answer)) { List newStates = new LinkedList<>( answerstates); newStates.add(new OntoPropAnswerState( new OntologyAnswerState(tree.get(nodelabel), null), null)); return new AnswersDepthFirstState(nodelabel, newStates, false, more); } // we're done. Set finished to true. return new AnswersDepthFirstState(nodelabel, answerstates, true, more); } }