Search in sources :

Example 1 with XPathFuncExpr

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

the class ExternalDataUtil method getSearchXPathExpression.

public static XPathFuncExpr getSearchXPathExpression(String appearance) {
    if (appearance == null) {
        appearance = "";
    }
    appearance = appearance.trim();
    Matcher matcher = SEARCH_FUNCTION_REGEX.matcher(appearance);
    if (matcher.find()) {
        String function = matcher.group(0);
        try {
            XPathExpression xpathExpression = XPathParseTool.parseXPath(function);
            if (XPathFuncExpr.class.isAssignableFrom(xpathExpression.getClass())) {
                XPathFuncExpr xpathFuncExpr = (XPathFuncExpr) xpathExpression;
                if (xpathFuncExpr.id.name.equalsIgnoreCase(ExternalDataHandlerSearch.HANDLER_NAME)) {
                    // also check that the args are either 1, 4 or 6.
                    if (xpathFuncExpr.args.length == 1 || xpathFuncExpr.args.length == 4 || xpathFuncExpr.args.length == 6) {
                        return xpathFuncExpr;
                    } else {
                        Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_wrong_arguments_error), Toast.LENGTH_SHORT).show();
                        Timber.i(Collect.getInstance().getString(R.string.ext_search_wrong_arguments_error));
                        return null;
                    }
                } else {
                    // this might mean a problem in the regex above. Unit tests required.
                    Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_wrong_function_error, xpathFuncExpr.id.name), Toast.LENGTH_SHORT).show();
                    Timber.i(Collect.getInstance().getString(R.string.ext_search_wrong_function_error, xpathFuncExpr.id.name));
                    return null;
                }
            } else {
                // this might mean a problem in the regex above. Unit tests required.
                Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_bad_function_error, function), Toast.LENGTH_SHORT).show();
                Timber.i(Collect.getInstance().getString(R.string.ext_search_bad_function_error, function));
                return null;
            }
        } catch (XPathSyntaxException e) {
            Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_generic_error, appearance), Toast.LENGTH_SHORT).show();
            Timber.i(Collect.getInstance().getString(R.string.ext_search_generic_error, appearance));
            return null;
        }
    } else {
        return null;
    }
}
Also used : XPathExpression(org.javarosa.xpath.expr.XPathExpression) XPathSyntaxException(org.javarosa.xpath.parser.XPathSyntaxException) Matcher(java.util.regex.Matcher) XPathFuncExpr(org.javarosa.xpath.expr.XPathFuncExpr)

Example 2 with XPathFuncExpr

use of org.javarosa.xpath.expr.XPathFuncExpr 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 3 with XPathFuncExpr

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

the class ExternalAnswerResolver method resolveAnswer.

@Override
public IAnswerData resolveAnswer(String textVal, TreeElement treeElement, FormDef formDef) {
    QuestionDef questionDef = XFormParser.ghettoGetQuestionDef(treeElement.getDataType(), formDef, treeElement.getRef());
    if (questionDef != null && (questionDef.getControlType() == Constants.CONTROL_SELECT_ONE || questionDef.getControlType() == Constants.CONTROL_SELECT_MULTI)) {
        boolean containsSearchExpression = false;
        XPathFuncExpr xpathExpression = null;
        try {
            xpathExpression = ExternalDataUtil.getSearchXPathExpression(questionDef.getAppearanceAttr());
        } catch (Exception e) {
            Timber.e(e);
            // there is a search expression, but has syntax errors
            containsSearchExpression = true;
        }
        if (xpathExpression != null || containsSearchExpression) {
            // that means that we have dynamic selects
            // read the static choices from the options sheet
            List<SelectChoice> staticChoices = questionDef.getChoices();
            for (int index = 0; index < staticChoices.size(); index++) {
                SelectChoice selectChoice = staticChoices.get(index);
                String selectChoiceValue = selectChoice.getValue();
                if (ExternalDataUtil.isAnInteger(selectChoiceValue)) {
                    Selection selection = selectChoice.selection();
                    switch(questionDef.getControlType()) {
                        case Constants.CONTROL_SELECT_ONE:
                            {
                                if (selectChoiceValue.equals(textVal)) {
                                    // we just need to make sure, so we will override that.
                                    if (questionDef.getControlType() == Constants.CONTROL_SELECT_ONE) {
                                        // we don't need another, just return the static choice.
                                        return new SelectOneData(selection);
                                    }
                                }
                                break;
                            }
                        case Constants.CONTROL_SELECT_MULTI:
                            {
                                // we should search in a potential comma-separated string of
                                // values for a match
                                // copied from org.javarosa.xform.util.XFormAnswerDataParser
                                // .getSelections()
                                List<String> textValues = DateUtils.split(textVal, XFormAnswerDataSerializer.DELIMITER, true);
                                if (textValues.contains(textVal)) {
                                    // choice.
                                    if (selectChoiceValue.equals(textVal)) {
                                        // this means that the user selected ONLY the static
                                        // answer, so just return that
                                        List<Selection> customSelections = new ArrayList<Selection>();
                                        customSelections.add(selection);
                                        return new SelectMultiData(customSelections);
                                    } else {
                                    // we will ignore it for now since we will return that
                                    // selection together with the dynamic ones.
                                    }
                                }
                                break;
                            }
                        default:
                            {
                                // There is a bug if we get here, so let's throw an Exception
                                throw createBugRuntimeException(treeElement, textVal);
                            }
                    }
                } else {
                    switch(questionDef.getControlType()) {
                        case Constants.CONTROL_SELECT_ONE:
                            {
                                // the default implementation will search for the "textVal"
                                // (saved answer) inside the static choices.
                                // Since we know that there isn't such, we just wrap the textVal
                                // in a virtual choice in order to
                                // create a SelectOneData object to be used as the IAnswer to the
                                // TreeElement.
                                // (the caller of this function is searching for such an answer
                                // to populate the in-memory model.)
                                SelectChoice customSelectChoice = new SelectChoice(textVal, textVal, false);
                                customSelectChoice.setIndex(index);
                                return new SelectOneData(customSelectChoice.selection());
                            }
                        case Constants.CONTROL_SELECT_MULTI:
                            {
                                // we should create multiple selections and add them to the pile
                                List<SelectChoice> customSelectChoices = createCustomSelectChoices(textVal);
                                List<Selection> customSelections = new ArrayList<Selection>();
                                for (SelectChoice customSelectChoice : customSelectChoices) {
                                    customSelections.add(customSelectChoice.selection());
                                }
                                return new SelectMultiData(customSelections);
                            }
                        default:
                            {
                                // There is a bug if we get here, so let's throw an Exception
                                throw createBugRuntimeException(treeElement, textVal);
                            }
                    }
                }
            }
            // if we get there then that means that we have a bug
            throw createBugRuntimeException(treeElement, textVal);
        }
    }
    // default behavior matches original behavior (for static selects, etc.)
    return super.resolveAnswer(textVal, treeElement, formDef);
}
Also used : SelectOneData(org.javarosa.core.model.data.SelectOneData) SelectChoice(org.javarosa.core.model.SelectChoice) Selection(org.javarosa.core.model.data.helper.Selection) XPathFuncExpr(org.javarosa.xpath.expr.XPathFuncExpr) SelectMultiData(org.javarosa.core.model.data.SelectMultiData) ArrayList(java.util.ArrayList) List(java.util.List) QuestionDef(org.javarosa.core.model.QuestionDef)

Aggregations

XPathFuncExpr (org.javarosa.xpath.expr.XPathFuncExpr)3 XPathExpression (org.javarosa.xpath.expr.XPathExpression)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Matcher (java.util.regex.Matcher)1 QuestionDef (org.javarosa.core.model.QuestionDef)1 SelectChoice (org.javarosa.core.model.SelectChoice)1 SelectMultiData (org.javarosa.core.model.data.SelectMultiData)1 SelectOneData (org.javarosa.core.model.data.SelectOneData)1 Selection (org.javarosa.core.model.data.helper.Selection)1 TreeReference (org.javarosa.core.model.instance.TreeReference)1 XPathBinaryOpExpr (org.javarosa.xpath.expr.XPathBinaryOpExpr)1 XPathPathExpr (org.javarosa.xpath.expr.XPathPathExpr)1 XPathUnaryOpExpr (org.javarosa.xpath.expr.XPathUnaryOpExpr)1 XPathSyntaxException (org.javarosa.xpath.parser.XPathSyntaxException)1