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