Search in sources :

Example 6 with DataBinding

use of org.javarosa.core.model.DataBinding in project javarosa by opendatakit.

the class XFormParser method parseGroup.

private void parseGroup(IFormElement parent, Element e, int groupType) {
    GroupDef group = new GroupDef();
    // until we come up with a better scheme
    group.setID(serialQuestionID++);
    IDataReference dataRef = null;
    boolean refFromBind = false;
    List<String> usedAtts = new ArrayList<>();
    usedAtts.add(REF_ATTR);
    usedAtts.add(NODESET_ATTR);
    usedAtts.add(BIND_ATTR);
    usedAtts.add(APPEARANCE_ATTR);
    usedAtts.add("count");
    usedAtts.add("noAddRemove");
    if (groupType == CONTAINER_REPEAT) {
        group.setRepeat(true);
    }
    String ref = e.getAttributeValue(null, REF_ATTR);
    String nodeset = e.getAttributeValue(null, NODESET_ATTR);
    String bind = e.getAttributeValue(null, BIND_ATTR);
    group.setAppearanceAttr(e.getAttributeValue(null, APPEARANCE_ATTR));
    if (bind != null) {
        DataBinding binding = bindingsByID.get(bind);
        if (binding == null) {
            throw new XFormParseException("XForm Parse: invalid binding ID [" + bind + "]", e);
        }
        dataRef = binding.getReference();
        refFromBind = true;
    } else {
        if (group.getRepeat()) {
            if (nodeset != null) {
                dataRef = new XPathReference(nodeset);
            } else {
                throw new XFormParseException("XForm Parse: <repeat> with no binding ('bind' or 'nodeset')", e);
            }
        } else {
            if (ref != null) {
                dataRef = new XPathReference(ref);
            } else if (nodeset != null) {
                dataRef = new XPathReference(nodeset);
            }
        // <group> not required to have a binding so no exception thrown
        }
    }
    if (!refFromBind) {
        dataRef = getAbsRef(dataRef, parent);
    }
    group.setBind(dataRef);
    if (group.getRepeat()) {
        repeats.add((TreeReference) dataRef.getReference());
        String countRef = e.getAttributeValue(NAMESPACE_JAVAROSA, "count");
        if (countRef != null) {
            group.count = getAbsRef(new XPathReference(countRef), parent);
            group.noAddRemove = true;
        } else {
            group.noAddRemove = (e.getAttributeValue(NAMESPACE_JAVAROSA, "noAddRemove") != null);
        }
    }
    for (int i = 0; i < e.getChildCount(); i++) {
        int type = e.getType(i);
        Element child = (type == Node.ELEMENT ? e.getElement(i) : null);
        String childName = (child != null ? child.getName() : null);
        String childNamespace = (child != null ? child.getNamespace() : null);
        if (group.getRepeat() && NAMESPACE_JAVAROSA.equals(childNamespace)) {
            if ("chooseCaption".equals(childName)) {
                group.chooseCaption = getLabel(child);
            } else if ("addCaption".equals(childName)) {
                group.addCaption = getLabel(child);
            } else if ("delCaption".equals(childName)) {
                group.delCaption = getLabel(child);
            } else if ("doneCaption".equals(childName)) {
                group.doneCaption = getLabel(child);
            } else if ("addEmptyCaption".equals(childName)) {
                group.addEmptyCaption = getLabel(child);
            } else if ("doneEmptyCaption".equals(childName)) {
                group.doneEmptyCaption = getLabel(child);
            } else if ("entryHeader".equals(childName)) {
                group.entryHeader = getLabel(child);
            } else if ("delHeader".equals(childName)) {
                group.delHeader = getLabel(child);
            } else if ("mainHeader".equals(childName)) {
                group.mainHeader = getLabel(child);
            }
        }
    }
    for (int i = 0; i < e.getChildCount(); i++) {
        if (e.getType(i) == Element.ELEMENT) {
            parseElement(e.getElement(i), group, groupLevelHandlers);
        }
    }
    // save all the unused attributes verbatim...
    for (int i = 0; i < e.getAttributeCount(); i++) {
        String name = e.getAttributeName(i);
        if (usedAtts.contains(name))
            continue;
        group.setAdditionalAttribute(e.getAttributeNamespace(i), name, e.getAttributeValue(i));
    }
    // print unused attribute warning message for parent element
    if (XFormUtils.showUnusedAttributeWarning(e, usedAtts)) {
        reporter.warning(XFormParserReporter.TYPE_UNKNOWN_MARKUP, XFormUtils.unusedAttWarning(e, usedAtts), getVagueLocation(e));
    }
    parent.addChild(group);
}
Also used : IDataReference(org.javarosa.core.model.IDataReference) DataBinding(org.javarosa.core.model.DataBinding) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) Element(org.kxml2.kdom.Element) IFormElement(org.javarosa.core.model.IFormElement) ArrayList(java.util.ArrayList) XPathReference(org.javarosa.model.xform.XPathReference) GroupDef(org.javarosa.core.model.GroupDef)

Example 7 with DataBinding

use of org.javarosa.core.model.DataBinding 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 8 with DataBinding

use of org.javarosa.core.model.DataBinding 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)

Aggregations

DataBinding (org.javarosa.core.model.DataBinding)8 IDataReference (org.javarosa.core.model.IDataReference)5 XPathReference (org.javarosa.model.xform.XPathReference)5 TreeReference (org.javarosa.core.model.instance.TreeReference)4 ArrayList (java.util.ArrayList)3 IFormElement (org.javarosa.core.model.IFormElement)2 EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)2 AbstractTreeElement (org.javarosa.core.model.instance.AbstractTreeElement)2 TreeElement (org.javarosa.core.model.instance.TreeElement)2 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)2 Element (org.kxml2.kdom.Element)2 Action (org.javarosa.core.model.Action)1 GroupDef (org.javarosa.core.model.GroupDef)1 QuestionDef (org.javarosa.core.model.QuestionDef)1 RangeQuestion (org.javarosa.core.model.RangeQuestion)1 SubmissionProfile (org.javarosa.core.model.SubmissionProfile)1 SetValueAction (org.javarosa.core.model.actions.SetValueAction)1 Condition (org.javarosa.core.model.condition.Condition)1 Constraint (org.javarosa.core.model.condition.Constraint)1 Recalculate (org.javarosa.core.model.condition.Recalculate)1