Search in sources :

Example 6 with XPathExpression

use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.

the class TreeReference method hashCode.

public int hashCode() {
    int hash = (Integer.valueOf(refLevel)).hashCode();
    for (int i = 0; i < size(); i++) {
        // NOTE(ctsims): It looks like this is only using Integer to
        // get the hashcode method, but that method
        // is just returning the int value, I think, so
        // this should potentially just be replaced by
        // an int.
        Integer mult = DataUtil.integer(getMultiplicity(i));
        if (i == 0 && mult.intValue() == INDEX_UNBOUND)
            mult = DataUtil.integer(0);
        hash ^= getName(i).hashCode();
        hash ^= mult.hashCode();
        List<XPathExpression> predicates = this.getPredicate(i);
        if (predicates == null) {
            continue;
        }
        int val = 0;
        for (XPathExpression xpe : predicates) {
            hash ^= val;
            hash ^= xpe.hashCode();
            ++val;
        }
    }
    return hash;
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression)

Example 7 with XPathExpression

use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.

the class XPathEvalTest method testEval.

private void testEval(String expr, FormInstance model, EvaluationContext ec, Object expected) {
    XPathExpression xpe = null;
    boolean exceptionExpected = (expected instanceof XPathException);
    if (ec == null) {
        ec = new EvaluationContext(model);
    }
    try {
        xpe = XPathParseTool.parseXPath(expr);
    } catch (XPathSyntaxException xpse) {
        System.out.println("Parsing " + expr + " failed with " + xpse.toString());
    }
    if (xpe == null) {
        fail("Null expression or syntax error");
    }
    try {
        Object result = xpe.eval(model, ec);
        if (exceptionExpected) {
            fail("Expected exception, expression : " + expr);
        } else if ((result instanceof Double && expected instanceof Double)) {
            if (!expected.equals(result)) {
                System.out.println(String.format("%s result %s differed from expected %s", expr, result, expected));
            }
            assertEquals((Double) expected, (Double) result, 1e-12);
        } else if (result instanceof XPathNodeset && expected instanceof XPathNodeset) {
            XPathNodeset expectedAsXPathNodeset = (XPathNodeset) expected;
            XPathNodeset resultAsXPathNodeset = (XPathNodeset) result;
            assertEquals(expectedAsXPathNodeset.size(), resultAsXPathNodeset.size());
            assertEquals(expectedAsXPathNodeset.getRefAt(0), resultAsXPathNodeset.getRefAt(0));
            assertEquals(expectedAsXPathNodeset.unpack(), resultAsXPathNodeset.unpack());
            assertEquals(expectedAsXPathNodeset.toArgList().length, resultAsXPathNodeset.toArgList().length);
            for (int i = 0; i < expectedAsXPathNodeset.toArgList().length; i++) {
                assertEquals(expectedAsXPathNodeset.toArgList()[i], resultAsXPathNodeset.toArgList()[i]);
            }
        } else {
            assertEquals(expected, result);
        }
    } catch (XPathException xpex) {
        if (!exceptionExpected) {
            fail("Unexpected exception: " + xpex);
        } else if (xpex.getClass() != expected.getClass()) {
            fail("Did not get expected exception type");
        }
    }
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) XPathException(org.javarosa.xpath.XPathException) XPathNodeset(org.javarosa.xpath.XPathNodeset) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext)

Example 8 with XPathExpression

use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.

the class XPathConditional method getTriggers.

private static void getTriggers(XPathExpression x, Set<TreeReference> v, TreeReference contextRef) {
    if (x instanceof XPathPathExpr) {
        TreeReference ref = ((XPathPathExpr) x).getReference();
        TreeReference contextualized = ref;
        if (contextRef != null) {
            contextualized = ref.contextualize(contextRef);
        }
        // TODO: It's possible we should just handle this the same way as "genericize". Not entirely clear.
        if (contextualized.hasPredicates()) {
            contextualized = contextualized.removePredicates();
        }
        v.add(contextualized);
        for (int i = 0; i < ref.size(); i++) {
            List<XPathExpression> predicates = ref.getPredicate(i);
            if (predicates == null) {
                continue;
            }
            // we can't generate this properly without an absolute reference
            if (!ref.isAbsolute()) {
                throw new IllegalArgumentException("can't get triggers for relative references");
            }
            TreeReference predicateContext = ref.getSubReference(i);
            for (XPathExpression predicate : predicates) {
                getTriggers(predicate, v, predicateContext);
            }
        }
    } else if (x instanceof XPathBinaryOpExpr) {
        getTriggers(((XPathBinaryOpExpr) x).a, v, contextRef);
        getTriggers(((XPathBinaryOpExpr) x).b, v, contextRef);
    } else if (x instanceof XPathUnaryOpExpr) {
        getTriggers(((XPathUnaryOpExpr) x).a, v, contextRef);
    } else if (x instanceof XPathFuncExpr) {
        XPathFuncExpr fx = (XPathFuncExpr) x;
        for (int i = 0; i < fx.args.length; i++) getTriggers(fx.args[i], v, contextRef);
    }
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) XPathPathExpr(org.javarosa.xpath.expr.XPathPathExpr) TreeReference(org.javarosa.core.model.instance.TreeReference) XPathFuncExpr(org.javarosa.xpath.expr.XPathFuncExpr) XPathBinaryOpExpr(org.javarosa.xpath.expr.XPathBinaryOpExpr) XPathUnaryOpExpr(org.javarosa.xpath.expr.XPathUnaryOpExpr)

Example 9 with XPathExpression

use of org.javarosa.xpath.expr.XPathExpression 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);
    }
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) ArrayList(java.util.ArrayList) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) TreeReference(org.javarosa.core.model.instance.TreeReference)

Example 10 with XPathExpression

use of org.javarosa.xpath.expr.XPathExpression in project collect by opendatakit.

the class ExternalAppsUtils method populateParameters.

public static void populateParameters(Intent intent, Map<String, String> exParams, TreeReference reference) throws ExternalParamsException {
    FormDef formDef = Collect.getInstance().getFormController().getFormDef();
    FormInstance formInstance = formDef.getInstance();
    EvaluationContext evaluationContext = new EvaluationContext(formDef.getEvaluationContext(), reference);
    if (exParams != null) {
        for (Map.Entry<String, String> paramEntry : exParams.entrySet()) {
            String paramEntryValue = paramEntry.getValue();
            try {
                Object result;
                if (paramEntryValue.startsWith("'")) {
                    // but not require an ending quote
                    if (paramEntryValue.endsWith("'")) {
                        result = paramEntryValue.substring(1, paramEntryValue.length() - 1);
                    } else {
                        result = paramEntryValue.substring(1, paramEntryValue.length());
                    }
                } else if (paramEntryValue.startsWith("/")) {
                    // treat this is an xpath
                    XPathPathExpr pathExpr = XPathReference.getPathExpr(paramEntryValue);
                    XPathNodeset xpathNodeset = pathExpr.eval(formInstance, evaluationContext);
                    result = XPathFuncExpr.unpack(xpathNodeset);
                } else if (paramEntryValue.equals("instanceProviderID()")) {
                    // instanceProviderID returns -1 if the current instance has not been
                    // saved to disk already
                    String path = Collect.getInstance().getFormController().getInstanceFile().getAbsolutePath();
                    String instanceProviderID = "-1";
                    Cursor c = new InstancesDao().getInstancesCursorForFilePath(path);
                    if (c != null && c.getCount() > 0) {
                        // should only ever be one
                        c.moveToFirst();
                        instanceProviderID = c.getString(c.getColumnIndex(InstanceColumns._ID));
                    }
                    if (c != null) {
                        c.close();
                    }
                    result = instanceProviderID;
                } else {
                    // treat this is a function
                    XPathExpression xpathExpression = XPathParseTool.parseXPath(paramEntryValue);
                    result = xpathExpression.eval(formInstance, evaluationContext);
                }
                if (result != null && result instanceof Serializable) {
                    intent.putExtra(paramEntry.getKey(), (Serializable) result);
                }
            } catch (Exception e) {
                throw new ExternalParamsException("Could not evaluate '" + paramEntryValue + "'", e);
            }
        }
    }
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) Serializable(java.io.Serializable) XPathPathExpr(org.javarosa.xpath.expr.XPathPathExpr) Cursor(android.database.Cursor) ExternalParamsException(org.odk.collect.android.exception.ExternalParamsException) ExternalParamsException(org.odk.collect.android.exception.ExternalParamsException) InstancesDao(org.odk.collect.android.dao.InstancesDao) FormDef(org.javarosa.core.model.FormDef) XPathNodeset(org.javarosa.xpath.XPathNodeset) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) FormInstance(org.javarosa.core.model.instance.FormInstance) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

XPathExpression (org.javarosa.xpath.expr.XPathExpression)14 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)6 XPathPathExpr (org.javarosa.xpath.expr.XPathPathExpr)5 EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)4 FormDef (org.javarosa.core.model.FormDef)3 TreeElement (org.javarosa.core.model.instance.TreeElement)3 XPathNodeset (org.javarosa.xpath.XPathNodeset)3 ArrayList (java.util.ArrayList)2 TreeReference (org.javarosa.core.model.instance.TreeReference)2 XPathException (org.javarosa.xpath.XPathException)2 XPathFuncExpr (org.javarosa.xpath.expr.XPathFuncExpr)2 SuppressLint (android.annotation.SuppressLint)1 Cursor (android.database.Cursor)1 TextView (android.widget.TextView)1 IOException (java.io.IOException)1 Serializable (java.io.Serializable)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 Vector (java.util.Vector)1