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);
}
}
}
}
}
}
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);
}
}
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;
}
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");
}
}
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;
}
Aggregations