protected List<SelectChoice> createCustomSelectChoices(String completeTextValue) { // copied from org.javarosa.xform.util.XFormAnswerDataParser.getSelections() List<String> textValues = DateUtils.split(completeTextValue, XFormAnswerDataSerializer.DELIMITER, true); int index = 0; List<SelectChoice> customSelectChoices = new ArrayList<SelectChoice>(); for (String textValue : textValues) { SelectChoice selectChoice = new SelectChoice(textValue, textValue, false); selectChoice.setIndex(index++); customSelectChoices.add(selectChoice); } return customSelectChoices; }
@Override public IAnswerData resolveAnswer(String textVal, TreeElement treeElement, FormDef formDef) { QuestionDef questionDef = XFormParser.ghettoGetQuestionDef(treeElement.getDataType(), formDef, treeElement.getRef()); if (questionDef != null && (questionDef.getControlType() == Constants.CONTROL_SELECT_ONE || questionDef.getControlType() == Constants.CONTROL_SELECT_MULTI)) { boolean containsSearchExpression = false; XPathFuncExpr xPathExpression = null; try { xPathExpression = ExternalDataUtil.getSearchXPathExpression(questionDef.getAppearanceAttr()); } catch (Exception e) { Log.e(ExternalDataUtil.LOGGER_NAME, e.getMessage(), e); // there is a search expression, but has syntax errors containsSearchExpression = true; } if (xPathExpression != null || containsSearchExpression) { // that means that we have dynamic selects // read the static choices from the options sheet List<SelectChoice> staticChoices = questionDef.getChoices(); for (int index = 0; index < staticChoices.size(); index++) { SelectChoice selectChoice = staticChoices.get(index); String selectChoiceValue = selectChoice.getValue(); if (ExternalDataUtil.isAnInteger(selectChoiceValue)) { Selection selection = selectChoice.selection(); switch (questionDef.getControlType()) { case Constants.CONTROL_SELECT_ONE: { if (selectChoiceValue.equals(textVal)) { // This means that the user selected a static selection. // // Although (for select1 fields) the default implementation will catch this and // return the right thing // (if we call super.resolveAnswer(textVal, treeElement, formDef)) // we just need to make sure, so we will override that. if (questionDef.getControlType() == Constants.CONTROL_SELECT_ONE) { // we don't need another, just return the static choice. return new SelectOneData(selection); } } } case Constants.CONTROL_SELECT_MULTI: { // we should search in a potential comma-separated string of values for a match // copied from org.javarosa.xform.util.XFormAnswerDataParser.getSelections() List<String> textValues = DateUtils.split(textVal, XFormAnswerDataSerializer.DELIMITER, true); if (textValues.contains(textVal)) { // this means that the user has selected AT LEAST the static choice. if (selectChoiceValue.equals(textVal)) { // this means that the user selected ONLY the static answer, so just return // that List<Selection> customSelections = new ArrayList<Selection>(); customSelections.add(selection); return new SelectMultiData(customSelections); } else { // we will ignore it for now since we will return that selection together with // the dynamic ones. } } break; } default: { // There is a bug if we get here, so let's throw an Exception throw createBugRuntimeException(treeElement, textVal); } } } else { switch (questionDef.getControlType()) { case Constants.CONTROL_SELECT_ONE: { // the default implementation will search for the "textVal" (saved answer) inside // the static choices. // Since we know that there isn't such, we just wrap the textVal in a virtual // choice in order to // create a SelectOneData object to be used as the IAnswer to the TreeElement. // (the caller of this function is searching for such an answer to populate the // in-memory model.) SelectChoice customSelectChoice = new SelectChoice(textVal, textVal, false); customSelectChoice.setIndex(index); return new SelectOneData(customSelectChoice.selection()); } case Constants.CONTROL_SELECT_MULTI: { // we should create multiple selections and add them to the pile List<SelectChoice> customSelectChoices = createCustomSelectChoices(textVal); List<Selection> customSelections = new ArrayList<Selection>(); for (SelectChoice customSelectChoice : customSelectChoices) { customSelections.add(customSelectChoice.selection()); } return new SelectMultiData(customSelections); } default: { // There is a bug if we get here, so let's throw an Exception throw createBugRuntimeException(treeElement, textVal); } } } } // if we get there then that means that we have a bug throw createBugRuntimeException(treeElement, textVal); } } // default behavior matches original behavior (for static selects, etc.) return super.resolveAnswer(textVal, treeElement, formDef); }