use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class FormInstanceParser method buildRepeatTree.
/**
* Builds a pseudo-data model tree that describes the repeat structure of the instance. The
* result is a FormInstance collapsed where all indexes are 0, and repeatable nodes are flagged as such.
* Ignores (invalid) repeats that bind outside the top-level instance data node. Returns null if no repeats.
*/
private static FormInstance buildRepeatTree(List<TreeReference> repeatRefs, String topLevelName) {
TreeElement root = new TreeElement(null, 0);
for (TreeReference repeatRef : repeatRefs) {
// check and see if this references a repeat from a non-main instance, if so, skip it
if (repeatRef.getInstanceName() != null) {
continue;
}
if (repeatRef.size() <= 1) {
// invalid repeat: binds too high. ignore for now and error will be raised in verifyBindings
continue;
}
TreeElement cur = root;
for (int j = 0; j < repeatRef.size(); j++) {
String name = repeatRef.getName(j);
TreeElement child = cur.getChild(name, 0);
if (child == null) {
child = new TreeElement(name, 0);
cur.addChild(child);
}
cur = child;
}
cur.setRepeatable(true);
}
return (root.getNumChildren() == 0) ? null : new FormInstance(root.getChild(topLevelName, TreeReference.DEFAULT_MULTIPLICITY));
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class FormEntryModel method isIndexRelevant.
/**
* Determine if the current FormIndex is relevant. Only relevant indexes
* should be returned when filling out a form.
*
* @param index
* @return true if current element at FormIndex is relevant
*/
public boolean isIndexRelevant(FormIndex index) {
TreeReference ref = form.getChildInstanceRef(index);
boolean isAskNewRepeat = (getEvent(index) == FormEntryController.EVENT_PROMPT_NEW_REPEAT);
boolean isRepeatJuncture = (getEvent(index) == FormEntryController.EVENT_REPEAT_JUNCTURE);
boolean relevant;
if (isAskNewRepeat) {
relevant = form.isRepeatRelevant(ref) && form.canCreateRepeat(ref, index);
// repeat junctures are still relevant if no new repeat can be created; that option
// is simply missing from the menu
} else if (isRepeatJuncture) {
relevant = form.isRepeatRelevant(ref);
} else {
TreeElement node = form.getMainInstance().resolveReference(ref);
// check instance flag first
relevant = node != null && node.isRelevant();
}
if (relevant) {
// if instance flag/condition says relevant, we still
// have to check the <group>/<repeat> hierarchy
FormIndex ancestorIndex = index;
while (!ancestorIndex.isTerminal()) {
// This should be safe now that the TreeReference is contained
// in the ancestor index itself
TreeElement ancestorNode = form.getMainInstance().resolveReference(ancestorIndex.getLocalReference());
if (!ancestorNode.isRelevant()) {
relevant = false;
break;
}
ancestorIndex = ancestorIndex.getNextLevel();
}
}
return relevant;
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class FormEntryModel method isIndexReadonly.
/**
* @param index
* @return true if the element at the specified index is read only
*/
public boolean isIndexReadonly(FormIndex index) {
if (index.isBeginningOfFormIndex() || index.isEndOfFormIndex())
return true;
TreeReference ref = form.getChildInstanceRef(index);
boolean isAskNewRepeat = (getEvent(index) == FormEntryController.EVENT_PROMPT_NEW_REPEAT || getEvent(index) == FormEntryController.EVENT_REPEAT_JUNCTURE);
if (isAskNewRepeat) {
return false;
} else {
TreeElement node = form.getMainInstance().resolveReference(ref);
return !node.isEnabled();
}
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class XFormsModule method registerModule.
public void registerModule() {
String[] classes = { "org.javarosa.model.xform.XPathReference", "org.javarosa.xpath.XPathConditional" };
PrototypeManager.registerPrototypes(classes);
PrototypeManager.registerPrototypes(XPathParseTool.xpathClasses);
RestoreUtils.xfFact = new IXFormyFactory() {
public TreeReference ref(String refStr) {
return FormInstance.unpackReference(new XPathReference(refStr));
}
public IDataPayload serializeInstance(FormInstance dm) {
try {
return (new XFormSerializingVisitor()).createSerializedPayload(dm);
} catch (IOException e) {
return null;
}
}
public FormInstance parseRestore(byte[] data, Class restorableType) {
return XFormParser.restoreDataModel(data, restorableType);
}
public IAnswerData parseData(String textVal, int dataType, TreeReference ref, FormDef f) {
return XFormAnswerDataParser.getAnswerData(textVal, dataType, XFormParser.ghettoGetQuestionDef(dataType, f, ref));
}
public String serializeData(IAnswerData data) {
return (String) (new XFormAnswerDataSerializer().serializeAnswerData(data));
}
public IConditionExpr refToPathExpr(TreeReference ref) {
return new XPathConditional(XPathPathExpr.fromRef(ref));
}
};
}
use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.
the class XPathPathExpr method eval.
public XPathNodeset eval(DataInstance m, EvaluationContext ec) {
TreeReference genericRef = getReference();
TreeReference ref;
if (genericRef.getContext() == TreeReference.CONTEXT_ORIGINAL) {
ref = genericRef.contextualize(ec.getOriginalContext());
} else {
ref = genericRef.contextualize(ec.getContextRef());
}
// check if this nodeset refers to a non-main instance
if (ref.getInstanceName() != null && ref.isAbsolute()) {
DataInstance nonMain = ec.getInstance(ref.getInstanceName());
if (nonMain != null) {
m = nonMain;
} else {
throw new XPathMissingInstanceException(ref.getInstanceName(), "Instance referenced by " + ref.toString(true) + " does not exist");
}
} else {
// TODO: We should really stop passing 'm' around and start just getting the right instance from ec
// at a more central level
m = ec.getMainInstance();
if (m == null) {
String refStr = ref == null ? "" : ref.toString(true);
throw new XPathException("Cannot evaluate the reference [" + refStr + "] in the current evaluation context. No default instance has been declared!");
}
}
// regardless of the above, we want to ensure there is a definition
if (m.getRoot() == null) {
// This instance is _declared_, but doesn't actually have any data in it.
throw new XPathMissingInstanceException(ref.getInstanceName(), "Instance referenced by " + ref.toString(true) + " has not been loaded");
}
// this makes no sense...
// if (ref.isAbsolute() && m.getTemplatePath(ref) == null) {
// List<TreeReference> nodesetRefs = new List<TreeReference>();
// return new XPathNodeset(nodesetRefs, m, ec);
// }
List<TreeReference> nodesetRefs = ec.expandReference(ref);
// to fix conditions based on non-relevant data, filter the nodeset by relevancy
for (int i = 0; i < nodesetRefs.size(); i++) {
if (!m.resolveReference(nodesetRefs.get(i)).isRelevant()) {
nodesetRefs.remove(i);
i--;
}
}
return new XPathNodeset(nodesetRefs, m, ec);
}
Aggregations