Search in sources :

Example 1 with CodeTimer

use of org.javarosa.core.util.CodeTimer 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 CodeTimer

use of org.javarosa.core.util.CodeTimer in project javarosa by opendatakit.

the class XFormParser method getXMLDocument.

/**
 * Uses xkml to parse the provided XML content, and then consolidates text elements.
 *
 * @param reader      the XML content provider
 * @param stringCache an optional string cache, whose presence will cause the use of
 *                    {@link InterningKXmlParser} rather than {@link KXmlParser}.
 * @return the parsed document
 * @throws IOException
 * @deprecated The InterningKXmlParser is not used.
 */
@Deprecated
public static Document getXMLDocument(Reader reader, CacheTable<String> stringCache) throws IOException {
    final CodeTimer ctParse = new CodeTimer("Reading XML and parsing with kXML2");
    Document doc = new Document();
    try {
        KXmlParser parser;
        if (stringCache != null) {
            parser = new InterningKXmlParser(stringCache);
        } else {
            parser = new KXmlParser();
        }
        parser.setInput(reader);
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
        doc.parse(parser);
    } catch (XmlPullParserException e) {
        String errorMsg = "XML Syntax Error at Line: " + e.getLineNumber() + ", Column: " + e.getColumnNumber() + "!";
        Std.err.println(errorMsg);
        Std.printStack(e);
        throw new XFormParseException(errorMsg);
    } catch (IOException e) {
        // CTS - 12/09/2012 - Stop swallowing IO Exceptions
        throw e;
    } catch (Exception e) {
        // #if debug.output==verbose || debug.output==exception
        String errorMsg = "Unhandled Exception while Parsing XForm";
        Std.err.println(errorMsg);
        Std.printStack(e);
        throw new XFormParseException(errorMsg);
    // #endif
    }
    try {
        reader.close();
    } catch (IOException e) {
        Std.out.println("Error closing reader");
        Std.printStack(e);
    }
    ctParse.logDone();
    final CodeTimer ctConsolidate = new CodeTimer("Consolidating text");
    XmlTextConsolidator.consolidateText(stringCache, doc.getRootElement());
    ctConsolidate.logDone();
    return doc;
}
Also used : KXmlParser(org.kxml2.io.KXmlParser) InterningKXmlParser(org.javarosa.xform.util.InterningKXmlParser) InterningKXmlParser(org.javarosa.xform.util.InterningKXmlParser) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) IOException(java.io.IOException) Document(org.kxml2.kdom.Document) CodeTimer(org.javarosa.core.util.CodeTimer) UnfullfilledRequirementsException(org.javarosa.xml.util.UnfullfilledRequirementsException) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) InvalidStructureException(org.javarosa.xml.util.InvalidStructureException) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) IOException(java.io.IOException) PrototypeFactoryDeprecated(org.javarosa.core.util.externalizable.PrototypeFactoryDeprecated)

Example 3 with CodeTimer

use of org.javarosa.core.util.CodeTimer in project javarosa by opendatakit.

the class Localizer method getLocaleData.

/**
 * Get the set of mappings for a locale.
 *
 * @param locale Locale
 * @returns HashMap representing text mappings for this locale. Returns null if locale not defined or null.
 */
public OrderedMap<String, String> getLocaleData(String locale) {
    final CodeTimer codeTimer = new CodeTimer("getLocaleData");
    if (locale == null || !this.locales.contains(locale)) {
        return null;
    }
    // It's very important that any default locale contain the appropriate strings to localize the interface
    // for any possible language. As such, we'll keep around a table with only the default locale keys to
    // ensure that there are no localizations which are only present in another locale, which causes ugly
    // and difficult to trace errors.
    final OrderedMap<String, Boolean> defaultLocaleKeys = new OrderedMap<>();
    // This table will be loaded with the default values first (when applicable), and then with any
    // language specific translations overwriting the existing values.
    final OrderedMap<String, String> data = new OrderedMap<>();
    // the current locale to overwrite any differences between the two.
    if (fallbackDefaultLocale && defaultLocale != null) {
        for (LocaleDataSource defaultResource : localeResources.get(defaultLocale)) {
            loadTable(data, defaultResource.getLocalizedText());
        }
        for (String key : data.keySet()) {
            defaultLocaleKeys.put(key, Boolean.TRUE);
        }
    }
    for (LocaleDataSource resource : localeResources.get(locale)) {
        loadTable(data, resource.getLocalizedText());
    }
    // a locale that doesn't contain the key.
    if (fallbackDefaultLocale && defaultLocale != null) {
        StringBuilder missingKeys = new StringBuilder();
        int keysMissing = 0;
        for (String key : data.keySet()) {
            if (!defaultLocaleKeys.containsKey(key)) {
                missingKeys.append(key).append(",");
                keysMissing++;
            }
        }
        if (keysMissing > 0) {
            // Is there a good way to localize these exceptions?
            throw new NoLocalizedTextException("Error loading locale " + locale + ". There were " + keysMissing + " keys which were contained in this locale, but were not " + "properly registered in the default Locale. Any keys which are added to a locale should always " + "be added to the default locale to ensure appropriate functioning.\n" + "The missing translations were for the keys: " + missingKeys, missingKeys.toString(), defaultLocale);
        }
    }
    codeTimer.logDone();
    return data;
}
Also used : OrderedMap(org.javarosa.core.util.OrderedMap) CodeTimer(org.javarosa.core.util.CodeTimer) NoLocalizedTextException(org.javarosa.core.util.NoLocalizedTextException)

Aggregations

CodeTimer (org.javarosa.core.util.CodeTimer)3 IOException (java.io.IOException)2 InvalidStructureException (org.javarosa.xml.util.InvalidStructureException)2 UnfullfilledRequirementsException (org.javarosa.xml.util.UnfullfilledRequirementsException)2 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)2 FormDef (org.javarosa.core.model.FormDef)1 IFormElement (org.javarosa.core.model.IFormElement)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 TreeElement (org.javarosa.core.model.instance.TreeElement)1 NoLocalizedTextException (org.javarosa.core.util.NoLocalizedTextException)1 OrderedMap (org.javarosa.core.util.OrderedMap)1 PrototypeFactoryDeprecated (org.javarosa.core.util.externalizable.PrototypeFactoryDeprecated)1 InterningKXmlParser (org.javarosa.xform.util.InterningKXmlParser)1 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)1 KXmlParser (org.kxml2.io.KXmlParser)1 Document (org.kxml2.kdom.Document)1