Search in sources :

Example 46 with TreeReference

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

the class FormInstanceParser method verifyBindings.

private void verifyBindings(FormInstance instance, String mainInstanceNodeName) {
    // check <bind>s (can't bind to '/', bound nodes actually exist)
    for (int i = 0; i < bindings.size(); i++) {
        DataBinding bind = bindings.get(i);
        TreeReference ref = FormInstance.unpackReference(bind.getReference());
        if (ref.size() == 0) {
            Std.out.println("Cannot bind to '/'; ignoring bind...");
            bindings.remove(i);
            i--;
        } else {
            List<TreeReference> nodes = new EvaluationContext(instance).expandReference(ref, true);
            if (nodes.size() == 0) {
                reporter.warning(XFormParserReporter.TYPE_ERROR_PRONE, "<bind> defined for a node that doesn't exist [" + ref.toString() + "]. The node's name was probably changed and the bind should be updated. ", null);
            }
        }
    }
    // check <repeat>s (can't bind to '/' or '/data')
    for (TreeReference ref : getRepeatableRefs()) {
        if (ref.size() <= 1) {
            throw new XFormParseException("Cannot bind repeat to '/' or '/" + mainInstanceNodeName + "'");
        }
    }
    // check control/group/repeat bindings (bound nodes exist, question can't bind to '/')
    List<String> bindErrors = new ArrayList<>();
    verifyControlBindings(formDef, instance, bindErrors);
    if (bindErrors.size() > 0) {
        String errorMsg = "";
        for (String bindError : bindErrors) {
            errorMsg += bindError + "\n";
        }
        throw new XFormParseException(errorMsg);
    }
    // check that repeat members bind to the proper scope (not above the binding of the parent repeat, and not within any sub-repeat (or outside repeat))
    verifyRepeatMemberBindings(formDef, instance, null);
    // check that label/copy/value refs are children of nodeset ref, and exist
    verifyItemsetBindings(instance);
    verifyItemsetSrcDstCompatibility(instance);
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) DataBinding(org.javarosa.core.model.DataBinding) ArrayList(java.util.ArrayList) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) Constraint(org.javarosa.core.model.condition.Constraint)

Example 47 with TreeReference

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

the class FormInstanceParser method verifyControlBindings.

private void verifyControlBindings(IFormElement fe, FormInstance instance, List<String> errors) {
    // throws XmlPullParserException {
    if (fe.getChildren() == null)
        return;
    for (int i = 0; i < fe.getChildren().size(); i++) {
        IFormElement child = fe.getChildren().get(i);
        IDataReference ref = null;
        String type = null;
        if (child instanceof GroupDef) {
            ref = child.getBind();
            type = (((GroupDef) child).getRepeat() ? "Repeat" : "Group");
        } else if (child instanceof QuestionDef) {
            ref = child.getBind();
            type = "Question";
        }
        TreeReference tref = FormInstance.unpackReference(ref);
        if (child instanceof QuestionDef && tref.size() == 0) {
            // group can bind to '/'; repeat can't, but that's checked above
            reporter.warning(XFormParserReporter.TYPE_INVALID_STRUCTURE, "Cannot bind control to '/'", null);
        } else {
            List<TreeReference> nodes = new EvaluationContext(instance).expandReference(tref, true);
            if (nodes.size() == 0) {
                String error = type + " bound to non-existent node: [" + tref.toString() + "]";
                reporter.error(error);
                errors.add(error);
            }
        // we can't check whether questions map to the right kind of node ('data' node vs. 'sub-tree' node) as that depends
        // on the question's data type, which we don't know yet
        }
        verifyControlBindings(child, instance, errors);
    }
}
Also used : IFormElement(org.javarosa.core.model.IFormElement) IDataReference(org.javarosa.core.model.IDataReference) TreeReference(org.javarosa.core.model.instance.TreeReference) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) QuestionDef(org.javarosa.core.model.QuestionDef) Constraint(org.javarosa.core.model.condition.Constraint) GroupDef(org.javarosa.core.model.GroupDef)

Example 48 with TreeReference

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

the class FormInstanceParser method applyInstanceProperties.

private void applyInstanceProperties(FormInstance instance) {
    for (DataBinding bind : bindings) {
        final TreeReference ref = FormInstance.unpackReference(bind.getReference());
        final List<TreeReference> nodes = new EvaluationContext(instance).expandReference(ref, true);
        if (nodes.size() > 0) {
            attachBindGeneral(bind);
        }
        for (TreeReference nref : nodes) {
            attachBind(instance.resolveReference(nref), bind);
        }
    }
    applyControlProperties(instance);
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) DataBinding(org.javarosa.core.model.DataBinding) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext)

Example 49 with TreeReference

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

the class FormEntryModel method createModelIfNecessary.

/**
 * For the current index: Checks whether the index represents a node which
 * should exist given a non-interactive repeat, along with a count for that
 * repeat which is beneath the dynamic level specified.
 *
 * If this index does represent such a node, the new model for the repeat is
 * created behind the scenes and the index for the initial question is
 * returned.
 *
 * Note: This method will not prevent the addition of new repeat elements in
 * the interface, it will merely use the xforms repeat hint to create new
 * nodes that are assumed to exist
 *
 * @param index The index to be evaluated as to whether the underlying model is
 *        hinted to exist
 */
private void createModelIfNecessary(FormIndex index) {
    if (index.isInForm()) {
        IFormElement e = getForm().getChild(index);
        if (e instanceof GroupDef) {
            GroupDef g = (GroupDef) e;
            if (g.getRepeat() && g.getCountReference() != null) {
                // Lu Gram: repeat count XPath needs to be contextualized for nested repeat groups
                TreeReference countRef = FormInstance.unpackReference(g.getCountReference());
                TreeReference contextualized = countRef.contextualize(index.getReference());
                IAnswerData count = getForm().getMainInstance().resolveReference(contextualized).getValue();
                if (count != null) {
                    long fullcount = ((Integer) count.getValue()).intValue();
                    TreeReference ref = getForm().getChildInstanceRef(index);
                    TreeElement element = getForm().getMainInstance().resolveReference(ref);
                    if (element == null) {
                        if (index.getTerminal().getInstanceIndex() < fullcount) {
                            try {
                                getForm().createNewRepeat(index);
                            } catch (InvalidReferenceException ire) {
                                Std.printStack(ire);
                                throw new RuntimeException("Invalid Reference while creting new repeat!" + ire.getMessage());
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : IAnswerData(org.javarosa.core.model.data.IAnswerData) IFormElement(org.javarosa.core.model.IFormElement) TreeReference(org.javarosa.core.model.instance.TreeReference) GroupDef(org.javarosa.core.model.GroupDef) InvalidReferenceException(org.javarosa.core.model.instance.InvalidReferenceException) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 50 with TreeReference

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

the class FormEntryModel method setRepeatNextMultiplicity.

private boolean setRepeatNextMultiplicity(List<IFormElement> elements, List<Integer> multiplicities) {
    // find out if node is repeatable
    TreeReference nodeRef = form.getChildInstanceRef(elements, multiplicities);
    TreeElement node = form.getMainInstance().resolveReference(nodeRef);
    if (node == null || node.isRepeatable()) {
        // node == null if there are no instances of the repeat
        IFormElement lastElement = elements.get(elements.size() - 1);
        if (lastElement instanceof GroupDef && !((GroupDef) lastElement).getRepeat()) {
            // it's a regular group inside a repeatable group
            return false;
        }
        int mult;
        if (node == null) {
            // no repeats; next is 0
            mult = 0;
        } else {
            String name = node.getName();
            TreeElement parentNode = form.getMainInstance().resolveReference(nodeRef.getParentRef());
            mult = parentNode.getChildMultiplicity(name);
        }
        multiplicities.set(multiplicities.size() - 1, repeatStructure == REPEAT_STRUCTURE_NON_LINEAR ? TreeReference.INDEX_REPEAT_JUNCTURE : mult);
        return true;
    } else {
        return false;
    }
}
Also used : IFormElement(org.javarosa.core.model.IFormElement) TreeReference(org.javarosa.core.model.instance.TreeReference) GroupDef(org.javarosa.core.model.GroupDef) TreeElement(org.javarosa.core.model.instance.TreeElement)

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