use of org.javarosa.core.model.instance.TreeElement 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.TreeElement 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;
}
}
use of org.javarosa.core.model.instance.TreeElement 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;
}
}
use of org.javarosa.core.model.instance.TreeElement in project javarosa by opendatakit.
the class FormEntryPrompt method getAnswerValue.
// note: code overlap with FormDef.copyItemsetAnswer
public IAnswerData getAnswerValue() {
QuestionDef q = getQuestion();
ItemsetBinding itemset = q.getDynamicChoices();
if (itemset != null) {
if (itemset.valueRef != null) {
List<SelectChoice> choices = getSelectChoices();
List<String> preselectedValues = new ArrayList<String>();
// determine which selections are already present in the answer
if (itemset.copyMode) {
TreeReference destRef = itemset.getDestRef().contextualize(mTreeElement.getRef());
List<TreeReference> subNodes = form.getEvaluationContext().expandReference(destRef);
for (int i = 0; i < subNodes.size(); i++) {
TreeElement node = form.getMainInstance().resolveReference(subNodes.get(i));
String value = itemset.getRelativeValue().evalReadable(form.getMainInstance(), new EvaluationContext(form.getEvaluationContext(), node.getRef()));
preselectedValues.add(value);
}
} else {
List<Selection> sels;
IAnswerData data = mTreeElement.getValue();
if (data instanceof SelectMultiData) {
sels = (List<Selection>) data.getValue();
} else if (data instanceof SelectOneData) {
sels = new ArrayList<Selection>(1);
sels.add((Selection) data.getValue());
} else {
sels = new ArrayList<Selection>(0);
}
for (int i = 0; i < sels.size(); i++) {
preselectedValues.add(sels.get(i).xmlValue);
}
}
// populate 'selection' with the corresponding choices (matching 'value') from the dynamic choiceset
List<Selection> selection = new ArrayList<Selection>();
for (int i = 0; i < preselectedValues.size(); i++) {
String value = preselectedValues.get(i);
SelectChoice choice = null;
for (int j = 0; j < choices.size(); j++) {
SelectChoice ch = choices.get(j);
if (value.equals(ch.getValue())) {
choice = ch;
break;
}
}
// will no longer be an option this go around
if (choice != null) {
selection.add(choice.selection());
}
}
// convert to IAnswerData
if (selection.size() == 0) {
return null;
} else if (q.getControlType() == Constants.CONTROL_SELECT_MULTI) {
return new SelectMultiData(selection);
} else if (q.getControlType() == Constants.CONTROL_SELECT_ONE) {
// do something if more than one selected?
return new SelectOneData(selection.get(0));
} else {
throw new RuntimeException("can't happen");
}
} else {
// cannot map up selections without <value>
return null;
}
} else {
// static choices
return mTreeElement.getValue();
}
}
use of org.javarosa.core.model.instance.TreeElement in project javarosa by opendatakit.
the class TreeElementParser method parse.
@Override
public TreeElement parse() throws InvalidStructureException, IOException, XmlPullParserException, UnfullfilledRequirementsException {
final int depth = parser.getDepth();
final TreeElement element = new TreeElement(parser.getName(), multiplicity);
element.setInstanceName(instanceId);
for (int i = 0; i < parser.getAttributeCount(); ++i) {
element.setAttribute(parser.getAttributeNamespace(i), parser.getAttributeName(i), parser.getAttributeValue(i));
}
final Map<String, Integer> multiplicitiesByName = new HashMap<>();
// loop parses all siblings at a given depth
while (parser.getDepth() >= depth) {
switch(nextNonWhitespace()) {
case KXmlParser.START_TAG:
String name = parser.getName();
final Integer multiplicity = multiplicitiesByName.get(name);
int newMultiplicity = (multiplicity != null) ? multiplicity + 1 : 0;
multiplicitiesByName.put(name, newMultiplicity);
TreeElement childTreeElement = new TreeElementParser(parser, newMultiplicity, instanceId).parse();
element.addChild(childTreeElement);
break;
case KXmlParser.END_TAG:
return element;
case KXmlParser.TEXT:
element.setValue(new UncastData(parser.getText().trim()));
break;
default:
throw new InvalidStructureException("Exception while trying to parse an XML Tree, got something other than tags and text", parser);
}
}
return element;
}
Aggregations