use of org.javarosa.core.model.instance.InvalidReferenceException in project javarosa by opendatakit.
the class CompactInstanceWrapper method readTreeElement.
/**
* recursively read in a node of the instance, by filling out the template instance
* @param e
* @param ref
* @param in
* @param pf
* @throws IOException
* @throws DeserializationException
*/
private void readTreeElement(TreeElement e, DataInputStream in, PrototypeFactory pf) throws IOException, DeserializationException {
TreeElement templ = instance.getTemplatePath(e.getRef());
boolean isGroup = !templ.isLeaf();
if (isGroup) {
List<String> childTypes = new ArrayList<String>(templ.getNumChildren());
for (int i = 0; i < templ.getNumChildren(); i++) {
String childName = templ.getChildAt(i).getName();
if (!childTypes.contains(childName)) {
childTypes.add(childName);
}
}
for (int i = 0; i < childTypes.size(); i++) {
String childName = childTypes.get(i);
TreeReference childTemplRef = e.getRef().extendRef(childName, 0);
TreeElement childTempl = instance.getTemplatePath(childTemplRef);
boolean repeatable = childTempl.isRepeatable();
int n = ExtUtil.readInt(in);
boolean relevant = (n > 0);
if (!repeatable && n > 1) {
throw new DeserializationException("Detected repeated instances of a non-repeatable node");
}
if (repeatable) {
int mult = e.getChildMultiplicity(childName);
for (int j = mult - 1; j >= 0; j--) {
e.removeChild(childName, j);
}
for (int j = 0; j < n; j++) {
TreeReference dstRef = e.getRef().extendRef(childName, j);
try {
instance.copyNode(childTempl, dstRef);
} catch (InvalidReferenceException ire) {
// If there is an invalid reference, this is a malformed instance,
// so we'll throw a Deserialization exception.
TreeReference r = ire.getInvalidReference();
if (r == null) {
throw new DeserializationException("Null Reference while attempting to deserialize! " + ire.getMessage());
} else {
throw new DeserializationException("Invalid Reference while attemtping to deserialize! Reference: " + r.toString(true) + " | " + ire.getMessage());
}
}
TreeElement child = e.getChild(childName, j);
child.setRelevant(true);
readTreeElement(child, in, pf);
}
} else {
TreeElement child = e.getChild(childName, 0);
child.setRelevant(relevant);
if (relevant) {
readTreeElement(child, in, pf);
}
}
}
} else {
e.setValue((IAnswerData) ExtUtil.read(in, new ExtWrapAnswerData(e.getDataType())));
}
}
use of org.javarosa.core.model.instance.InvalidReferenceException in project javarosa by opendatakit.
the class FormInstanceParser method createMissingTemplates.
// if repeatables have no template node, duplicate first as template
private void createMissingTemplates(FormInstance instance, List<TreeReference> missingTemplates) {
// every ref is listed after a ref that could be its parent. checkRepeatsForTemplate currently behaves this way
for (TreeReference templRef : missingTemplates) {
final TreeReference firstMatch;
// make template ref generic and choose first matching node
final TreeReference ref = templRef.clone();
for (int j = 0; j < ref.size(); j++) {
ref.setMultiplicity(j, TreeReference.INDEX_UNBOUND);
}
final List<TreeReference> nodes = new EvaluationContext(instance).expandReference(ref);
if (nodes.size() == 0) {
// binding error; not a single node matches the repeat binding; will be reported later
continue;
} else {
firstMatch = nodes.get(0);
}
try {
instance.copyNode(firstMatch, templRef);
} catch (InvalidReferenceException e) {
reporter.warning(XFormParserReporter.TYPE_INVALID_STRUCTURE, "Could not create a default repeat template; this is almost certainly a homogeneity error! Your form will not work! (Failed on " + templRef.toString() + ")", null);
}
trimRepeatChildren(instance.resolveReference(templRef));
}
}
use of org.javarosa.core.model.instance.InvalidReferenceException 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.InvalidReferenceException in project javarosa by opendatakit.
the class FormEntryController method answerQuestion.
/**
* Attempts to save the answer at the specified FormIndex into the
* datamodel.
*
* @param index
* @param data
* @return OK if save was successful, error if a constraint was violated.
*/
public int answerQuestion(FormIndex index, IAnswerData data, boolean midSurvey) {
QuestionDef q = model.getQuestionPrompt(index).getQuestion();
if (model.getEvent(index) != FormEntryController.EVENT_QUESTION) {
throw new RuntimeException("Non-Question object at the form index.");
}
TreeElement element = model.getTreeElement(index);
boolean complexQuestion = q.isComplex();
boolean hasConstraints = false;
if (element.isRequired() && data == null) {
return ANSWER_REQUIRED_BUT_EMPTY;
} else if (!complexQuestion && !model.getForm().evaluateConstraint(index.getReference(), data)) {
return ANSWER_CONSTRAINT_VIOLATED;
} else if (!complexQuestion) {
commitAnswer(element, index, data, midSurvey);
return ANSWER_OK;
} else if (complexQuestion && hasConstraints) {
// TODO: itemsets: don't currently evaluate constraints for itemset/copy -- haven't figured out how handle it yet
throw new RuntimeException("Itemsets do not currently evaluate constraints. Your constraint will not work, please remove it before proceeding.");
} else {
try {
model.getForm().copyItemsetAnswer(q, element, data, midSurvey);
} catch (InvalidReferenceException ire) {
Std.printStack(ire);
throw new RuntimeException("Invalid reference while copying itemset answer: " + ire.getMessage());
}
return ANSWER_OK;
}
}
Aggregations