use of org.javarosa.core.model.instance.AbstractTreeElement in project javarosa by opendatakit.
the class XFormParser method parseDoc.
private void parseDoc(Map<String, String> namespacePrefixesByUri) {
final CodeTimer codeTimer = new CodeTimer("Creating FormDef from parsed XML");
_f = new FormDef();
initState();
final String defaultNamespace = _xmldoc.getRootElement().getNamespaceUri(null);
parseElement(_xmldoc.getRootElement(), _f, topLevelHandlers);
collapseRepeatGroups(_f);
final FormInstanceParser instanceParser = new FormInstanceParser(_f, defaultNamespace, reporter, bindings, repeats, itemsets, selectOnes, selectMultis, actionTargets);
// if this assumption is wrong, well, then we're screwed.
if (instanceNodes.size() > 1) {
for (int instanceIndex = 1; instanceIndex < instanceNodes.size(); instanceIndex++) {
final Element instance = instanceNodes.get(instanceIndex);
final String instanceId = instanceNodeIdStrs.get(instanceIndex);
final String ediPath = getPathIfExternalDataInstance(instance.getAttributeValue(null, "src"));
if (ediPath != null) {
try {
/* todo implement better error handling */
_f.addNonMainInstance(ExternalDataInstance.buildFromPath(ediPath, instanceId));
} catch (IOException | UnfullfilledRequirementsException | InvalidStructureException | XmlPullParserException e) {
e.printStackTrace();
}
} else {
FormInstance fi = instanceParser.parseInstance(instance, false, instanceNodeIdStrs.get(instanceNodes.indexOf(instance)), namespacePrefixesByUri);
// same situation as below
loadNamespaces(_xmldoc.getRootElement(), fi);
loadInstanceData(instance, fi.getRoot(), _f);
_f.addNonMainInstance(fi);
}
}
}
// now parse the main instance
if (mainInstanceNode != null) {
FormInstance fi = instanceParser.parseInstance(mainInstanceNode, true, instanceNodeIdStrs.get(instanceNodes.indexOf(mainInstanceNode)), namespacePrefixesByUri);
/*
Load namespaces definition (map of prefixes -> URIs) into a form instance so later it can be used
during the form instance serialization (XFormSerializingVisitor#visit). If the map is not present, then
serializer will provide own prefixes for the namespaces present in the nodes.
This will lead to inconsistency between prefixes used in the form definition (bindings)
and prefixes in the form instance after the instance is restored and inserted into the form definition.
*/
loadNamespaces(_xmldoc.getRootElement(), fi);
addMainInstanceToFormDef(mainInstanceNode, fi);
}
// Clear the caches, as these may not have been initialized
// entirely correctly during the validation steps.
Enumeration<DataInstance> e = _f.getNonMainInstances();
while (e.hasMoreElements()) {
DataInstance instance = e.nextElement();
final AbstractTreeElement treeElement = instance.getRoot();
if (treeElement instanceof TreeElement) {
((TreeElement) treeElement).clearChildrenCaches();
}
treeElement.clearCaches();
}
_f.getMainInstance().getRoot().clearChildrenCaches();
_f.getMainInstance().getRoot().clearCaches();
codeTimer.logDone();
}
use of org.javarosa.core.model.instance.AbstractTreeElement in project javarosa by opendatakit.
the class DataModelSerializer method serialize.
/*
* (non-Javadoc)
* @see org.javarosa.core.model.utils.ITreeVisitor#visit(org.javarosa.core.model.DataModelTree)
*/
public void serialize(DataInstance instance, TreeReference base) throws IOException {
// TODO: Namespaces?
AbstractTreeElement root;
if (base == null) {
root = instance.getRoot();
} else {
root = instance.resolveReference(base);
}
// write root
serializer.startTag(root.getNamespace(), root.getName());
for (int i = 0; i < root.getNumChildren(); i++) {
// write children
AbstractTreeElement childAt = root.getChildAt(i);
serializeNode(childAt);
}
// end root
serializer.endTag(root.getNamespace(), root.getName());
serializer.flush();
}
use of org.javarosa.core.model.instance.AbstractTreeElement in project javarosa by opendatakit.
the class EvaluationContext method expandReferenceAccumulator.
/**
* Recursively performs the search for all repeated nodes that match the pattern of the 'ref' argument.
*
* @param sourceRef original path we're matching against
* @param sourceInstance original node obtained from sourceRef
* @param workingRef explicit path that refers to the current node
* @param refs accumulator List to collect matching paths.
*/
private void expandReferenceAccumulator(TreeReference sourceRef, DataInstance sourceInstance, TreeReference workingRef, List<TreeReference> refs, boolean includeTemplates) {
final int depth = workingRef.size();
// check to see if we've matched fully
if (depth == sourceRef.size()) {
// TODO: Do we need to clone these references?
refs.add(workingRef);
return;
}
// Get the next set of matching references
final String name = sourceRef.getName(depth);
List<XPathExpression> predicates = sourceRef.getPredicate(depth);
// Copy predicates for batch fetch
if (predicates != null) {
List<XPathExpression> predCopy = new ArrayList<XPathExpression>(predicates.size());
for (XPathExpression xpe : predicates) {
predCopy.add(xpe);
}
predicates = predCopy;
}
// ETHERTON: Is this where we should test for predicates?
final int mult = sourceRef.getMultiplicity(depth);
final List<TreeReference> treeReferences = new ArrayList<>(1);
final AbstractTreeElement node = sourceInstance.resolveReference(workingRef);
if (node.getNumChildren() > 0) {
if (mult == TreeReference.INDEX_UNBOUND) {
final List<TreeElement> childrenWithName = node.getChildrenWithName(name);
final int count = childrenWithName.size();
for (int i = 0; i < count; i++) {
TreeElement child = childrenWithName.get(i);
if (child.getMultiplicity() != i) {
throw new IllegalStateException("Unexpected multiplicity mismatch");
}
treeReferences.add(child.getRef());
}
if (includeTemplates) {
AbstractTreeElement template = node.getChild(name, TreeReference.INDEX_TEMPLATE);
if (template != null) {
treeReferences.add(template.getRef());
}
}
} else if (mult != TreeReference.INDEX_ATTRIBUTE) {
// TODO: Make this test mult >= 0?
// If the multiplicity is a simple integer, just get
// the appropriate child
AbstractTreeElement child = node.getChild(name, mult);
if (child != null) {
treeReferences.add(child.getRef());
}
}
}
if (mult == TreeReference.INDEX_ATTRIBUTE) {
AbstractTreeElement attribute = node.getAttribute(null, name);
if (attribute != null) {
treeReferences.add(attribute.getRef());
}
}
if (predicates != null && predicateEvaluationProgress != null) {
predicateEvaluationProgress[1] += treeReferences.size();
}
if (predicates != null) {
boolean firstTime = true;
List<TreeReference> passed = new ArrayList<TreeReference>(treeReferences.size());
for (XPathExpression xpe : predicates) {
for (int i = 0; i < treeReferences.size(); ++i) {
// if there are predicates then we need to see if e.nextElement meets the standard of the predicate
TreeReference treeRef = treeReferences.get(i);
// test the predicate on the treeElement
EvaluationContext evalContext = rescope(treeRef, (firstTime ? treeRef.getMultLast() : i));
Object o = xpe.eval(sourceInstance, evalContext);
if (o instanceof Boolean) {
boolean testOutcome = (Boolean) o;
if (testOutcome) {
passed.add(treeRef);
}
}
}
firstTime = false;
treeReferences.clear();
treeReferences.addAll(passed);
passed.clear();
if (predicateEvaluationProgress != null) {
predicateEvaluationProgress[0]++;
}
}
}
for (TreeReference treeRef : treeReferences) {
expandReferenceAccumulator(sourceRef, sourceInstance, treeRef, refs, includeTemplates);
}
}
use of org.javarosa.core.model.instance.AbstractTreeElement in project javarosa by opendatakit.
the class Fast2014DagImpl method addChildrenOfElement.
// Recursive step of utility method
private void addChildrenOfElement(FormInstance mainInstance, EvaluationContext evalContext, AbstractTreeElement el, Set<TreeReference> toAdd, boolean expandRepeatables) {
TreeElement repeatTemplate = expandRepeatables ? mainInstance.getTemplatePath(el.getRef()) : null;
if (repeatTemplate != null) {
for (int i = 0; i < repeatTemplate.getNumChildren(); ++i) {
TreeElement child = repeatTemplate.getChildAt(i);
toAdd.add(child.getRef().genericize());
addChildrenOfElement(mainInstance, evalContext, child, toAdd, expandRepeatables);
}
} else {
for (int i = 0; i < el.getNumChildren(); ++i) {
AbstractTreeElement child = el.getChildAt(i);
toAdd.add(child.getRef().genericize());
addChildrenOfElement(mainInstance, evalContext, child, toAdd, expandRepeatables);
}
}
}
use of org.javarosa.core.model.instance.AbstractTreeElement in project javarosa by opendatakit.
the class Safe2014DagImpl method addChildrenOfElement.
// Recursive step of utility method
private void addChildrenOfElement(FormInstance mainInstance, EvaluationContext evalContext, AbstractTreeElement el, Set<TreeReference> toAdd, boolean expandRepeatables) {
TreeElement repeatTemplate = expandRepeatables ? mainInstance.getTemplatePath(el.getRef()) : null;
if (repeatTemplate != null) {
for (int i = 0; i < repeatTemplate.getNumChildren(); ++i) {
TreeElement child = repeatTemplate.getChildAt(i);
toAdd.add(child.getRef().genericize());
addChildrenOfElement(mainInstance, evalContext, child, toAdd, expandRepeatables);
}
} else {
for (int i = 0; i < el.getNumChildren(); ++i) {
AbstractTreeElement child = el.getChildAt(i);
toAdd.add(child.getRef().genericize());
addChildrenOfElement(mainInstance, evalContext, child, toAdd, expandRepeatables);
}
}
}
Aggregations