Search in sources :

Example 36 with TreeReference

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

the class April2014DagImpl method fillTriggeredElements.

/**
 * Get all of the elements which will need to be evaluated (in order) when
 * the triggerable is fired.
 *
 * @param qt
 */
private void fillTriggeredElements(EvaluationContext evalContext, QuickTriggerable qt, ArrayList<QuickTriggerable> destination) {
    if (qt.t.canCascade()) {
        for (int j = 0; j < qt.t.getTargets().size(); j++) {
            TreeReference target = qt.t.getTargets().get(j);
            ArrayList<TreeReference> updatedNodes = new ArrayList<TreeReference>();
            updatedNodes.add(target);
            // elements as well.
            if (qt.t.isCascadingToChildren()) {
                addChildrenOfReference(evalContext, target, updatedNodes);
            }
            // cascade.
            for (TreeReference ref : updatedNodes) {
                // Check our index to see if that target is a Trigger for
                // other conditions
                // IE: if they are an element of a different calculation or
                // relevancy calc
                // We can't make this reference generic before now or we'll
                // lose the target information, so we'll be more inclusive
                // than needed and see if any of our triggers are keyed on
                // the predicate-less path of this ref
                ArrayList<QuickTriggerable> triggered = triggerIndex.get(ref.hasPredicates() ? ref.removePredicates() : ref);
                if (triggered != null) {
                    // If so, walk all of these triggerables that we found
                    for (int k = 0; k < triggered.size(); k++) {
                        QuickTriggerable qu = triggered.get(k);
                        // already
                        if (!destination.contains(qu))
                            destination.add(qu);
                    }
                }
            }
        }
    }
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList)

Example 37 with TreeReference

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

the class EvaluationContext method expandReferenceAccumulator.

/**
 * Recursively performs the search for all repeated nodes that match the pattern of the 'ref' argument.
 *
 * @param sourceRef      original path we're matching against
 * @param sourceInstance original node obtained from sourceRef
 * @param workingRef     explicit path that refers to the current node
 * @param refs           accumulator List to collect matching paths.
 */
private void expandReferenceAccumulator(TreeReference sourceRef, DataInstance sourceInstance, TreeReference workingRef, List<TreeReference> refs, boolean includeTemplates) {
    final int depth = workingRef.size();
    // check to see if we've matched fully
    if (depth == sourceRef.size()) {
        // TODO: Do we need to clone these references?
        refs.add(workingRef);
        return;
    }
    // Get the next set of matching references
    final String name = sourceRef.getName(depth);
    List<XPathExpression> predicates = sourceRef.getPredicate(depth);
    // Copy predicates for batch fetch
    if (predicates != null) {
        List<XPathExpression> predCopy = new ArrayList<XPathExpression>(predicates.size());
        for (XPathExpression xpe : predicates) {
            predCopy.add(xpe);
        }
        predicates = predCopy;
    }
    // ETHERTON: Is this where we should test for predicates?
    final int mult = sourceRef.getMultiplicity(depth);
    final List<TreeReference> treeReferences = new ArrayList<>(1);
    final AbstractTreeElement node = sourceInstance.resolveReference(workingRef);
    if (node.getNumChildren() > 0) {
        if (mult == TreeReference.INDEX_UNBOUND) {
            final List<TreeElement> childrenWithName = node.getChildrenWithName(name);
            final int count = childrenWithName.size();
            for (int i = 0; i < count; i++) {
                TreeElement child = childrenWithName.get(i);
                if (child.getMultiplicity() != i) {
                    throw new IllegalStateException("Unexpected multiplicity mismatch");
                }
                treeReferences.add(child.getRef());
            }
            if (includeTemplates) {
                AbstractTreeElement template = node.getChild(name, TreeReference.INDEX_TEMPLATE);
                if (template != null) {
                    treeReferences.add(template.getRef());
                }
            }
        } else if (mult != TreeReference.INDEX_ATTRIBUTE) {
            // TODO: Make this test mult >= 0?
            // If the multiplicity is a simple integer, just get
            // the appropriate child
            AbstractTreeElement child = node.getChild(name, mult);
            if (child != null) {
                treeReferences.add(child.getRef());
            }
        }
    }
    if (mult == TreeReference.INDEX_ATTRIBUTE) {
        AbstractTreeElement attribute = node.getAttribute(null, name);
        if (attribute != null) {
            treeReferences.add(attribute.getRef());
        }
    }
    if (predicates != null && predicateEvaluationProgress != null) {
        predicateEvaluationProgress[1] += treeReferences.size();
    }
    if (predicates != null) {
        boolean firstTime = true;
        List<TreeReference> passed = new ArrayList<TreeReference>(treeReferences.size());
        for (XPathExpression xpe : predicates) {
            for (int i = 0; i < treeReferences.size(); ++i) {
                // if there are predicates then we need to see if e.nextElement meets the standard of the predicate
                TreeReference treeRef = treeReferences.get(i);
                // test the predicate on the treeElement
                EvaluationContext evalContext = rescope(treeRef, (firstTime ? treeRef.getMultLast() : i));
                Object o = xpe.eval(sourceInstance, evalContext);
                if (o instanceof Boolean) {
                    boolean testOutcome = (Boolean) o;
                    if (testOutcome) {
                        passed.add(treeRef);
                    }
                }
            }
            firstTime = false;
            treeReferences.clear();
            treeReferences.addAll(passed);
            passed.clear();
            if (predicateEvaluationProgress != null) {
                predicateEvaluationProgress[0]++;
            }
        }
    }
    for (TreeReference treeRef : treeReferences) {
        expandReferenceAccumulator(sourceRef, sourceInstance, treeRef, refs, includeTemplates);
    }
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) ArrayList(java.util.ArrayList) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) TreeReference(org.javarosa.core.model.instance.TreeReference)

Example 38 with TreeReference

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

the class EvaluationContext method expandReference.

/**
 * Searches for all repeated nodes that match the pattern of the 'ref'
 * argument.
 *
 * '/' returns {'/'}
 * can handle sub-repetitions (e.g., {/a[1]/b[1], /a[1]/b[2], /a[2]/b[1]})
 *
 * @param ref Potentially ambiguous reference
 * @return Null if 'ref' is relative reference. Otherwise, returns a vector
 * of references that point to nodes that match 'ref' argument. These
 * references are unambiguous (no index will ever be INDEX_UNBOUND). Template
 * nodes won't be included when matching INDEX_UNBOUND, but will be when
 * INDEX_TEMPLATE is explicitly set.
 */
public List<TreeReference> expandReference(TreeReference ref, boolean includeTemplates) {
    if (!ref.isAbsolute()) {
        return null;
    }
    final DataInstance baseInstance = (ref.getInstanceName() != null) ? getInstance(ref.getInstanceName()) : instance;
    if (baseInstance == null) {
        throw new RuntimeException("Unable to expand reference " + ref.toString(true) + ", no appropriate instance in evaluation context");
    }
    List<TreeReference> treeReferences = new ArrayList<>(1);
    TreeReference workingRef = baseInstance.getRoot().getRef();
    expandReferenceAccumulator(ref, baseInstance, workingRef, treeReferences, includeTemplates);
    return treeReferences;
}
Also used : DataInstance(org.javarosa.core.model.instance.DataInstance) TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList)

Example 39 with TreeReference

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

the class Triggerable method print.

public void print(OutputStreamWriter w) throws IOException {
    w.write("   waveCount: " + Integer.toString(waveCount) + "\n");
    w.write("   isCascading: " + (isCascadingToChildren() ? "true" : "false") + "\n");
    w.write("   expr: " + expr.toString() + "\n");
    w.write("   contextRef: " + ((contextRef != null) ? contextRef.toString(true) : "null") + "\n");
    w.write("   originalContextRef: " + ((originalContextRef != null) ? originalContextRef.toString(true) : "null") + "\n");
    int j;
    for (j = 0; j < getTargets().size(); ++j) {
        TreeReference r = getTargets().get(j);
        w.write("   targets[" + Integer.toString(j) + "] :" + r.toString(true) + "\n");
    }
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference)

Example 40 with TreeReference

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

the class Triggerable method findAffectedTriggers.

/**
 * Searches in the triggers of this Triggerable, trying to find the ones that are
 * contained in the given list of contextualized refs.
 *
 * @param firedAnchorsMap a map of absolute refs
 * @return a list of affected nodes.
 */
public List<TreeReference> findAffectedTriggers(Map<TreeReference, List<TreeReference>> firedAnchorsMap) {
    List<TreeReference> affectedTriggers = new ArrayList<TreeReference>(0);
    Set<TreeReference> triggers = this.getTriggers();
    for (TreeReference trigger : triggers) {
        List<TreeReference> firedAnchors = firedAnchorsMap.get(trigger.genericize());
        if (firedAnchors == null) {
            continue;
        }
        affectedTriggers.addAll(firedAnchors);
    }
    return affectedTriggers;
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList)

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