Search in sources :

Example 1 with XPathException

use of org.javarosa.xpath.XPathException 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 2 with XPathException

use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.

the class XPathPathExpr method eval.

public XPathNodeset eval(DataInstance m, EvaluationContext ec) {
    TreeReference genericRef = getReference();
    TreeReference ref;
    if (genericRef.getContext() == TreeReference.CONTEXT_ORIGINAL) {
        ref = genericRef.contextualize(ec.getOriginalContext());
    } else {
        ref = genericRef.contextualize(ec.getContextRef());
    }
    // check if this nodeset refers to a non-main instance
    if (ref.getInstanceName() != null && ref.isAbsolute()) {
        DataInstance nonMain = ec.getInstance(ref.getInstanceName());
        if (nonMain != null) {
            m = nonMain;
        } else {
            throw new XPathMissingInstanceException(ref.getInstanceName(), "Instance referenced by " + ref.toString(true) + " does not exist");
        }
    } else {
        // TODO: We should really stop passing 'm' around and start just getting the right instance from ec
        // at a more central level
        m = ec.getMainInstance();
        if (m == null) {
            String refStr = ref == null ? "" : ref.toString(true);
            throw new XPathException("Cannot evaluate the reference [" + refStr + "] in the current evaluation context. No default instance has been declared!");
        }
    }
    // regardless of the above, we want to ensure there is a definition
    if (m.getRoot() == null) {
        // This instance is _declared_, but doesn't actually have any data in it.
        throw new XPathMissingInstanceException(ref.getInstanceName(), "Instance referenced by " + ref.toString(true) + " has not been loaded");
    }
    // this makes no sense...
    // if (ref.isAbsolute() && m.getTemplatePath(ref) == null) {
    // List<TreeReference> nodesetRefs = new List<TreeReference>();
    // return new XPathNodeset(nodesetRefs, m, ec);
    // }
    List<TreeReference> nodesetRefs = ec.expandReference(ref);
    // to fix conditions based on non-relevant data, filter the nodeset by relevancy
    for (int i = 0; i < nodesetRefs.size(); i++) {
        if (!m.resolveReference(nodesetRefs.get(i)).isRelevant()) {
            nodesetRefs.remove(i);
            i--;
        }
    }
    return new XPathNodeset(nodesetRefs, m, ec);
}
Also used : DataInstance(org.javarosa.core.model.instance.DataInstance) XPathException(org.javarosa.xpath.XPathException) TreeReference(org.javarosa.core.model.instance.TreeReference) XPathNodeset(org.javarosa.xpath.XPathNodeset) XPathMissingInstanceException(org.javarosa.xpath.XPathMissingInstanceException)

Example 3 with XPathException

use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.

the class StandardBindAttributesProcessor method createBinding.

DataBinding createBinding(IXFormParserFunctions parserFunctions, FormDef formDef, Collection<String> usedAttributes, Collection<String> passedThroughAttributes, Element element) {
    final DataBinding binding = new DataBinding();
    binding.setId(element.getAttributeValue("", ID_ATTR));
    final String nodeset = element.getAttributeValue(null, NODESET_ATTR);
    if (nodeset == null) {
        throw new XFormParseException("XForm Parse: <bind> without nodeset", element);
    }
    IDataReference ref;
    try {
        ref = new XPathReference(nodeset);
    } catch (XPathException xpe) {
        throw new XFormParseException(xpe.getMessage());
    }
    ref = parserFunctions.getAbsRef(ref, formDef);
    binding.setReference(ref);
    binding.setDataType(getDataType(element.getAttributeValue(null, "type")));
    String xpathRel = element.getAttributeValue(null, "relevant");
    if (xpathRel != null) {
        if ("true()".equals(xpathRel)) {
            binding.relevantAbsolute = true;
        } else if ("false()".equals(xpathRel)) {
            binding.relevantAbsolute = false;
        } else {
            Condition c = buildCondition(xpathRel, "relevant", ref);
            c = (Condition) formDef.addTriggerable(c);
            binding.relevancyCondition = c;
        }
    }
    String xpathReq = element.getAttributeValue(null, "required");
    if (xpathReq != null) {
        if ("true()".equals(xpathReq)) {
            binding.requiredAbsolute = true;
        } else if ("false()".equals(xpathReq)) {
            binding.requiredAbsolute = false;
        } else {
            Condition c = buildCondition(xpathReq, "required", ref);
            c = (Condition) formDef.addTriggerable(c);
            binding.requiredCondition = c;
        }
    }
    String xpathRO = element.getAttributeValue(null, "readonly");
    if (xpathRO != null) {
        if ("true()".equals(xpathRO)) {
            binding.readonlyAbsolute = true;
        } else if ("false()".equals(xpathRO)) {
            binding.readonlyAbsolute = false;
        } else {
            Condition c = buildCondition(xpathRO, "readonly", ref);
            c = (Condition) formDef.addTriggerable(c);
            binding.readonlyCondition = c;
        }
    }
    final String xpathConstr = element.getAttributeValue(null, "constraint");
    if (xpathConstr != null) {
        try {
            binding.constraint = new XPathConditional(xpathConstr);
        } catch (XPathSyntaxException xse) {
            throw new XFormParseException("bind for " + nodeset + " contains invalid constraint expression [" + xpathConstr + "] " + xse.getMessage());
        }
        binding.constraintMessage = element.getAttributeValue(NAMESPACE_JAVAROSA, "constraintMsg");
    }
    final String xpathCalc = element.getAttributeValue(null, "calculate");
    if (xpathCalc != null) {
        Recalculate r;
        try {
            r = buildCalculate(xpathCalc, ref);
        } catch (XPathSyntaxException xpse) {
            throw new XFormParseException("Invalid calculate for the bind attached to \"" + nodeset + "\" : " + xpse.getMessage() + " in expression " + xpathCalc);
        }
        r = (Recalculate) formDef.addTriggerable(r);
        binding.calculate = r;
    }
    binding.setPreload(element.getAttributeValue(NAMESPACE_JAVAROSA, "preload"));
    binding.setPreloadParams(element.getAttributeValue(NAMESPACE_JAVAROSA, "preloadParams"));
    saveUnusedAttributes(binding, element, usedAttributes, passedThroughAttributes);
    return binding;
}
Also used : Condition(org.javarosa.core.model.condition.Condition) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) Recalculate(org.javarosa.core.model.condition.Recalculate) XPathException(org.javarosa.xpath.XPathException) IDataReference(org.javarosa.core.model.IDataReference) DataBinding(org.javarosa.core.model.DataBinding) XPathConditional(org.javarosa.xpath.XPathConditional) XPathReference(org.javarosa.model.xform.XPathReference)

Example 4 with XPathException

use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.

the class XPathReference method getPathExpr.

public static XPathPathExpr getPathExpr(String nodeset) {
    XPathExpression path;
    boolean validNonPathExpr = false;
    try {
        path = XPathParseTool.parseXPath(nodeset);
        if (!(path instanceof XPathPathExpr)) {
            validNonPathExpr = true;
            throw new XPathSyntaxException();
        }
    } catch (XPathSyntaxException xse) {
        // make these checked exceptions?
        if (validNonPathExpr) {
            throw new XPathTypeMismatchException("Expected XPath path, got XPath expression: [" + nodeset + "]," + xse.getMessage());
        } else {
            Std.printStack(xse);
            throw new XPathException("Parse error in XPath path: [" + nodeset + "]." + (xse.getMessage() == null ? "" : "\n" + xse.getMessage()));
        }
    }
    return (XPathPathExpr) path;
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) XPathException(org.javarosa.xpath.XPathException) XPathPathExpr(org.javarosa.xpath.expr.XPathPathExpr) XPathTypeMismatchException(org.javarosa.xpath.XPathTypeMismatchException)

Example 5 with XPathException

use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.

the class FormDef method populateDynamicChoices.

/**
 * Identify the itemset in the backend model, and create a set of
 * SelectChoice objects at the current question reference based on the data
 * in the model.
 * <p/>
 * Will modify the itemset binding to contain the relevant choices
 *
 * @param itemset The binding for an itemset, where the choices will be populated
 * @param curQRef A reference to the current question's element, which will be
 *                used to determine the values to be chosen from.
 */
public void populateDynamicChoices(ItemsetBinding itemset, TreeReference curQRef) {
    getEventNotifier().publishEvent(new Event("Dynamic choices", new EvaluationResult(curQRef, null)));
    List<SelectChoice> choices = new ArrayList<SelectChoice>();
    List<TreeReference> matches = itemset.nodesetExpr.evalNodeset(this.getMainInstance(), new EvaluationContext(exprEvalContext, itemset.contextRef.contextualize(curQRef)));
    DataInstance fi = null;
    if (// We're not dealing
    itemset.nodesetRef.getInstanceName() != null) // with the default
    // instance
    {
        fi = getNonMainInstance(itemset.nodesetRef.getInstanceName());
        if (fi == null) {
            throw new XPathException("Instance " + itemset.nodesetRef.getInstanceName() + " not found");
        }
    } else {
        fi = getMainInstance();
    }
    if (matches == null) {
        throw new XPathException("Could not find references depended on by" + itemset.nodesetRef.getInstanceName());
    }
    for (int i = 0; i < matches.size(); i++) {
        TreeReference item = matches.get(i);
        // String label =
        // itemset.labelExpr.evalReadable(this.getMainInstance(), new
        // EvaluationContext(exprEvalContext, item));
        String label = itemset.labelExpr.evalReadable(fi, new EvaluationContext(exprEvalContext, item));
        String value = null;
        TreeElement copyNode = null;
        if (itemset.copyMode) {
            copyNode = this.getMainInstance().resolveReference(itemset.copyRef.contextualize(item));
        }
        if (itemset.valueRef != null) {
            // value = itemset.valueExpr.evalReadable(this.getMainInstance(),
            // new EvaluationContext(exprEvalContext, item));
            value = itemset.valueExpr.evalReadable(fi, new EvaluationContext(exprEvalContext, item));
        }
        // SelectChoice choice = new
        // SelectChoice(labelID,labelInnerText,value,isLocalizable);
        SelectChoice choice = new SelectChoice(label, value != null ? value : "dynamic:" + i, itemset.labelIsItext);
        choice.setIndex(i);
        if (itemset.copyMode)
            choice.copyNode = copyNode;
        choices.add(choice);
    }
    if (choices.size() == 0) {
        // throw new
        // RuntimeException("dynamic select question has no choices! [" +
        // itemset.nodesetRef + "]");
        // When you exit a survey mid way through and want to save it, it seems
        // that Collect wants to
        // go through all the questions. Well of course not all the questions
        // are going to have answers
        // to chose from if the user hasn't filled them out. So I'm just going
        // to make a note of this
        // and not throw an exception.
        Std.out.println("Dynamic select question has no choices! [" + itemset.nodesetRef + "]. If this occurs while filling out a form (and not while saving an incomplete form), the filter condition may have eliminated all the choices. Is that what you intended?\n");
    }
    itemset.clearChoices();
    itemset.setChoices(choices, this.getLocalizer());
}
Also used : DataInstance(org.javarosa.core.model.instance.DataInstance) XPathException(org.javarosa.xpath.XPathException) ArrayList(java.util.ArrayList) EvaluationResult(org.javarosa.debug.EvaluationResult) Constraint(org.javarosa.core.model.condition.Constraint) TreeElement(org.javarosa.core.model.instance.TreeElement) TreeReference(org.javarosa.core.model.instance.TreeReference) Event(org.javarosa.debug.Event) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext)

Aggregations

XPathException (org.javarosa.xpath.XPathException)6 TreeReference (org.javarosa.core.model.instance.TreeReference)3 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)3 EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)2 DataInstance (org.javarosa.core.model.instance.DataInstance)2 XPathNodeset (org.javarosa.xpath.XPathNodeset)2 XPathExpression (org.javarosa.xpath.expr.XPathExpression)2 ArrayList (java.util.ArrayList)1 DataBinding (org.javarosa.core.model.DataBinding)1 IDataReference (org.javarosa.core.model.IDataReference)1 QuickTriggerable (org.javarosa.core.model.QuickTriggerable)1 Condition (org.javarosa.core.model.condition.Condition)1 Constraint (org.javarosa.core.model.condition.Constraint)1 Recalculate (org.javarosa.core.model.condition.Recalculate)1 TreeElement (org.javarosa.core.model.instance.TreeElement)1 EvaluationResult (org.javarosa.debug.EvaluationResult)1 Event (org.javarosa.debug.Event)1 XPathReference (org.javarosa.model.xform.XPathReference)1 XPathConditional (org.javarosa.xpath.XPathConditional)1 XPathMissingInstanceException (org.javarosa.xpath.XPathMissingInstanceException)1