use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class IDag method getConditionExpressionForTrueAction.
/**
* Pull this in from FormOverview so that we can make fields private.
*
* @param instanceNode
* @param action
* @return
*/
public final IConditionExpr getConditionExpressionForTrueAction(FormInstance mainInstance, TreeElement instanceNode, int action) {
IConditionExpr expr = null;
for (int i = 0; i < triggerablesDAG.size() && expr == null; i++) {
// Clayton Sims - Jun 1, 2009 : Not sure how legitimate this
// cast is. It might work now, but break later.
// Clayton Sims - Jun 24, 2009 : Yeah, that change broke things.
// For now, we won't bother to print out anything that isn't
// a condition.
QuickTriggerable qt = triggerablesDAG.get(i);
if (qt.t instanceof Condition) {
Condition c = (Condition) qt.t;
if (c.trueAction == action) {
List<TreeReference> targets = c.getTargets();
for (int j = 0; j < targets.size() && expr == null; j++) {
TreeReference target = targets.get(j);
TreeReference tr = (TreeReference) (new XPathReference(target)).getReference();
TreeElement element = mainInstance.getTemplatePath(tr);
if (instanceNode == element) {
expr = c.getExpr();
}
}
}
}
}
return expr;
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class IDag method addTriggerable.
/**
* Add the triggerables to the dataset prior to finalizing.
*
* @param t
*/
public final Triggerable addTriggerable(Triggerable t) {
QuickTriggerable qt = findTriggerable(t);
if (qt != null) {
// one node may control access to many nodes; this means many nodes
// effectively have the same condition
// let's identify when conditions are the same, and store and calculate
// it only once
// nov-2-2011: ctsims - We need to merge the context nodes together
// whenever we do this (finding the highest
// common ground between the two), otherwise we can end up failing to
// trigger when the ignored context
// exists and the used one doesn't
Triggerable existingTriggerable = qt.t;
existingTriggerable.changeContextRefToIntersectWithTriggerable(t);
return existingTriggerable;
// note, if the contextRef is unnecessarily deep, the condition will be
// evaluated more times than needed
// perhaps detect when 'identical' condition has a shorter contextRef,
// and use that one instead?
} else {
qt = new QuickTriggerable(t);
unorderedTriggerables.add(qt);
Set<TreeReference> triggers = t.getTriggers();
for (TreeReference trigger : triggers) {
ArrayList<QuickTriggerable> triggered = triggerIndex.get(trigger);
if (triggered == null) {
triggered = new ArrayList<QuickTriggerable>();
triggerIndex.put(trigger.clone(), triggered);
}
if (!triggered.contains(qt)) {
triggered.add(qt);
}
}
return t;
}
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class LegacyDagImpl method initializeTriggerables.
/**
* Walks the current set of conditions, and evaluates each of them with the
* current context.
*/
@Override
public Collection<QuickTriggerable> initializeTriggerables(FormInstance mainInstance, EvaluationContext evalContext, TreeReference rootRef, boolean midSurvey) {
TreeReference genericRoot = rootRef.genericize();
ArrayList<QuickTriggerable> applicable = new ArrayList<QuickTriggerable>();
for (int i = 0; i < triggerablesDAG.size(); i++) {
QuickTriggerable qt = triggerablesDAG.get(i);
for (int j = 0; j < qt.t.getTargets().size(); j++) {
TreeReference target = qt.t.getTargets().get(j);
if (genericRoot.isParentOf(target, false)) {
applicable.add(qt);
break;
}
}
}
return evaluateTriggerables(mainInstance, evalContext, applicable, rootRef);
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class LegacyDagImpl method evaluateTriggerables.
/**
* Step 2 in evaluating DAG computation updates from a value being changed
* in the instance. This step is responsible for taking the root set of
* directly triggered conditions, identifying which conditions should
* further be triggered due to their update, and then dispatching all of the
* evaluations.
* @param tv
* A list of all of the trigerrables directly triggered by the
* value changed
* @param anchorRef
*/
private List<QuickTriggerable> evaluateTriggerables(FormInstance mainInstance, EvaluationContext evalContext, ArrayList<QuickTriggerable> tv, TreeReference anchorRef) {
// add all cascaded triggerables to queue
for (int i = 0; i < tv.size(); i++) {
QuickTriggerable qt = tv.get(i);
if (qt.t.canCascade()) {
for (int j = 0; j < qt.t.getTargets().size(); j++) {
TreeReference target = qt.t.getTargets().get(j);
ArrayList<QuickTriggerable> triggered = triggerIndex.get(target);
if (triggered != null) {
for (int k = 0; k < triggered.size(); k++) {
QuickTriggerable qu = triggered.get(k);
if (!tv.contains(qu))
tv.add(qu);
}
}
}
}
}
// in the order they appear in 'triggerables'
for (int i = 0; i < triggerablesDAG.size(); i++) {
QuickTriggerable qt = triggerablesDAG.get(i);
if (tv.contains(qt)) {
evaluateTriggerable(mainInstance, evalContext, qt, anchorRef);
}
}
return tv;
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class LegacyDagImpl method finalizeTriggerables.
/**
* Finalize the DAG associated with the form's triggered conditions. This
* will create the appropriate ordering and dependencies to ensure the
* conditions will be evaluated in the appropriate orders.
*
* @throws IllegalStateException
* - If the trigger ordering contains an illegal cycle and the
* triggers can't be laid out appropriately
*/
@Override
public void finalizeTriggerables(FormInstance mainInstance, EvaluationContext evalContext) throws IllegalStateException {
//
// DAGify the triggerables based on dependencies and sort them so that
// triggerables come only after the triggerables they depend on
//
triggerablesDAG.clear();
//
// DAGify the triggerables based on dependencies and sort them so that
// trigbles come only after the trigbles they depend on
//
ArrayList<QuickTriggerable[]> partialOrdering = new ArrayList<QuickTriggerable[]>();
for (int i = 0; i < unorderedTriggerables.size(); i++) {
QuickTriggerable qt = unorderedTriggerables.get(i);
Triggerable t = qt.t;
ArrayList<QuickTriggerable> deps = new ArrayList<QuickTriggerable>();
if (t.canCascade()) {
for (int j = 0; j < t.getTargets().size(); j++) {
TreeReference target = t.getTargets().get(j);
ArrayList<QuickTriggerable> triggered = triggerIndex.get(target);
if (triggered != null) {
for (int k = 0; k < triggered.size(); k++) {
QuickTriggerable qu = triggered.get(k);
if (!deps.contains(qu))
deps.add(qu);
}
}
}
}
for (int j = 0; j < deps.size(); j++) {
QuickTriggerable qu = deps.get(j);
QuickTriggerable[] edge = { qt, qu };
partialOrdering.add(edge);
}
}
ArrayList<QuickTriggerable> vertices = new ArrayList<QuickTriggerable>(unorderedTriggerables);
ArrayList<QuickTriggerable> roots = new ArrayList<QuickTriggerable>(unorderedTriggerables.size());
while (vertices.size() > 0) {
// determine root nodes
roots.clear();
roots.addAll(vertices);
for (int i = 0; i < partialOrdering.size(); i++) {
QuickTriggerable[] edge = partialOrdering.get(i);
roots.remove(edge[1]);
}
// if no root nodes while graph still has nodes, graph has cycles
if (roots.size() == 0) {
throw new RuntimeException("Cannot create partial ordering of triggerables due to dependency cycle. Why wasn't this caught during parsing?");
}
// remove root nodes and edges originating from them
for (int i = 0; i < roots.size(); i++) {
QuickTriggerable root = roots.get(i);
triggerablesDAG.add(root);
vertices.remove(root);
}
for (int i = partialOrdering.size() - 1; i >= 0; i--) {
QuickTriggerable[] edge = partialOrdering.get(i);
if (roots.contains(edge[0]))
partialOrdering.remove(i);
}
}
//
// build the condition index for repeatable nodes
//
conditionRepeatTargetIndex.clear();
for (QuickTriggerable qt : triggerablesDAG) {
if (qt.t instanceof Condition) {
List<TreeReference> targets = qt.t.getTargets();
for (TreeReference target : targets) {
if (mainInstance.getTemplate(target) != null) {
conditionRepeatTargetIndex.put(target, qt);
}
}
}
}
// printTriggerables();
}
Aggregations