Search in sources :

Example 56 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormDef method copyItemsetAnswer.

public void copyItemsetAnswer(QuestionDef q, TreeElement targetNode, IAnswerData data, boolean midSurvey) throws InvalidReferenceException {
    ItemsetBinding itemset = q.getDynamicChoices();
    TreeReference targetRef = targetNode.getRef();
    TreeReference destRef = itemset.getDestRef().contextualize(targetRef);
    List<Selection> selections = null;
    if (data instanceof SelectMultiData) {
        selections = (List<Selection>) data.getValue();
    } else if (data instanceof SelectOneData) {
        selections = new ArrayList<Selection>(1);
        selections.add((Selection) data.getValue());
    }
    List<String> selectedValues;
    if (itemset.valueRef != null) {
        selectedValues = new ArrayList<String>(selections.size());
        for (Selection selection : selections) {
            selectedValues.add(selection.choice.getValue());
        }
    } else {
        selectedValues = new ArrayList<String>(0);
    }
    // delete existing dest nodes that are not in the answer selection
    HashMap<String, TreeElement> existingValues = new HashMap<String, TreeElement>();
    List<TreeReference> existingNodes = exprEvalContext.expandReference(destRef);
    for (TreeReference existingNode : existingNodes) {
        TreeElement node = getMainInstance().resolveReference(existingNode);
        if (itemset.valueRef != null) {
            String value = itemset.getRelativeValue().evalReadable(this.getMainInstance(), new EvaluationContext(exprEvalContext, node.getRef()));
            if (selectedValues.contains(value)) {
                // cache node if in selection
                existingValues.put(value, node);
            // and already exists
            }
        }
        // delete from target
        targetNode.removeChild(node);
    }
    // copy in nodes for new answer; preserve ordering in answer
    for (int i = 0; i < selections.size(); i++) {
        Selection s = selections.get(i);
        SelectChoice ch = s.choice;
        TreeElement cachedNode = null;
        if (itemset.valueRef != null) {
            String value = ch.getValue();
            if (existingValues.containsKey(value)) {
                cachedNode = existingValues.get(value);
            }
        }
        if (cachedNode != null) {
            cachedNode.setMult(i);
            targetNode.addChild(cachedNode);
        } else {
            getMainInstance().copyItemsetNode(ch.copyNode, destRef, this);
        }
    }
    dagImpl.copyItemsetAnswer(getMainInstance(), getEvaluationContext(), destRef, targetNode, midSurvey);
}
Also used : SelectOneData(org.javarosa.core.model.data.SelectOneData) HashMap(java.util.HashMap) Selection(org.javarosa.core.model.data.helper.Selection) ArrayList(java.util.ArrayList) Constraint(org.javarosa.core.model.condition.Constraint) TreeElement(org.javarosa.core.model.instance.TreeElement) SelectMultiData(org.javarosa.core.model.data.SelectMultiData) TreeReference(org.javarosa.core.model.instance.TreeReference) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext)

Example 57 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormDef method findQuestionByRef.

public static QuestionDef findQuestionByRef(TreeReference ref, IFormElement fe) {
    if (fe instanceof FormDef) {
        ref = ref.genericize();
    }
    if (fe instanceof QuestionDef) {
        QuestionDef q = (QuestionDef) fe;
        TreeReference bind = FormInstance.unpackReference(q.getBind());
        return (ref.equals(bind) ? q : null);
    } else {
        for (int i = 0; i < fe.getChildren().size(); i++) {
            QuestionDef ret = findQuestionByRef(ref, fe.getChild(i));
            if (ret != null)
                return ret;
        }
        return null;
    }
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) Constraint(org.javarosa.core.model.condition.Constraint)

Example 58 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormDef method getNumRepetitions.

public int getNumRepetitions(FormIndex index) {
    List<Integer> indexes = new ArrayList<Integer>();
    List<Integer> multiplicities = new ArrayList<Integer>();
    List<IFormElement> elements = new ArrayList<IFormElement>();
    if (!index.isInForm()) {
        throw new RuntimeException("not an in-form index");
    }
    collapseIndex(index, indexes, multiplicities, elements);
    if (!(elements.get(elements.size() - 1) instanceof GroupDef) || !((GroupDef) elements.get(elements.size() - 1)).getRepeat()) {
        throw new RuntimeException("current element not a repeat");
    }
    // so painful
    TreeElement templNode = mainInstance.getTemplate(index.getReference());
    TreeReference parentPath = templNode.getParent().getRef().genericize();
    TreeElement parentNode = mainInstance.resolveReference(parentPath.contextualize(index.getReference()));
    return parentNode.getChildMultiplicity(templNode.getName());
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 59 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormDef method populateDynamicChoices.

/**
 * Identify the itemset in the backend model, and create a set of
 * SelectChoice objects at the current question reference based on the data
 * in the model.
 * <p/>
 * Will modify the itemset binding to contain the relevant choices
 *
 * @param itemset The binding for an itemset, where the choices will be populated
 * @param curQRef A reference to the current question's element, which will be
 *                used to determine the values to be chosen from.
 */
public void populateDynamicChoices(ItemsetBinding itemset, TreeReference curQRef) {
    getEventNotifier().publishEvent(new Event("Dynamic choices", new EvaluationResult(curQRef, null)));
    List<SelectChoice> choices = new ArrayList<SelectChoice>();
    List<TreeReference> matches = itemset.nodesetExpr.evalNodeset(this.getMainInstance(), new EvaluationContext(exprEvalContext, itemset.contextRef.contextualize(curQRef)));
    DataInstance fi = null;
    if (// We're not dealing
    itemset.nodesetRef.getInstanceName() != null) // with the default
    // instance
    {
        fi = getNonMainInstance(itemset.nodesetRef.getInstanceName());
        if (fi == null) {
            throw new XPathException("Instance " + itemset.nodesetRef.getInstanceName() + " not found");
        }
    } else {
        fi = getMainInstance();
    }
    if (matches == null) {
        throw new XPathException("Could not find references depended on by" + itemset.nodesetRef.getInstanceName());
    }
    for (int i = 0; i < matches.size(); i++) {
        TreeReference item = matches.get(i);
        // String label =
        // itemset.labelExpr.evalReadable(this.getMainInstance(), new
        // EvaluationContext(exprEvalContext, item));
        String label = itemset.labelExpr.evalReadable(fi, new EvaluationContext(exprEvalContext, item));
        String value = null;
        TreeElement copyNode = null;
        if (itemset.copyMode) {
            copyNode = this.getMainInstance().resolveReference(itemset.copyRef.contextualize(item));
        }
        if (itemset.valueRef != null) {
            // value = itemset.valueExpr.evalReadable(this.getMainInstance(),
            // new EvaluationContext(exprEvalContext, item));
            value = itemset.valueExpr.evalReadable(fi, new EvaluationContext(exprEvalContext, item));
        }
        // SelectChoice choice = new
        // SelectChoice(labelID,labelInnerText,value,isLocalizable);
        SelectChoice choice = new SelectChoice(label, value != null ? value : "dynamic:" + i, itemset.labelIsItext);
        choice.setIndex(i);
        if (itemset.copyMode)
            choice.copyNode = copyNode;
        choices.add(choice);
    }
    if (choices.size() == 0) {
        // throw new
        // RuntimeException("dynamic select question has no choices! [" +
        // itemset.nodesetRef + "]");
        // When you exit a survey mid way through and want to save it, it seems
        // that Collect wants to
        // go through all the questions. Well of course not all the questions
        // are going to have answers
        // to chose from if the user hasn't filled them out. So I'm just going
        // to make a note of this
        // and not throw an exception.
        Std.out.println("Dynamic select question has no choices! [" + itemset.nodesetRef + "]. If this occurs while filling out a form (and not while saving an incomplete form), the filter condition may have eliminated all the choices. Is that what you intended?\n");
    }
    itemset.clearChoices();
    itemset.setChoices(choices, this.getLocalizer());
}
Also used : DataInstance(org.javarosa.core.model.instance.DataInstance) XPathException(org.javarosa.xpath.XPathException) ArrayList(java.util.ArrayList) EvaluationResult(org.javarosa.debug.EvaluationResult) Constraint(org.javarosa.core.model.condition.Constraint) TreeElement(org.javarosa.core.model.instance.TreeElement) TreeReference(org.javarosa.core.model.instance.TreeReference) Event(org.javarosa.debug.Event) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext)

Example 60 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormDef method deleteRepeat.

/**
 * Deletes the inner-most repeat that this node belongs to and returns the
 * corresponding FormIndex. Behavior is currently undefined if you call this
 * method on a node that is not contained within a repeat.
 *
 * @param index
 * @return
 */
public FormIndex deleteRepeat(FormIndex index) {
    List<Integer> indexes = new ArrayList<Integer>();
    List<Integer> multiplicities = new ArrayList<Integer>();
    List<IFormElement> elements = new ArrayList<IFormElement>();
    collapseIndex(index, indexes, multiplicities, elements);
    // TODO: should probably check to make sure size > 0
    for (int i = elements.size() - 1; i >= 0; i--) {
        IFormElement e = elements.get(i);
        if (e instanceof GroupDef && ((GroupDef) e).getRepeat()) {
            break;
        } else {
            indexes.remove(i);
            multiplicities.remove(i);
            elements.remove(i);
        }
    }
    // build new formIndex which includes everything
    // up to the node we're going to remove
    FormIndex newIndex = buildIndex(indexes, multiplicities, elements);
    TreeReference deleteRef = getChildInstanceRef(newIndex);
    TreeElement deleteElement = mainInstance.resolveReference(deleteRef);
    TreeReference parentRef = deleteRef.getParentRef();
    TreeElement parentElement = mainInstance.resolveReference(parentRef);
    int childMult = deleteElement.getMult();
    parentElement.removeChild(deleteElement);
    // update multiplicities of other child nodes
    for (int i = 0; i < parentElement.getNumChildren(); i++) {
        TreeElement child = parentElement.getChildAt(i);
        if (child.getName().equals(deleteElement.getName()) && child.getMult() > childMult) {
            child.setMult(child.getMult() - 1);
            // When a group changes it multiplicity, then all caches of its
            // children must clear.
            child.clearChildrenCaches();
        }
    }
    dagImpl.deleteRepeatGroup(getMainInstance(), getEvaluationContext(), deleteRef, parentElement, deleteElement);
    return newIndex;
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList) Constraint(org.javarosa.core.model.condition.Constraint) TreeElement(org.javarosa.core.model.instance.TreeElement)

Aggregations

TreeReference (org.javarosa.core.model.instance.TreeReference)85 ArrayList (java.util.ArrayList)30 TreeElement (org.javarosa.core.model.instance.TreeElement)29 EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)16 Constraint (org.javarosa.core.model.condition.Constraint)12 HashSet (java.util.HashSet)11 Test (org.junit.Test)9 FormInstance (org.javarosa.core.model.instance.FormInstance)8 AbstractTreeElement (org.javarosa.core.model.instance.AbstractTreeElement)7 IFormElement (org.javarosa.core.model.IFormElement)6 Condition (org.javarosa.core.model.condition.Condition)6 IAnswerData (org.javarosa.core.model.data.IAnswerData)6 InstanceInitializationFactory (org.javarosa.core.model.instance.InstanceInitializationFactory)6 GroupDef (org.javarosa.core.model.GroupDef)5 XPathReference (org.javarosa.model.xform.XPathReference)5 DataBinding (org.javarosa.core.model.DataBinding)4 IDataReference (org.javarosa.core.model.IDataReference)4 DataInstance (org.javarosa.core.model.instance.DataInstance)4 EvaluationResult (org.javarosa.debug.EvaluationResult)4 XPathException (org.javarosa.xpath.XPathException)4