Search in sources :

Example 6 with Condition

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

the class StandardBindAttributesProcessor method createBinding.

DataBinding createBinding(IXFormParserFunctions parserFunctions, FormDef formDef, Collection<String> usedAttributes, Collection<String> passedThroughAttributes, Element element) {
    final DataBinding binding = new DataBinding();
    binding.setId(element.getAttributeValue("", ID_ATTR));
    final String nodeset = element.getAttributeValue(null, NODESET_ATTR);
    if (nodeset == null) {
        throw new XFormParseException("XForm Parse: <bind> without nodeset", element);
    }
    IDataReference ref;
    try {
        ref = new XPathReference(nodeset);
    } catch (XPathException xpe) {
        throw new XFormParseException(xpe.getMessage());
    }
    ref = parserFunctions.getAbsRef(ref, formDef);
    binding.setReference(ref);
    binding.setDataType(getDataType(element.getAttributeValue(null, "type")));
    String xpathRel = element.getAttributeValue(null, "relevant");
    if (xpathRel != null) {
        if ("true()".equals(xpathRel)) {
            binding.relevantAbsolute = true;
        } else if ("false()".equals(xpathRel)) {
            binding.relevantAbsolute = false;
        } else {
            Condition c = buildCondition(xpathRel, "relevant", ref);
            c = (Condition) formDef.addTriggerable(c);
            binding.relevancyCondition = c;
        }
    }
    String xpathReq = element.getAttributeValue(null, "required");
    if (xpathReq != null) {
        if ("true()".equals(xpathReq)) {
            binding.requiredAbsolute = true;
        } else if ("false()".equals(xpathReq)) {
            binding.requiredAbsolute = false;
        } else {
            Condition c = buildCondition(xpathReq, "required", ref);
            c = (Condition) formDef.addTriggerable(c);
            binding.requiredCondition = c;
        }
    }
    String xpathRO = element.getAttributeValue(null, "readonly");
    if (xpathRO != null) {
        if ("true()".equals(xpathRO)) {
            binding.readonlyAbsolute = true;
        } else if ("false()".equals(xpathRO)) {
            binding.readonlyAbsolute = false;
        } else {
            Condition c = buildCondition(xpathRO, "readonly", ref);
            c = (Condition) formDef.addTriggerable(c);
            binding.readonlyCondition = c;
        }
    }
    final String xpathConstr = element.getAttributeValue(null, "constraint");
    if (xpathConstr != null) {
        try {
            binding.constraint = new XPathConditional(xpathConstr);
        } catch (XPathSyntaxException xse) {
            throw new XFormParseException("bind for " + nodeset + " contains invalid constraint expression [" + xpathConstr + "] " + xse.getMessage());
        }
        binding.constraintMessage = element.getAttributeValue(NAMESPACE_JAVAROSA, "constraintMsg");
    }
    final String xpathCalc = element.getAttributeValue(null, "calculate");
    if (xpathCalc != null) {
        Recalculate r;
        try {
            r = buildCalculate(xpathCalc, ref);
        } catch (XPathSyntaxException xpse) {
            throw new XFormParseException("Invalid calculate for the bind attached to \"" + nodeset + "\" : " + xpse.getMessage() + " in expression " + xpathCalc);
        }
        r = (Recalculate) formDef.addTriggerable(r);
        binding.calculate = r;
    }
    binding.setPreload(element.getAttributeValue(NAMESPACE_JAVAROSA, "preload"));
    binding.setPreloadParams(element.getAttributeValue(NAMESPACE_JAVAROSA, "preloadParams"));
    saveUnusedAttributes(binding, element, usedAttributes, passedThroughAttributes);
    return binding;
}
Also used : Condition(org.javarosa.core.model.condition.Condition) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) Recalculate(org.javarosa.core.model.condition.Recalculate) XPathException(org.javarosa.xpath.XPathException) IDataReference(org.javarosa.core.model.IDataReference) DataBinding(org.javarosa.core.model.DataBinding) XPathConditional(org.javarosa.xpath.XPathConditional) XPathReference(org.javarosa.model.xform.XPathReference)

Example 7 with Condition

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

the class FormDef method writeExternal.

/**
 * Writes the form definition object to the supplied stream.
 *
 * @param dos - the stream to write to.
 * @throws IOException
 */
@Override
public void writeExternal(DataOutputStream dos) throws IOException {
    ExtUtil.writeNumeric(dos, getID());
    ExtUtil.writeString(dos, ExtUtil.emptyIfNull(getName()));
    ExtUtil.write(dos, new ExtWrapNullable(getTitle()));
    ExtUtil.write(dos, new ExtWrapListPoly(getChildren()));
    ExtUtil.write(dos, getMainInstance());
    ExtUtil.write(dos, new ExtWrapNullable(localizer));
    List<Condition> conditions = dagImpl.getConditions();
    List<Recalculate> recalcs = dagImpl.getRecalculates();
    ExtUtil.write(dos, new ExtWrapList(conditions));
    ExtUtil.write(dos, new ExtWrapList(recalcs));
    ExtUtil.write(dos, new ExtWrapListPoly(outputFragments));
    ExtUtil.write(dos, new ExtWrapMap(submissionProfiles));
    // for support of multi-instance forms
    ExtUtil.write(dos, new ExtWrapMap(formInstances, new ExtWrapTagged()));
    ExtUtil.write(dos, new ExtWrapMap(eventListeners, new ExtWrapListPoly()));
    ExtUtil.write(dos, new ExtWrapListPoly(extensions));
}
Also used : Condition(org.javarosa.core.model.condition.Condition) ExtWrapListPoly(org.javarosa.core.util.externalizable.ExtWrapListPoly) Recalculate(org.javarosa.core.model.condition.Recalculate) ExtWrapTagged(org.javarosa.core.util.externalizable.ExtWrapTagged) ExtWrapMap(org.javarosa.core.util.externalizable.ExtWrapMap) ExtWrapList(org.javarosa.core.util.externalizable.ExtWrapList) ExtWrapNullable(org.javarosa.core.util.externalizable.ExtWrapNullable)

Example 8 with Condition

use of org.javarosa.core.model.condition.Condition 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;
}
Also used : Condition(org.javarosa.core.model.condition.Condition) IConditionExpr(org.javarosa.core.model.condition.IConditionExpr) TreeReference(org.javarosa.core.model.instance.TreeReference) XPathReference(org.javarosa.model.xform.XPathReference) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 9 with Condition

use of org.javarosa.core.model.condition.Condition 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();
}
Also used : Condition(org.javarosa.core.model.condition.Condition) TreeReference(org.javarosa.core.model.instance.TreeReference) ArrayList(java.util.ArrayList) Triggerable(org.javarosa.core.model.condition.Triggerable)

Example 10 with Condition

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

the class Safe2014DagImpl 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> newDestinationSet = new HashSet<QuickTriggerable>();
    for (QuickTriggerable qt : vertices) {
        HashSet<QuickTriggerable> deps = new HashSet<QuickTriggerable>();
        newDestinationSet.clear();
        fillTriggeredElements(mainInstance, evalContext, qt, deps, newDestinationSet);
        // 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 - so the order is fixed
        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)

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