Search in sources :

Example 21 with EvaluationContext

use of org.javarosa.core.model.condition.EvaluationContext 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 22 with EvaluationContext

use of org.javarosa.core.model.condition.EvaluationContext in project javarosa by opendatakit.

the class FormDef method fillTemplateString.

public String fillTemplateString(String template, TreeReference contextRef, HashMap<String, ?> variables) {
    HashMap<String, String> args = new HashMap<String, String>();
    int depth = 0;
    List<String> outstandingArgs = Localizer.getArgs(template);
    while (outstandingArgs.size() > 0) {
        for (String argName : outstandingArgs) {
            if (!args.containsKey(argName)) {
                int ix = -1;
                try {
                    ix = Integer.parseInt(argName);
                } catch (NumberFormatException nfe) {
                    Std.err.println("Warning: expect arguments to be numeric [" + argName + "]");
                }
                if (ix < 0 || ix >= outputFragments.size())
                    continue;
                IConditionExpr expr = outputFragments.get(ix);
                EvaluationContext ec = new EvaluationContext(exprEvalContext, contextRef);
                ec.setOriginalContext(contextRef);
                ec.setVariables(variables);
                String value = expr.evalReadable(this.getMainInstance(), ec);
                args.put(argName, value);
            }
        }
        template = Localizer.processArguments(template, args);
        outstandingArgs = Localizer.getArgs(template);
        depth++;
        if (depth >= TEMPLATING_RECURSION_LIMIT) {
            throw new RuntimeException("Dependency cycle in <output>s; recursion limit exceeded!!");
        }
    }
    return template;
}
Also used : IConditionExpr(org.javarosa.core.model.condition.IConditionExpr) HashMap(java.util.HashMap) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) Constraint(org.javarosa.core.model.condition.Constraint)

Example 23 with EvaluationContext

use of org.javarosa.core.model.condition.EvaluationContext 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 24 with EvaluationContext

use of org.javarosa.core.model.condition.EvaluationContext in project javarosa by opendatakit.

the class LatestDagBase method evaluateTriggerable.

/**
 * Step 3 in DAG cascade. evaluate the individual triggerable expressions
 * against the anchor (the value that changed which triggered recomputation)
 *
 * @param qt
 *            The triggerable to be updated
 * @param anchorRefs
 */
private List<EvaluationResult> evaluateTriggerable(FormInstance mainInstance, EvaluationContext evalContext, QuickTriggerable qt, List<TreeReference> anchorRefs) {
    List<EvaluationResult> evaluationResults = new ArrayList<EvaluationResult>(0);
    // Contextualize the reference used by the triggerable against the
    // anchor
    Set<TreeReference> updatedContextRef = new HashSet<TreeReference>();
    for (TreeReference anchorRef : anchorRefs) {
        TreeReference contextRef = qt.t.contextualizeContextRef(anchorRef);
        if (updatedContextRef.contains(contextRef)) {
            continue;
        }
        try {
            // Now identify all of the fully qualified nodes which this
            // triggerable
            // updates. (Multiple nodes can be updated by the same trigger)
            List<TreeReference> qualifiedList = evalContext.expandReference(contextRef);
            // Go through each one and evaluate the trigger expression
            for (TreeReference qualified : qualifiedList) {
                EvaluationContext ec = new EvaluationContext(evalContext, qualified);
                evaluationResults.addAll(qt.t.apply(mainInstance, ec, qualified));
            }
            boolean fired = evaluationResults.size() > 0;
            if (fired) {
                accessor.getEventNotifier().publishEvent(new Event(qt.t.getClass().getSimpleName(), evaluationResults));
            }
            updatedContextRef.add(contextRef);
        } catch (Exception e) {
            throw new RuntimeException("Error evaluating field '" + contextRef.getNameLast() + "': " + e.getMessage(), e);
        }
    }
    return evaluationResults;
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList) Event(org.javarosa.debug.Event) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) EvaluationResult(org.javarosa.debug.EvaluationResult) HashSet(java.util.HashSet)

Example 25 with EvaluationContext

use of org.javarosa.core.model.condition.EvaluationContext in project javarosa by opendatakit.

the class SetValueAction method processAction.

public void processAction(FormDef model, TreeReference contextRef) {
    // Qualify the reference if necessary
    TreeReference qualifiedReference = contextRef == null ? target : target.contextualize(contextRef);
    // insert events should only trigger on the right nodes
    if (contextRef != null) {
        // strategy
        if (!contextRef.isParentOf(qualifiedReference, false)) {
            return;
        }
    }
    // TODO: either the target or the value's node might not exist here, catch and throw
    // reasonably
    EvaluationContext context = new EvaluationContext(model.getEvaluationContext(), qualifiedReference);
    Object result;
    if (explicitValue != null) {
        result = explicitValue;
    } else {
        result = XPathFuncExpr.unpack(value.eval(model.getMainInstance(), context));
    }
    AbstractTreeElement node = context.resolveReference(qualifiedReference);
    if (node == null) {
        throw new NullPointerException("Target of TreeReference " + qualifiedReference.toString(true) + " could not be resolved!");
    }
    int dataType = node.getDataType();
    IAnswerData val = Recalculate.wrapData(result, dataType);
    model.setValue(val == null ? null : AnswerDataFactory.templateByDataType(dataType).cast(val.uncast()), qualifiedReference, true);
}
Also used : IAnswerData(org.javarosa.core.model.data.IAnswerData) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) TreeReference(org.javarosa.core.model.instance.TreeReference) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext)

Aggregations

EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)28 TreeReference (org.javarosa.core.model.instance.TreeReference)16 ArrayList (java.util.ArrayList)8 Constraint (org.javarosa.core.model.condition.Constraint)8 TreeElement (org.javarosa.core.model.instance.TreeElement)8 FormDef (org.javarosa.core.model.FormDef)4 XPathNodeset (org.javarosa.xpath.XPathNodeset)4 XPathExpression (org.javarosa.xpath.expr.XPathExpression)4 FormInstance (org.javarosa.core.model.instance.FormInstance)3 EvaluationResult (org.javarosa.debug.EvaluationResult)3 Event (org.javarosa.debug.Event)3 XPathException (org.javarosa.xpath.XPathException)3 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)3 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 List (java.util.List)2 DataBinding (org.javarosa.core.model.DataBinding)2 QuestionDef (org.javarosa.core.model.QuestionDef)2 SelectChoice (org.javarosa.core.model.SelectChoice)2 IFunctionHandler (org.javarosa.core.model.condition.IFunctionHandler)2