Search in sources :

Example 1 with InvalidStructureException

use of org.javarosa.xml.util.InvalidStructureException 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();
}
Also used : AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) ExternalDataInstance.getPathIfExternalDataInstance(org.javarosa.core.model.instance.ExternalDataInstance.getPathIfExternalDataInstance) DataInstance(org.javarosa.core.model.instance.DataInstance) ExternalDataInstance(org.javarosa.core.model.instance.ExternalDataInstance) UnfullfilledRequirementsException(org.javarosa.xml.util.UnfullfilledRequirementsException) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) Element(org.kxml2.kdom.Element) IFormElement(org.javarosa.core.model.IFormElement) InvalidStructureException(org.javarosa.xml.util.InvalidStructureException) IOException(java.io.IOException) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) FormDef(org.javarosa.core.model.FormDef) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) FormInstance(org.javarosa.core.model.instance.FormInstance) CodeTimer(org.javarosa.core.util.CodeTimer)

Example 2 with InvalidStructureException

use of org.javarosa.xml.util.InvalidStructureException 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;
}
Also used : HashMap(java.util.HashMap) UncastData(org.javarosa.core.model.data.UncastData) InvalidStructureException(org.javarosa.xml.util.InvalidStructureException) TreeElement(org.javarosa.core.model.instance.TreeElement)

Aggregations

TreeElement (org.javarosa.core.model.instance.TreeElement)2 InvalidStructureException (org.javarosa.xml.util.InvalidStructureException)2 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 FormDef (org.javarosa.core.model.FormDef)1 IFormElement (org.javarosa.core.model.IFormElement)1 UncastData (org.javarosa.core.model.data.UncastData)1 AbstractTreeElement (org.javarosa.core.model.instance.AbstractTreeElement)1 DataInstance (org.javarosa.core.model.instance.DataInstance)1 ExternalDataInstance (org.javarosa.core.model.instance.ExternalDataInstance)1 ExternalDataInstance.getPathIfExternalDataInstance (org.javarosa.core.model.instance.ExternalDataInstance.getPathIfExternalDataInstance)1 FormInstance (org.javarosa.core.model.instance.FormInstance)1 CodeTimer (org.javarosa.core.util.CodeTimer)1 UnfullfilledRequirementsException (org.javarosa.xml.util.UnfullfilledRequirementsException)1 Element (org.kxml2.kdom.Element)1 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)1