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);
}
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);
}
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);
}
Aggregations