Search in sources :

Example 1 with Condition

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

the class StandardBindAttributesProcessor method buildCondition.

private Condition buildCondition(String xpath, String type, IDataReference contextRef) {
    final int trueAction;
    final int falseAction;
    final String prettyType;
    switch(type) {
        case "relevant":
            prettyType = "display";
            trueAction = Condition.ACTION_SHOW;
            falseAction = Condition.ACTION_HIDE;
            break;
        case "required":
            prettyType = "require";
            trueAction = Condition.ACTION_REQUIRE;
            falseAction = Condition.ACTION_DONT_REQUIRE;
            break;
        case "readonly":
            prettyType = "readonly";
            trueAction = Condition.ACTION_DISABLE;
            falseAction = Condition.ACTION_ENABLE;
            break;
        default:
            throw new XFormParseException("Unsupported type " + type + " passed to buildCondition");
    }
    final XPathConditional xPathConditional;
    try {
        xPathConditional = new XPathConditional(xpath);
    } catch (XPathSyntaxException xse) {
        String errorMessage = "Encountered a problem with " + prettyType + " condition for node [" + contextRef.getReference().toString() + "] at line: " + xpath + ", " + xse.getMessage();
        reporter.error(errorMessage);
        throw new XFormParseException(errorMessage);
    }
    return new Condition(xPathConditional, trueAction, falseAction, FormInstance.unpackReference(contextRef));
}
Also used : Condition(org.javarosa.core.model.condition.Condition) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) XPathConditional(org.javarosa.xpath.XPathConditional)

Example 2 with Condition

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

the class Fast2014DagImpl 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
    // 
    ArrayList<QuickTriggerable> vertices = new ArrayList<QuickTriggerable>(unorderedTriggerables);
    triggerablesDAG.clear();
    ArrayList<QuickTriggerable[]> partialOrdering = new ArrayList<QuickTriggerable[]>();
    HashSet<QuickTriggerable> deps = new HashSet<QuickTriggerable>();
    HashSet<QuickTriggerable> newDestinationSet = new HashSet<QuickTriggerable>();
    for (QuickTriggerable qt : vertices) {
        deps.clear();
        newDestinationSet.clear();
        fillTriggeredElements(mainInstance, evalContext, qt, deps, newDestinationSet, true);
        // remove any self-reference if we have one...
        deps.remove(qt);
        for (QuickTriggerable qu : deps) {
            QuickTriggerable[] edge = { qt, qu };
            partialOrdering.add(edge);
        }
        // save for aggressive 2014 behavior
        qt.t.setImmediateCascades(deps);
    }
    ArrayList<QuickTriggerable> orderedRoots = new ArrayList<QuickTriggerable>();
    HashSet<QuickTriggerable> roots = new HashSet<QuickTriggerable>(vertices.size());
    int waveCount = -1;
    while (vertices.size() > 0) {
        ++waveCount;
        // 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) {
            String hints = "";
            for (QuickTriggerable qt : vertices) {
                for (TreeReference r : qt.t.getTargets()) {
                    hints += "\n" + r.toString(true);
                }
            }
            String message = "Cycle detected in form's relevant and calculation logic!";
            if (!hints.equals("")) {
                message += "\nThe following nodes are likely involved in the loop:" + hints;
            }
            throw new IllegalStateException(message);
        }
        // order the root nodes - mainly for clean textual diffs when
        // printing
        // When this code is rewritten to use HashSet, this will become
        // important.
        orderedRoots.clear();
        orderedRoots.addAll(roots);
        Collections.sort(orderedRoots, QuickTriggerable.quickTriggerablesRootOrdering);
        // add them to the triggerablesDAG.
        for (int i = 0; i < orderedRoots.size(); i++) {
            QuickTriggerable root = orderedRoots.get(i);
            root.t.setWaveCount(waveCount);
            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();
}
Also used : Condition(org.javarosa.core.model.condition.Condition) ArrayList(java.util.ArrayList) TreeReference(org.javarosa.core.model.instance.TreeReference) HashSet(java.util.HashSet)

Example 3 with Condition

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

the class FormDef method readExternal.

/**
 * Reads the form definition object from the supplied stream.
 * <p/>
 * Requires that the instance has been set to a prototype of the instance
 * that should be used for deserialization.
 *
 * @param dis - the stream to read from.
 * @throws IOException
 * @throws InstantiationException
 * @throws IllegalAccessException
 */
@Override
public void readExternal(DataInputStream dis, PrototypeFactory pf) throws IOException, DeserializationException {
    setID(ExtUtil.readInt(dis));
    setName(ExtUtil.nullIfEmpty(ExtUtil.readString(dis)));
    setTitle((String) ExtUtil.read(dis, new ExtWrapNullable(String.class), pf));
    setChildren((List<IFormElement>) ExtUtil.read(dis, new ExtWrapListPoly(), pf));
    setInstance((FormInstance) ExtUtil.read(dis, FormInstance.class, pf));
    setLocalizer((Localizer) ExtUtil.read(dis, new ExtWrapNullable(Localizer.class), pf));
    List<Condition> vcond = (List<Condition>) ExtUtil.read(dis, new ExtWrapList(Condition.class), pf);
    for (Condition condition : vcond) {
        addTriggerable(condition);
    }
    List<Recalculate> vcalc = (List<Recalculate>) ExtUtil.read(dis, new ExtWrapList(Recalculate.class), pf);
    for (Recalculate recalculate : vcalc) {
        addTriggerable(recalculate);
    }
    finalizeTriggerables();
    outputFragments = (List<IConditionExpr>) ExtUtil.read(dis, new ExtWrapListPoly(), pf);
    submissionProfiles = (HashMap<String, SubmissionProfile>) ExtUtil.read(dis, new ExtWrapMap(String.class, SubmissionProfile.class));
    formInstances = (HashMap<String, DataInstance>) ExtUtil.read(dis, new ExtWrapMap(String.class, new ExtWrapTagged()), pf);
    eventListeners = (HashMap<String, List<Action>>) ExtUtil.read(dis, new ExtWrapMap(String.class, new ExtWrapListPoly()), pf);
    extensions = (List<XFormExtension>) ExtUtil.read(dis, new ExtWrapListPoly(), pf);
    resetEvaluationContext();
}
Also used : Condition(org.javarosa.core.model.condition.Condition) IConditionExpr(org.javarosa.core.model.condition.IConditionExpr) DataInstance(org.javarosa.core.model.instance.DataInstance) Recalculate(org.javarosa.core.model.condition.Recalculate) ExtWrapTagged(org.javarosa.core.util.externalizable.ExtWrapTagged) ExtWrapMap(org.javarosa.core.util.externalizable.ExtWrapMap) Localizer(org.javarosa.core.services.locale.Localizer) ExtWrapListPoly(org.javarosa.core.util.externalizable.ExtWrapListPoly) List(java.util.List) ArrayList(java.util.ArrayList) ExtWrapList(org.javarosa.core.util.externalizable.ExtWrapList) ExtWrapList(org.javarosa.core.util.externalizable.ExtWrapList) ExtWrapNullable(org.javarosa.core.util.externalizable.ExtWrapNullable)

Example 4 with Condition

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

the class FormDef method isRepeatRelevant.

public boolean isRepeatRelevant(TreeReference repeatRef) {
    boolean relev = true;
    QuickTriggerable qc = dagImpl.getTriggerableForRepeatGroup(repeatRef.genericize());
    if (qc != null) {
        Condition c = (Condition) qc.t;
        relev = c.evalBool(mainInstance, new EvaluationContext(exprEvalContext, repeatRef));
    }
    // check the relevancy of the immediate parent
    if (relev) {
        TreeElement templNode = mainInstance.getTemplate(repeatRef);
        TreeReference parentPath = templNode.getParent().getRef().genericize();
        TreeElement parentNode = mainInstance.resolveReference(parentPath.contextualize(repeatRef));
        relev = parentNode.isRelevant();
    }
    return relev;
}
Also used : Condition(org.javarosa.core.model.condition.Condition) TreeReference(org.javarosa.core.model.instance.TreeReference) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 5 with Condition

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

the class April2014DagImpl 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();
    ArrayList<QuickTriggerable[]> partialOrdering = new ArrayList<QuickTriggerable[]>();
    for (int i = 0; i < unorderedTriggerables.size(); i++) {
        QuickTriggerable qt = unorderedTriggerables.get(i);
        ArrayList<QuickTriggerable> deps = new ArrayList<QuickTriggerable>();
        fillTriggeredElements(evalContext, qt, deps);
        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) {
            String hints = "";
            for (QuickTriggerable qt : vertices) {
                for (TreeReference r : qt.t.getTargets()) {
                    hints += "\n" + r.toString(true);
                }
            }
            String message = "Cycle detected in form's relevant and calculation logic!";
            if (!hints.equals("")) {
                message += "\nThe following nodes are likely involved in the loop:" + hints;
            }
            throw new IllegalStateException(message);
        }
        // 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();
}
Also used : Condition(org.javarosa.core.model.condition.Condition) TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList)

Aggregations

Condition (org.javarosa.core.model.condition.Condition)10 TreeReference (org.javarosa.core.model.instance.TreeReference)6 ArrayList (java.util.ArrayList)5 Recalculate (org.javarosa.core.model.condition.Recalculate)3 HashSet (java.util.HashSet)2 IConditionExpr (org.javarosa.core.model.condition.IConditionExpr)2 TreeElement (org.javarosa.core.model.instance.TreeElement)2 ExtWrapList (org.javarosa.core.util.externalizable.ExtWrapList)2 ExtWrapListPoly (org.javarosa.core.util.externalizable.ExtWrapListPoly)2 ExtWrapMap (org.javarosa.core.util.externalizable.ExtWrapMap)2 ExtWrapNullable (org.javarosa.core.util.externalizable.ExtWrapNullable)2 ExtWrapTagged (org.javarosa.core.util.externalizable.ExtWrapTagged)2 XPathReference (org.javarosa.model.xform.XPathReference)2 XPathConditional (org.javarosa.xpath.XPathConditional)2 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)2 List (java.util.List)1 DataBinding (org.javarosa.core.model.DataBinding)1 IDataReference (org.javarosa.core.model.IDataReference)1 EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)1 Triggerable (org.javarosa.core.model.condition.Triggerable)1